Team Hax: eps, aksnowman, solus, coeus and Madsy. To make things go smoothly we tried to outline a game plan for our team. We would have certain people do specific tasks to help secure the box before grace ended, and when it came time to attack we pretty much all did what we could. It eventually looked like this: ->discover OS [eps] upgrade kernel ->install screen nano ->upgrade/disable/remove services ->set up stunnel telnet on port 11692 [coeus] take care of SUID/SGID/WW files/dirs [aksnowman] move ssh to port 554 [aksnowman] install MySQL, port 11967 [aksnowman] move shells, set up restricted and otp shells [aksnowman] set up discardd on several ports (listed in discardd.txt) [aksnowman] set up port forwarding on several ports (listed in forward.txt) [aksnowman] backdoor ssh (log failed logins, insert backdoor password) [coeus] block access to port 554, 2 forwarded ports, and 8 discardd ports from all IPs except gateway [solus] code a service to remotely execute some commands if they are in a white list Things didn’t go exactly as planned though. eps could not locate the driver that was the source of a kernel panic on boot up, so the patched kernel could never be installed. Instead the kernel was just upgraded via apt-get, since our distribution was Ubuntu Server. We did a full system upgrade with apt-get and all the packages were updated. coeus wrote a quick shell script to identify suid/guid binaries and world writable directories. We removed the suid bit from all binaries except /bin/su, which would bit us in the butt later on in the games. After removing all world writable directories, except /tmp and /var/tmp (symlink to /tmp), eps created a ramdisk and mounted it as /tmp with the noexec and nosuid options. This would severely restrict any dot-slash exploits and provide a file system that would make it very hard for a user to execute any of their own compiled binaries. Sometime during grace period the root password got changed. We still don’t know who did it, but we suspect it happened when they were trying to sudo passwd to change their own account’s password, since passwd wasn’t suid. So we had to guide ocyrus through the recovery process of booting up into a live CD and change the root password. This worked and we got our root account back. When it came to services, we had telnet over an SSL tunnel, solus’ remote command execution service, modified openssh, mysql, and aksnowman’s discardd. Solus’ service was down from time to time for some reason, and aksnowman’s discardd was down sometimes as well. The original plan was to use telnet over the SSL tunnel instead of ssh, but we all just used ssh anyways. After grace ended, we all started nmaping each others box, which is probably one of the reasons for the lag. tcpdump on the gateway was taking up 50% of the CPU when it was being run. eps worked on the gateway and ended up with access to Plasmatonic’s account. The original plan was to edit his .profile and prepend a directory controlled by us in his PATH environment variable that held a backdoored version of an ssh client. This way if he didn’t use /usr/bin/ssh and just ssh, it would log his password and then log him into their box. However, he was using lattera’s ssh client, which luckly he copied into his home directory and was using that. eps also noticed that voodohul was using the ssh binary in Plas’ home dir as well. So we modified the ssh client to work with their modified ssh server and waited. Unfortunately Plasmatonic or vooduhul didn’t use the binary for almost 3 days, and it took a little coercing Plas to get him to login. This didn’t help though because the password never worked. When asked about it later, he said that it was missing one letter, so I don’t know what happened with that. We never captured vooduhul’s password either as he started using a different ssh client. While eps was doing that other members on the team were trying to attack the other boxes. Absolut’s box had some vulnerable services up that were meant to be a challenge. After a while aksnowman exploited the first one which dropped us into a shell that was either in a VM or chrooted, probably a VM. We were never able to do anything with this shell. In the end it turned out to be a stalemate. We were forced to give out shells, and we were never owned and never owned anybody else. Around this time our team started to lose interest. I’m still not sure but I think somebody owned team Retoros. It’ll be interesting to see all the other whitepapers. ------------------------------------ gotcha.txt ------------------------------------ :liv!gobbles@h3c-19127579.xmission.com PRIVMSG ###### :livinded auth 2916 :liv!gobbles@h3c-19127579.xmission.com PRIVMSG ###### :I changed the root pass to "f3B;a^]kR5" (without the quotes) :liv!gobbles@h3c-19127579.xmission.com PRIVMSG ###### :I'll be updating to slack 11 later tonight ------------------------------------ aksnowman's log ------------------------------------ Pre-game ======== opened multiple instances of my C logbot under nicks that might accidently be tab-completed in order to potentially capture useful info from the unwary IRCer at some point, lattera noticed the false lattera_ and started looking to find who it was Grace ===== created user accounts changed root password added all users to sudoers updated apt-get upgraded stuff w/ apt-get uninstalled un-needed services left mysql and ssh installed nano screen wireshark tcpdump tshark watched coeus paste a list of our open ports and info about our distro in #roothack for all to see ran `who` on gateway to find which teams had which boxes ran `cat /etc/hosts` on gateway to match boxes->IPs noticed one of my log bots captured some potentially useful data changed mysql port to 11967 changed mysql root password "zxcvbnm,./" watched nooks paste an nmap scan of our box in #roothack for all to see changed ssh port to 18965 'cause we had it on 554 and s0kket told everyone in #roothack that, basically set up ~/.ssh/config files on gateway so our new ssh port wouldn't show up ("ssh gothicus", no -l or user@) dinked around and somehow wasted several hours worked on securing solus's whitelistRemoteExec.py script looked around on the gateway searched for SUID/SGID/world writables changed a bunch of accounts shells to /bin/false at some point in the day, an ircbot named lattera_ captured the contents of gotcha.txt, may have been some sort of Social Engineering (SE) attempt or something == end day 1, 0340 == ran w on gw, saw "ssh root@captainmorgan" root login on captainmorgan's ssh isn't disabled set up otpShell as default user shell worked on updating ssh set up a script to start all the custom services should be added to wherever but I'm lazy and tired at this point and don't really care, I'll start them all manually, hahaha discardd is now run over 9200 times, wewt! later decreased to around 100 times, was killing our box memory hog, heh sshd is running mysqld is running several instances of solus' whitelistRemoteExec.py several instances of portForwarder forwarding to various ports on other boxes In-Game ====== looked for obvious signs of backdooring in latteras modified ssh went to girlfriends, slept for about 8 hours, still felt tired came back, we still had control over the box, had to restart most of the services, kernel panic'd in the night and services were started manually downloaded and reverse-engineered retoros' numLogin used objdump on the binary to dump assembly started skimming over it, got stuck looking over the getnumber or w/e loop 'cause I was talking in IRC too and getting distracted moved on to main loop, finally noticed where the numbers were being stored and when they were being accessed again takes 4 numbers for input the 4 numbers had to add up to 1337 confirmed using 1334\n1\n1\n1\n explored retoros' numLogin shell seems to be vmware, probably server ran ifconfig, googled interfaces (lnc0) whole first page all said VMware interface that means don't do anything stupid on it... went to girlfriends for the night, came back nice and rested updated suid/sgid backdoor started messing w/ retoros' tbbs =================================== Choice: 22^?^?^? SQL error: unrecognized token: "" SQL error: unrecognized token: "" =================================== Parent Thread ID: -1 Forum ID: quack Post Subject: yay .. .. SQL error: no such column: quack =================================== started exploring the gateway and chickenman and z3x's accounts as they had default passwords set =================================== /tmp/.`cje$ ls -la total 60 drwxrwxrwx 2 lattera lattera 4096 2008-05-19 01:36 . drwxrwxrwt 14 root root 4096 2008-05-19 01:39 .. -rw-r--r-- 1 marshallmellow marshallmellow 5 2008-05-18 12:23 14151MApS3j_asdf -rw-r--r-- 1 livinded livinded 6 2008-05-19 01:23 263997bu8kZ_asdf -rw-r--r-- 1 livinded livinded 6 2008-05-19 01:17 26403c6Hhzh_asdf -rw-r--r-- 1 livinded livinded 5 2008-05-18 17:24 26411MhsJik_asdf -rw-r--r-- 1 livinded livinded 6 2008-05-19 01:04 26441wK3qB2_asdf -rw-r--r-- 1 livinded livinded 6 2008-05-19 01:16 29217GtyVIl_asdf -rw-r--r-- 1 chickenman chickenman 6 2008-05-19 01:36 844_a6sQQMY_asdf -rw-r--r-- 1 chickenman chickenman 6 2008-05-19 01:14 866_a33l2iK_asdf -rwxr-xr-x 1 beist beist 5297 2008-05-18 00:05 bash -rwxr-xr-x 1 marshallmellow marshallmellow 1156 2008-05-18 12:16 .bash_history -rwxrwxrwx 1 beist beist 5459 2008-05-19 00:34 .beist_bash_history /tmp/.`cje$ ls -la total 60 drwxrwxrwx 2 lattera lattera 4096 2008-05-19 01:36 . drwxrwxrwt 14 root root 4096 2008-05-19 01:39 .. -rw-r--r-- 1 marshallmellow marshallmellow 5 2008-05-18 12:23 14151MApS3j_asdf -rw-r--r-- 1 livinded livinded 6 2008-05-19 01:23 263997bu8kZ_asdf -rw-r--r-- 1 livinded livinded 6 2008-05-19 01:17 26403c6Hhzh_asdf -rw-r--r-- 1 livinded livinded 5 2008-05-18 17:24 26411MhsJik_asdf -rw-r--r-- 1 livinded livinded 6 2008-05-19 01:04 26441wK3qB2_asdf -rw-r--r-- 1 livinded livinded 6 2008-05-19 01:16 29217GtyVIl_asdf -rw-r--r-- 1 chickenman chickenman 6 2008-05-19 01:36 844_a6sQQMY_asdf -rw-r--r-- 1 chickenman chickenman 6 2008-05-19 01:14 866_a33l2iK_asdf -rwxr-xr-x 1 beist beist 5297 2008-05-18 00:05 bash -rwxr-xr-x 1 marshallmellow marshallmellow 1156 2008-05-18 12:16 .bash_history -rwxrwxrwx 1 beist beist 5459 2008-05-19 00:34 .beist_bash_history =================================== got bored, decided to install qemu on gothicus & set up a debian box on 10.0.1.2 w/ faked accounts and copies of the services so I can give out shells for trade or w/e never got qemu running, gothicus kept getting disconnected from the network when I'd try setting up the bridging, didn't have enough experience to know what I needed to do there messed with retoros' bbs some more =================================== Choice: ' SQL error: unrecognized token: "' AND ParentPostID = -1 AND Flags = 1" =================================== Parent Thread ID: " Forum ID: " Post Subject: " " .. SQL error: 5 values for 6 columns =================================== Parent Thread ID: ' Forum ID: ' Post Subject: ' ' .. SQL error: 4 values for 6 columns =================================== "parentPostID", ?, user, subject, content, ? users: 1 lattera 2 dummy 3 tbbs power went out came back the next day, webserver w/ all my notes wouldn't boot don't remember if I did anything, probably nothing productive oh, I noticed windo had set something in his home directory to execute whenever chickenmans account logged in I disabled that from .profile and tried to get a copy of it, it was chmod 711 or such though livinded started talking w/ me, discussed a possible trade of information he had about that executable (apparently a keylogger) for a local shell on our box, said I'd consider it, later forgot about it and got distracted looking at executables beist had downloaded from his domain found beist was being slightly paranoid (and for good reason) and had downloaded his own statically compiled copies of 'watch', 'ssh', and something else that I don't remember next thing I remember, came back and heard game was over, stalemate --------------------------------------------- remoteWhitelistExec.py by solus with edits by aksnowman --------------------------------------------- #!/usr/bin/env python from socket import * import sys, os, thread def checkWhiteList(command): whitelist = open(sys.argv[2], "r") allowed = [] response = "" for line in whitelist: allowed.append(line.rstrip()) if command.find('&') != -1 OR command.find('`') != -1 OR command.find('$(') != -1 OR command.find('|') != -1 OR command.find(';') != -1: return response try: index = allowed.index(command) except ValueError: response = "Could not execute command: %s\n" % command except IndexError: response = None return response def handler(clientSocket, address): command = "" response = "" data = "" while True: try: clientSocket.send("# ") data = clientSocket.recv(100) command = data[:-2] if command == "": continue if command == "exit": break response = checkWhiteList(command) if response == None: break if response == "": f = os.popen(command) for line in f: response += line clientSocket.send(response) response = "" except error, e: clientSocket.close() break clientSocket.close() ##MAIN## if len(sys.argv) != 2: print "Usage: %s " % sys.argv[0] sys.exit() if os.fork() != 0: sys.exit() serverSocket = socket(AF_INET, SOCK_STREAM) serverSocket.bind(('', int(sys.argv[1]))) serverSocket.listen(5) while True: clientSocket, address = serverSocket.accept() thread.start_new(handler, (clientSocket, address)) serverSocket.close() -------------------------------------------------- spitServer.py by solus -------------------------------------------------- #!/usr/bin/env python from socket import * import sys, os, thread def handler(clientSocket, address): command = "" response = "" data = "" try: outputFile = open(sys.argv[2], "rb") for byte in outputFile: response += byte clientSocket.send(response) except socket.error: clientSocket.close() clientSocket.close() ##MAIN## if os.fork() != 0: sys.exit() if len(sys.argv) != 3: print "Usage: %s " % sys.argv[0] sys.exit() serverSocket = socket(AF_INET, SOCK_STREAM) serverSocket.bind(('', int(sys.argv[1]))) serverSocket.listen(5) while True: clientSocket, address = serverSocket.accept() thread.start_new(handler, (clientSocket, address)) serverSocket.close() ------------------------------------------------- discardd.c by aksnowman ------------------------------------------------- #include #include #include #include #include #include #include #include int main (int argc, char *argv[]){ char recvBuf[1024]; int mysock, theirsock, recvBufLen = 1023; struct sockaddr_in my_addr; struct sockaddr_in their_addr; int returnInt, sinSize; if (argc != 3){ printf("Syntax: %s \n", argv[0]); exit(1); } if (strcmp(argv[2], "tcp") == 0){ mysock = socket(PF_INET, SOCK_STREAM, 0); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(atoi(argv[1])); my_addr.sin_addr.s_addr = INADDR_ANY; memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero); returnInt = bind(mysock, (struct sockaddr *)&my_addr, sizeof my_addr); if (returnInt == -1){ printf("Error: failed to bind.\n"); exit(1); } listen(mysock, 10); while(1){ sinSize = sizeof their_addr; theirsock = accept(mysock, (struct sockaddr *)&their_addr, &sinSize); printf("Connection made from %s\n", inet_ntoa(their_addr.sin_addr)); while ( recv(theirsock, recvBuf, recvBufLen, 0) != 0){ } close(theirsock); printf("Connection closed.\n"); } }else if(strcmp(argv[2], "udp") == 0){ }else{ printf("Error: chose \"tcp\" or \"udp\" for service to run on.\n"); exit(1); } exit(0); }