Hoy me ha entrado del vicio de escribir un shellcode, aquí queda el proceso para quien se pregunte como se escriben estos extraños seres de la fauna binaria.
Actualización: me había olvidado del BITS 32 en el shellcode para que funcione bien
Un shellcode, llamados así porque generalmente lo que hacían era presentar una shell (aunque se puede hacer cualquier cosa con ellos), son trozos de código ensamblador, normalmente pasados a formato hexadecimal para un "consumo" más cómodo, cuya característica más importante es que se pueden cargar en cualquier posición de memoria.
Mostrando entradas con la etiqueta shellcode. Mostrar todas las entradas
Mostrando entradas con la etiqueta shellcode. Mostrar todas las entradas
sábado, 11 de diciembre de 2010
Proceso de escritura de un shellcode
Etiquetas:
asm,
ensamblador,
nasm,
shellcode
lunes, 31 de mayo de 2010
Probando shellcodes
Pues hoy vengo con poca cosa, andaba escribiendo algo para pasar el rato... un programilla para probar shellcodes ¿porque no?
Y este es el resultado [ shellcode_tester.c ] o al final coloreado con Pygments
La compilacion es simple, solo hay que hacer
Las opciones al lanzarlo son:
Mas o menos, usarlo seria algo asi:
/*
* Shellcode Tester (Yet Another Shellcode Tester)
* Copyright (c) 2010 Kenkeiras
*
* DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
* Version 2, December 2004
*
* Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
*
* Everyone is permitted to copy and distribute verbatim or modified
* copies of this license document, and changing it is allowed as long
* as the name is changed.
*
* DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
* TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
*
* 0. You just DO WHAT THE FUCK YOU WANT TO.
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#define max_size 1024 //Caracteres maximos para el shellcode
// Como (sh en Gnu/Linux de 32 bits)
// \x31\xdb\x8d\x43\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80\x31\xc0\x40\xcd\x80
char *scs = NULL;
char *sc = NULL;
char a2h(char c){
char r;
if (c>'9'){
if (c>'Z')
r=c-0x57;
else
r=c-0x37;
}
else
r=c-0x30;
return r;
}
// Formas de leer los shellcode
// \x99\xAA\xaa (\x<numero en hexa>)
int bar_hexa(char *in,char *out){
char curr;
int i,r=-1,len=0;
for (i=0; (i < max_size) && in[i] != '\0'; i++){
if((r == 2) || ((in[i] == '\\') && (r > 0))){
r =- 1;
out[len] = curr;
len++;
}
if(in[i] == '\n'){
break;
}
else if (in[i] == '\r'){
continue;
}
else if (in[i] == 'x'){
r = 0;
}
else if(r >- 1){
if (r == 0){
curr = a2h(in[i])*16;
}
else{
curr = a2h(in[i]) + curr;
}
r++;
}
}
return len;
}
// Escrito directamente
int raw_bin(char *in,char *out){
int i,len=strlen(in);
for (i = 0;i < len;i++){
out[i] = in[i];
}
return len;
}
int main(int argc,char **argv){
FILE *f = stdin;
char verbose = 1;
char stack_write = 1;
char stack_read = 1;
int i,len,r;
sc=malloc(max_size+1);
if (argc>1){
for (i=1;i<argc;i++){
if ((strcmp(argv[i],"-nv") == 0) && (strcmp(argv[i],"--no-verbose") == 0)){
verbose = 0;
}
else if ((strcmp(argv[i],"-f") == 0) && ((i+1)<argc) ){
f = fopen(argv[i+1],"r");
i++;
}
else if ((strcmp(argv[i],"-nw") == 0) && (strcmp(argv[i],"--no-write") == 0)){
stack_write = 0;
}
else if ((strcmp(argv[i],"-nr") == 0) && (strcmp(argv[i],"--no-read") == 0)){
stack_read = 0;
}
else{
printf("Uso: ./shellcode_tester [-nv] [-nw] [-nr] [-f <archivo>]\n");
printf("-nv: No verbose (no se imprimira nada por pantalla)[--no-verbose]\n");
printf("-nw: No write (no se permitira escribir en la memoria del shellcode)[--no-write]\n");
printf("-nr: No read (no se permitira leer la memoria del shellcode)[--no-read]\n");
printf("-f: Introduce el shellcode a traves de un archivo\n");
}
}
}
int PROT_MODE = PROT_EXEC|PROT_NONE ;
if (stack_write){
PROT_MODE |= PROT_WRITE;
}
if (stack_read){
PROT_MODE |= PROT_READ;
}
if (verbose){
printf("\tShellcode Tester\n\n");
printf("Introduce el shellcode: ");
}
char *s = malloc((max_size*4)+1);
fgets(s,max_size*4,f);
r=-1;
len = bar_hexa(s,sc);
if (len < (strlen(s)/4)){
len = raw_bin(s,sc);
}
free(s);
scs=mmap(0,len+1,PROT_MODE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
for (i=0;i<len;i++){
scs[i]=sc[i];
}
free(sc);
if (verbose){
printf("\nEjecutando Shellcode... [%i]\n",len);
}
(*(void(*)()) scs)();
if (verbose){
printf("Fin del Shellcode\n");
}
return 0;
}
Hasta otra
Y este es el resultado [ shellcode_tester.c ] o al final coloreado con Pygments
La compilacion es simple, solo hay que hacer
gcc shellcode_tester.c -o shellcode_testerLas opciones al lanzarlo son:
./shellcode_tester [-nv] [-nw] [-nr] [-f <archivo>]
-nv: No verbose (no se imprimira nada por pantalla)[--no-verbose]
-nw: No write (no se permitira escribir en la memoria del shellcode)[--no-write]
-nr: No read (no se permitira leer la memoria del shellcode)[--no-read]
-f: Introduce el shellcode a traves de un archivoMas o menos, usarlo seria algo asi:
kenkeiras@viaxante:~/%%%%%$ ./shellcode_tester
Shellcode Tester
Introduce el shellcode: \x31\xdb\x8d\x43\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80\x31\xc0\x40\xcd\x80
Ejecutando Shellcode... [36]
$ echo "Esto es otra shell :D}"
Esto es otra shell :D}
$
kenkeiras@viaxante:~/%%%%%$/*
* Shellcode Tester (Yet Another Shellcode Tester)
* Copyright (c) 2010 Kenkeiras
*
* DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
* Version 2, December 2004
*
* Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
*
* Everyone is permitted to copy and distribute verbatim or modified
* copies of this license document, and changing it is allowed as long
* as the name is changed.
*
* DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
* TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
*
* 0. You just DO WHAT THE FUCK YOU WANT TO.
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#define max_size 1024 //Caracteres maximos para el shellcode
// Como (sh en Gnu/Linux de 32 bits)
// \x31\xdb\x8d\x43\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80\x31\xc0\x40\xcd\x80
char *scs = NULL;
char *sc = NULL;
char a2h(char c){
char r;
if (c>'9'){
if (c>'Z')
r=c-0x57;
else
r=c-0x37;
}
else
r=c-0x30;
return r;
}
// Formas de leer los shellcode
// \x99\xAA\xaa (\x<numero en hexa>)
int bar_hexa(char *in,char *out){
char curr;
int i,r=-1,len=0;
for (i=0; (i < max_size) && in[i] != '\0'; i++){
if((r == 2) || ((in[i] == '\\') && (r > 0))){
r =- 1;
out[len] = curr;
len++;
}
if(in[i] == '\n'){
break;
}
else if (in[i] == '\r'){
continue;
}
else if (in[i] == 'x'){
r = 0;
}
else if(r >- 1){
if (r == 0){
curr = a2h(in[i])*16;
}
else{
curr = a2h(in[i]) + curr;
}
r++;
}
}
return len;
}
// Escrito directamente
int raw_bin(char *in,char *out){
int i,len=strlen(in);
for (i = 0;i < len;i++){
out[i] = in[i];
}
return len;
}
int main(int argc,char **argv){
FILE *f = stdin;
char verbose = 1;
char stack_write = 1;
char stack_read = 1;
int i,len,r;
sc=malloc(max_size+1);
if (argc>1){
for (i=1;i<argc;i++){
if ((strcmp(argv[i],"-nv") == 0) && (strcmp(argv[i],"--no-verbose") == 0)){
verbose = 0;
}
else if ((strcmp(argv[i],"-f") == 0) && ((i+1)<argc) ){
f = fopen(argv[i+1],"r");
i++;
}
else if ((strcmp(argv[i],"-nw") == 0) && (strcmp(argv[i],"--no-write") == 0)){
stack_write = 0;
}
else if ((strcmp(argv[i],"-nr") == 0) && (strcmp(argv[i],"--no-read") == 0)){
stack_read = 0;
}
else{
printf("Uso: ./shellcode_tester [-nv] [-nw] [-nr] [-f <archivo>]\n");
printf("-nv: No verbose (no se imprimira nada por pantalla)[--no-verbose]\n");
printf("-nw: No write (no se permitira escribir en la memoria del shellcode)[--no-write]\n");
printf("-nr: No read (no se permitira leer la memoria del shellcode)[--no-read]\n");
printf("-f: Introduce el shellcode a traves de un archivo\n");
}
}
}
int PROT_MODE = PROT_EXEC|PROT_NONE ;
if (stack_write){
PROT_MODE |= PROT_WRITE;
}
if (stack_read){
PROT_MODE |= PROT_READ;
}
if (verbose){
printf("\tShellcode Tester\n\n");
printf("Introduce el shellcode: ");
}
char *s = malloc((max_size*4)+1);
fgets(s,max_size*4,f);
r=-1;
len = bar_hexa(s,sc);
if (len < (strlen(s)/4)){
len = raw_bin(s,sc);
}
free(s);
scs=mmap(0,len+1,PROT_MODE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
for (i=0;i<len;i++){
scs[i]=sc[i];
}
free(sc);
if (verbose){
printf("\nEjecutando Shellcode... [%i]\n",len);
}
(*(void(*)()) scs)();
if (verbose){
printf("Fin del Shellcode\n");
}
return 0;
}
Hasta otra
Etiquetas:
C,
pasando el rato,
pentesting,
shellcode
Suscribirse a:
Entradas (Atom)