[ prog / sol / mona ]

prog


SPAM BOOTS ON SCHEMEBBS

1 2021-06-28 19:03

Just wondering... those honeypot inputs/textareas, they really work?

2 2021-06-28 22:09

>>1
This is a pretty old technique. They obviously don't work if you're aware of them, and any human making a spambot for any particular site would be. I guess the idea is that there are certain entities, who write bots which scour the web for orphases to vomit and shit into on contact. Alternatively and perhaps more likely one could imagine children running generalized orphases filler even if they themselves were not capable of creating a trivial spam bot (or even configuring one properly). In theory most adults don't suffer from this sort of degeneracy, so you need only have a basic test to weed out the children and the most perverse of the deviants to have a spam filter that often works.

3 2021-06-29 02:44

>>3
Considering there's an official API I think they're ok with hand crafted bots.

4 2021-06-29 15:08 *

>>3
I've noticed some classic mitigations implemented for bespoke spambots as well; although, I won't describe them. Generally when it comes to hand rolled spambots we rely on Ben Bitliddle to come in, manually delete the posts, and then pwn the spammer even behind their proxy as he did last time. I imagine the API is mostly intended to be used by archivers and user-clients.

5 2021-07-03 18:33

It doesn't block out anyone who targets this site specifically but it will block out those weird bots that randomly crawls sites and spew ads into the text fields

6 2021-07-07 18:52 *

There's actually a huge botnet targeting /mona/. Something ludicrously oversized for a site with such a low traffic. 99.999999999% of visits are from spambots and crawlers.
SchemeBBS is often unattended for a long period of time, so /mona/ was shut down for some months before a quick fix was written leveraging ngx-auth-request-module. The authentication server is written in Gerbil Scheme, it checks if the request origin is in a dnsbl-like blacklist and replies 403 if that happens to be the case.

location / {
    ...
    auth_request /auth;
    auth_request_set $auth_status $upstream_status;
}
#auth server
location /auth {
    internal;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
    if ($request_method = POST ) {
        proxy_pass http://localhost:<port>/check?ip=$remote_addr;
    }
    if ($request_method = GET ) {
        return 200;
    }
}

Unfortunately, it makes it much harder to use a proxy for privacy-savvy users to post but real anonymous anons should really start using i2p. (an update to i2pd seems to have fixed the recurring segfaults and this home-cooked ``WAF'' is still better than routing everything through something evil like Cloudflare.

7 2021-07-07 19:01 *

The authentication server, below. Gerbil and Gambit were a nightmare to port on FreeBSD and once again patches weren't shared upstream because having to register anywhere to post something is such a pain. Gerbil's included batteries allows to write server programs roughly as terses as their goland counterparts.

(import :std/net/httpd
        :std/net/address
        :std/text/json
        :std/sugar
        :std/iter
        :std/getopt
        :std/misc/alist
        :std/net/request
        :gerbil/gambit/threads
        :std/misc/bytes)
(export main)

(define BLACKLIST "listed_ip_180.txt") ; fetch https://www.stopforumspam.com/downloads/listed_ip_180.zip
(define APIKEY "<get_your_own>")
(define banlist (make-hash-table-eq))

(define (params->alist p)
   (map (lambda (x)
          (let (l (string-split x #\=))
            (cons (car l) (cadr l))))
        (string-split p #\&)))

(define (ip->uint ip)
  (u8vector->uint
   (uint-list->u8vector
    (map string->number (string-split ip #\.))
    'little
    1)))

(define (uint->ip n)
  (string-join
   (map number->string (u8vector->list (uint->u8vector n)))
   #\.))

(define (readlines file)
 (let ((infile (open-input-file file)))
   (let loop ((lines '())
              (next-line (read-line infile)))
    (if (eof-object? next-line)
        (begin (close-input-port infile)
               (reverse lines))
        (loop (cons next-line  lines)
              (read-line infile))))))

(define (is-banned? ip)
  (hash-key? banlist (ip->uint ip)))

(define (in-abuseipdb? ip)
  (let* ((json (http-get "http://api.abuseipdb.com/api/v2/check"
                        headers: `(("Key" . ,APIKEY)
                                   ("Accept" . "application/json"))
                        params: `(("ipAddress" . ,ip))))
         (score (hash-get (hash-get (request-json json) 'data) 'abuseConfidenceScore)))
    (if (> score 1)
      (begin (hash-put! banlist (ip->uint ip) '()) #t)
      #f)))
8 2021-07-07 19:10 *
;;; This is basically the web server in gerbil/src/tutorial/httpd/
;;; (C) vyzo at hackzen.org
;;; insanely fast, you should use that for Scheme web applications

(define (run address)
  (let (httpd (start-http-server! address mux: (make-default-http-mux default-handler)))
    (http-register-handler httpd "/" root-handler)
    (http-register-handler httpd "/check" check-handler)
    (thread-join! httpd)))

;; /
(define (root-handler req res)
  (http-response-write res 200 '(("Content-Type" . "text/plain")) "Ok"))

;; /check
(define (check-handler req res)
  (let* ((params (params->alist (http-request-params req)))
         (ip (cdr (assoc "ip" params))))
    (if (or (is-banned? ip) (in-abuseipdb? ip))
      (http-response-write res 403 '(("Content-Type" . "text/plain")) "banned")
      (http-response-write res 200 '(("Content-Type" . "text/plain")) "not banned"))))

;; default
(define (default-handler req res)
  (http-response-write res 404 '(("Content-Type" . "text/plain"))
    "these aren't the droids you are looking for.\n"))

(def (main . args)
  (for-each (lambda (x) (hash-put! banlist x '() ))
            (map ip->uint (readlines BLACKLIST)))

  (define gopt
    (getopt (option 'address "-a" "--address"
                    help: "server address"
                    default: "127.0.0.1:<port>")))

  (try
   (let (opt (getopt-parse gopt args))
     (run (hash-get opt 'address)))
   (catch (getopt-error? exn)
     (getopt-display-help exn "hellod" (current-error-port))
     (exit 1))))
9 2021-07-12 03:15 *

>>6-8
This is pretty nasty, but shit gets nasty in times of war.

10 2022-01-31 02:55

i will take advantage of this thread

i am working on a funny-captcha
a little port of samegame in javascript
a 3x3 grid, if you solve it, you can post it
but javascript = not good

i do not want collect user data of any kind, including cookies, and no javascript
i wonder if this is possible... a fun captcha that can be solved quickly

11 2022-01-31 07:51

>>10
Sounds like something that would break sbbs.el.

12 2022-01-31 13:53

>>6

replies 403

But I get that error and I'm not a robot yet

13 2022-02-01 02:48

don't need no fuckin' cpathcast

14 2022-02-01 03:21

There ought to be bots performing some kind of service, like irc bots. Maybe a bot can make a thread and host some kind of game in it.

15 2022-02-02 05:12

>>11
why? because of javascript?

>>10
i have given up on "samegame" captcha, i do not like javascript at all
i made a "picross" captcha, it is so silly-easy, just checkboxes, pretty css and cute perl :3

A1:A2:A3:A4
B1:B2:B3:B4
C1:C2:C3:C4
D1:D2:D3:D4

4x4 grid is enough to draw japanese characters,,,

==2 2 3 1
==□ □ □ ■ 1==
==■ ■ ■ □ 3==
==□ □ ■ □ 1==
==■ ■ ■ □ 3==

it can be solved in a few seconds, but i do not think it is enough to stop custom-made spam boots
maybe another one, more complicated, bigger, that should be done once a day or so, after completed you could post successfully for a whole day or some hours
but messing with ips and/or cookies is not funny, cute and pretty :(

16 2022-02-03 13:10 *

<script> is meant to run other languages, here is our gnu guile. With sxml modules wrapper.

<script language ="guile">
(use-modules (sxml sxml))
(define dom (sxml:modify
  '(("html/head/title" delete)
  ("html/head" insert-into (title "YOU HAVE BEEN SCREENFETCHED BY LAINANON")))
  (sxml:document (current-dom)))
)
(overwrite-dom (current-dom) (srl:sxml->html dom))
</script>

Something else that doesn't overwrite the whole document or force browser calls.

<script language ="guile">
(use-modules (sxml web))
(sxmlweb:modify
  '(("html/head/title" delete)
  ("html/head" insert-into (title "YOU HAVE BEEN SCREENFETCHED BY LAINANON")))
)
</script>
17


VIP:

do not edit these