飘云阁

标题: 【非越狱环境】钉钉躺床上打卡之WIFI篇 [打印本页]

作者: gengjf025    时间: 2017-2-7 16:02
标题: 【非越狱环境】钉钉躺床上打卡之WIFI篇
本帖最后由 gengjf025 于 2017-2-8 10:01 编辑

钉钉iOS客户端WIFI修改(非越狱环境)

本文续自上一篇:【非越狱环境】钉钉躺床上打卡之GPS篇https://www.chinapyg.com/thread-88593-1-1.html

一、背景
最近有朋友公司移动考勤用的是wifi考勤,即公司设置签到的wifi热点之后,员工只有在连接上该热点后才能打考勤成功,就顺手做了点小事情。


二、工具准备
见上一篇。

三、分析
1、iOS的wifi获取用到的CNCopySupportedInterfaces()和CNCopyCurrentNetworkInfo()两个函数,组合使用获取到一个CFDictionaryRef,能够读取SSID(wifi热点名)、BSSID(路由器的Mac地址)、SSIDDATA(SSID的十六进制);
2、很多app会获取当前网络状态,常用的是函数SCNetworkReachabilityGetFlags(),Reachability中会通过该函数判断当前网络是wifi还是其他状态;

知道这些东西之后就可以直接对这几个系统函数动手了,一劳永逸。

四、编码
    我们在上一篇的代码基础上增加wifi信息修改的相关代码,这里使用的是fishhook这个库,为了避免命名冲突,所有函数都加了前缀;
1、创建一个wifi信息类DTWifiModel,头文件如下:
[Objective-C] 纯文本查看 复制代码
//
//  DTWifiModel.h
//  DingTalkDylib
//
//
//

#import <Foundation/Foundation.h>
#import <SystemConfiguration/SCNetworkReachability.h>

@interface DTWifiModel : NSObject

// en0
@property (nonatomic, copy) NSString *ifnam;

@property (nonatomic, assign) SCNetworkReachabilityFlags flags;

// WIFI昵称,例如:公司办公wifi、公司客户wifi
@property (nonatomic, copy) NSString *nickName;

// BSSID:路由器的Mac地址
@property (nonatomic, copy) NSString *BSSID;

// SSID:路由器的广播名称
@property (nonatomic, copy) NSString *SSID;

// SSIDDATA:SSID的十六进制
@property (nonatomic, strong) NSData *SSIDDATA;

@property (nonatomic, assign) BOOL isSelected;

- (instancetype)initWithDictionary:(NSDictionary *)dictionary;

- (instancetype)initWith:(NSString *)ifnam dictionary:(NSDictionary *)dictionary;

@end

2、创建wifi信息展示类DTWifiSettingViewController,该类主要用于展示当前连接的wifi、已经设置过的wifi历史,便于切换:
核心函数如下:
(1)、获取当前wifi信息,获取到之后会额外记录当前网络状态的flags,存出以备后用:
[Objective-C] 纯文本查看 复制代码
- (void)fetchCurrentWifi {
   
    [_currentWifi.array removeAllObjects];
   
    CFArrayRef arrayRef = CNCopySupportedInterfaces();
    NSArray *ifs = (__bridge_transfer NSArray *)arrayRef;
   
    if(ifs && [ifs count] > 0) {
        
        NSString *ifnam = [ifs objectAtIndex:0];
        
        CFDictionaryRef info = CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        
        NSDictionary *dictionary = (__bridge_transfer NSDictionary *)info;
        
        if (dictionary && [dictionary count]) {
            
            DTWifiModel *wifi = [[DTWifiModel alloc] initWith:ifnam dictionary:dictionary];
            
            wifi.flags = [self fetchCurrentNetworkStatus];
            
            [_currentWifi addObject:wifi];
        }
    }
}
(2)、获取当前网络状态,很多app都会先获取网络状态判断是否为wifi连接,一次获取到wifi热点信息之后再记录一次当前网络状态,用于篡改系统函数返回的flags,代码如下:
[Objective-C] 纯文本查看 复制代码
- (SCNetworkReachabilityFlags)fetchCurrentNetworkStatus {
   
    // 创建零地址,0.0.0.0的地址表示查询本机的网络连接状态
    struct sockaddr_in zeroAddress;//sockaddr_in是与sockaddr等价的数据结构
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;//sin_family是地址家族,一般都是“AF_xxx”的形式。通常大多用的是都是AF_INET,代表TCP/IP协议族
   
    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress); //创建测试连接的引用:
    SCNetworkReachabilityFlags flags;
   
    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);
   
    if (!didRetrieveFlags) {
        NSLog(@"Error. Could not recover network reachability flagsn");
        return 0;
    }
   
    return flags;
}

3、创建类DTWIFIHook,用于hook系统函数:CNCopySupportedInterfaces()、CNCopyCurrentNetworkInfo()和SCNetworkReachabilityGetFlags(),代码如下:
[Objective-C] 纯文本查看 复制代码
// CFArrayRef CNCopySupportedInterfaces        (void)
static CFArrayRef (*orig_CNCopySupportedInterfaces)();

static CFArrayRef jf_CNCopySupportedInterfaces() {
   
    CFArrayRef re = NULL;
   
    DTWifiModel *wifi = [DTWIFIHook wifiHooked];
   
    if(wifi && wifi.ifnam) {
        
        NSArray *array = [NSArray arrayWithObject:wifi.ifnam];
        
        re = CFRetain((__bridge CFArrayRef)(array));
    }
   
    if(!re) {
        
        re = orig_CNCopySupportedInterfaces();
    }
   
    return re;
}

[Objective-C] 纯文本查看 复制代码
// CFDictionaryRef CNCopyCurrentNetworkInfo        (CFStringRef interfaceName)
static CFDictionaryRef (*orig_CNCopyCurrentNetworkInfo)(CFStringRef interfaceName);

static CFDictionaryRef jf_CNCopyCurrentNetworkInfo(CFStringRef interfaceName) {
   
    CFDictionaryRef re = NULL;
   
    DTWifiModel *wifi = [DTWIFIHook wifiHooked];
   
    if(wifi) {
        
        NSDictionary *dictionary = @{
                                     @"BSSID" : (wifi.BSSID ? wifi.BSSID : @""),
                                     @"SSID" : (wifi.SSID ? wifi.SSID : @""),
                                     @"SSIDDATA" : (wifi.SSIDDATA ? wifi.SSIDDATA : @""),
                                     };
        re = CFRetain((__bridge CFDictionaryRef)(dictionary));
    }
   
    if(!re) {
        
        re = orig_CNCopyCurrentNetworkInfo(interfaceName);
    }
   
    return re;
}

[Objective-C] 纯文本查看 复制代码
// Boolean SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags *flags)
static Boolean (*orig_SCNetworkReachabilityGetFlags)(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags *flags);

static Boolean jf_SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags *flags) {
   
    Boolean re = false;
   
    DTWifiModel *wifi = [DTWIFIHook wifiHooked];
   
    if(wifi && wifi.flags > 0) {
        
        re = true;
        
        *flags = wifi.flags;
    }
   
    if(!re) {
        
        re = orig_SCNetworkReachabilityGetFlags(target, flags);
    }
   
    return re;
}

[Objective-C] 纯文本查看 复制代码
+ (void)load {
   
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        _jf_rebind_symbols((struct _jf_rebinding[3]){
            {"CNCopySupportedInterfaces", jf_CNCopySupportedInterfaces, (void *)&orig_CNCopySupportedInterfaces},
            {"CNCopyCurrentNetworkInfo", jf_CNCopyCurrentNetworkInfo, (void *)&orig_CNCopyCurrentNetworkInfo},
            {"SCNetworkReachabilityGetFlags", jf_SCNetworkReachabilityGetFlags, (void *)&orig_SCNetworkReachabilityGetFlags},
        }, 3);
    });
}

五、注入、打包、签名
操作步骤同上一篇,安装测试:
(, 下载次数: 88)
(, 下载次数: 75)
可以看到即使使用3G网络也可以实现wifi考勤,大功告成;

六、代码地址
[url=https://github.com/gengjf/DingTalkDylib/tree/master/DingTalkDylib%2BWIFI][/url]

七、结束语
谨慎使用!








作者: hzq999    时间: 2017-2-7 16:48
我们单位居然用分享逍客
作者: gengjf025    时间: 2017-2-7 16:54
hzq999 发表于 2017-2-7 16:48
我们单位居然用分享逍客

不管什么app,应该都是通用的,提供的代码是hook的系统函数,与app本身无关

作者: ytyay    时间: 2017-2-7 20:04
学习,感谢分享  。
作者: 0xcb    时间: 2017-2-7 21:38
6 钉钉还有动态补丁,我的一直没升级之前的bug钉钉都补上了
作者: 雲裏霧裏    时间: 2017-2-7 21:54
看起來不錯,先收藏,備用了
作者: Superhero    时间: 2017-2-7 22:09
我想有个安卓版。。。。

买不起苹果。。。
作者: jia87921    时间: 2017-2-7 23:16
顶楼主啦..希望楼主多发精品好帖啦.....
作者: samvon    时间: 2017-2-8 02:39
学习了~~谢谢
作者: orz    时间: 2017-2-8 09:11
不错不错。学习了。 。收藏一下。有空也玩玩。
作者: nociabx    时间: 2017-2-8 09:49
楼主好人,谢谢分享!
作者: Rooking    时间: 2017-2-8 09:59
很给力啊 可惜用不起苹果
作者: sunshine_liu    时间: 2017-2-8 10:22
太牛逼了,安卓的,用其他手机设置热点,ssid改成公司一样的,但是mac肯定不一样,如果自己是管理员的话也能骗过去了
作者: sunshine_liu    时间: 2017-2-8 10:23
hzq999 发表于 2017-2-7 16:48
我们单位居然用分享逍客

我们差点也用了,那个太贵,最后就么用了


作者: lov    时间: 2017-2-8 11:04
这个得好好看看学习下
作者: kuniao    时间: 2017-2-8 12:18
学习,感谢分享  。
作者: carreyxiang    时间: 2017-2-8 14:14

学习,感谢分享  。
作者: hu007    时间: 2017-2-8 15:27
向楼主学习了!
作者: KKKevin    时间: 2017-2-8 17:12
支持楼主大刀阔斧改革
作者: tree_fly    时间: 2017-2-8 18:13
学习,好文章。
作者: huyusha    时间: 2017-2-9 11:03
这个太棒了 谢谢楼主!!
作者: huyusha    时间: 2017-2-9 11:04
完美完美  等下试试
作者: imlove    时间: 2017-2-9 15:13
WIFI  打卡这么牛
作者: myfamilyx    时间: 2017-2-9 16:11
这个真是没想到,先学一学。
作者: lxcjy    时间: 2017-2-10 09:39
谢谢分享!!!

作者: zwc123xyz    时间: 2017-2-10 14:16
大神啊,膜拜!
作者: felicity    时间: 2017-2-10 14:21
哈哈 我们公司用的也是纷享销客 android hook定位功能就好了 后来没事分析了打卡接口 直接写了个app打卡  每天定时打卡 爽YY
作者: ioeso    时间: 2017-2-13 07:01
谢谢分享,学习
作者: 静水流深    时间: 2017-2-13 12:51
学习一下,谢谢楼主
作者: zpb_520    时间: 2017-2-13 18:19
看看咋用,感谢分享
作者: 论坛管理员    时间: 2017-2-14 09:47
此贴已执行加分操作!
作者: kyle250    时间: 2017-2-15 11:22
收藏学习,但是还不懂怎么具体投入使用
作者: pygcnm    时间: 2017-2-16 00:38
好东西啊,谢谢楼主分享
作者: kangaroo    时间: 2017-2-17 08:09
哈。这个正好给老婆用

作者: 世态炎凉    时间: 2017-2-17 14:39
不错不错  楼主出一个安卓吧,非常需要安卓啊

作者: mancong122    时间: 2017-2-18 12:33
楼主是不是,对软件进行欺骗的方式来模拟已在制定WiFi环境下,然而软件的签到网络通讯可以是用wifi或流量都可以的,那在后台增加一个签到流量的来源过滤不就不能用了。

作者: tree_fly    时间: 2017-2-18 15:59
mancong122 发表于 2017-2-18 12:33
楼主是不是,对软件进行欺骗的方式来模拟已在制定WiFi环境下,然而软件的签到网络通讯可以是用wifi或流量都 ...

总是道高一尺魔高一丈,大牛喜欢在源头处下手

作者: gengjf025    时间: 2017-2-18 22:05
本帖最后由 gengjf025 于 2017-2-18 22:06 编辑
mancong122 发表于 2017-2-18 12:33
楼主是不是,对软件进行欺骗的方式来模拟已在制定WiFi环境下,然而软件的签到网络通讯可以是用wifi或流量都 ...

请看代码,或者看文章中的分析,主要做了有两个工作,一个是劫持并修改获取当前网络状态的系统函数,永远返回当前网络是wifi连接状态,另一个是劫持并修改获取当前wifi信息的两个系统函数,返回指定的wifi信息(热点名、mac地址及其16进制的数据)。所以并不是hook钉钉的类或方法,直接hook的系统函数。从目前一段时间的使用情况看,钉钉应该没有其他特殊的防作弊方式。

作者: mancong122    时间: 2017-2-19 12:45
gengjf025 发表于 2017-2-18 22:05
请看代码,或者看文章中的分析,主要做了有两个工作,一个是劫持并修改获取当前网络状态的系统函数,永远 ...

你的文章我看到了,我的意思是:如果说签到的wifi网络属于局域网范畴,只能是在该网络下才能访问到指定的服务端,这个服务端并不与外面一切的网络连接方式有数据交换,就类似于说:在公司门口放一台不联网的电脑,并且每个人都是把自己的手机连接这台电脑发出的WiFi一次才算是成功,那这样子不就是变相的进行了签到数据的来源,除非你要吧wifi中继到你的卧室。。以上是菜鸟想法,不要见笑。
作者: mancong122    时间: 2017-2-19 12:46
tree_fly 发表于 2017-2-18 15:59
总是道高一尺魔高一丈,大牛喜欢在源头处下手

菜鸟的级别的见解,就是拿出来说笑一下。
作者: gengjf025    时间: 2017-2-19 17:07
mancong122 发表于 2017-2-19 12:45
你的文章我看到了,我的意思是:如果说签到的wifi网络属于局域网范畴,只能是在该网络下才能访问到指定的 ...

你说的这种情况,还要移动考勤干啥?直接打指纹或者刷卡算了。
作者: abcat    时间: 2017-2-20 10:13
感谢 还是希望给个成品啊
作者: 不要说以后    时间: 2017-2-21 09:58
要是有成品就更好了
作者: gengjf025    时间: 2017-2-21 10:20
不要说以后 发表于 2017-2-21 09:58
要是有成品就更好了

企业证书哪能随便乱用,现在Apple查的很严的,一不小心就会被封的
作者: sbygupyg    时间: 2017-2-21 15:06
不明觉厉,感谢楼主分享!
作者: smallhorse    时间: 2017-2-21 20:04
不带你们这么玩的!难怪咱上班跑断腿啊.................情何以堪?
作者: tfh22    时间: 2017-2-22 07:47
有签名工具和证书呢,楼主给个成品!!!呜.
作者: 翊鸣    时间: 2017-2-22 13:03
感谢楼主无私共享~。~
作者: yohunl    时间: 2017-2-22 17:42
查看源码地址
作者: 左岸麦田    时间: 2017-2-22 21:25
有安卓的就好了。

作者: dengxian89    时间: 2017-2-25 19:32
看起来很厉害的样子

作者: 狐狸.Z.z.    时间: 2017-3-4 15:53
看起来很不错哦,收藏之~~~ 谢谢LZ啦!!!学习一下先
作者: cyclonekid    时间: 2017-3-8 11:09
我去·   这个太强大了·    支持下你···
作者: 小锤子起钉儿    时间: 2017-3-9 18:00
再来看看了,顶贴。

作者: glts    时间: 2017-3-10 13:37
额,PYG人才倍出.是一种学习和探究的方式.但并不是一种逃班的工作态度.
作者: Alonc    时间: 2017-3-10 20:31
感谢楼主分享。有空试试看
作者: wang2515611    时间: 2017-3-11 16:42
好东西,谢谢大神
作者: var_dump    时间: 2017-3-11 20:21
哈哈 坏事干的
作者: 清明风    时间: 2017-3-12 09:37
谢谢分享了。
作者: bresan    时间: 2017-3-12 22:41
看起来很不错哦,收藏之~~~谢谢LZ啦!!!
作者: lovesoft    时间: 2017-3-14 10:41
精品,不错啊!
作者: 浪漫人字脱    时间: 2017-3-15 16:55
这也行,太帅了
作者: 天线宝宝    时间: 2017-3-21 18:59
厉害啊,哈哈哈
作者: 斌哥    时间: 2017-3-22 20:29
大神,安卓有嘛?感谢
作者: qientin085    时间: 2017-3-28 13:38
我就不清楚你那个选择Wi-Fi和定位的界面在哪里打开的?
作者: gengjf025    时间: 2017-3-28 14:37
qientin085 发表于 2017-3-28 13:38
我就不清楚你那个选择Wi-Fi和定位的界面在哪里打开的?

屏幕右下角有个绿色设置按钮,如果第一次登陆之后没显示,双击home键并杀掉app,重新打开程序之应该就能看见了,再找不到请看代码,一共也没多少代码量
作者: 皮尔斯    时间: 2017-3-29 14:35
有点强大,确实是大神,试一试效果如何
作者: 873116202    时间: 2017-4-1 20:12
666666666666666

作者: Celia    时间: 2017-4-1 21:37
直接打指纹或者刷卡算了。
作者: sytvch    时间: 2017-4-3 14:27

不错不错。学习了。 。收藏一下。有空也玩玩。
作者: shanghsunlee    时间: 2017-4-3 18:52
太感谢了  学习一番
作者: vtiansin    时间: 2017-4-7 16:16
好东西

作者: 隔壁老王好善良    时间: 2017-4-8 04:09
有成品就好了
作者: zhangwcx    时间: 2017-4-8 13:24
谢谢,好久没用钉钉了
作者: yang946009    时间: 2017-4-17 20:56
赞一个,PYG有你更精彩
作者: 绞尽乳汁6    时间: 2017-4-17 21:35
厉害了我的楼主
作者: jokerfox    时间: 2017-4-18 09:25
不错不错。学习了。 。收藏一下。
作者: 海梦君    时间: 2017-4-24 09:22
支持大大技术帖子 学习一下
作者: 1007892159    时间: 2017-4-24 15:51
我也来看看感谢楼主的教程

作者: acai    时间: 2017-4-27 14:08
ios的啊,,,可惜我用的是安卓,,,xposed里面有,但好像最近不灵了
作者: 英杰    时间: 2017-5-4 10:21
Good,如果是安卓,root后,有N种方法
作者: king82    时间: 2017-5-5 09:26
3G打卡都可以成功,这就厉害了。我的构思是把家里的SSID和MAC地址更改成和公司一样的,就实现WIFI打卡,3G也能实现,这才是真大牛。
作者: tha    时间: 2017-5-6 00:18
知己知彼百战百胜
作者: haida    时间: 2017-5-7 18:20
高手。。。。。。。。。膜拜。。。。。。。。。。。。

作者: 每天有艳遇    时间: 2017-5-10 10:18
谢谢 我拿来用下
作者: atop885    时间: 2017-5-17 20:19
不错的东西赞一个!
作者: zxs25    时间: 2017-5-18 13:47

不错不错。学习了。 。收藏一下。有空也玩玩
作者: 461688115    时间: 2017-5-18 14:14
我注册了这么就还是初来乍到
作者: 77356614    时间: 2017-5-18 16:33
新人看不懂.但是要学习一下.
作者: 雪衣少年    时间: 2017-5-24 09:31
叼啊  大佬真强啊!!!
作者: gnsb    时间: 2017-6-5 10:24
学习了解一下---------
作者: voogoo    时间: 2017-6-8 14:52
感谢分享此文件!躺床上也打卡 外勤偷懒必备!

作者: zzmaster    时间: 2017-6-10 18:24
如果路由器可以改MAC会不会更好?
作者: 红尘旧梦i    时间: 2017-6-12 06:22
技术宅!!!
作者: zhangjy_12    时间: 2017-6-12 14:32
感谢楼主分享,顶贴支持~
作者: gaomengcao    时间: 2017-6-16 13:41
支持~~~~~~~~~~~~~~~
作者: luabc123    时间: 2017-6-19 20:08
这个很厉害啊,哈哈
作者: flyfly    时间: 2017-6-21 21:20
这也行,楼主真是太给力了
作者: gapp    时间: 2017-6-23 16:41
非常不错,顶赞
作者: bingonle    时间: 2017-6-24 14:07
思路值得参看,谢谢分享,很给力




欢迎光临 飘云阁 (https://www.chinapyg.com/) Powered by Discuz! X3.4