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:
Boa manim ❤ by S4n1
hummmmmmmm
Vlw s4n1 e Zod hehe é nois...
Boa man <3
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