简体   繁体   中英

Artificial delay in TCP socket with C, for race condition exploitation

I am trying to introduce an artificial delay in a TCP socket server implemented in C.

The idea is for it to take a while for a client to connect to the server on purpose.

To implement this, I tried instead of simply using a blocking accept() to receive connections, polling for a waiting connection and then sleep() ing before accept() ing.

However, it seems as though data is written to some other buffer anyway, and the only effect is that it takes the sleep() delay for my program to read from the buffer. Meanwhile the client has happily connected and sent the data already.

Am I going about this the right way? Possibly relevant information: both client and server are connecting via loopback interface on the same virtual machine (VMWare Player).

My client code:

printf("Connecting to %s:18211 .. ", host); fflush(stdout);

fd = socket(AF_INET, SOCK_STREAM, 0);

memset(&sin, 0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(host);
sin.sin_port = htons(18211);

if(connect(fd, (void *)&sin, sizeof(struct sockaddr_in)) == -1) {
  printf("Unable to connect to host %s\n", host);
  exit(EXIT_FAILURE);
}

#define HITHERE ".oO Oo.\n"
if(write(fd, HITHERE, strlen(HITHERE)) == -1) {
  printf("Unable to write banner to host %s\n", host);
  exit(EXIT_FAILURE);
}
#undef HITHERE

printf("Connected!\nSending file .. "); fflush(stdout);

ffd = open(file, O_RDONLY);
if(ffd == -1) {
  printf("Damn. Unable to open file\n");
  exit(EXIT_FAILURE);
}

Server code:

I tried doing a socket poll() and then sleeping before accept() here, but whilst data was received there was no delay in the client.

The TCP handshake (SYN, SYN/ACK, ACK) happens before you get notified, at the OS level, and the client is free to send data immediately. accept() is just a server side thing giving you a fd for that specific connection.

If you want to delay establishing the connection, you should probably do in in your firewall.

I second the firewall idea, eg some delay for ACKs in iptables. Another thing to try might be setting the listen() backlog to 0 or something very small. However IIRC (though Im unsure) Linux does not set it to the number you give listen() so youll have to experiment to see how large it is. See how many clients connect before you call accept() and then add one more to be "exploited".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM