• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #define _GNU_SOURCE
2 
3 #include <arpa/inet.h>
4 #include <errno.h>
5 #include <fcntl.h>
6 #include <linux/if_tun.h>
7 #include <net/if.h>
8 #include <netinet/in.h>
9 #include <netinet/ip.h>
10 #include <netinet/tcp.h>
11 #include <sched.h>
12 #include <stdarg.h>
13 #include <stdint.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <sys/ioctl.h>
18 #include <sys/socket.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <sys/uio.h>
22 #include <unistd.h>
23 
24 void HF_ITER(uint8_t**, size_t*);
25 
fatal(const char * fmt,...)26 void fatal(const char* fmt, ...)
27 {
28     fprintf(stdout, "[-] ");
29 
30     va_list args;
31     va_start(args, fmt);
32     vfprintf(stdout, fmt, args);
33     va_end(args);
34 
35     fprintf(stdout, "\n");
36 
37     exit(1);
38 }
39 
pfatal(const char * fmt,...)40 void pfatal(const char* fmt, ...)
41 {
42     fprintf(stdout, "[-] ");
43 
44     va_list args;
45     va_start(args, fmt);
46     vfprintf(stdout, fmt, args);
47     va_end(args);
48 
49     fprintf(stdout, ": %s\n", strerror(errno));
50 
51     exit(1);
52 }
53 
mlog(const char * fmt,...)54 void mlog(const char* fmt, ...)
55 {
56     fprintf(stdout, "[+] ");
57 
58     va_list args;
59     va_start(args, fmt);
60     vfprintf(stdout, fmt, args);
61     va_end(args);
62 
63     fprintf(stdout, "\n");
64 }
65 
main(void)66 int main(void)
67 {
68     if (unshare(CLONE_NEWUSER | CLONE_NEWNET) == -1) {
69         pfatal("unshare()");
70     }
71 
72     struct ifreq ifr;
73     memset(&ifr, '\0', sizeof(ifr));
74     ifr.ifr_flags = IFF_TUN | IFF_NO_PI | IFF_NOFILTER;
75     strcpy(ifr.ifr_name, "FUZZ0");
76 
77     int fd = open("/dev/net/tun", O_RDWR);
78     if (fd == -1) {
79         pfatal("open('/dev/net/tun')");
80     }
81     if (ioctl(fd, TUNSETIFF, (void*)&ifr) != 0) {
82         pfatal("ioctl(TUNSETIFF)");
83     }
84     if (ioctl(fd, TUNSETOFFLOAD, TUN_F_CSUM | TUN_F_TSO_ECN | TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_UFO) == -1) {
85         pfatal("ioctl(fd, TUNSETOFFLOAD)");
86     }
87 
88     int udp_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
89     if (udp_sock == -1) {
90         pfatal("socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)");
91     }
92     int tcp_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
93     if (tcp_sock == -1) {
94         pfatal("socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)");
95     }
96     int sctp_sock = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
97     if (sctp_sock == -1) {
98         pfatal("socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)");
99     }
100     int udp_lite_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE);
101     if (udp_lite_sock == -1) {
102         pfatal("socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE)");
103     }
104 
105     int disable = 1;
106     if (setsockopt(udp_sock, SOL_SOCKET, SO_NO_CHECK, (void*)&disable, sizeof(disable)) == -1) {
107         pfatal("setsockopt(udp_sock, SOL_SOCKET, SO_NO_CHECK)");
108     }
109     if (setsockopt(tcp_sock, SOL_SOCKET, SO_NO_CHECK, (void*)&disable, sizeof(disable)) == -1) {
110         pfatal("setsockopt(tcp_sock, SOL_SOCKET, SO_NO_CHECK)");
111     }
112     const uint8_t md5s[TCP_MD5SIG_MAXKEYLEN] = { 0 };
113     setsockopt(tcp_sock, SOL_TCP, TCP_MD5SIG, (void*)md5s, sizeof(md5s));
114     if (setsockopt(sctp_sock, SOL_SOCKET, SO_NO_CHECK, (void*)&disable, sizeof(disable)) == -1) {
115         pfatal("setsockopt(sctp_sock, SOL_SOCKET, SO_NO_CHECK)");
116     }
117     if (setsockopt(udp_lite_sock, SOL_SOCKET, SO_NO_CHECK, (void*)&disable, sizeof(disable)) == -1) {
118         pfatal("setsockopt(udp_lite_sock, SOL_SOCKET, SO_NO_CHECK)");
119     }
120 
121     struct sockaddr_in* sa = (struct sockaddr_in*)(&ifr.ifr_addr);
122     sa->sin_family = AF_INET;
123     sa->sin_addr.s_addr = inet_addr("192.168.255.1");
124     if (ioctl(tcp_sock, SIOCSIFADDR, &ifr) == -1) {
125         pfatal("ioctl(tcp_sock, SIOCSIFADDR, &ifr)");
126     }
127     sa->sin_addr.s_addr = inet_addr("192.168.255.2");
128     if (ioctl(tcp_sock, SIOCSIFDSTADDR, &ifr) == -1) {
129         pfatal("ioctl(tcp_sock, SIOCSIFDSTADDR, &ifr)");
130     }
131 
132     if (ioctl(tcp_sock, SIOCGIFFLAGS, &ifr) == -1) {
133         pfatal("ioctl(tcp_sock, SIOCGIFFLAGS, &ifr)");
134     }
135     ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
136     if (ioctl(tcp_sock, SIOCSIFFLAGS, &ifr) == -1) {
137         pfatal("ioctl(tcp_sock, SIOCSIFFLAGS, &ifr)");
138     }
139 
140     struct sockaddr_in addr = {
141         .sin_family = AF_INET,
142         .sin_port = htons(1337),
143         .sin_addr.s_addr = INADDR_ANY,
144     };
145 
146     if (bind(tcp_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
147         pfatal("bind(tcp)");
148     }
149     if (bind(udp_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
150         pfatal("bind(udp)");
151     }
152     if (bind(sctp_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
153         pfatal("bind(sctp)");
154     }
155     if (bind(udp_lite_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
156         pfatal("bind(udp_lite)");
157     }
158     if (fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR) == -1) {
159         pfatal("fcntl(fd, F_SETFL, O_NONBLOCK|O_RDWR)");
160     }
161     if (fcntl(tcp_sock, F_SETFL, O_NONBLOCK | O_RDWR) == -1) {
162         pfatal("fcntl(tcp_sock, F_SETFL, O_NONBLOCK|O_RDWR)");
163     }
164     if (fcntl(udp_sock, F_SETFL, O_NONBLOCK | O_RDWR) == -1) {
165         pfatal("fcntl(udp_sock, F_SETFL, O_NONBLOCK|O_RDWR)");
166     }
167     if (fcntl(sctp_sock, F_SETFL, O_NONBLOCK | O_RDWR) == -1) {
168         pfatal("fcntl(sctp_sock, F_SETFL, O_NONBLOCK|O_RDWR)");
169     }
170     if (fcntl(udp_lite_sock, F_SETFL, O_NONBLOCK | O_RDWR) == -1) {
171         pfatal("fcntl(udp_lite_sock, F_SETFL, O_NONBLOCK|O_RDWR)");
172     }
173 
174     if (listen(tcp_sock, SOMAXCONN) == -1) {
175         pfatal("listen(tcp_sock)");
176     }
177     if (listen(sctp_sock, SOMAXCONN) == -1) {
178         pfatal("listen(sctp_sock)");
179     }
180 
181     int tcp_acc_sock = -1;
182 
183     for (;;) {
184         char b[1024 * 128];
185         for (;;) {
186             if (read(fd, b, sizeof(b)) <= 0) {
187                 break;
188             }
189         }
190 
191         uint8_t* buf;
192         size_t len;
193 
194         HF_ITER(&buf, &len);
195 
196         const size_t pkt_size = 1400UL;
197         size_t num_iov = 0;
198         if (len > 0) {
199             num_iov = ((len - 1) / pkt_size) + 1;
200         }
201         for (size_t i = 0; i < num_iov; i++) {
202             size_t off = pkt_size * i;
203             size_t sz = ((len - off) > pkt_size) ? pkt_size : (len - off);
204             write(fd, &buf[off], sz);
205 
206             char b[1024 * 128];
207             for (;;) {
208                 if (read(fd, b, sizeof(b)) <= 0) {
209                     break;
210                 }
211             }
212 
213             if (tcp_acc_sock == -1) {
214                 struct sockaddr_in nsock;
215                 socklen_t slen = sizeof(nsock);
216                 tcp_acc_sock = accept4(tcp_sock, (struct sockaddr*)&nsock, &slen, SOCK_NONBLOCK);
217             }
218             if (tcp_acc_sock != -1) {
219                 if (recv(tcp_acc_sock, b, sizeof(b), MSG_DONTWAIT) == 0) {
220                     close(tcp_acc_sock);
221                     tcp_acc_sock = -1;
222                 }
223                 send(tcp_acc_sock, b, 1, MSG_NOSIGNAL | MSG_DONTWAIT);
224             }
225 
226             struct sockaddr_in addr;
227             socklen_t slen = sizeof(addr);
228             if (recvfrom(udp_sock, b, sizeof(b), MSG_DONTWAIT, (struct sockaddr*)&addr, &slen) > 0) {
229                 sendto(udp_sock, b, 1, MSG_NOSIGNAL | MSG_DONTWAIT, (struct sockaddr*)&addr, slen);
230             }
231 
232             slen = sizeof(addr);
233             if (recvfrom(sctp_sock, b, sizeof(b), MSG_DONTWAIT, (struct sockaddr*)&addr, &slen) > 0) {
234                 sendto(sctp_sock, b, 1, MSG_NOSIGNAL | MSG_DONTWAIT, (struct sockaddr*)&addr, slen);
235             }
236 
237             slen = sizeof(addr);
238             if (recvfrom(udp_lite_sock, b, sizeof(b), MSG_DONTWAIT, (struct sockaddr*)&addr, &slen) > 0) {
239                 sendto(udp_lite_sock, b, 1, MSG_NOSIGNAL | MSG_DONTWAIT, (struct sockaddr*)&addr, slen);
240             }
241         }
242     }
243 }
244