Move command registry from components/command/ into components/core/. New modules: mod_canbus, mod_honeypot, mod_fallback, mod_redteam, mod_ota. Replace mod_proxy with tun_core (multiplexed SOCKS5 tunnel). Kconfig extended with per-module settings and async worker config.
107 lines
3.6 KiB
C
107 lines
3.6 KiB
C
/*
|
|
* svc_http.c
|
|
* HTTP honeypot handler — request logging + POST body capture.
|
|
* Serves a fake login page to capture credentials.
|
|
*/
|
|
#include "sdkconfig.h"
|
|
|
|
#ifdef CONFIG_MODULE_HONEYPOT
|
|
|
|
#include "svc_common.h"
|
|
|
|
/* Extract server name from NVS banner (e.g. "Apache/2.4.54 (Ubuntu)") */
|
|
static void extract_server_name(char *out, size_t out_len)
|
|
{
|
|
char banner[128];
|
|
hp_config_get_banner("http", banner, sizeof(banner));
|
|
|
|
/* Banner format: "HTTP/1.1 200 OK\r\nServer: Apache/2.4.54 (Ubuntu)\r\n" */
|
|
char *srv = strstr(banner, "Server: ");
|
|
if (srv) {
|
|
srv += 8;
|
|
char *end = strstr(srv, "\r\n");
|
|
size_t len = end ? (size_t)(end - srv) : strlen(srv);
|
|
if (len >= out_len) len = out_len - 1;
|
|
memcpy(out, srv, len);
|
|
out[len] = '\0';
|
|
} else {
|
|
snprintf(out, out_len, "Apache/2.4.54");
|
|
}
|
|
}
|
|
|
|
/* Login page body */
|
|
static const char LOGIN_PAGE[] =
|
|
"<html><head><title>Admin Panel</title>"
|
|
"<style>body{font-family:sans-serif;background:#f0f0f0;display:flex;"
|
|
"justify-content:center;align-items:center;height:100vh;margin:0}"
|
|
".box{background:#fff;padding:2rem;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.2)}"
|
|
"input{display:block;margin:0.5rem 0;padding:0.4rem;width:200px}"
|
|
"button{padding:0.5rem 1rem;cursor:pointer}</style></head>"
|
|
"<body><div class='box'><h2>Authentication Required</h2>"
|
|
"<form method='POST' action='/login'>"
|
|
"<input name='user' placeholder='Username'>"
|
|
"<input name='pass' type='password' placeholder='Password'>"
|
|
"<button type='submit'>Login</button>"
|
|
"</form></div></body></html>";
|
|
|
|
void handle_http_client(int client_fd, const char *client_ip,
|
|
uint16_t client_port, hp_svc_desc_t *svc)
|
|
{
|
|
svc->connections++;
|
|
|
|
char buf[MAX_CLIENT_BUF];
|
|
int n = recv(client_fd, buf, sizeof(buf) - 1, 0);
|
|
if (n <= 0) return;
|
|
buf[n] = '\0';
|
|
|
|
/* Extract first line without modifying buf (needed for POST body search) */
|
|
char first_line[130];
|
|
char *eol = strstr(buf, "\r\n");
|
|
size_t fl_len = eol ? (size_t)(eol - buf) : (size_t)n;
|
|
if (fl_len >= sizeof(first_line)) fl_len = sizeof(first_line) - 1;
|
|
memcpy(first_line, buf, fl_len);
|
|
first_line[fl_len] = '\0';
|
|
|
|
char detail[192];
|
|
snprintf(detail, sizeof(detail), "service=http request='%.128s'", first_line);
|
|
event_send("SVC_CONNECT", "MEDIUM", "00:00:00:00:00:00",
|
|
client_ip, client_port, 80, detail, NULL);
|
|
|
|
/* Check for POST data → auth attempt */
|
|
if (strncmp(buf, "POST", 4) == 0) {
|
|
svc->auth_attempts++;
|
|
char *body = strstr(buf, "\r\n\r\n");
|
|
if (body) {
|
|
body += 4;
|
|
char post_detail[192];
|
|
snprintf(post_detail, sizeof(post_detail),
|
|
"service=http post='%.128s'", body);
|
|
event_send("SVC_AUTH_ATTEMPT", "HIGH", "00:00:00:00:00:00",
|
|
client_ip, client_port, 80, post_detail, NULL);
|
|
}
|
|
}
|
|
|
|
/* Build proper HTTP response */
|
|
char server_name[64];
|
|
extract_server_name(server_name, sizeof(server_name));
|
|
|
|
int body_len = (int)sizeof(LOGIN_PAGE) - 1;
|
|
char resp_hdr[256];
|
|
int hdr_len = snprintf(resp_hdr, sizeof(resp_hdr),
|
|
"HTTP/1.1 200 OK\r\n"
|
|
"Server: %s\r\n"
|
|
"Content-Type: text/html\r\n"
|
|
"Content-Length: %d\r\n"
|
|
"Connection: close\r\n\r\n",
|
|
server_name, body_len);
|
|
|
|
send(client_fd, resp_hdr, hdr_len, 0);
|
|
send(client_fd, LOGIN_PAGE, body_len, 0);
|
|
|
|
int tarpit = hp_config_get_threshold("tarpit_ms");
|
|
if (tarpit > 0)
|
|
vTaskDelay(pdMS_TO_TICKS(tarpit));
|
|
}
|
|
|
|
#endif
|