zardus/preeny

Documentation request: why desock uses threads?

d33tah opened this issue · 12 comments

As in the issue name - what is the reason why desock uses threads instead of performing all the operations in the main thread?

Sorry for the laggy response! I was dealing with conference deadlines and then HITCON travel.

There are three ways that I can think to implement desock:

  1. LD_PRELOAD all functions that do any sort of socket operations (reads, writes, sockopts, fdopen, etc). I didn't choose this because getting the full exhaustive list seemed like a pain and it seemed impossible to test.
  2. (only for programs that dup() connections to stdin/stdout) Disable dup2. This is what desock_dup.so does.
  3. Open a socketpair and synchronize input and output between the socketpair and stdin/stdout. There's no way that I can see to do it fully inline without tricks, though. I see a few ways to implement this:
    1. Spin off a thread and synchronize the socketpair in that thread. This is the route that I chose, because I already had some easily-adaptable code laying around for it.
    2. Use alarm(), and in the handler do the synchronization and set another alarm. This seems messy, as programs frequently use alarm for other stuff.
    3. Use some other way to implement timers (http://www.2net.co.uk/tutorial/periodic_threads), many of which use threads or alarm in the backend.

I happened to implement options 2 and 3i. Of course, I'm totally open to PRs to add more methods!

Hello,

Thank you for the exhaustive reply! I have one more question:

W dniu 01.09.2015 o 22:51, Yan pisze:

  1. Open a socketpair and synchronize input and output between the socketpair and stdin/stdout. There's no way that I can see to do it fully inline without tricks, though. I see a few ways to implement this:
    1. Spin off a thread and synchronize the socketpair in that thread. This is the route that I chose, because I already had some easily-adaptable code laying around for it.

What kind of problems would you get if socket() would just return stdin?

Cheers,
d33tah

Some operations work differently on sockets versus regular file
descriptors. For example, recv and send will return ENOTSOCK if the
descriptor isn't a socket. Otherwise, things would be a lot more
straightforward :-)

W dniu 02.09.2015 o 00:51, Yan pisze:

Some operations work differently on sockets versus regular file
descriptors. For example, recv and send will return ENOTSOCK if the
descriptor isn't a socket. Otherwise, things would be a lot more
straightforward :-)

I thought that it boils down to a read. Anyway, I think I will once
try to build wrappers around all socket operation functions.

Yeah, that's what had I thought as well, but it doesn't fly... Run this
with strace and you'll see:

int main()
{
  char asdf[100] = { 0 };
  recv(0, asdf, 20);
}

If you get a wrapper like that together and want to send a PR, I'd really
appreciate it! It'd be awesome to have more desock modules. Keep in mind,
though, that to be general, you'd have to support stuff like fdopen (and,
conversely, fileno). This might involve some tracking of libc state.

Good luck!

Thanks, I might play with that. By the way, I think I found out all that I wanted, so add a link to this discussion if you feel like and anyway, I'm good to close this issue ;)

Sounds good. I added a link to this issue from the README.

Hey @d33tah out of curiosity: did you ever manage to work on those wrappers that you were talking about, that won't require an extra thread?

@andronat unfortunately, not. IIRC afl++ supports much better network fuzzing features now, so is it actually still needed?

@d33tah wow! Thanks for your super fast reply! May I ask you if you could point me to this feature of afl++ you are talking about? I couldn't find it... 😕

@andronat you might be right - it looks like I can't quickly find it either. Perhaps there actually is some point to implementing my idea then.

(Necro-ing this bug) There was a fork of AFL that would fuzz programs that communicated over network sockets, but it was never merged. Current AFL++ requires that input / output is on stdin/out just as the original AFL did.