segunda-feira, 17 de outubro de 2016

CyberSecurity 1 -Criação de Shellcode/payload


                         CyberSecurity 1 -Criação de Shellcode/payload

/*
 * Obrigado a todos que estiveram comigo até aqui.
 * S4n1 , X , Isc0rp10n , Kiritorange1920, Zod, Detr0id, Gohan, Cybermeme ...
 */

Booom , novamente se alguem acompanha esse blog ja viu que eu fiquei uns 2-3 dias sem postar nada ... motivo ? pura preguiça ( sorry ... ) bom ... eu decidi fazer esse post pra auxiliar em um futuro , que vocês teram que saber isso...

Então gravem essa bagaça nas suas grandes mentes ok ??!

OBS : Um conhecimento básico de assembly e C se faz necessário para o entendimento desse post ! Todo o conteudo apresentado aqui foi focado para usuários LINUX , é preciso ter o gcc e nasm instalado, caso você use windows msm sabendo que esse post é para usuários do linux, putss recomendo que você instale o "cygwin" pra auxiliar "na hora da prática"...

PS : Esse post não irá te ensinar a programar ... verifique se você contem os atributos citados no "OBS" acima !

É quase 1 da manhã e eu to escrevendo isso , mas foda-se!



--------------------------------------------------------------------------------


Agora vamos ao post ... primeiramente o'que é shellcode ( ou payload ) ...

Shellcode uma ordem de opcodes ( código de maquina ) em hexadecimal da arquitetura alvo 32/64 bits por exemplo , utilizados muito na exploração de vulnerabilidades de overflow/overruns para a execução de determinada tarefa ... pelo própio nome SHELLcode já diz que o objetivo principal disso ( ao menos a principio ) era abrir uma shell...

Tambem pode ser usado para outros fíns ... ae vai da sua imaginação!

--------------------------------------------------------------------------------

O'que vocês teram que ter em mente ? shellcode é basicamente o código de maquina que vocês iram pegar para injetar em um programa vulneravel a buffer overflow por exemplo ( existem outros tipos de overflows ) ...


--------------------------------------------------------------------------------

Agora que vocês sabem o'que é shellcode teram que saber algo... o maldito assembly ( temido por muitos haha ) ao menos um básico por favor ... bom ... levando em conta que você sabe ao menos um basico em assembly , vamos criar um programa na linguagem que apenas executa um exit e vamos gerar o shellcode desse mesmo programa !

Source abaixo :

<--code

section .data
section .text
global _start
mov eax,0x1
mov ebx,0x0
int 0x80

-->code

Bom , vocês ja sabem o'que isso faz ... vamos pular as explicações pra isso aqui não ficar muito grande ... se quiserem eu faço algo mais detalhado depois...

Temos o código o'que fazemos agora ? compilamos ora bolas !


$ nasm -f elf32 exploit.s
$ ld exploit.o -o exploit


Agora ja ta tudo feito ... como gerar o shellcode desse programa ? simples, vamos utilizar um recurso do linux chamado "objdump" ...

Basta digitarmos na linha de comando ...

$ objdump -d exploit

E você tera esse resultado :


exploit:     file format elf32-i386

Disassembly of section .text:

08048060 <_start>:
 8048060:    b8 01 00 00 00           mov    $0x1,%eax
 8048065:    bb 00 00 00 00           mov    $0x0,%ebx
 804806a:    cd 80                          int    $0x80

Bugou sua mente ??? bom ... vamos extrair o shellcode agora ...
Mas aonde ele ta ????

Alí ... são aqueles numeros em hexa ... b8 01 00 00 00 e por ae vai... só temos q copiar tudo isso na seguinte sintaxe ...

\xNUMERO

No nósso caso ...

"\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80"

Pronto , shellcode montado ? facil não ... mas calma ... não pare de ler isso ainda !


Vamos montar agora em C um exploit que execute esse treco...

Código abaixo ...

 <--code
/* Nome do programa : shell.c */
/* Coloque o shellcode dentro da variavel shellcode[]  */

char shellcode[] =  "\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80";
int main(void){
int (*f)() = (int(*)())shellcode;
f();
}
-->code

Nósso primeiro Shellcode !!!!!!



Pronto , agora basta compilar essa bagaça ...

$ gcc shell.c -o shell
$ ./shell
$

Agora se você compilou e executou viu que não aconteceu nada !
Porque ? Simples ... é isso que ele faz .. nada ! só fecha !


Saindo agora desse esquema vazio , vamos montar algo vísivel...
Vamos montar um programa que imprima algo na tela

<--code

;
; Nome do programa : exploit.s
;

section .data
section .text
global _start
_start:
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
push ebx
push 0x78696e75
push 0x2d6f646e
push 0x756d2061
push 0x6c6f
mov al,0x4
mov ecx,esp
mov bl,0x1
mov dx,16
int 0x80

mov al,0x1
mov bl,0x0
int 0x80


-->code

Vamos por partes agora ... porque essa "complexidade" no codigo ? bom , primeiramente ... porque o codigo mudou tanto ?

Bom , percebeu que no seu antigo shellcode continha alguns \x00 ? bom isso são os malditos "bytes nulos" ... bom eu não vou ficar falando muito disso, porque quero que dessa vez o post seja pequeno , o'que você tem que saber é , essa merda vai queimar seu shellcode ...

Precisamos retirar essa porcaria ... como faz ???

Primeiro , precisamos zerar o registrador ... utilizaremos a função xor pra isso!

No caso zeramos todos os registradores 32bits que normalmente iriamos usar.

xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx

Agora utilizamos push ebx

Para por na pilha o valor \0 que representa nulo ... isso é utilizado para expecificar o fim da string ...


push 0x78696e75
push 0x2d6f646e
push 0x756d2061
push 0x6c6f

Isso na verdade é a string convertida para os valores dos caracters que formão "Ola mundo-unix"... esses valores estão em hexadecimal como podem ver...

no caso isso ae separado fica...

0x78 0x69 0x6e 0x75
0x2d 0x6f 0x65 0x6e
0x6c 0x6f

Porque eu não coloquei toda a string "Ola mundo-unix" de uma unica vez na pilha ? porque não posso passar valores muito grandes pela função push ... então dividi ela por partes...

Junte tudo isso ae e cole num conversor de hexa pra ascii !

A mensagem "Ola mundo-unix" está de traz pra frente ! por causa do esquema de LIFO da pilha !

Ou seja, tu tem que escrever de traz pra frente na pilha , porq o ultimo dado colocado na pilha é o primeiro a sair ... ( parece confuso não ? )


--------------------------------------------------------------------------------

Bom depois disso precisamos mover nossos dados para areas baixas dos registradores ( os bits menos significativos ) ...

no caso todos os registradores que iremos usar, tem suas "partes menores"...

No caso do eax é o AX e do ax são o AL e AH ...

AL = Low
AH = Hight

Bom ae você ja consegue decorar a parte menor e maior ... nós iremos usar a menor , no caso AL ...

Iremos usar as partes menores de todos os registradores gerais basicos menos o CX ou ECX...

AX = AL
BX = BL
DX = DL

Bom , tendo isso em mente ( use apenas as partes menores dos registradores ... )

o resto do código é simples de se explicar ...

mov al,0x4
mov ecx,esp
mov bl,0x1
mov dx,16
int 0x80

mov al,0x1
mov bl,0x0
int 0x80

 --------------------------------------------------------------------------------

isso ae é como nós fizemos no post que eu fiz sobre assembly para i386... a conversão disso ae pra quele post fica ...

mov eax,0x4
mov ecx,esp
mov ebx,0x1
mov edx,16
int 0x80

mov eax,0x1
mov ebx,0x0
int 0x80

Mas e o mov ecx,esp ? O'que diabos isso faz ?

Simples ... se lembra nóssa mensagem na pilha ?

Se fossemos retira-la utilizando a função pop

Iriamos por somente o ultimo caracter em ecx , pois essa função tira apenas 1 caracter da pilha ... o ultimo no caso ...

o registrado ESP , aponta para a base da pilha ... ta ae o nome ESP ( Stack pointer )

Bom ... fingimos que todo o conteudo da pilha fica dentro do registrador stack ... então nossa string "Ola mundo-unix" ta dentro de esp certo ? então é isso !

Movemos essa bagaça pro ECX hehehe !

E assim a mágica acontece !

Simples não ???

Agora vamos compilar esse treco todo...

$ nasm -f elf32 exploit.s
$ ld exploit.o -o exploit
$ ./exploit
Ola mundo-unix$

Bom , como não ouve uma quebra de linha na string ...

Bom , logo agora vamos montar o shellcode disso ae e montar um hello world em shellcode hahaha


$ objdump -d exploit


exploit:     file format elf32-i386

Disassembly of section .text:
08048060 <_start>:
 8048060:    31 c0                    xor    %eax,%eax
 8048062:    31 db                    xor    %ebx,%ebx
 8048064:    31 c9                    xor    %ecx,%ecx
 8048066:    31 d2                    xor    %edx,%edx
 8048068:    53                       push   %ebx
 8048069:    68 75 6e 69 78           push   $0x78696e75
 804806e:    68 6e 64 6f 2d           push   $0x2d6f646e
 8048073:    68 61 20 6d 75           push   $0x756d2061
 8048078:    68 6f 6c 00 00           push   $0x6c6f
 804807d:    b0 04                    mov    $0x4,%al
 804807f:    89 e1                    mov    %esp,%ecx
 8048081:    b3 01                    mov    $0x1,%bl
 8048083:    66 ba 10 00              mov    $0x10,%dx
 8048087:    cd 80                    int    $0x80
 8048089:    b0 01                    mov    $0x1,%al
 804808b:    b3 00                    mov    $0x0,%bl
 804808d:    cd 80                    int    $0x80

 --------------------------------------------------------------------------------

Como percebeu , praticamente sumiram aquela cambada de 00 do shellcode ...

Tem 1 ou outro , mas ae é byte nulo da nóssa própia string :)

Vai ser cansativo montar esse treco ... mas vamos la...

Vamos aquele basico código em C pra executar nósso shellcode.

<--code

/* Nome do programa : shell.c */
/* Coloque o shellcode dentro da variavel shellcode[]  */

char shellcode[] =  "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x53\x68\x75\x6e\x69\x78\x68\x6e\x64\x6f\x2d\x68\x61\x20\x6d\x75\x68\x6f\x6c\x00\x00\xb0\x04\x89\xe1\xb3\x01\x66\xba\x10\x00\xcd\x80\xb0\x01\xb3\x00\xcd\x80";
int main(void){
int (*f)() = (int(*)())shellcode;
f();
}

-->code

Agora só compilar e executar ...

$ gcc shell.c -o shell
$ ./shell
Ola mundo-unix$

Bom , executou normalmente hehehe...

Não tem erros ... bom ... isso serve para qualquer código ...

Basta criar algo em assembly e dumpar os opcodes ... se lembre tambem de ritar os bytes nulos !

Vou ficando por aqui , não quero aprofundar o post tanto nisso , isso é mais uma humilde introdução ao assunto !

Notou algo errado ou incorreto nesse post ? Nos informe > Aqui!

Vou ficando por aqui ! Até um proximo post !

5 comentários:

Kasyade disse...

Boa manim ❤ by S4n1

Dion Makaveli disse...

hummmmmmmm

mundounix disse...

Vlw s4n1 e Zod hehe é nois...

Unknown disse...

Boa man <3

Unknown disse...

Bom post mano, tu poderia botar coisas falando de brechas simples que nos usuarios de pc que somos leigos podemos tomar cuidado e alguma smedidas preventivas

Postar um comentário

Tecnologia do Blogger.

Popular Posts