4 ms·
This follow-up post has the details of the "Markov babbler": https://maurycyz.com/projects/trap_bots/ https://maurycyz.com/projects/trap_bots/
by fainpul 1y ago
This follow-up post has the details of the "Markov babbler":
https://maurycyz.com/projects/trap_bots/ https://maurycyz.com/projects/trap_bots/
- isoprophlex 1y agoVery elegant and surprisingly performant. I hope the llm bros have a hard time cleaning this shit out of their scrapes.
- dang 1y agoThanks, we'll put that in the toptext as well.
- kelnos 1y agoInteresting that babble.c doesn't compile (with gcc 14): babble.c: In function ‘main’: babble.c:651:40: error: passing argument 1 of ‘pthread_detach’ makes integer from pointer without a cast [-Wint-conversion] 651 | pthread_detach(&thread); | ^~~~~~~ | | | pthread_t * {aka long unsigned int *} In file included from babble.c:77: /usr/include/pthread.h:269:38: note: expected ‘pthread_t’ {aka ‘long unsigned int’} but argument is of type ‘pthread_t *’ {aka ‘long unsigned int *’} 269 | extern int pthread_detach (pthread_t __th) __THROW; I assume the author is using a compiler that either doesn't show that warning by default, or doesn't error out on that warning by default. But I'm surprised the program doesn't crash (at the very least, I'm surprised it doesn't run out of memory eventually, as presumably libc can't actually detach those threads, and pthread_join() is never called). As this binary does a bunch of manual text parsing and string operations in C (including implementing a basic HTTP server), I'd recommend at the very least running it as an unprivileged user (which the author implicitly recommends via the provided systemd unit file) inside a container (which won't definitely save you, but is perhaps better than nothing). The program also uses unsafe C functions like sprintf(). A quick look at one of the instances suggests that the use is indeed safe, but that sort of thing raises red flags for me as to the safety of the program as a whole. And while it does process requests very quickly, it also appears to have no limit on the number of concurrent threads it will create to process each request, so... beware.
- maurycyz 1y agoSorry about that, stupid mistake on my side. I've fix the version on the server, an you can just edit the line to "pthread_detach(thread);" The snprintf() is only part of a status page, so you can remove it if you want. As for the threads, that could be an issue if directly exposed to the internet: All it would take for an attacker to open a whole a whole bunch of connections and never send anything to OOM the process. However, this isn't possible if it's behind a reverse proxy, because the proxy has to receive all the information the needs server before routing the request. That should also filter out any malformed requests, which while I'm fairly sure the parser has sane error handling, it doesn't hurt to be safe.
- kelnos 1y agoNot sure if I agree with you on the thread exhaustion issue. The client can still send a flood of correctly-formed requests; the reverse proxy will pass them all through. As I said above, yes, the fact that babble processes requests so quickly would make this harder, but you could still end up with (tens of?) thousands of concurrent requests if someone is really determined to mess with you. A solution could be to limit concurrent requests in the reverse proxy, but personally I prefer to write software that doesn't require another piece of software, configured correctly, to keep it safe. And regardless, even with ~25 years of C experience under my belt, I don't think I'd ever be wholly comfortable exposing my C code to the internet, even behind a reverse proxy. Not coming at you directly with this, but I'm frankly skeptical of anyone who is comfortable with that, especially for a one-off service that won't see a lot of use and won't get a lot of eyeballs on it. (And I'm especially uncomfortable with the idea of posting something like this on a website and encouraging others to use it, when readers may not understand the issues involved.)
- gridspy 1y agoThread exhaustion attack 1. Start <thread_count> connections to a server 2. Hold connections open 3. Do nothing else Server 1. Incoming connection. assign a thread. 2. Wait for request <--- Attack causes us to get stuck here 3. Serve request 4. Close connection and thread / return to threadpool Solution: Use a reverse proxy to handle the incoming connections. Typical reverse proxies such as nginx use event-based polling not a per-connection thread so they are immune to this issue.