首页
社区
课程
招聘
[原创]自己动手从iOS Keychain中恢复保存的Wifi密码
发表于: 2014-11-12 21:53 27992

[原创]自己动手从iOS Keychain中恢复保存的Wifi密码

2014-11-12 21:53
27992

最近在学用Theos编写插件和小工具,本来打算自己动手写个类似Wifi Passwords的工具,用于查看保存在iOS设备中的Wifi密码的。不过搜了下居然没找到具体的实现方法。

本来以为iOS和Android一样保存在某个plist里(Android的Wifi密码明文保存在/data/misc/wifi/wpa_supplicant.conf),不过Google了才发现iOS虽然在 /private/var/preferences/SystemConfiguration/com.apple.wifi.plist 里保存了Wifi信息,但密码却是存储在Keychain中的,而且网上没有给出具体的读取办法

鉴于对Keychain Services不熟,只好用 Hopper Disassembler 反汇编WiFiPasswords自己看了。代码不多,大部分都是和UITableView相关的内容,排除掉这些很快发现 -[RootViewController refresh] 就是要找的函数:



这里读取了 /private/var/preferences/SystemConfiguration/com.apple.wifi.plist 的List of known networks中的信息(意义不明,实际上直接用SecItemCopyMatching也是能获取到Wifi名的,而且它后面也这样做了)。到机器上用plutil查看该plist文件,会看到类似下面的内容:

    "List of known networks" =     (
                {
            "80211D_IE" =             {
                "IE_KEY_80211D_COUNTRY_CODE" = JP;
            };
            "80211W_ENABLED" = 0;
            AGE = 41;
            "AP_MODE" = 2;
            "ASSOC_FLAGS" = 1;
            "BEACON_INT" = 20;
            BSSID = "00:2e:1f:54:1d:82";
            CAPABILITIES = 1041;
            CHANNEL = 12;
    ...
CFTypeRef kSecClassGenericPassword ;
CFTypeRef kSecClassInternetPassword ;
CFTypeRef kSecClassCertificate ;
CFTypeRef kSecClassKey ;
CFTypeRef kSecClassIdentity;
#import <Security/Security.h>

int main(int argc, char **argv, char **envp)
{
  NSMutableDictionary *query = [NSMutableDictionary dictionary];

  [query setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
  [query setObject:(__bridge id)kSecMatchLimitAll forKey:(__bridge id)kSecMatchLimit];
  [query setObject:(__bridge id)@"AirPort" forKey:(__bridge id)kSecAttrService];
  [query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];

  CFTypeRef result = NULL;
  OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
  if (status != errSecSuccess) {
    printf("[ERROR] SecItemCopyMatching() failed! error = %d\n", (int)status);
    return;
  }

  NSArray *wifi_list = (NSArray *)result;
  for (int i = 0; i < wifi_list.count; i++) {
    NSDictionary *wifi = (NSDictionary*)wifi_list[i];

    NSString *output = [NSString stringWithFormat:@"%@", wifi];
    printf("%s\n", [output cStringUsingEncoding:NSUTF8StringEncoding]);
  }

  if (result != NULL) {
    CFRelease(result);
  }

  return 0;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>application-identifier</key>
  <string>com.zzz.my-idevice-tools</string>
  <key>get-task-allow</key>
  <true/>
  <key>keychain-access-groups</key>
  <array>
    <string>apple</string>
  </array>
</dict>
</plist>

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 3
支持
分享
最新回复 (8)
雪    币: 1098
活跃值: (193)
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
2
这个程序也可以实现。
https://github.com/ptoomey3/Keychain-Dumper
2014-11-13 15:12
0
雪    币: 302
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
还是IDA看的直观:
上传的附件:
2014-11-13 17:54
0
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
4
[QUOTE=zhuliang;1330557]这个程序也可以实现。
https://github.com/ptoomey3/Keychain-Dumper[/QUOTE]

赞!已经star,早点看到就不用去反汇编了
2014-11-14 10:06
0
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
5
[QUOTE=suntiger;1330604]还是IDA看的直观:
[/QUOTE]

确实,IDA这个易懂多了。Hopper Disassembler虽然也有正确的字符串标注,不过
movw r2, #11a8
movt r2, #0xd
add r2, pc

跟进去才知道,实际就是取 @"/private/var/preferences/SystemConfiguration/com.apple.wifi.plist"
2014-11-14 10:11
0
雪    币: 136
活跃值: (135)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
6
不错 分析的很好 很给力啊
2014-11-14 17:11
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
虽然看不懂,但是觉得你很牛逼
2014-11-20 21:12
0
雪    币: 16
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
很不错!
2014-11-22 10:46
0
雪    币: 244
活跃值: (189)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
原来是在tt的大神
2016-8-17 17:17
0
游客
登录 | 注册 方可回帖
返回
//