环境:添加后门可以配置请求地址。后门通过监听按键的方式来启动,监听到一定的后门即可启动一个网络服务线程来等待客户端链接。客户端使用的是网页请求的方式,直接使用get的方式。本文重点在后门网络配置服务端写法。
一、方案很简单,具体不累述:
1、开启服务端。等待客户端响应
2、在网页输入get请求
3、服务端收到请求,并执行操作。
二、服务端代码
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 12306 //定义通信端口
#define BACKLOG 5 //定义侦听队列长度
#define buflen 1024
#define OK_CLINET "HTTP/1.1 200 OK\r\nContent-Length: 17\r\n\r\n{activeResp: 200}"
#define ERR_CLINET "HTTP/1.1 404 Not Found\r\nContent-type error text/html\r\n\r\n"
typedef struct{
char acKey[32];
char acValue[64];
}MSG_PARSE_t;
static LRESULT CALLBACK BackDoorDialog (HCSWND hWnd, WPARAM wParam, LPARAM lParam)
{
LRESULT iRet = 0;
int nBoxRet = 0;
char strTmp[32] = {0},strMsg[256] = {0};
char swstrTmp[32] = {0},swstrMsg[256] = {0};
int ret = -1;
pthread_t id;
if(backdoor_id != 0){
return -1;
}
ret = pthread_create(&id, NULL, HttpServer, (void *)NULL);
if(ret != 0){
printf("pthread create error \n");
return -1;
}
backdoor_id = id;
pthread_detach(id);
if(backdoor_id > 0){
ret = pthread_kill(backdoor_id , 0);
if(ret == ESRCH){
printf("CSPlayService_GetBackList : the specified thread did not exists or already quit\n");
}else if(ret == EINVAL){
printf("CSPlayService_GetBackList : signal is invalid\n");
}else{
printf("CSPlayService_GetBackList : the specified thread is alive\n");
pthread_cancel(backdoor_id);
backdoor_id = 0;
}
GUI_DEBUG("pthread_kill backdoor_id !\n");
}
return iRet;
}
int StringParseToKeyValueArray( char *pcOriginMsg,
MSG_PARSE_t *psItems,
int nItemCunt)
{
char *pSaveOuter;
char *pSaveInner;
char *token;
char *key;
char *value;
char *pstart;
int i = 0;
const int BUFSIZE = 1024*10;
char *pcDumpMsg=NULL;
if( NULL == pcOriginMsg || NULL == psItems )
{
return -1;
}
pcDumpMsg =(char *)malloc(BUFSIZE);
if(pcDumpMsg == NULL)
{
return -1;
}
if(strlen(pcOriginMsg)<BUFSIZE)
{
strncpy(pcDumpMsg, pcOriginMsg, strlen(pcOriginMsg));
}
else
{
strncpy(pcDumpMsg, pcOriginMsg, BUFSIZE);
}
pstart = pcDumpMsg;
while( NULL != (token = strtok_r(pstart, "&", &pSaveOuter)) && i < nItemCunt)
{
pstart = token;
//key
if( NULL == (key = strtok_r(pstart, "=", &pSaveInner)))
{
free(pcDumpMsg);
return -1;
}
strcpy(psItems[i].acKey, key);
//value
if( NULL == (value = strtok_r(NULL, "=", &pSaveInner)))
{
}
else
{
strcpy(psItems[i].acValue, value);
}
pstart = NULL;
i++;
}
free(pcDumpMsg);
pcDumpMsg=NULL;
return i;
}
static int HttpServer()
{
struct sockaddr_in server_addr; //存储服务器端socket地址结构
struct sockaddr_in client_addr; //存储客户端 socket地址结构
int sockfd,newfd;
char readbuf[1024];
fd_set fds;
int maxfd;
int PARSE_PARAM_MAX = 250;
MSG_PARSE_t stMsgArray[PARSE_PARAM_MAX];
const char *GET_SETCFG = "GET /setinfo?";
const int LEN_SETCFG = strlen(GET_SETCFG);
int ret = -1; //返回值
sockfd = socket(AF_INET, SOCK_STREAM, 0); //建立一个序列化的,可靠的,双向连接的的字节流
if (sockfd<0)
{
printf("server : server socket create error\n");
return -1;
}
//初始化地址结构
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET; //协议族
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //本地地址
server_addr.sin_port = htons(PORT);
ret = bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
if (ret < 0)
{
printf("server : bind error\n");
return -1;
}
ret = listen(sockfd, BACKLOG); //设置监听的队列大小
if (ret < 0)
{
printf("server : listen error\n");
return -1;
}
for (;;)
{
FD_ZERO(&fds);
FD_SET(sockfd, &fds);
maxfd = sockfd + 1;
printf("\n\nserver : accept \n\n");
if( (ret = select(maxfd + 1, &fds, NULL, NULL, NULL)) < 0)
{
GUI_DEBUG("select fail\n");
return;
}
if(!FD_ISSET(sockfd, &fds))
{
continue;
}
socklen_t addrlen = sizeof(client_addr);
memset(readbuf, 0,strlen(readbuf));
memset(stMsgArray, 0,strlen(stMsgArray));
//accept返回客户端套接字描述符
newfd = accept(sockfd, (struct sockaddr *)&client_addr, &addrlen); //注,此处为了获取返回值使用 指针做参数
if(newfd < 0) //出错
{
write(newfd, ERR_CLINET, strlen(ERR_CLINET));
continue; //结束此次循环
}
printf("server : connected\n");
ret = recv(newfd, readbuf, 1024-1, 0);
if(ret <= 0)
{
GUI_DEBUG("receive fail\n");
write(newfd, ERR_CLINET, strlen(ERR_CLINET));
close(newfd);
continue;
}
write(newfd, OK_CLINET, strlen(OK_CLINET));
printf("readbuf = %s", readbuf);
//请求格式为 GET /xxxx?xxxx HTTP/1.1,去除末尾的 HTTP/1.1
char *space1 = strstr(readbuf, " HTTP/1");
if(space1) *space1 = '\0';
GUI_DEBUG("readbuf = %s", readbuf);
//http://172.30.15.56:12306/setinfo?tang=tang
if(!strncmp(readbuf, GET_SETCFG, LEN_SETCFG))
{
GUI_DEBUG("action = %s %d", readbuf, LEN_SETCFG);
//char *action = readbuf[LEN_SETCFG -1];
GUI_DEBUG("action = %s", readbuf+LEN_SETCFG);
int count = StringParseToKeyValueArray(readbuf+LEN_SETCFG, stMsgArray, PARSE_PARAM_MAX);
for(int i = 0; i<count;i++){
printf("acKey = %s", stMsgArray[i].acKey);
printf("acValue = %s", stMsgArray[i].acValue);
if(!strncmp(stMsgArray[i].acKey, "ChListAddr", strlen("ChListAddr"))){
setChListAddr(stMsgArray[i].acValue);
printf("set ChListAddr ok");
}
if(!strncmp(stMsgArray[i].acKey, "ChTypeAddr", strlen("ChTypeAddr"))){
setChTypeAddr(stMsgArray[i].acValue);
printf("set ChTypeAddr ok");
}
}
}
close(newfd);
}
//never run here
printf("http thread error\n");
close(sockfd);
return -1;
}
三、客户端请求
http://172.30.15.56:12306/setinfo?tang=tang&sdk=102152&ChListAddr=192.168.15.43:8088&tangtang=tang
四、总结
就不总结了,很简单。有问题留言给我