Skip to content

Commit d69ae58

Browse files
committed
Use scan randomness for TCP too
1 parent 72bcc9b commit d69ae58

4 files changed

Lines changed: 32 additions & 23 deletions

File tree

src/scan-responder.c

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,27 @@
1313
#include "banner.h"
1414
#include "util.h"
1515

16+
enum {
17+
IP_SZ = FRAME_ETH_SIZE + FRAME_IP_SIZE,
18+
TCP_SZ = IP_SZ + TCP_HEADER_SIZE,
19+
};
20+
1621
static struct {
1722
/* TODO: better sharing of these vars with scan.c */
1823
FILE *outfile;
1924
const struct outputdef *outdef;
2025
uint16_t source_port;
26+
uint32_t scan_randomness;
2127

22-
uint8_t _Alignas(uint32_t) buffer[FRAME_ETH_SIZE + FRAME_IP_SIZE + TCP_HEADER_SIZE + BANNER_QUERY_MAX_LENGTH];
28+
uint8_t _Alignas(uint32_t) buffer[TCP_SZ + BANNER_QUERY_MAX_LENGTH];
2329

2430
pthread_t tcp_thread;
2531
atomic_bool tcp_thread_exit;
2632
} responder;
2733

2834
static void *tcp_thread(void *unused);
2935

30-
int scan_responder_init(FILE *outfile, const struct outputdef *outdef, uint16_t source_port)
36+
int scan_responder_init(FILE *outfile, const struct outputdef *outdef, uint16_t source_port, uint32_t scan_randomness)
3137
{
3238
uint8_t *spacket = responder.buffer;
3339

@@ -38,6 +44,7 @@ int scan_responder_init(FILE *outfile, const struct outputdef *outdef, uint16_t
3844
responder.outfile = outfile;
3945
responder.outdef = outdef;
4046
responder.source_port = source_port;
47+
responder.scan_randomness = scan_randomness;
4148

4249
if(tcp_state_init() < 0)
4350
return -1;
@@ -70,9 +77,9 @@ void scan_responder_process(uint64_t ts, int len, const uint8_t *rpacket)
7077
tcp_decode_header(TCP_HEADER(rpacket), &data_offset);
7178
// ordinary packet with data
7279
if(!TCP_HEADER(rpacket)->f_rst && !TCP_HEADER(rpacket)->f_syn &&
73-
len > FRAME_ETH_SIZE + FRAME_IP_SIZE + data_offset) {
80+
len > IP_SZ + data_offset) {
7481
tcp_decode2(TCP_HEADER(rpacket), &rseqnum, NULL);
75-
unsigned int plen = len - (FRAME_ETH_SIZE + FRAME_IP_SIZE + data_offset);
82+
unsigned int plen = len - (IP_SZ + data_offset);
7683

7784
tcp_debug("< seqnum = %08x got data", rseqnum);
7885
if(!tcp_state_find(rsrcaddr, rport, &p))
@@ -97,7 +104,7 @@ void scan_responder_process(uint64_t ts, int len, const uint8_t *rpacket)
97104
tcp_debug("> ack%s seq=%08x ack=%08x",
98105
TCP_HEADER(spacket)->f_fin?"+fin":"", lseqnum, rseqnum + plen + x);
99106
tcp_checksum(IP_FRAME(spacket), TCP_HEADER(spacket), 0);
100-
rawsock_send(spacket, FRAME_ETH_SIZE + FRAME_IP_SIZE + TCP_HEADER_SIZE);
107+
rawsock_send(spacket, TCP_SZ);
101108
// FIN packet (no data)
102109
} else if(TCP_HEADER(rpacket)->f_fin) {
103110
tcp_decode2(TCP_HEADER(rpacket), &rseqnum, NULL);
@@ -121,19 +128,21 @@ void scan_responder_process(uint64_t ts, int len, const uint8_t *rpacket)
121128
tcp_debug("> ack+fin seq=%08x ack=%08x",
122129
lseqnum, rseqnum + x);
123130
tcp_checksum(IP_FRAME(spacket), TCP_HEADER(spacket), 0);
124-
rawsock_send(spacket, FRAME_ETH_SIZE + FRAME_IP_SIZE + TCP_HEADER_SIZE);
131+
rawsock_send(spacket, TCP_SZ);
125132
// ACK packet (no data)
126133
} else if(TCP_HEADER(rpacket)->f_ack) {
127134
tcp_decode2(TCP_HEADER(rpacket), &rseqnum, &acknum);
128135

129-
tcp_debug("< seqnum = %08x acked: %08x", rseqnum, acknum);
136+
tcp_debug("< seqnum = %08x %sacked: %08x", rseqnum,
137+
TCP_HEADER(rpacket)->f_syn?"syn-":"", acknum);
130138
if(!TCP_HEADER(rpacket)->f_syn)
131139
return;
132140

133-
uint32_t lseqnum = FIRST_SEQNUM + 1; // expected acknum for the initial answer
141+
// expected acknum for the syn-ack
142+
uint32_t lseqnum = tcp_first_seqnum(responder.scan_randomness) + 1;
134143
if(acknum != lseqnum)
135144
return;
136-
rseqnum += 1; // syn-ack increases seqnum by one
145+
rseqnum += 1; // syn-ack counts as one
137146

138147
unsigned int plen;
139148
const char *payload = banner_get_query(IP_TYPE_TCP, rport, &plen);
@@ -145,7 +154,7 @@ void scan_responder_process(uint64_t ts, int len, const uint8_t *rpacket)
145154
tcp_modify(TCP_HEADER(spacket), responder.source_port, rport);
146155

147156
tcp_checksum(IP_FRAME(spacket), TCP_HEADER(spacket), 0);
148-
rawsock_send(spacket, FRAME_ETH_SIZE + FRAME_IP_SIZE + TCP_HEADER_SIZE);
157+
rawsock_send(spacket, TCP_SZ);
149158
tcp_debug("> ack+rst seq=%08x ack=%08x", lseqnum, rseqnum);
150159
return;
151160
}
@@ -158,7 +167,7 @@ void scan_responder_process(uint64_t ts, int len, const uint8_t *rpacket)
158167
memcpy(TCP_DATA(spacket, TCP_HEADER_SIZE), payload, plen);
159168

160169
tcp_checksum(IP_FRAME(spacket), TCP_HEADER(spacket), plen);
161-
rawsock_send(spacket, FRAME_ETH_SIZE + FRAME_IP_SIZE + TCP_HEADER_SIZE + plen);
170+
rawsock_send(spacket, TCP_SZ + plen);
162171
tcp_debug("> ack%s seq=%08x ack=%08x",
163172
TCP_HEADER(spacket)->f_psh?"+psh":"", lseqnum, rseqnum);
164173

@@ -180,7 +189,7 @@ void scan_responder_process(uint64_t ts, int len, const uint8_t *rpacket)
180189
tcp_modify(TCP_HEADER(spacket), responder.source_port, rport);
181190

182191
tcp_checksum(IP_FRAME(spacket), TCP_HEADER(spacket), 0);
183-
rawsock_send(spacket, FRAME_ETH_SIZE + FRAME_IP_SIZE + TCP_HEADER_SIZE);
192+
rawsock_send(spacket, TCP_SZ);
184193
tcp_debug("> ack+rst seq=%08x ack=%08x", lseqnum, rseqnum);
185194
} else {
186195
tcp_debug("want to send rst but can't..."); // because we don't know our local seqnum
@@ -193,12 +202,9 @@ static void *tcp_thread(void *unused)
193202
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
194203
set_thread_name("tcp");
195204

196-
enum {
197-
packet_sz = FRAME_ETH_SIZE + FRAME_IP_SIZE + TCP_HEADER_SIZE
198-
};
199-
uint8_t _Alignas(uint32_t) packet[packet_sz];
205+
uint8_t _Alignas(uint32_t) packet[TCP_SZ];
200206
// Copy the prepared structure from the "global" packet buffer
201-
memcpy(packet, responder.buffer, packet_sz);
207+
memcpy(packet, responder.buffer, TCP_SZ);
202208

203209
do {
204210
usleep(BANNER_TIMEOUT * 1000 / 2);
@@ -230,7 +236,7 @@ static void *tcp_thread(void *unused)
230236
tcp_modify(TCP_HEADER(packet), responder.source_port, srcport);
231237

232238
tcp_checksum(IP_FRAME(packet), TCP_HEADER(packet), 0);
233-
rawsock_send(packet, packet_sz);
239+
rawsock_send(packet, TCP_SZ);
234240
tcp_debug("> rst seq=%08x", lseqnum);
235241
}
236242

src/scan.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ int scan_main(const char *interface, int quiet)
8686
atomic_store(&pkts_recv, 0);
8787
atomic_store(&status_bits, 0);
8888
if(banners && ip_type == IP_TYPE_TCP) {
89-
if(scan_responder_init(outfile, &outdef, source_port) < 0)
89+
if(scan_responder_init(outfile, &outdef, source_port, scan_randomness) < 0)
9090
goto err;
9191
}
9292
if(!banners && ip_type == IP_TYPE_UDP)
@@ -188,7 +188,7 @@ static void *send_thread_tcp(void *unused)
188188
goto err;
189189
rawsock_ip_modify(IP_FRAME(packet), TCP_HEADER_SIZE, dstaddr);
190190
tcp_prepare(TCP_HEADER(packet));
191-
tcp_make_syn(TCP_HEADER(packet), FIRST_SEQNUM);
191+
tcp_make_syn(TCP_HEADER(packet), tcp_first_seqnum(scan_randomness));
192192
ports_iter_begin(&ports, &it);
193193

194194
while(1) {

src/scan.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ struct ports;
1111
#define FINISH_WAIT_TIME 5 // s
1212
#define BANNER_TIMEOUT 2500 // ms
1313

14-
#define FIRST_SEQNUM 0xf0000000
15-
1614
void scan_set_general(const struct ports *ports, int max_rate, int show_closed, int banners);
1715
void scan_set_network(const uint8_t *source_addr, int source_port, uint8_t ip_type);
1816
void scan_set_output(FILE *outfile, const struct outputdef *outdef);
@@ -32,7 +30,7 @@ int scan_reader_main(FILE *infile);
3230
#define TCP_DATA(buf, data_offset) ( (uint8_t*) &(buf)[FRAME_ETH_SIZE + FRAME_IP_SIZE + data_offset] )
3331
#define UDP_DATA(buf) TCP_DATA(buf, UDP_HEADER_SIZE)
3432

35-
int scan_responder_init(FILE *outfile, const struct outputdef *outdef, uint16_t source_port);
33+
int scan_responder_init(FILE *outfile, const struct outputdef *outdef, uint16_t source_port, uint32_t scan_randomness);
3634
void scan_responder_process(uint64_t ts, int len, const uint8_t *rpacket);
3735
void scan_responder_finish();
3836

src/tcp.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ void tcp_decode_header(const struct tcp_header *pkt, unsigned int *data_offset);
4242
void tcp_decode(const struct tcp_header *pkt, int *srcport, int *dstport);
4343
void tcp_decode2(const struct tcp_header *pkt, uint32_t *seqnum, uint32_t *acknum);
4444

45+
static inline uint32_t tcp_first_seqnum(uint32_t rnd) {
46+
rnd &= ~(1 << 15); // make room to avoid overflow
47+
return rnd;
48+
}
49+
4550

4651
int tcp_state_init(void);
4752
void tcp_state_create(const uint8_t *srcaddr, uint16_t srcport,

0 commit comments

Comments
 (0)