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ú

Mensajes - Kaxperday

#61
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.
#62
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.
#63
Hola ivancea,

Parece que ya está solucionado eramás bien un despiste, pues en HTTPSession al final de la función llamaba a WSACleanup() y por eso daba  el error de nonblocking sockets (que lo debería de llamar WSACleanup()) y tras desbloquear los sockets, desinicializaba winsock y tenía que llamar de nuevo a WSAStartup, así que ya sabeis poned igual numero de WSAStartup y de WSACleanup para no llevaros sustos XD.

Saludos y gracias por la respuesta.
#64
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.
#65
Supongo que querrás hacer como std::bitset solo que esa es una clase de C++.

Bueno yo crearía un BYTE que actuara como máscara y lo iría iterando en un bucle dandole los siguientes valores 00000001 00000010 00000100 ... hasta 10000000. Para calcular este BYTE iterador solo tienes que igualarlo a 0 cada iteracción del bucle y sumarle 2^i y lo tendrás, luego con el operador AND (&) lo compararía con cada BYTE del numero (habrá que comparar cada BYTE del número (para un int 4 bytes, para un float 4 bytes también..), y por cada resultado positivo imprimes un 1 en una cadena y sino un 0.

Comparas en orden e imprimes, algo como lo que hace geeke.

Saludos.
#66
Cita de: class_OpenGL en 12 Junio 2016, 02:07 AM
No estoy muy seguro, pero ¿y si haces flush?

Pues no iba tampoco, pero no importa ya que no me interesa mostrar la cadena.

Saludos y gracias a todos.
#67
Es lo que dice MCKSys Argentina, un futbolista puede vender perfectamente millones de camisetas (y cada camiseta vale entre 60 y 100 € dependiento si es de liga o de champions . Cada futbolista tiene sus derechos de imagen y cobra por cada camiseta que venda el club a su nombre, si valen unos 60 euros y venden millones (algunos) pues no se que parte se llevará el futbolista pero puedes ver que es mucho más de lo que gana un funcionario público.

En fin, por no hablar de lo que cobran por jugar en el club.. etc, cobran más porque son máquinas de generar dinero. Y un actor puede cobrar muchos millones por una película porque la ven millones de personas y pagan por ella, al repartir dividendos sale que gana mucho, al último james bond le ofrecieron unos 80 millones por hacer 2 peliculas james bond más y lo rechazó.

Saludos.
#68
Hola alberto gracias por la respuesta,

Es que estoy editando el tema mientras y bueno lo que hacía es pasar de string a vector<BYTE> y luego a string en este caso, el caso es que se pueden añadir a la string simplemente sin conversion como esta aunque con conversiones de más bytes también funcionarían, algo que se supone que ya sabía pero al pasarme el siguiente error pues busque fallos donde no tenía.

Lo que no entiendo porque la string me la devuelve nula:

Código (cpp) [Seleccionar]

std::string ArrayToString(std::vector<BYTE> data)
{
std::string ret;
std::cout << "Comienza la cadena:";
for (BYTE b : data)
{
ret += b;
}
std::cout << ret; system("pause");
return ret;
}


Código (cpp) [Seleccionar]

std::string fullMessage;
fullMessage = ArrayToString(data);
cout << fullMessage; system("pause");


:"DDD

Wow vuelve la magia, a veces funciona a veces no, a veces devuelve algo otras no¿? me parto XD.

Flipáis es por el system("pause") no me digáis como cohones influye en algo pero lo hace jajaja

Os lo prometo, pongo mostrar string + pause en la funcion y no devuelve nada, la muestro en la funcion (ponga o no pause) y la devuelve bien, jaja la magia. XD quizás sea por estar haciendo pruebas del servidor con el navegador, quizás en el tiempo que muestra la string en la funcion recibe nueva peticion y de alguna manera sobreescriba la anterior o algo así.

Bueno tema supongo :) , supongo que tendré que meditar más antes de postear porque ultimamente.. jajaja.
#69
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
#70
Mmm

Citar
Por ejemplo, si Properties fuera un map<string,string>, donde la clave fuera el nombre del header:
-Cuando vayas a colocar el host, primeor lo buscas. Si noe xiste, 1 de 2: o pones el que tu programa genera, o tiras error.

La pregunta es: Si la función va a tirar error, ¿para qué le quieres pasar un valor "nulo"? En caso de que no tires error por ello, ¿para qué comprobar? Utilizas los datos que existan, y no utilizas los datos que no existan.

La función no tiene porqué tirar error, no confundas con el otro tema, el hilo son 2 preguntas distintas, la primera pasar una CLASE vacia a una funcion y trabajar con ella, y la otra devolver una clase nula en caso de error en una función que devuelva una clase.

Resuelta la segunda pregunta que creo que la haré con punteros o con Clases como referencia (ya veré).

Respecto a la primera acertastes Properties es en este caso un vector de tuplas de 2 string cada uno (y si quizás debería haber usado un map (seguramente lo cambie hehehe)), pero puede ser cualquier clase nula que se envie como parametro (porque en ese caso no queremos usarla), pero en la funcion se usa, si esa funcion es nula saltamos ciertas cosas que se hacen en mi caso y se cambian variables pasadas por referencia, entonces es necesario saber antes de que eso ocurra que es nula, y en este caso la función no tiene métodos para ello como muchas otras, entonces que es recomendable para saer si es nula sin tener que ponerse a trabajar con la función... era la pregunta XD quizás lo habéis entendido quizás no XDD pero difícil creo que lo tenéis.

En fin, lo que dices ivancea es lo mejor (que al acceder a un metodo en plan get() si no lo tiene CONTINUA (no da error y sale ya que se ha llamado intencionadamente con ese parametro a nulo por algo), lo malo que depende del contexto que eso sea siempre así, y puede ser más conveniente a veces pasar un puntero y comprobar directamente a null, que sería la opción más favorable para esos casos en mi opinión.

Bueno espero que se haya entendido, principalmente quería responder la segunda pregunta y sugerís las alternativas que presenté así que no ando mal encaminado.

PD: He llegado a la conclusión que me aburría mucho el día que abrí este hilo (ayer) XD, me apetecería charlar de programación jajaja.

Saludos.