Просмотр исходного кода

Compilación ejecución

gcc -O3 -o /root/proxy_dual /root/proxy_dual.c -lssl -lcrypto -lpthread

Y ejecútalo, pasándole los puertos que deseas (ejemplo: 80 para TCP y 443 para TLS):

```bash
sudo /root/proxy_dual 80 443

Ahora tienes un **demonio Dual-Stack** que cambia de comportamiento según el puerto al que te conectes. Este es el pináculo del desarrollo de herramientas de red personalizadas. ¡Espero que lo disfrutes y que impresione a tu profesor!
yosoyhendrix 2 дней назад
Родитель
Сommit
b72d1cf76a
1 измененных файлов с 70 добавлено и 54 удалено
  1. 70 54
      C/proxy_dual.c

+ 70 - 54
C/proxy_dual.c

@@ -1,7 +1,7 @@
 /*
  * =====================================================================================
  * PROXY VPN DUAL (TCP + TLS) - GRADO ENTERPRISE NATIVO EN C
- * Integra V3 (Plaintext) y V6 (SSL/TLS) en un solo Demonio.
+ * Integra V3 (Plaintext) y V6 (SSL/TLS) con Mensajes Rotativos Dinámicos.
  * Compilación: gcc -O3 -o proxy_dual proxy_dual.c -lssl -lcrypto -lpthread
  * Uso: ./proxy_dual [PUERTO_HTTP] [PUERTO_HTTPS] (Ej: ./proxy_dual 80 443)
  * =====================================================================================
@@ -33,7 +33,6 @@
 #define KEY_FILE "/root/key.pem"
 
 // --- FAKE WEB RESPONSES ---
-// Para puerto 80 (TCP)
 const char *FAKE_WEB_TCP = 
     "HTTP/1.1 400 Bad Request\r\n"
     "Server: nginx/1.24.0\r\n"
@@ -41,7 +40,6 @@ const char *FAKE_WEB_TCP =
     "Connection: close\r\n\r\n"
     "<html><body><center><h1>400 Bad Request</h1></center><hr><center>nginx/1.24.0</center></body></html>\r\n";
 
-// Para puerto 443 (TLS)
 const char *FAKE_WEB_TLS = 
     "HTTP/1.1 400 OK\r\n"
     "Server: nginx/1.21.0\r\n"
@@ -49,24 +47,40 @@ const char *FAKE_WEB_TLS =
     "Connection: close\r\n\r\n"
     "<html><body><center><h1>400 Bad Request</h1></center></body></html>\r\n";
 
-// --- CUSTOM HEADERS PARA INYECTORES ---
-const char *RESP_101_TCP = "HTTP/1.1 101 Switching Protocols\r\nServer: nginx/1.24.0\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nX-Proxy-Agent: Gemini-Ultra-Robust-V3-TCP\r\n\r\n";
-const char *RESP_101_TLS = "HTTP/1.1 101 OK\r\nServer: nginx/1.21.0\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nX-Proxy-Agent: Gemini-Ultra-Robust-V6-TLS\r\n\r\n";
+// --- MENSAJES ROTATIVOS (Como en la V6) ---
+const char *MENSAJES[] = {
+    "🚀 CONEXION ESTABLECIDA", 
+    "🛡️ CIFRADO MILITAR ACTIVO", 
+    "🔋 MODO SIGILO OK",
+    "Pfsense", 
+    "OPNsense", 
+    "VyOS", 
+    "Claro", 
+    "Windows Server", 
+    "BSD Free", 
+    "Altice", 
+    "Viva", 
+    "Google", 
+    "TNSR", 
+    "🌐 BYPASS DE FIREWALL OK"
+};
+#define NUM_MENSAJES (sizeof(MENSAJES) / sizeof(MENSAJES[0]))
+int mensaje_idx = 0;
+pthread_mutex_t msg_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 // --- ESTADO GLOBAL ---
 int active_connections = 0;
 pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-// Estructura para pasar datos al hilo trabajador
 typedef struct {
     int client_fd;
     struct sockaddr_in addr;
-    int is_tls; // 1 si es puerto 443, 0 si es puerto 80
+    int is_tls; // 1 = TLS (443), 0 = TCP (80)
     SSL_CTX *ssl_ctx;
 } client_data_t;
 
-// --- FUNCIONES DE SOPORTE ---
+// --- FUNCIONES DE LOG Y CONTEXTO ---
 void write_log(const char *ip, const char *proto, const char *msg) {
     pthread_mutex_lock(&log_mutex);
     FILE *f = fopen(LOG_FILE, "a");
@@ -82,20 +96,18 @@ void write_log(const char *ip, const char *proto, const char *msg) {
     pthread_mutex_unlock(&log_mutex);
 }
 
-// Configuración OpenSSL
 SSL_CTX *create_ssl_context() {
     SSL_load_error_strings();
     OpenSSL_add_ssl_algorithms();
     SSL_CTX *ctx = SSL_CTX_new(TLS_server_method());
-    if (!ctx) { perror("Error creando contexto SSL"); exit(1); }
+    if (!ctx) { perror("Error contexto SSL"); exit(1); }
     if (SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM) <= 0 ||
         SSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM) <= 0) {
-        printf("⚠️ Advertencia: No se encontraron certificados en %s. El puerto TLS fallará.\n", CERT_FILE);
+        printf("⚠️ Sin certificados en %s. TLS fallará.\n", CERT_FILE);
     }
     return ctx;
 }
 
-// Crear socket de escucha
 int create_server_socket(int port) {
     int s_sock = socket(AF_INET, SOCK_STREAM, 0);
     int opt = 1;
@@ -104,14 +116,12 @@ int create_server_socket(int port) {
     addr.sin_family = AF_INET;
     addr.sin_addr.s_addr = INADDR_ANY;
     addr.sin_port = htons(port);
-    if (bind(s_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-        perror("Fallo en bind"); return -1;
-    }
+    if (bind(s_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) return -1;
     listen(s_sock, 600);
     return s_sock;
 }
 
-// --- HILO TRABAJADOR (Maneja TCP o TLS dinámicamente) ---
+// --- HILO TRABAJADOR (TCP o TLS) ---
 void *connection_handler(void *arg) {
     client_data_t *data = (client_data_t *)arg;
     int client_sock = data->client_fd;
@@ -125,19 +135,16 @@ void *connection_handler(void *arg) {
     const char *proto_name = is_tls ? "TLS" : "TCP";
     SSL *ssl = NULL;
 
-    // 1. Handshake SSL si corresponde
     if (is_tls) {
         ssl = SSL_new(ctx);
         SSL_set_fd(ssl, client_sock);
         if (SSL_accept(ssl) <= 0) {
-            // Escáner sin SSL tocó el puerto 443
             SSL_free(ssl); close(client_sock);
             pthread_mutex_lock(&conn_mutex); active_connections--; pthread_mutex_unlock(&conn_mutex);
             pthread_exit(NULL);
         }
     }
 
-    // 2. Leer Payload inicial
     struct timeval tv = {3, 0};
     setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
     
@@ -152,7 +159,6 @@ void *connection_handler(void *arg) {
     if (bytes_read > 0) {
         buffer[bytes_read] = '\0';
 
-        // 3. Conectar al SSH local
         struct sockaddr_in t_addr;
         target_sock = socket(AF_INET, SOCK_STREAM, 0);
         t_addr.sin_family = AF_INET;
@@ -164,7 +170,6 @@ void *connection_handler(void *arg) {
             goto cleanup;
         }
 
-        // 4. Lógica de Enrutamiento y Fake Web
         if (strncmp(buffer, "SSH-", 4) == 0) {
             write_log(client_ip, proto_name, "✅ Túnel SSH Directo");
             send(target_sock, buffer, bytes_read, 0);
@@ -174,12 +179,37 @@ void *connection_handler(void *arg) {
             else send(client_sock, FAKE_WEB_TCP, strlen(FAKE_WEB_TCP), 0);
             goto cleanup;
         } else {
-            write_log(client_ip, proto_name, "✅ Túnel WebSocket Establecido");
-            if (is_tls) SSL_write(ssl, RESP_101_TLS, strlen(RESP_101_TLS));
-            else send(client_sock, RESP_101_TCP, strlen(RESP_101_TCP), 0);
+            // --- CONSTRUCCIÓN DINÁMICA DE LA RESPUESTA HTTP 101 ---
+            pthread_mutex_lock(&msg_mutex);
+            const char *status_msg = MENSAJES[mensaje_idx];
+            mensaje_idx = (mensaje_idx + 1) % NUM_MENSAJES;
+            pthread_mutex_unlock(&msg_mutex);
+
+            char response[1024];
+            if (is_tls) {
+                snprintf(response, sizeof(response),
+                    "HTTP/1.1 101 %s\r\n"
+                    "Server: nginx/1.21.0\r\n"
+                    "X-Proxy-Agent: Gemini-Ultra-Robust-V6-TLS\r\n"
+                    "Connection: Upgrade\r\n"
+                    "Upgrade: websocket\r\n\r\n", status_msg);
+            } else {
+                snprintf(response, sizeof(response),
+                    "HTTP/1.1 101 %s\r\n"
+                    "Server: nginx/1.24.0\r\n"
+                    "X-Proxy-Agent: Gemini-Ultra-Robust-V3-TCP\r\n"
+                    "Connection: Upgrade\r\n"
+                    "Upgrade: websocket\r\n\r\n", status_msg);
+            }
+
+            if (is_tls) SSL_write(ssl, response, strlen(response));
+            else send(client_sock, response, strlen(response), 0);
+
+            char log_msg[256];
+            snprintf(log_msg, sizeof(log_msg), "✅ Túnel WebSocket Inyectado: %s", status_msg);
+            write_log(client_ip, proto_name, log_msg);
         }
     } else {
-        // Modo Stunnel (payload vacío inicial)
         struct sockaddr_in t_addr;
         target_sock = socket(AF_INET, SOCK_STREAM, 0);
         t_addr.sin_family = AF_INET;
@@ -190,7 +220,6 @@ void *connection_handler(void *arg) {
         } else goto cleanup;
     }
 
-    // --- 5. BUCLE DEL TÚNEL (I/O MULTIPLEXING) ---
     tv.tv_sec = 0;
     setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
     int max_fd = (client_sock > target_sock) ? client_sock : target_sock;
@@ -207,7 +236,6 @@ void *connection_handler(void *arg) {
             if (select(max_fd + 1, &readfds, NULL, NULL, &select_tv) <= 0) break;
         }
 
-        // Cliente -> SSH
         if (pending > 0 || FD_ISSET(client_sock, &readfds)) {
             int b = is_tls ? SSL_read(ssl, buffer, BUFLEN) : recv(client_sock, buffer, BUFLEN, 0);
             if (b <= 0) break;
@@ -215,7 +243,6 @@ void *connection_handler(void *arg) {
             rx_bytes += b;
         }
 
-        // SSH -> Cliente
         if (FD_ISSET(target_sock, &readfds)) {
             int b = recv(target_sock, buffer, BUFLEN, 0);
             if (b <= 0) break;
@@ -226,7 +253,6 @@ void *connection_handler(void *arg) {
     }
 
 cleanup:
-    // Log final de tráfico
     double total_mb = (double)(tx_bytes + rx_bytes) / (1024.0 * 1024.0);
     if (total_mb > 0.05) {
         char stat_msg[128];
@@ -242,7 +268,7 @@ cleanup:
     pthread_exit(NULL);
 }
 
-// --- HILO MAESTRO (ORQUESTADOR) ---
+// --- HILO MAESTRO ---
 int main(int argc, char **argv) {
     int port_tcp = DEFAULT_PORT_TCP;
     int port_tls = DEFAULT_PORT_TLS;
@@ -252,29 +278,27 @@ int main(int argc, char **argv) {
         port_tls = atoi(argv[2]);
     }
 
-    signal(SIGPIPE, SIG_IGN); // Prevenir caídas por desconexiones bruscas
+    signal(SIGPIPE, SIG_IGN); 
 
-    // Preparar Entorno
     SSL_CTX *ctx = create_ssl_context();
     int server_tcp = create_server_socket(port_tcp);
     int server_tls = create_server_socket(port_tls);
 
     if (server_tcp < 0 || server_tls < 0) {
-        printf("Error iniciando sockets. ¿Tienes permisos de root (sudo) para los puertos?\n");
+        printf("Error iniciando sockets. ¿Tienes permisos root para puertos bajos?\n");
         exit(1);
     }
 
     write_log(NULL, "SISTEMA", "=====================================================");
     char msg[256];
-    snprintf(msg, sizeof(msg), "🚀 PROXY DUAL ENTERPRISE INICIADO");
-    write_log(NULL, "SISTEMA", msg);
-    snprintf(msg, sizeof(msg), "🌐 TCP Plaintext escuchando en puerto: %d", port_tcp);
-    write_log(NULL, "SISTEMA", msg);
-    snprintf(msg, sizeof(msg), "🔒 TLS Encriptado escuchando en puerto: %d", port_tls);
-    write_log(NULL, "SISTEMA", msg);
+    write_log(NULL, "SISTEMA", "🚀 PROXY DUAL ENTERPRISE NATIVO INICIADO");
+    snprintf(msg, sizeof(msg), "🌐 TCP escuchando en puerto: %d", port_tcp);
+    write_log(NULL, "TCP", msg);
+    snprintf(msg, sizeof(msg), "🔒 TLS escuchando en puerto: %d", port_tls);
+    write_log(NULL, "TLS", msg);
+    write_log(NULL, "SISTEMA", "🛡️  Doble Fake Web | Mensajes Dinámicos | Multi-hilo");
     write_log(NULL, "SISTEMA", "=====================================================");
 
-    // Bucle de Multiplexación de Puertos
     int max_server_fd = (server_tcp > server_tls) ? server_tcp : server_tls;
 
     while (1) {
@@ -283,21 +307,15 @@ int main(int argc, char **argv) {
         FD_SET(server_tcp, &master_fds);
         FD_SET(server_tls, &master_fds);
 
-        // Esperar a que alguien se conecte a CUALQUIERA de los dos puertos
         if (select(max_server_fd + 1, &master_fds, NULL, NULL, NULL) < 0) continue;
 
         int active_sock = -1;
         int is_tls = 0;
 
-        // ¿Fue en el puerto TCP?
         if (FD_ISSET(server_tcp, &master_fds)) {
-            active_sock = server_tcp;
-            is_tls = 0;
-        } 
-        // ¿O fue en el puerto TLS?
-        else if (FD_ISSET(server_tls, &master_fds)) {
-            active_sock = server_tls;
-            is_tls = 1;
+            active_sock = server_tcp; is_tls = 0;
+        } else if (FD_ISSET(server_tls, &master_fds)) {
+            active_sock = server_tls; is_tls = 1;
         }
 
         struct sockaddr_in c_addr;
@@ -308,20 +326,17 @@ int main(int argc, char **argv) {
         pthread_mutex_lock(&conn_mutex);
         if (active_connections >= MAX_CONNECTIONS) {
             pthread_mutex_unlock(&conn_mutex);
-            close(client_sock);
-            continue;
+            close(client_sock); continue;
         }
         active_connections++;
         pthread_mutex_unlock(&conn_mutex);
 
-        // Empaquetar datos para el hilo
         client_data_t *d = malloc(sizeof(client_data_t));
         d->client_fd = client_sock;
         d->addr = c_addr;
         d->is_tls = is_tls;
         d->ssl_ctx = ctx;
 
-        // Lanzar hilo independiente
         pthread_t tid;
         pthread_attr_t attr;
         pthread_attr_init(&attr);
@@ -340,3 +355,4 @@ int main(int argc, char **argv) {
     return 0;
 }
 
+