事情是这样子的,公司有个运维想转到实验室(andiSEC)做安全,经过不到两个月的学习和指导,感觉自己掌握了一些东西,但一直有个疑问,“dvwa上的这些漏洞他都知道,但是遇到一个网站后还是不知道如何下手”,所以就把公司的一个系统交给他让他练练手,和所有初学者一样,拿到一个网站不知如何下手,上来就用wvs一通扫描,因为整个系统的接口的参数都是经过加密的,所以扫描的结果当然是一无所获。然后他就不知道该做什么了,问我应该怎么办,我说,你一上来就用wvs的作法就是不对的,首先,像这类工具都有一个特点,它是通过向服务器发送大量payload来进行测试的,会导致有很多脏数据,也会删除服务器上的数据。其次,该系统是前后端分离的框架,前端根本就没有源码,所以它只能爬到几个js链接,当然扫不出来什么结果了。正常的做法是架上代理,自己先手动点点网站,看看系统都有哪些功能,每个接口都是怎么传参的,然后手动向可疑的接口中添加payload,观察系统的响应。通过简单指点后,这个小子还真的找到几个可疑点,又因其不会任何开发语言,所以尴尬的事来了…
运行环境
目标系统IP:19.19.19.11
信息收集
NMAP扫描端口,发现目标设备开启了3306端口,MySQL版本号是5.6.47-87
漏洞挖掘
步骤1:登录系统,页面浏览
发现大多数接口传递的参数都进行了加密
加密格式类似base64,尝试使用base64解密失败
步骤2:继续浏览,找到未加密的页面接口
该页面是用户管理页面,点击页面中的“开通状态”开关,可修改用户的开通状态。
步骤3:猜测此操作作用
id为用户的id号,status为开通状态,status=1表示权限关闭,status=0表示权限开通。猜测执行的语句为:update “用户表” set status = 1 where id = 55;
步骤4:使用sqlmap进入post注入测试,失败
步骤5:手工注入过程
a.正常输入时,接口返回结果分别为权限开通和权限关闭。
猜测用户id应该为数值型,输入字符加单引号,预期会执行失败,来判断是否存在sql注入。当输入id=abc’&status=0后并没有达到预期报错 ,结果如下图:
多次测试后发现,无论id是否填写是否正确,返回结果均为执行成功,权限开通。
b.字符型注入没有报错,尝试数字型注入
当输入id=55 and 1=1&status=0和id=55 and 1=2&status=0后,期待返回结果分别为成功和失败,结果事与愿违,同上面的注入一样,返回结果均为执行成功,权限开通。一般在这个时候,大家可能就会判定为,此处无sql注入。(类似sqlmap这样的工具也是这种判断原理)
不过初学者是非常期待挖出他的第一个漏洞的,所以还想要坚持一下,疑惑为什么输入单引号不报错,为什么输入and 1=2也不报错,这样是不是可以判断一定没有sql注入漏洞。其实不是的,判断有没有注入一个基本原则是看数据库有没有执行成功,当然,实际情况下,大家是没办法去看数据库内容的,所以,可以通过刷新用户管理列表页面,看看用户开通状态是否有变化,这样就可以判断and 1=1有没有执行成功,然后漫长的血泪遍开始上演…
每当在id后面加一句sql语句就就需要刷新一下用户管理列表,看看修改的那个用户状态开关是否有变化,如果状态有变化,就说明id后添加的sql语句正确执行了
当他输入and 1=1后刷新页面,用户管理页面的用户状态真的被修改了,然后接着输入and 1=2时,再次刷新用户管理页面用户状态没有被修改,所以很确定这里就存在sql注入了。给你们看看一个初学者在真实场景下拿到人生第一个漏洞时的心情:
找到了注入点,接下来就是继续扩大战果,需要知道数据名、表名、表中的数据,同时让他写下他的挖掘过程,内容过于真实,就不一一列举了,直接看他的笔记:
他就这样一句句地在判断数据库名,还有……还有……表名……
比较认真的小伙子,当执行完这一切后,他还写了修复建议,虽然修复建议写的不好,但是态度很重要:
后续
我告诉他可以用python写个脚本,替换id后的sql语句,然后再通过请求用户管理列表状态看结果,这样就可以自动化完成上面的步骤,奈何他不会写任何开发语言,所以就有了他上述过程,执行一步刷新一下页面看一下用户状态变化。
来源:freebuf.com 2020-07-20 09:37:41 by: andiSEC
请登录后发表评论
注册