360免费360破解wifi密码软件码

360电脑免费无线网密码是多少_百度知道
360电脑免费无线网密码是多少
360电脑免费无线网密码查询以及修改设置的方法:1、打开360安全卫士面板,点击右下角的【更多】;2、找到【360免费WiFi】并且打开3、进入到如下面板后,点击显示密码,密码就显示了;& & &鼠标双击第一行就是修改WiFi的名字, &第二行就是修改WiFi密码了。
采纳率:75%
来自团队:
己设置..........
安装的时候随机产生的,可以设置
该无线网速有多快
自己设置的
其他2条回答
为您推荐:
其他类似问题
无线网的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。钓鱼WiFi 实时检测
避免隐私泄露财产损失
一秒拉黑蹭网设备
保护自家WiFi不被蹭网
WiFi测速快人一步
找到网速最快的免费WiFi
专业更专注
构建核心优势 续航手机网络
感谢您对我们工作的支持与帮助,提交成功后我们会尽快与您取得联系
以下均为必填项,请选择产品类型、问题类型
感谢您对我们工作的支持与帮助
感谢您对我们工作的支持与帮助,提交已成功
免费WiFi电脑版
插入设备后创建WiFi失败
可以创建但无法连接
连上了wifi但上不了网
校园网问题
网速慢/没信号
找不到免费WiFi
运营商WiFi连不上
免费WiFi连不上
免费WiFi创建失败了
提示没有无线网卡
可以创建但无法连接
连上了WiFi但不能上网
校园网问题
网速慢/没信号360免费WIFI加密签名破解获取他人无线明文密码(还可刷金币换运营商流量)
360免费WIFI加密签名破解获取他人无线明文密码(还可刷金币换运营商流量)
设计错误/逻辑缺陷
厂商已经确认
第一回合:加解密破除
根据特征定位功能点代码
根据 http 请求中method=Wifi.password 为特征,定位请求封装代码存在 qE 类中
接下来对函数进行hook 分析
追踪到其加密方式为DESede (DESede 是由DES对称加密算法改进后的一种对称加密算法。使用 168 位的密钥对资料进行三次加密的一种机制 ),实现类为 vA
接下要做的就是定位DESede key 就可以破解完成 http 请求加解密的整个过程并且自己用代码实现.
现在开始跟踪 key 的生成算法.从以下代码可以得知 init 中的 key 是由 public static String a(String arg2) 方法获取的. 从代码中得知 key 的生成实际是由com.qihoo.freewifi.utils.SecurityUtils完成的
其中 getkey 是一个 native 方法 (可以看出 app 的保护工作主要放在保护 key 上)
public static native String getKey(String paramString1, String paramString2);
接下来就要分析 so 咯.
>> strings libsecurity.so |grep -i getkey
Java_com_qihoo_freewifi_utils_SecurityUtils_getKey
然后再对 IDA F5中参数类型进行修复就得到了如下
一个 hash 过程,这个函数在so 没有啥包含可以直接引用
主导 key 生成因子2的就是 getKey(String paramString1, String paramString2) 第二个参数了. (因子1就是一些固定 method 字符串)
SecurityUtils#b(Context arg1, String arg2, String arg3)的 arg3引入
回看vA#a代码
public static String a(String arg2) {
return SecurityUtils.b(Application.a(), arg2, vB.a(Application.a()));
vB#a 得到类似 UUID 的东西传入 SecurityUtils#getKey 得到 key.
(这里在可以否定前面的推断 类UUID 的字符串比和服务端有关.不然服务端无法得到 key 解密,客户端会把生成 key 的因子2传到服务端,在 http 请求中是 m2 参数. 这样服务端就有了生成 key 的两个因子来生成 key 进行解密了)
设备关联 id 生成函数vB#a 分析 ,主要逻辑如下:将 imei,deviceid,android_id拼接后进行 md5
v0 = vB.b(arg6);
String v1 = Settings$System.getString(arg6.getContentResolver(), &android_id&);
String v2 = vB.a();
vB.a = vP.a(&& + v0 + v1 + v2);
其中 v0是由vB#b(Context arg2)生成 ,一种情况是返回vB.b = arg2.getSystemService(&phone&).getDeviceId() ,如果若空则返回&360_DEFAULT_IMEI&
public static String b(Context arg2) {
vB.b = wa.a(arg2, &APP_STORE_IMEI0&, &&);
if(!TextUtils.isEmpty(vB.b)) {
String v0_1 = vB.b;
return v0_1;
vB.b = arg2.getSystemService(&phone&).getDeviceId();
if(TextUtils.isEmpty(vB.b)) {
return &360_DEFAULT_IMEI&;
wa.b(arg2, &APP_STORE_IMEI0&, vB.b);
return vB.b;
catch(Exception v0) {
return &360_DEFAULT_IMEI&;
v1是由 Settings$System.getString(arg6.getContentResolver(), &android_id&) 生成
v2是由 vB#a() 生成,连接之后传入vP#a(String arg1) 算出 md5 值.即得到生成的 key 因子2.
public static String a() {
String v0_3;
String v1 = &&;
Class v0_1 = Class.forName(&android.os.SystemProperties&);
Object v0_2 = v0_1.getMethod(&get&, String.class).invoke(v0_1, &ro.serialno&);
catch(Exception v0) {
v0_3 = v1;
return v0_3;
响应包的加密方法和请求包的加密方法一致.直接解密响应包
其中 pwd 参数就是 wifi 的密码了,若未查询到则为空.
梳理一下整个流程:
1.通过拼接imie/android_id/deviceid 再进行 md5得 m2
2.将 m2 和 method 传入 native 函数getkey 得到对称密钥 key
3.通过 key 对请求相应包内的 data 进行 DESede 加解密
自此数据的加解密工作已经基本完成.进入第二个环节:签名
第二回合:签名破除
其中 sign 参数由
v0_1.add(new BasicNameValuePair(&sign&, tM.b(v0_1, v1)));
函数生成,v0_1为 url 中参数的 list 集合,而 v1则由tM.b()方法生成的一个32位字符串
tm#b生成字符串的的过程又和tM.c(); 以及 vA.b(v1, &User.getConfig&);有关联
private static String b() {
String v0 = &&;
String v1 = tM.c();
if(!TextUtils.isEmpty(((CharSequence)v1))) {
v0 = vA.b(v1, &User.getConfig&); // DESede 解密函数
catch(Exception v1_1) {
v1_1.printStackTrace();
return v0;
而在 tM.c()方法中主要是调用了wa.a(Application.a().getBaseContext(), &qlink_secret_key&, &&)
private static String c() {
String v0;
if(!TextUtils.isEmpty(tM.a)) {
v0 = tM.a;
tM.a = wa.a(Application.a().getBaseContext(), &qlink_secret_key&, &&);
v0 = tM.a;
return v0;
wa#a(Context arg1, String arg2, String arg3)方法调用了sV#b(Context arg2, String arg3, String arg4)
public static String a(Context arg1, String arg2, String arg3) {
return sV.b(arg1, arg2, arg3);
hook sV#b(Context arg2, String arg3, String arg4) 输入输出如下
09-15 11:02:27.749
/? I/QihooWifi﹕ in sV#b(C|s|s) = last_update_date| para2 =
09-15 11:02:27.749
/? I/QihooWifi﹕ out sV#b(C|s|s) =
09-15 11:56:55.622
/? I/QihooWifi﹕ in sV#b(C|s|s) = qlink_secret_key| para2 =
09-15 11:56:55.632
/? I/QihooWifi﹕ out sV#b(C|s|s) = Rd36RTbNXij5tjaqHZiEQY7ulZdvnrjbRWFtcIUBivz6wPxjdAMfYw==
//DESede 加密后的32位字符串
09-15 11:57:00.032
/? I/QihooWifi﹕ in sV#b(C|s|s) = APP_STORE_IMEI| para2 =
09-15 11:57:00.032
/? I/QihooWifi﹕ out sV#b(C|s|s) = 9f2de7ceb7dc3e4a0e9
其中qlink_secret_key字符串将传入sV#b(Context arg7, String arg8)
private static Cursor b(Context arg7, String arg8) {
Cursor v0_2;
Cursor v6 =
if(arg7 != null && !TextUtils.isEmpty(((CharSequence)arg8))) {
ContentResolver v0 = arg7.getContentResolver();
v0_2 = v0.query(SharedPrefProvider.a, null, &key=\'& + arg8 + &\'&, null, null);
catch(Throwable v0_1) {
v0_2 = v6;
if(v0_2 == null) {
String v0_3 = &select value from sharedpref where key=?&;
if(sV.b == null || !sV.b.isOpen()) {
sV.b = new SPDBHelper(arg7).getReadableDatabase();
v0_2 = sV.b.rawQuery(v0_3, new String[]{arg8});
catch(Throwable v0_1) {
v0_2 = v6;
v0_2 = v6;
return v0_2;
从代码中可以看出qlink_secret_key的值是从表 sharepref 中取出
那这个值又是如何生成并存储到 sqlite 中的了?
会看tM#c()方法,当成员变量 tM.a 为空的时候是通过 tM#a(String paramString) 来赋值的.
public static void a(String paramString)
a = paramS
wa.b(Application.a().getBaseContext(), &qlink_secret_key&, paramString);
追踪到 wa#b(Context paramContext, String paramString1, String paramString2)
public static void b(Context paramContext, String paramString1, String paramString2)
sV.a(paramContext, paramString1, paramString2);
继续跟踪sV#a(Context paramContext, String paramString1, String paramString2)
public static void a(Context paramContext, String paramString1, String paramString2)
if (paramContext == null) {}
paramContext = paramContext.getContentResolver();
ContentValues localContentValues = new ContentValues();
localContentValues.put(&key&, paramString1);
localContentValues.put(&value&, paramString2);
if (paramContext.update(SharedPrefProvider.a, localContentValues, &key=?&, new String[] { paramString1 }) == 0)
paramContext.insert(SharedPrefProvider.a, localContentValues);
catch (Throwable paramContext) {}
可以确定是通过tM#c()方法写入qlink_secret_key这个键值的,现在又要用xref 来查看改方法的调用了. (猜测一:这个值是服务端返回的,恰巧返回包就是用 DESede 加密的,此处也是加密的. 猜测二:之前提到的 update_key可能是更新此处的 key)
有两处引用,其中一处是rn#a(rp arg3) ,其中 arg3.c 是通过取 json 中的 data 下 url 键值.(可以佐证猜测一)
public void a(rp arg3) {
if(arg3 != null && arg3.c != null) {
String v0_1 = arg3.c.optString(&url&);
if(TextUtils.isEmpty(((CharSequence)v0_1))) {
goto label_9;
tM.a(v0_1);
catch(Exception v0) {
rh.a(this.a, arg3);
第二处应用在tk#a(tz arg7) , 其中
tk.a = &http://api.free./intf.php&;
method 阐述为User.getConfig(继续佐证猜测一这个返回值是通过此处 url 请求到的)
public static void a(tz arg7) {
vO.a(&ApiHelper&, &getUserConfig&);
tL v0 = tK.a(tk.a, &User.getConfig&, null, null, null, null);
//请求 api
vO.a(&ApiHelper&, &getUserConfig end:& + v0.h);
JSONObject v1 = tk.a(v0);
//从返回值中取出 data 字段 既为 qlink_secret_key
if(v1 == null) {
tk.a(v0, arg7, new Object[0]);
String v1_1 = v1.optString(&url&);
if(!TextUtils.isEmpty(((CharSequence)v1_1))) {
tM.a(v1_1);
tk.a(v0, arg7, new Object[0]);
接下来清除 app 数据后抓包来捕获此请求,东静态结合提高效率.
重置应用后第一个请求就是获取此参数,那么问题来了.知道那是用来计算 sign 的,那么第一请求包的sign是如何来的了? (猜测:和另外两个 native 函数有关)
回看tM#a(String arg9, String arg10, List arg11, String arg12, boolean arg13) 方法,若 method 为User.getConfig那么 v1 便为空来计算 sign....
v1 = &User.getConfig&.equals(arg10) ? && : tM.b();
v0_1.add(new BasicNameValuePair(&sign&, tM.b(v0_1, v1)));
回看tM#a(Context paramContext, String paramString1, String paramString2) 方法,若 para2为空则调用的是SecurityUtils.b(paramContext, paramString1)函数
private static String a(Context paramContext, String paramString1, String paramString2)
if (TextUtils.isEmpty(paramString1)) {
return &&;
synchronized (rz.a)
if (TextUtils.isEmpty(paramString2))
paramContext = SecurityUtils.b(paramContext, paramString1);
paramContext = paramContext.toLowerCase();
return paramC
paramContext = SecurityUtils.a(paramContext, paramString1, paramString2);
而 tM#b(Context paramContext, String paramString)
public static String b(Context paramContext, String paramString)
if ((paramContext == null) || (paramString == null) || (paramString.equals(&&)))
if (paramContext == null) {
return &contextisnull&;
if ((paramString == null) || (paramString.length() == 0)) {
return &signstrisnull&;
a(paramContext);
return paramString + &&loadsoerror=true&;
paramContext = initnew(paramContext.getApplicationContext(), paramString, &&, false);
return paramC
catch (Throwable paramContext) {}
return &&;
又要到查看 so 的时候啦
这里显然做了个包判断,若像getkey 一样直接调用肯定会返回 none,所以得分析下isVaild函数来尝试绕过这个限制.
这时有两个选择 1.path so 在判断处将 BEQ 改成 BNE 2.最后一个布尔型变量传 true..
这里选择第二种简单的方法.算出如下结果
09-15 18:29:20.060
/org.wooyun.qihoowifi I/Hi360﹕ MySign = 5c1c5d32ebd2ee7f8beea1b
对比之前 hook 的结果,证明猜测是正确的
09-15 15:09:14.610
/? I/QihooWifi﹕ in tM#a(c|s|s) = channel=100001&devtype=android&inviter_qid=0&m2=9f2de7ceb7dc3e4a0e94&manufacturer=LGE&method=User.getConfig&model=Nexus%205&nance=9&nettype=WIFI&os=4.4.4&qid=0&v=237 | para3 =
09-15 15:09:14.610
/? I/QihooWifi﹕ out tM#a(c|s|s) = 5c1c5d32ebd2ee7f8beea1b
nance 为时间戳生成方式如下:
v3[18] = &nance&;
v3[19] = String.valueOf(System.currentTimeMillis());
至此 sign 的破解基本完成.简单梳理下整个流程
1.先将 url 中参数按序拼接成字符串
2.若 method为User.getConfig将拼接字符串传入native 函数 initnew 计算出 sign 值,并且得到 sign 的加密盐值 data:url
3.若 method 不等于 User.getConfig 则将拼接字符串传入 native 函数 sign 中, 并且对2得到的加密盐进行 DESede 解密后一同传入. (注意大小写敏感)
漏洞证明:
有了上面的分析就可以自己写程序刷下金币了..再加上之前搞过万能钥匙...现在不用装两个应用.可以集成到一个 app 里啦.
修复方案:
版权声明:转载请注明来源 @
快来写下你的想法吧!
文章数:38565
(C) 安全脉搏}

我要回帖

更多关于 免费wifi密码破解器 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信