Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 421 Vote(s) - 3.54 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Can `recv()` result in a buffer overflow?

#1
I'm introducing myself to socket programming in C/C++, and am using `send()` and `recv()` to exchange data between a client and server program over `TCP` sockets.

Here are some relevant excerpts from my code:

**server.c**:

char recv_data[1024];

// Socket setup and so on ommited...

bytes_recieved = recv(connected, recv_data, 1024, 0);
recv_data[bytes_recieved] = '\0';

**client.c:**

char send_data[1024];

// Setup ommited...

send(connected, send_data, strlen(send_data), 0);

Does `recv()` itself provide any protection against buffer overflows? For instance if I changed the 3rd argument to `recv()` to something higher than the buffer pointed to by `recv_data` (e.g. 4000) - would this cause a buffer overflow? (I've actually tried doing this, but can't seem to trigger a segfault).

I'm actually trying to create an intentionally vulnerable server program to better understand these issues, which is why I've tried to overflow via `recv()`.

**Amendment**:

Not unrelated, would be finding out why `client.c` above would ever send more than the `1024` bytes specified by `strlen(send_data)`. I'm using `gets(send_data)` to populate that buffer from standard input, but if I enter many more than 1024 bytes via standard in, the `server.c` program shows that it receives ALL THE BYTES! :). Does the `strlen(send_data)` for `send()` not restrict the number of bytes sent?
Reply

#2
> For instance if I changed the 3rd argument to recv() to something higher than the buffer pointed to by recv_data (e.g. 4000) - would this cause a buffer overflow?

Ofcourse yes. If the network buffer has data of 4000 bytes, it will put it in the buffer. The key point is that, recv like any other C API which takes a buffer and it's length believes that the caller will pass the actual length of the buffer and if the caller passes incorrect length, then the fault lies with the caller and it can lead to undefined behavior.

In C when you pass arrays to a function, there is no way for the called function to know the size of the array. So, all API(s) just rely on the input provided by you.

char recv_data[1024];

// Socket setup and so on ommited...

bytes_recieved = recv(connected, recv_data, 1024, 0);
recv_data[bytes_recieved] = '\0';

The above code can cause trouble in more ways than one. It will lead to undefined behavior under the following conditions:<br>
(a) If recv returns `-1`, then you are directly indexing into the recv_data buffer without checking the return value<br>
(b) If recv returns `1024`, then again, it leads to out of bound access as the array of size `1024` should be accessed from `0` to `1023`.
Reply

#3
Even if you send larger bytes than the `recv()` buffer, you are still able to `recv()` it on succeeding calls to `recv()`, that's why you said that `bytes_received` is still `5000` bytes, because, let's say you send `5000` bytes, and your receive buffer is `1000` bytes, on the first call to `recv()` it will only get `1000` bytes, on the next call, `1000` bytes again, until it receives all your data. So, I think there's no buffer overflow here. This is by the way how TCP works.
Reply

#4
This

recv_data[bytes_recieved] = '\0';

could result in a buffer overflow, if 1024 bytes were received.

You might like to change this

bytes_recieved = recv(connected, recv_data, 1024, 0);

to become

bytes_recieved = recv(connected, recv_data, 1024 - 1, 0);

so that `bytes_recieved` would never become larger than 1023, which is the maximum valid index to `recv_data`.

----------
Also your system calls (`recv()`/`send()`) lack error checking. Test them for having returned `-1` prior to using the result in any other way.


----------

Referring your amendment:

`strlen()` tries to return the number of characters starting from the character pointed to by its argument up until the first `NUL`/`0`-character. This number could be any value, depending on where **you** placed the terminating `0`.

In case the seach for this `0`-terminator runs behind the memory allocated to `strlen()`s argument the program most certainly runs into undefined behaviour, and therefore could return any value.

So to answer your question: If `send_data` is **not** 0-terminated `strlen()` makes the app run into undefined behaviuor so it might crash or `strlen()` returns a value greater than 1024, so `send()` would try to send this number of characters.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through