月額480円〜の高速レンタルサーバー ColorfulBox

PPTP URL Recorder

经常使用别个共享的梯子的人要注意了,你的隐私去哪儿了?

把HTTP请求的URL全部记录下来,vps上用的~~ 日志记录在 “/var/log/url_record.txt” 程序守护进程方式运行在后台
pptp类型的vpn,每个vpn用户登录的时候,系统会创建一个虚拟网卡pppx, 程序捕获到事件后会自动一个线程针对这个虚拟网卡抓包

Debian/Ubuntu: apt-get install libpcap-dev -y
CentOS:yum install libpcap-devel -y

gcc -o url_recorder url_recorder.c -lpcap -lpthread

需要root权限
./url_recoder

代码:

1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <sys/types.h>
5#include <sys/socket.h>
6#include <linux/if.h>
7#include <netinet/in.h>
8#include <linux/netlink.h>
9#include <linux/rtnetlink.h>
10#include <arpa/inet.h>
11#include <pcap.h>
12#include <unistd.h>
13#include <time.h>
14#include <pthread.h>
15 
16#define PROMISC 1
17#define SNAPLEN 1600
18 
19static char log_file[] = "/var/log/url_record.txt";
20static char pidfile[] = "/var/run/url_recorder";
21static FILE* log_fp;
22static pthread_mutex_t log_mutex;
23static char nic_bitmap[20];
24static char nic[10];
25 
26int log_init()
27{
28    int ret;
29     
30    pthread_mutex_init(&log_mutex,NULL);
31    log_fp = fopen(log_file,"a+");
32    if (log_fp == NULL){
33        printf("open log file failedn");
34    }
35     
36    return 0;
37}
38 
39int logging(char *data,int len)
40{
41    time_t timet;
42    struct tm *p;
43    char str_time[100];
44 
45    timet = time(NULL);
46    p = localtime(&timet);
47     
48    pthread_mutex_lock(&log_mutex);
49 
50    strftime(str_time,sizeof(str_time),"<--%m-%d %H:%M:%S-->  ",p);
51    fwrite(str_time,strlen(str_time),1,log_fp);
52    fwrite(data,len,1,log_fp);
53    fputc('n',log_fp);
54    fflush(log_fp);
55 
56    pthread_mutex_unlock(&log_mutex);  
57 
58    return 0;
59}
60 
61int create_pidfile()
62{
63    return 0;
64}
65 
66 
67int is_http_request(const unsigned char* buf, int len)
68{
69    if (buf[0] == 'G' && buf[1] == 'E' && buf[2] == 'T'){
70        return 1;
71    }
72 
73    if (buf[0] == 'P' && buf[1] == 'O' && buf[2] == 'S' && buf[3] == 'T'){
74        return 2;
75    }
76 
77    return 0;
78}
79 
80int http_hdr_len(const unsigned char* buf, int len)
81{
82    int i = 0;
83    int hdr_len = 0;
84 
85    for (i = 0; i < len - 3; i++){
86        if (buf[i] == 'r' && buf[i + 1] == 'n'
87            && buf[i + 2] == 'r' && buf[i + 3] == 'n'){
88            hdr_len = i;
89            break;
90        }
91    }
92 
93    return hdr_len;
94 
95}
96 
97int get_url(unsigned char* buf, int *url_len, const unsigned char *pkt_data, int hdr_len)
98{
99   const  unsigned char* cur;
100    int host_len;
101    int uri_len;
102 
103    memcpy(buf, "http://", 7);
104    buf += 7;
105    *url_len = 7;
106 
107    cur = strstr(pkt_data, "Host:");
108    if (cur == NULL)
109        return -1;
110    cur += 6;
111    host_len = field_len(cur, hdr_len - (cur - pkt_data));
112 
113    if (host_len && (*url_len +host_len<1200)){
114        memcpy(buf, cur, host_len);
115        buf += host_len;
116    *url_len += host_len;
117    }
118    else
119    {
120        return -1;
121    }
122 
123    cur = pkt_data;
124    if (pkt_data[0] == 'G')
125        cur += 4;
126    else if (pkt_data[0] == 'P'){
127        cur += 5;
128    }
129 
130    uri_len = field_len(cur, hdr_len - (cur - pkt_data));
131    uri_len -= 9;
132 
133    if((*url_len + uri_len) < 1200){
134    memcpy(buf, cur, uri_len);
135        *url_len += uri_len;
136    }
137     
138    return 0;
139     
140}
141 
142int field_len(const unsigned char* buf, int len)
143{
144    int i = 0;
145    int field_len = 0;
146     
147    for (i = 0; i < len-1; i++){
148        if (buf[i] == 'r' && buf[i + 1] == 'n'){
149            field_len = i;
150            break;
151        }
152    }
153 
154    return field_len;
155}
156 
157int is_tcp(const unsigned char* buf, int len)
158{
159    if (len < 54)
160        return 0;
161     
162    //l2proto = Linux cooked capture
163    //if (buf[12] != 0x08 || buf[13] != 0x00){
164    if (buf[14] != 0x08 || buf[15] != 0x00){
165        return 0;
166    }
167     
168    //if (buf[23] != 0x06){//tcp flag
169    if (buf[25] != 0x06){//tcp flag
170        return 0;
171    }
172 
173    return 1;
174}
175 
176void callback(unsigned char *user, const struct pcap_pkthdr *h, const unsigned char *bytes)
177{
178    int len;
179    const unsigned char *buf;
180    const unsigned char *cur;
181    unsigned char url[1024];
182    int url_len = 0;
183    char data[1400];
184    int is_req;
185    int hdr_len;
186    int ret;
187 
188    buf = bytes;
189    len = h->caplen;
190    cur = buf;
191 
192    if (!is_tcp(buf, len)){
193        return;
194    }
195 
196    //cur += 54;
197    //len -= 54;//tcp hdr ip hdr
198    cur += 56;
199    len += 56;
200 
201    is_req = is_http_request(cur, len);
202    hdr_len = http_hdr_len(cur, len);
203 
204    switch (is_req){
205    case 0:
206        break;
207    case 1:
208        ret = get_url(url,&url_len, cur, hdr_len);
209        if (ret == 0){
210        logging(url,url_len);
211    //printf("url_len:%dn",url_len);
212        }
213        break;
214    case 2:
215        ret = get_url(url,&url_len, cur, hdr_len);
216        if (ret == 0){
217        logging(url,url_len);
218        }
219        //get_data(data, curl, len);
220        break;
221    default:
222        break;
223    }
224}
225 
226 
227void *capture_thread(void* arg)
228{
229 
230    char dev[10];
231    pcap_t *pt;
232    char errbuf[PCAP_ERRBUF_SIZE];
233 
234    strcpy(dev,(char*)arg);
235        dev[9] = 0;
236 
237     
238    pt = pcap_open_live(dev, SNAPLEN, PROMISC, -1, errbuf);
239        if (pt == NULL){
240            printf("open dev failedn");
241            return;
242        }
243 
244    pcap_loop(pt, -1, callback,NULL);
245//  pthread_detach(pthread_self());
246    printf("capture thread createn");
247 
248}
249 
250int start_capture(char *dev)
251{
252 
253    char dev_vpath[30] = "/sys/class/net/";
254    pthread_t thread;
255    pthread_attr_t attr;
256 
257    strcpy(nic,dev);
258    sleep(1);
259    strcat(dev_vpath,nic);
260    if(access(dev_vpath,0) == 0){
261        int ret;
262        pthread_attr_init(&attr);
263        pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
264        pthread_create(&thread,&attr,capture_thread,nic);
265        pthread_attr_destroy(&attr);
266    }
267 
268    return 0;  
269}
270 
271 
272void parseBinaryNetLinkMessage(struct nlmsghdr *nlh)
273{
274    int len = nlh->nlmsg_len - sizeof(*nlh);
275    struct ifinfomsg *ifi;
276 
277    if(sizeof(*ifi) > (size_t)len){
278        printf("Got a short messagen");
279        return ;
280    }
281 
282    ifi = (struct  ifinfomsg*)NLMSG_DATA(nlh);
283    if((ifi->ifi_flags & IFF_LOOPBACK) != 0){
284        return ;
285    }
286 
287    struct rtattr *rta = (struct rtattr*)
288        ((char*)ifi + NLMSG_ALIGN(sizeof(*ifi)));
289    len = NLMSG_PAYLOAD(nlh,sizeof(*ifi));
290 
291    while(RTA_OK(rta,len)){
292        switch(rta->rta_type){
293            case IFLA_IFNAME:
294            {
295                char ifname[IFNAMSIZ];
296                int  up;
297                char id;
298                snprintf(ifname,sizeof(ifname),"%s",
299                    (char*)RTA_DATA(rta));
300                up = (ifi->ifi_flags & IFF_RUNNING)? 1 : 0;
301                if (up && ((ifname[0] == 'p')&&(ifname[1] == 'p')&&
302                    (ifname[2] == 'p'))){
303                    printf("msg from:%s",ifname);
304                    sscanf(ifname+3,"%d",(int*)&id);
305                    if(nic_bitmap[id])
306                        break;
307                    start_capture(ifname);
308                    nic_bitmap[id] = 1;
309                    printf("%s  %dn",ifname,up);
310                }
311                if (!up && ((ifname[0] == 'p')&&(ifname[1] == 'p')&&
312                                        (ifname[2] == 'p'))){
313                    sscanf(ifname+3,"%d",(int*)&id);
314                    nic_bitmap[id] = 0;
315                    printf("%s %dn",ifname,up);
316                }
317            }
318        }
319 
320        rta = RTA_NEXT(rta,len);
321    }
322 
323}
324 
325 
326int main(int argc,char** argv)
327{
328 
329    struct sockaddr_nl addr;
330    struct nlmsghdr *nlh;
331    char buffer[4096];
332    int sock,len;
333 
334 
335    daemon(0,0);
336    create_pidfile();
337    log_init();
338 
339     
340    if((sock = socket(AF_NETLINK,SOCK_RAW,NETLINK_ROUTE)) == -1){
341        printf("open NETLINK_ROUTE socket failedn");
342        goto exit;
343    }
344 
345    memset(&addr,0,sizeof(addr));
346    addr.nl_family = AF_NETLINK;
347    addr.nl_groups = RTMGRP_LINK |RTMGRP_IPV4_IFADDR;
348     
349    if(bind(sock,(struct sockaddr*)&addr,sizeof(addr)) == -1){
350        printf("bind failedn");
351        goto exit;
352    }
353 
354    while((len = recv(sock,buffer,4096,0)) > 0){
355        nlh = (struct nlmsghdr*)buffer;
356        while((NLMSG_OK(nlh,len)) && (nlh->nlmsg_type != NLMSG_DONE)){
357            if(nlh->nlmsg_type == RTM_NEWLINK){
358                parseBinaryNetLinkMessage(nlh);
359            }
360            nlh = NLMSG_NEXT(nlh,len);
361        }
362    }
363 
364    close(sock);
365     
366exit:
367        exit(0);
368}