├── .gitmodules ├── CNAME ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── analyses ├── d_keep_alive2.md ├── error_no.md └── pppoe_realworld.md ├── c_version ├── README.md └── esp8266 │ ├── Udp_server.ino │ └── readme.md ├── custom ├── Drcom_CQU.py ├── Drcom_CQU_HuxiCampus.py ├── Drcom_LYU.py ├── Drcom_SWUPL.py ├── S99drcom ├── bistu_drcom_d.py ├── drcom-generic-debug-u62.py ├── drcom_BISTU.py ├── drcom_d_gxnuedu.py ├── drcom_d_hnist.py ├── drcom_d_version.py ├── drcom_d_中国民航大学.py ├── drcom_d_云南师范大学商学院(杨林校区).py ├── drcom_d_云南师范大学商学院(海源校区).py ├── drcom_d_广东财经大学.py ├── drcom_d_广西工业职业技术学院(武鸣三校区).py ├── drcom_d_衡水学院.py ├── drcom_for_dlnu_520(x).py ├── haue_drcom.py ├── haust_drcom.py ├── heau-drcom.py ├── ppp_esc.sh ├── pppoe.sh ├── ynudcc_dr.py ├── 湖南信息职业技术学院_d.py ├── 重庆第二师范学院 ├── 长沙保险职业学院_u6x.py └── 长沙联通.py ├── drcom_d_config.py ├── drcom_p_config.py ├── images ├── pppoe1.jpg └── pppoe2.jpg ├── latest-pppoe-python3.py ├── latest-pppoe.py ├── latest-wired-python3-lyu.pyw ├── latest-wired-python3.py ├── latest-wired.py ├── openwrt ├── README.md └── root │ ├── bin │ ├── drcom │ └── transdrcom │ ├── etc │ ├── config │ │ └── drcom │ ├── init.d │ │ └── drcom │ └── rc.d │ │ └── S99drcom │ └── usr │ └── lib │ └── lua │ └── luci │ ├── controller │ └── drcom.lua │ └── model │ └── cbi │ └── drcom.lua ├── tests ├── drcom_d.lua ├── fake_svr.py └── pppoe_heartbeat_analysis.py └── utils ├── database_passcode.py └── drcom_2016.lua /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "c_version/dogcom"] 2 | path = c_version/dogcom 3 | url = https://github.com/mchome/dogcom 4 | [submodule "c_version/openwrt-dogcom"] 5 | path = c_version/openwrt-dogcom 6 | url = https://github.com/mchome/openwrt-dogcom 7 | [submodule "c_version/luci-app-dogcom"] 8 | path = c_version/luci-app-dogcom 9 | url = https://github.com/mchome/luci-app-dogcom 10 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | drco.me 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 请大家发issue之前,先务必看清楚wiki里面的内容,如果你们觉得wiki写的不够详细,请自行修改,谢谢。 2 | https://github.com/drcoms/drcom-generic/wiki 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # drcom-generic [![Join the chat at https://gitter.im/drcoms/drcom-generic](https://badges.gitter.im/drcoms/drcom-generic.svg)](https://gitter.im/drcoms/drcom-generic?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 3 | 4 | ## 注意 5 | 6 | 本项目会随着 *DrCOM* 客户端更新而跟进,建议您直接 *Watch* 而不要 *fork*,除非您想提交代码,不然 *fork* 毫无意义。请可以折腾 *DrCOM* 的同学,请发邮件到 latyas@gmail.com, 让我把您加入开发者。 7 | 8 | ## 发起Issue(提问的要求) 9 | [提问的智慧](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/master/README-zh_CN.md) 10 | 11 | 如果你不能登录,请发Issue的时候附上用哪个脚本文件,脚本的日志输出,正常客户端的抓包,并且附上你的学校的名称,最好可以提供相关的Windows和Linux下的客户端,提高沟通效率。 12 | 13 | 所有的 Issue 在 15 天内没有**任何更新的**或者**已经解决**的将做关闭处理,除非再提供更有帮助于解决问题的资料,否则Issue不会Reopen,并且同一个人同样的Issue请不要重复提交。 14 | 15 | 同一个学校的同学请先自行搜索是否有已经解决的方案,强烈建议线下交流讨论,传播相关的解决方案,不赞成同样的问题提问多次,被判断为同样的Issue时,会给出可能相关的Issue,并且关闭掉当前的,如确有不同请在该issue下提交comment说明不同的地方,包括但不限于版本升级,不同校区,多版本共存等等。 16 | 17 | 请勿发表和本repo无关的issue,无关的issue一般包含但不限于下列议题: 18 | 19 | * 学校11点半断网怎么破? 20 | * p版如何多播? 21 | * 为什么不做一个GUI? 22 | * 路由器怎么刷openwrt? 23 | 24 | 有些问题需要你提供更详细的说明,而不是纯粹的描述你所看到的现象,如: 25 | 26 | * Windows下程序闪退 - 请给出具体的错误或者异常栈 27 | * Address has already used (一般广泛见于windows) - 请检查官方客户端是否关闭 28 | 29 | 等等 30 | 31 | 使用问题 **不建议** 在 issue 中提问,因为wiki中已经描述的足够清晰,这类问题大致上会问: 32 | 33 | * 脚本怎么启动啊? 34 | * 怎么放到路由器里 35 | 36 | 提问的标题最好可以直击主题,诸如以下的标题是不礼貌的: 37 | 38 | * 老掉线 39 | * 5.2.1(p)用不了 40 | * 无法登陆 41 | 42 | 等等,合适的标题参考 43 | 44 | * 如果掉了不能自动重连,已添加hotplug但还是得重启路由器才能连上 45 | * drcom版本 5.2.0d,使用路由器登陆,多台设备时掉线 46 | * 5.20x版802.1x正常,心跳包执行不到几次后802.1x收到下线报文 47 | * “禁止商业使用“不属 AGPL 范畴(x 48 | * 关于测试latest-pppoe.py 文件出现socket.timeout: timed out 49 | * 已经拨号成功了,运行latest-pppoe.py 报错:socket.error: [Errno 10013] 50 | * 吉大定制版,无限 被服务器拒绝 ([login] server return exception.retry) 51 | * 如果IP是自动获取,那个host_ip = 应该怎么填写啊? 52 | 53 | 等等 54 | 55 | 如果你在 linux 环境下做测试,请在发 issue 的时候将发行版和其对应的版本一并发上来(假设没有进行过部件的升级),如果你使用的是 openwrt 系统,请使用官方源代码编译出的固件或者使用官方提供的编译好的固件,并提供对应的版本号。**请不要使用其他第三方的基于openwrt修改的系统进行测试** 我们没有测试条件。 56 | 57 | 与协议无关的问题,请尽量到gitter上问。 58 | 59 | ## 说明 60 | 本页面仅供drcom客户端开发的童鞋有价值,需要有一些相关的知识。有关drcom所有项目仅供研究使用,由滥用造成的法律后果与作者无关。 61 | 62 | 建议有问题先读wiki,再发issue 63 | 64 | * 在线配置器 http://drcoms.github.io/drcom-generic/ by NTR君 65 | * 相关工具和验证用的代码在 *utils* 目录下 66 | * 测试数据在 *tests* 目录下 67 | * 某些学校的版本请在 *custom* 目录中寻找 68 | * 所有说明已移动到 [wiki](https://github.com/drcoms/generic/wiki) 中 69 | 70 | ## 其他 71 | #### 黑科技:drcom client on 8266 72 | 73 | 74 | #### drcom_2016.lua 75 | 这是一个由 *googlecode* 上 *jdrcom* 项目中的 *wireshark* 插件
76 | 项目地址:(https://code.google.com/p/jdrcom/)
77 | 使用(for windows): 78 | > 将 *drcom_2016.lua* 放到 *Wireshark.exe* 所在的目录下, 打开 *init.lua* ,在 `dofile(DATA_DIR.."console.lua")` 之后添加 `dofile(DATA_DIR.."drcom_2016.lua")`. 79 | 80 | 之后就可以在过滤器中使用 *drcom* 协议了。 81 | 82 | #### 其他最新客户端 83 | HITwh的Shindo酱的项目也是非常优秀,适用x版,请参考
84 | https://github.com/coverxit/EasyDrcom/ 85 | 86 | **NTR君的dogcom** 87 | https://github.com/mchome/dogcom 88 | 89 | 90 | #### 其他哦莫西罗伊的版本 91 | PHP版: https://github.com/dantmnf/drcom-client 92 | 93 | ## 许可证 94 | 95 | AGPLv3 96 | 97 | 特别指出禁止任何个人或者公司将 [drcoms](http://github.com/drcoms/) 的代码投入商业使用,由此造成的后果和法律责任均与本人无关。 98 | -------------------------------------------------------------------------------- /analyses/d_keep_alive2.md: -------------------------------------------------------------------------------- 1 | 发第一个82bytes的包(drcom载荷为40bytes)服务器返回一个 File 的函数名 2 | `SendNextDownloadModuleFileCmd` 3 | 4 | 这个函数包括了keep_alive2的两种心跳包,这里我们主要分析第三种类型(0b 03)的包 5 | 6 | ```c 7 | int __usercall SendNextDownloadModuleFileCmd(int a1, int a2) 8 | { 9 | int v2; // eax@1 10 | int v3; // eax@1 11 | int v4; // eax@15 12 | int result; // eax@18 13 | char v6; // [sp+4h] [bp-224h]@14 14 | char v7; // [sp+20h] [bp-208h]@1 15 | char v8; // [sp+21h] [bp-207h]@1 16 | signed __int16 v9; // [sp+22h] [bp-206h]@1 17 | char v10; // [sp+24h] [bp-204h]@1 18 | signed __int16 v11; // [sp+26h] [bp-202h]@1 19 | int v12; // [sp+28h] [bp-200h]@1 20 | __int64 v13; // [sp+30h] [bp-1F8h]@1 21 | int v14; // [sp+48h] [bp-1E0h]@18 22 | char *v15; // [sp+220h] [bp-8h]@1 23 | 24 | v2 = time(); 25 | srandom(v2); 26 | rand(); 27 | g_RandomIndex = v3; 28 | memset(&v7, 0, 0x28u); 29 | v15 = &v7; 30 | v7 = 7; 31 | v8 = g_DownLoadReqPacketIndex; 32 | v12 = v3; 33 | v9 = 40; //0x0028 28 00 34 | v10 = 11;//0x0b 35 | v13 = TMPcode1recExtchalleng; 36 | v11 = 9999; //0x270f (大端序是 0f 27) 37 | /* 38 | 举一个常见的例子是 39 | 0f 27 和 dc 02,换成小端序就是 0x270f 0x02dc 27和02对应v15[6], 0f和dc对应v15[7] 40 | */ 41 | if ( *(_WORD *)&DownloadModuleBuff[12] ) 42 | *((_WORD *)v15 + 3) = *(_WORD *)&DownloadModuleBuff[12]; 43 | //(_WORD *)v15 + 3 就是v15[6] 44 | //下面会替换 45 | if ( !a2 ) 46 | { 47 | g_nStartUpdateCount = 0; 48 | v15[5] = 1; //0b 01中那个 01 49 | } 50 | if ( a2 == 1 ) 51 | { 52 | //&as[204]是客户端ip 53 | //v15[28]是客户端ip 54 | *((_DWORD *)v15 + 7) = *(_DWORD *)&as[204]; 55 | v15[5] = 3; //0b 03中那个03,现在分析的是03,所以知a2=1 56 | } 57 | /* 58 | 没见过0b 05,忽略 59 | */ 60 | if ( a2 == 2 ) 61 | v15[5] = 5; 62 | 63 | //dc 02 XX XX <= DownloadModuleBuff[4] 64 | *((_DWORD *)v15 + 3) = *(_DWORD *)&DownloadModuleBuff[4]; 65 | 66 | if ( a2 == 2 ) //a2=1 67 | *((_WORD *)v15 + 3) = *(_WORD *)&DownloadModuleBuff[12]; 68 | 69 | //DownloadModuleBuff[12]非0就把DownloadModuleBuff[12]放到dc 02那个位置 70 | if ( *(_WORD *)&DownloadModuleBuff[12] ) 71 | *((_WORD *)v15 + 3) = *(_WORD *)&DownloadModuleBuff[12]; 72 | 73 | if ( v15[5] == 3 ) //=3则要做crc校验 74 | { 75 | //v15 + 6*4 = v15[24]正好对应校验段四个字节 76 | *((_DWORD *)v15 + 6) = MadeCmdPacketCRCSum((int)&v7, *((_WORD *)v15 + 1)); 77 | //第二个参数正好是那个0x0028 就是 40, 就是说对现在的包做一次crc16 * 711 得到的值填充到校验段 78 | ++g_nStartUpdateCount; 79 | if ( (unsigned int)g_nStartUpdateCount > 3 ) 80 | { 81 | v4 = drlang_get_lang((int)"客户端核心模块通信3重试超时,重置状态!!!"); 82 | ErrorMessage(v4, v6); 83 | g_nStartUpdateCount = 0; 84 | AntiProxyModuleUpdateStatus = 0; 85 | g_DownLoadReqPacketIndex = 0; 86 | } 87 | } 88 | if ( g_nModuleOnlineCount == 10 ) 89 | { 90 | *((_WORD *)v15 + 3) = *(_WORD *)&DownloadModuleBuff[12] - 1; 91 | g_nModuleOnlineCount = 0; 92 | } 93 | result = SendAuthCmd((int)&v14, a1); 94 | NextUpdateModuleCmdWaitTime = 2; 95 | return result; 96 | } 97 | ``` 98 | 99 | ```c 100 | // PACKET_CRC_CONST = 711 101 | //----- (0805D18C) -------------------------------------------------------- 102 | int __cdecl MadeCmdPacketCRCSum(int a1, int a2) 103 | { 104 | int i; // [sp+0h] [bp-10h]@1 105 | int v4; // [sp+8h] [bp-8h]@1 106 | 107 | v4 = 0; 108 | *(_WORD *)(a1 + a2) = 0; 109 | for ( i = 0; i < (a2 + 1) / 2; ++i ) 110 | v4 ^= *(_WORD *)(a1 + 2 * i); 111 | return (unsigned __int16)PACKET_CRC_CONST * (unsigned __int16)v4; 112 | } 113 | ``` 114 | 115 | 对应测试的python代码 116 | 117 | 1. 原始数据 118 | 119 | ``` 120 | 0000 07 19 28 00 0b 03 dc 02 54 53 00 00 00 00 00 00 121 | 0010 5a 47 a8 00 00 00 00 00 ab fc 49 02 ac 1a 0f c4 122 | 0020 00 00 00 00 00 00 00 00 123 | ``` 124 | 2. 先将已经算出的校验值去掉, 得到 125 | 126 | ``` 127 | 0000 07 19 28 00 0b 03 dc 02 54 53 00 00 00 00 00 00 128 | 0010 5a 47 a8 00 00 00 00 00 00 00 00 00 ac 1a 0f c4 129 | 0020 00 00 00 00 00 00 00 00 130 | ``` 131 | 3. 编写测试脚本 132 | 133 | ```python 134 | # -*- coding: utf-8 -*- 135 | """ 136 | Created on Mon Nov 17 03:15:03 2014 137 | 138 | @author: root 139 | """ 140 | import struct 141 | from binascii import hexlify 142 | a = '\x07\x19\x28\x00\x0b\x03\xdc\x02\x54\x53\x00\x00\x00\x00\x00\x00\x5a\x47\xa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x1a\x0f\xc4\x00\x00\x00\x00\x00\x00\x00\x00' 143 | 144 | fuck = 0 145 | for i in range(len(a))[::2]: 146 | fuck ^= struct.unpack('H',a[i:i+2])[0] 147 | 148 | print hexlify(struct.pack('I', fuck * 711)) 149 | ``` 150 | 4. 结果检验 151 | 152 | ``` 153 | >>> runfile('untitled0.py') 154 | abfc4902 155 | ``` 156 | 157 | 正好与原来校验值相同 158 | -------------------------------------------------------------------------------- /analyses/error_no.md: -------------------------------------------------------------------------------- 1 | 登陆错误信息 2 | --------------------- 3 | ```c 4 | #define AUTH_ERR_CODE_CHECK_MAC 0x01 5 | #define AUTH_ERR_CODE_SERVER_BUSY 0x02 6 | #define AUTH_ERR_CODE_WRONG_PASS 0x03 7 | #define AUTH_ERR_CODE_NOT_ENOUGH 0x04 8 | #define AUTH_ERR_CODE_FREEZE_UP 0x05 9 | #define AUTH_ERR_CODE_NOT_ON_THIS_IP 0x07 10 | #define AUTH_ERR_CODE_NOT_ON_THIS_MAC 0x0B 11 | #define AUTH_ERR_CODE_TOO_MUCH_IP 0x14 12 | #define AUTH_ERR_CODE_UPDATE_CLIENT 0x15 13 | #define AUTH_ERR_CODE_NOT_ON_THIS_IP_MAC 0x16 14 | #define AUTH_ERR_CODE_MUST_USE_DHCP 0x17 15 | #define AUTH_ERR_CODE_24 0x18 16 | #define AUTH_ERR_CODE_25 0x19 17 | #define AUTH_ERR_CODE_26 0x1A 18 | #define AUTH_ERR_CODE_27 0x1B 19 | #define AUTH_ERR_CODE_28 0x1C 20 | ``` 21 | 22 | 对应客户端中文提示 23 | * 0x01 有人正在使用这个账号,且是有线的方式 24 | * 0x02 服务器繁忙,请稍候重新登录 25 | * 0x03 帐号或密码错误 26 | * 0x04 本帐号的累计时间或流量已超出限制 27 | * 0x05 本帐号暂停使用 28 | * 0x07 IP地址不匹配,本帐号只能在指定IP地址上使用 29 | * 0x0b MAC(物理)地址不匹配,本帐号只能在指定的IP和MAC(物理)地址上使用 30 | * 0x14 本帐IP地址太多 31 | * 0x15 客户端版本不正确 32 | * 0x16 本帐号只能在指定的Mac和IP上使用 33 | * 0x17 你的PC设置了静态IP,请改为动态获取方式(DHCP),然后重新登录 34 | * 0x18 - 0x1c 保留错误信息 35 | -------------------------------------------------------------------------------- /analyses/pppoe_realworld.md: -------------------------------------------------------------------------------- 1 | 有关PPPOE之后的扩展认证 2 | ---------------------- 3 | 状态 4 | - [X] 完成分析 5 | - [ ] 验证正确性 6 | - [ ] 编写代码 7 | - [ ] 实际测试通过 8 | 9 | 心跳分两部分,一个是正常心跳(07心跳),和目前已有算法一样,一个是pppoe的心跳,两者独立运行,注意要去掉ff开头的那个心跳换成pppoe心跳
10 | pppoe心跳分析如下 11 | 12 | pppoe心跳 13 | 正常心跳 14 | (以上总共20s) 15 | 16 | pppoe心跳 17 | 正常心跳 18 | 19 | 其中有关正常心跳的tail部分继承上一个正常心跳的,和pppoe心跳无关 20 | 21 | [send]PKT1:
22 | ``` 23 | 07 //code 24 | 55 //id 25 | 08 00 //length 26 | 01 //type 27 | 00 00 00 //other[3] 28 | ``` 29 | 30 | [recv]PKT2:
31 | ``` 32 | 07 // header.code 33 | 55 // header.id 34 | 10 00 // header.length 35 | 02 // header.type 36 | 00 00 00 // other[3] other[0]确定加密方式,0为不加密 37 | cf 89 a8 03 // ChallengeSeed[4] 38 | ac 15 05 0f // ClientSouIp 39 | a8 a4 00 00 3a ae 6f 3c 00 00 00 00 d8 02 00 00 40 | ``` 41 | 42 | [send]PKT3:
43 | ``` 44 | 07 //header.code 45 | 56 //header.id 46 | 60 00 //header.length = Loginpack + uidlength + networkinfo * 4 = 96 47 | 03 //header.type 48 | 00 //uid length (strlen(us.Account)) 49 | 00 00 00 00 00 00 //mac 50 | ac 15 05 0f // AuthHostIP 51 | 00 62 00 14 // option, 第一次发送是这个,第二次则是 00 63 00 14 (0x14006300) 52 | /* 53 | 这里由于上方other[0] == 0 为老版本,不采用加密 54 | */ 55 | cf 89 a8 03 // ChallengeSeed[4] 56 | 57 | // 先初始化为20000711,126 58 | 66 cc 58 2f 00 00 00 00 // crc[2] (unsigned long) 59 | 旧版本,此时CRC计算方法为 60 | crc[0]: 19680126 * DrCOMCRC32(0, loginpacket, 96) 61 | crc[1]: 0 62 | 63 | //代码中应该是要对这个进行加密的,但是实际上却没发现加密了,奇怪 64 | //_tagDrcomDialExtProtoNetWorkInfo 65 | //基本格式 66 | 67 | 00 00 00 00 00 00 // mac 68 | 00 //netmark 69 | 8b //type 70 | ac 2a 14 78 //sip 71 | ff ff ff ff //smask 72 | //下同 73 | 00 a0 59 06 00 20 00 03 c0 51 25 08 ff ff ff 00 74 | 00 a0 59 06 00 01 00 03 c0 51 2b 08 ff ff ff 00 75 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 76 | ``` 77 | 78 | [recv]PKT4:
79 | ``` 80 | 07 81 | 56 82 | 30 00 83 | 04 84 | 00 85 | 20 00 86 | 19 33 d6 8b 00 00 00 00 87 | 44 39 d8 ed ca c0 f7 46 a9 86 2b a2 50 78 04 d0 88 | b0 82 00 60 00 00 00 00 00 00 00 00 00 00 00 00 89 | ``` 90 | 91 | 92 | 接下来正常心跳 93 | 先发 94 | ``` 95 | 0000 07 00 28 00 0b 01 0f 27 1b 35 00 00 00 00 00 00 96 | 0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 | 0020 00 00 00 00 00 00 00 00 98 | ``` 99 | 100 | pkt3 校验 101 | 加密: 102 | ```c 103 | for (int index = 0; index < pcrcLen; index++) 104 | { 105 | pcrcstart[index] = (unsigned char)((pcrcstart[index] << (index & 0x07) + (pcrcstart[index] >> (8 - (index & 0x07)))); 106 | } 107 | ``` 108 | ```python 109 | def _netinfo_encrypt(self, data): 110 | s = '' 111 | for index, c in enumerate(data): 112 | foo = ord(c) << index & 0x07 113 | foo &= 0xFF # 去掉多余位 114 | bar = ord(c) >> (8 - (index & 0x07)) 115 | bar &= 0xFF 116 | s += chr((foo + bar) & 0xFF) 117 | return s 118 | ``` 119 | 解密: 120 | ```python 121 | def _netinfo_decrypt(data): 122 | s = '' 123 | for index, c in enumerate(data): 124 | foo = ord(c) >> index & 0x07 125 | foo &= 0xFF # 去掉多余位 126 | bar = ord(c) << (8 - (index & 0x07)) 127 | bar &= 0xFF 128 | s += chr((foo + bar) & 0xFF) 129 | return s 130 | ``` 131 | -------------------------------------------------------------------------------- /c_version/README.md: -------------------------------------------------------------------------------- 1 | # dogcom 2 | 3 | - **dogcom**是C语言的drcom-generic实现的源文件 4 | - **openwrt-dogcom**是dogcom的openwrt包的源文件 5 | - **luci-app-dogcom**是openwrt-dogcom的luci界面源文件 6 | -------------------------------------------------------------------------------- /c_version/esp8266/readme.md: -------------------------------------------------------------------------------- 1 | # 安装Arduino配置esp8266 2 | ##### reference arudino-ide-esp8266-setup-guide [defendtheplanet.net](https://defendtheplanet.net/2016/12/28/arudino-ide-esp8266-setup-guide/) 3 | 4 | ## 第 1 步:下载 arudino 软件 5 | 转到arudinoIDE的最新版本下载页面。请记住,您至少需要1.6.x版本。在某些情况下,它不在您心爱的 Debian 分发的包存储库中。 6 | ## 第 2 步:设置 IDE 以与 ESP8266 合作。 7 | 我们需要在board manager 来源列表中添加一个额外的网址。对于该打开的文件>首选项 8 | 并将http://arduino.esp8266.com/stable/package_esp8266com_index.json添加到其他板管理器URL中。 9 | (速度极慢需要科学上网) 10 | ## 第 3 步 连接电脑 11 | Windows可能需要安装驱动,网上自己找下,我下的windows驱动不知道为什么蓝屏,做好准备 12 | ## 第 4 步 打开文件改下密码编译上传 13 | 我是按照p版python改的,代码写的比较乱,兄弟们各凭本事 14 | -------------------------------------------------------------------------------- /custom/Drcom_SWUPL.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Code Adapted for SouthWest University of Political Science and Law,2016-11-3 5 | # Modify the 3 lines commented with chinese below 6 | # Run as root user if error occours 7 | # The Client is (D) version 8 | # Tested under Ubuntu 16.10 64-bit,have fun~ 9 | 10 | import socket, struct, time 11 | from hashlib import md5 12 | import sys 13 | import os 14 | import random 15 | 16 | # CONFIG 17 | server = '10.250.250.12' 18 | username='@xnzf1' #用户名 19 | password='' #密码 20 | CONTROLCHECKSTATUS = '\x20' 21 | ADAPTERNUM = '\x02' 22 | host_ip = '172.18.33.11' #本机IP地址 23 | IPDOG = '\x01' 24 | host_name = 'GILIGILIEYE' 25 | PRIMARY_DNS = '127.0.1.1' 26 | dhcp_server = '255.255.255.255' 27 | AUTH_VERSION = '\x0a\x00' 28 | mac = 0x3065ecaad01d 29 | host_os = 'NOTE7' 30 | KEEP_ALIVE_VERSION = '\xdc\x02' 31 | ror_version = False 32 | # CONFIG_END 33 | 34 | nic_name = '' #Indicate your nic, e.g. 'eth0.2'.nic_name 35 | bind_ip = '0.0.0.0' 36 | 37 | class ChallengeException (Exception): 38 | def __init__(self): 39 | pass 40 | 41 | class LoginException (Exception): 42 | def __init__(self): 43 | pass 44 | 45 | def bind_nic(): 46 | try: 47 | import fcntl 48 | def get_ip_address(ifname): 49 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 50 | return socket.inet_ntoa(fcntl.ioctl( 51 | s.fileno(), 52 | 0x8915, # SIOCGIFADDR 53 | struct.pack('256s', ifname[:15]) 54 | )[20:24]) 55 | return get_ip_address(nic_name) 56 | except ImportError as e: 57 | print('Indicate nic feature need to be run under Unix based system.') 58 | return '0.0.0.0' 59 | except IOError as e: 60 | print(nic_name + 'is unacceptable !') 61 | return '0.0.0.0' 62 | finally: 63 | return '0.0.0.0' 64 | 65 | if nic_name != '': 66 | bind_ip = bind_nic() 67 | 68 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 69 | # s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 70 | s.bind((bind_ip, 61440)) 71 | 72 | s.settimeout(3) 73 | SALT = '' 74 | IS_TEST = false 75 | # specified fields based on version 76 | CONF = "/etc/drcom.conf" 77 | UNLIMITED_RETRY = True 78 | EXCEPTION = False 79 | DEBUG = False #log saves to file 80 | LOG_PATH = '/var/log/drcom_client.log' 81 | if IS_TEST: 82 | DEBUG = True 83 | LOG_PATH = 'drcom_client.log' 84 | 85 | 86 | def log(*args, **kwargs): 87 | s = ' '.join(args) 88 | print s 89 | if DEBUG: 90 | with open(LOG_PATH,'a') as f: 91 | f.write(s + '\n') 92 | 93 | def challenge(svr,ran): 94 | while True: 95 | t = struct.pack(">5)) 130 | return ret 131 | 132 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 133 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 134 | if first : 135 | data += '\x0f\x27' 136 | else: 137 | data += KEEP_ALIVE_VERSION 138 | data += '\x2f\x12' + '\x00' * 6 139 | data += tail 140 | data += '\x00' * 4 141 | #data += struct.pack("!H",0xdc02) 142 | if type == 3: 143 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 144 | #CRC 145 | # edited on 2014/5/12, filled zeros to checksum 146 | # crc = packet_CRC(data+foo) 147 | crc = '\x00' * 4 148 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 149 | data += crc + foo + '\x00' * 8 150 | else: #packet type = 1 151 | data += '\x00' * 16 152 | return data 153 | 154 | # def packet_CRC(s): 155 | # ret = 0 156 | # for i in re.findall('..', s): 157 | # ret ^= struct.unpack('>h', i)[0] 158 | # ret &= 0xFFFF 159 | # ret = ret * 0x2c7 160 | # return ret 161 | 162 | def keep_alive2(*args): 163 | #first keep_alive: 164 | #number = number (mod 7) 165 | #status = 1: first packet user sended 166 | # 2: first packet user recieved 167 | # 3: 2nd packet user sended 168 | # 4: 2nd packet user recieved 169 | # Codes for test 170 | tail = '' 171 | packet = '' 172 | svr = server 173 | ran = random.randint(0,0xFFFF) 174 | ran += random.randint(1,10) 175 | # 2014/10/15 add by latyas, maybe svr sends back a file packet 176 | svr_num = 0 177 | packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1,True) 178 | while True: 179 | log('[keep-alive2] send1',packet.encode('hex')) 180 | s.sendto(packet, (svr, 61440)) 181 | data, address = s.recvfrom(1024) 182 | log('[keep-alive2] recv1',data.encode('hex')) 183 | if data.startswith('\x07\x00\x28\x00') or data.startswith('\x07' + chr(svr_num) + '\x28\x00'): 184 | break 185 | elif data[0] == '\x07' and data[2] == '\x10': 186 | log('[keep-alive2] recv file, resending..') 187 | svr_num = svr_num + 1 188 | # packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1, False) 189 | break 190 | else: 191 | log('[keep-alive2] recv1/unexpected',data.encode('hex')) 192 | #log('[keep-alive2] recv1',data.encode('hex')) 193 | 194 | ran += random.randint(1,10) 195 | packet = keep_alive_package_builder(svr_num, dump(ran),'\x00'*4,1,False) 196 | log('[keep-alive2] send2',packet.encode('hex')) 197 | s.sendto(packet, (svr, 61440)) 198 | while True: 199 | data, address = s.recvfrom(1024) 200 | if data[0] == '\x07': 201 | svr_num = svr_num + 1 202 | break 203 | else: 204 | log('[keep-alive2] recv2/unexpected',data.encode('hex')) 205 | log('[keep-alive2] recv2',data.encode('hex')) 206 | tail = data[16:20] 207 | 208 | 209 | ran += random.randint(1,10) 210 | packet = keep_alive_package_builder(svr_num,dump(ran),tail,3,False) 211 | log('[keep-alive2] send3',packet.encode('hex')) 212 | s.sendto(packet, (svr, 61440)) 213 | while True: 214 | data, address = s.recvfrom(1024) 215 | if data[0] == '\x07': 216 | svr_num = svr_num + 1 217 | break 218 | else: 219 | log('[keep-alive2] recv3/unexpected',data.encode('hex')) 220 | log('[keep-alive2] recv3',data.encode('hex')) 221 | tail = data[16:20] 222 | log("[keep-alive2] keep-alive2 loop was in daemon.") 223 | 224 | i = svr_num 225 | while True: 226 | try: 227 | time.sleep(20) 228 | keep_alive1(*args) 229 | ran += random.randint(1,10) 230 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 231 | #log('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 232 | log('[keep_alive2] send',str(i),packet.encode('hex')) 233 | s.sendto(packet, (svr, 61440)) 234 | data, address = s.recvfrom(1024) 235 | log('[keep_alive2] recv',data.encode('hex')) 236 | tail = data[16:20] 237 | #log('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 238 | 239 | ran += random.randint(1,10) 240 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 241 | #log('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 242 | s.sendto(packet, (svr, 61440)) 243 | log('[keep_alive2] send',str(i+1),packet.encode('hex')) 244 | data, address = s.recvfrom(1024) 245 | log('[keep_alive2] recv',data.encode('hex')) 246 | tail = data[16:20] 247 | #log('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 248 | i = (i+2) % 0xFF 249 | except: 250 | pass 251 | 252 | def checksum(s): 253 | ret = 1234 254 | x = 0 255 | for i in [x*4 for x in range(0, -(-len(s)//4))]: 256 | ret ^= int(s[i:i+4].ljust(4, '\x00')[::-1].encode('hex'), 16) 257 | ret = (1968 * ret) & 0xffffffff 258 | return struct.pack(' 271 | data += '\00' * 4 #your ipaddress 2 272 | data += '\00' * 4 #your ipaddress 3 273 | data += '\00' * 4 #your ipaddress 4 274 | data += md5sum(data + '\x14\x00\x07\x0B')[:8] #md53 275 | data += IPDOG 276 | data += '\x00'*4 #delimeter 277 | data += host_name.ljust(32, '\x00') 278 | data += ''.join([chr(int(i)) for i in PRIMARY_DNS.split('.')]) #primary dns 279 | data += ''.join([chr(int(i)) for i in dhcp_server.split('.')]) #DHCP server 280 | data += '\x00\x00\x00\x00' #secondary dns:0.0.0.0 281 | data += '\x00' * 8 #delimeter 282 | data += '\x94\x00\x00\x00' # unknow 283 | data += '\x05\x00\x00\x00' # os major 284 | data += '\x01\x00\x00\x00' # os minor 285 | data += '\x28\x0A\x00\x00' # OS build 286 | data += '\x02\x00\x00\x00' #os unknown 287 | data += host_os.ljust(32, '\x00') 288 | data += '\x00' * 96 289 | data += AUTH_VERSION 290 | if ror_version: 291 | data += '\x00' + chr(len(pwd)) 292 | data += ror(md5sum('\x03\x01' + salt + pwd), pwd) 293 | data += '\x02\x0C' 294 | data += checksum(data + '\x01\x26\x07\x11\x00\x00' + dump(mac)) 295 | data += '\x00\x00' #delimeter 296 | data += dump(mac) 297 | data += '\x00' # auto logout / default: False 298 | data += '\x00' # broadcast mode / default : False 299 | data += '\xE9\x13' #unknown, filled numbers randomly =w= 300 | 301 | log('[mkpkt]',data.encode('hex')) 302 | return data 303 | 304 | def login(usr, pwd, svr): 305 | import random 306 | global SALT 307 | 308 | i = 0 309 | while True: 310 | salt = challenge(svr,time.time()+random.randint(0xF,0xFF)) 311 | SALT = salt 312 | packet = mkpkt(salt, usr, pwd, mac) 313 | log('[login] send',packet.encode('hex')) 314 | s.sendto(packet, (svr, 61440)) 315 | data, address = s.recvfrom(1024) 316 | log('[login] recv',data.encode('hex')) 317 | log('[login] packet sent.') 318 | if address == (svr, 61440): 319 | if data[0] == '\x04': 320 | log('[login] loged in') 321 | break 322 | else: 323 | log('[login] login failed.') 324 | if IS_TEST: 325 | time.sleep(3) 326 | else: 327 | time.sleep(30) 328 | continue 329 | else: 330 | if i >= 5 and UNLIMITED_RETRY == False : 331 | log('[login] exception occured.') 332 | sys.exit(1) 333 | else: 334 | continue 335 | 336 | log('[login] login sent') 337 | #0.8 changed: 338 | return data[23:39] 339 | #return data[-22:-6] 340 | 341 | def keep_alive1(salt,tail,pwd,svr): 342 | foo = struct.pack('!H',int(time.time())%0xFFFF) 343 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 344 | data += tail 345 | data += foo + '\x00\x00\x00\x00' 346 | log('[keep_alive1] send',data.encode('hex')) 347 | 348 | s.sendto(data, (svr, 61440)) 349 | while True: 350 | data, address = s.recvfrom(1024) 351 | if data[0] == '\x07': 352 | break 353 | else: 354 | log('[keep-alive1]recv/not expected',data.encode('hex')) 355 | log('[keep-alive1] recv',data.encode('hex')) 356 | 357 | def empty_socket_buffer(): 358 | #empty buffer for some fucking schools 359 | log('starting to empty socket buffer') 360 | try: 361 | while True: 362 | data, address = s.recvfrom(1024) 363 | log('recived sth unexpected',data.encode('hex')) 364 | if s == '': 365 | break 366 | except: 367 | # get exception means it has done. 368 | log('exception in empty_socket_buffer') 369 | pass 370 | log('emptyed') 371 | def daemon(): 372 | with open('/var/run/jludrcom.pid','w') as f: 373 | f.write(str(os.getpid())) 374 | 375 | def main(): 376 | if not IS_TEST: 377 | daemon() 378 | execfile(CONF, globals()) 379 | log("auth svr: " + server + "\nusername: " + username + "\npassword: " + password + "\nmac: " + str(hex(mac))) 380 | log("bind ip: " + bind_ip) 381 | while True: 382 | try: 383 | package_tail = login(username, password, server) 384 | except LoginException: 385 | continue 386 | log('package_tail',package_tail.encode('hex')) 387 | #keep_alive1 is fucking bullshit! 388 | empty_socket_buffer() 389 | keep_alive1(SALT,package_tail,password,server) 390 | keep_alive2(SALT,package_tail,password,server) 391 | if __name__ == "__main__": 392 | main() 393 | -------------------------------------------------------------------------------- /custom/S99drcom: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | # put it into /etc/rc.d 3 | START=99 4 | APP="python /usr/bin/drcom.py" 5 | start() { 6 | sleep 30 7 | start-stop-daemon -S -x $APP 8 | } 9 | 10 | stop() { 11 | killall python 12 | } 13 | -------------------------------------------------------------------------------- /custom/bistu_drcom_d.py: -------------------------------------------------------------------------------- 1 | #coding=UTF-8 2 | #test version 3 | #Licensed under the AGPLv3 4 | #thx all authors before 5 | #此版本适配北京信息科技大学 6 | 7 | import socket, struct, time,random,re 8 | from hashlib import md5 9 | 10 | #config 11 | server = '192.168.211.3' 12 | username='' #学号 13 | password='' #密码 14 | CONTROLCHECKSTATUS = '\x20' 15 | ADAPTERNUM = '\x02' 16 | host_ip = '' #dhcp到的ip地址 17 | IPDOG = '\x01' 18 | host_name = 'DRCOMFUCKER' 19 | PRIMARY_DNS = '211.82.96.1' 20 | dhcp_server = '211.68.32.204' 21 | AUTH_VERSION = '\x0a\x00' 22 | mac = 0x001c4209e63c 23 | host_os = 'WINDIAOS' 24 | KEEP_ALIVE_VERSION = '\xdb\x02' 25 | #config_end 26 | 27 | class ChallengeException (Exception): 28 | def __init__(self): 29 | pass 30 | 31 | class loginException (Exception): 32 | def __init__(self): 33 | pass 34 | 35 | def try_socket(): 36 | #sometimes cannot get the port 37 | global s,salt 38 | try: 39 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 40 | s.bind(("0.0.0.0", 61440)) 41 | s.settimeout(3) 42 | except: 43 | print ".", 44 | time.sleep(0.5) 45 | print ".", 46 | time.sleep(0.5) 47 | print "." 48 | time.sleep(0.5) 49 | print "...wait 3 seconds" 50 | time.sleep(3) 51 | version() 52 | main() 53 | else: 54 | SALT= '' 55 | 56 | UNLIMITED_RETRY = True 57 | EXCEPTION = False 58 | 59 | def randomMAC(): 60 | mac = [ 0x0a, 0x16, 0x00, 61 | random.randint(0x00, 0x7f), 62 | random.randint(0x00, 0xff), 63 | random.randint(0x00, 0xff) ] 64 | return long(''.join(map(lambda x: "%02x" % x, mac)),16) 65 | 66 | def version(): 67 | print "=====================================================================" 68 | print "DrCOM Auth Router for u6x" 69 | print "with keep-alive1&keep-alive2" 70 | print "=====================================================================" 71 | 72 | def challenge(svr,ran): 73 | while True: 74 | t = struct.pack(">5)) 109 | return ret 110 | 111 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 112 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 113 | data += KEEP_ALIVE_VERSION+'\x2f\x12' + '\x00' * 6 114 | data += tail 115 | data += '\x00' * 4 116 | #data += struct.pack("!H",0xdc02) 117 | if type == 3: 118 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 119 | #use double keep in main to keep online .Ice 120 | crc = '\x00' * 4 121 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 122 | data += crc + foo + '\x00' * 8 123 | else: #packet type = 1 124 | data += '\x00' * 16 125 | return data 126 | 127 | def packet_CRC(s): 128 | ret = 0 129 | for i in re.findall('..', s): 130 | ret ^= struct.unpack('>h', i)[0] 131 | ret &= 0xFFFF 132 | ret = ret * 0x2c7 133 | return ret 134 | 135 | 136 | 137 | def keep_alive2(*args): 138 | tail = '' 139 | packet = '' 140 | svr = server 141 | ran = random.randint(0,0xFFFF) 142 | ran += random.randint(1,10) 143 | 144 | packet = keep_alive_package_builder(0,dump(ran),'\x00'*4,1,True) 145 | #packet = keep_alive_package_builder(0,dump(ran),dump(ran)+'\x22\x06',1,True) 146 | print '[keep-alive2] send1'#packet.encode('hex') 147 | while True: 148 | s.sendto(packet, (svr, 61440)) 149 | data, address = s.recvfrom(1024) 150 | if data.startswith('\x07'): 151 | break 152 | else: 153 | continue 154 | #print '[keep-alive2] recv/unexpected',data.encode('hex') 155 | #print '[keep-alive2] recv1',data.encode('hex') 156 | 157 | ran += random.randint(1,10) 158 | packet = keep_alive_package_builder(1,dump(ran),'\x00'*4,1,False) 159 | #print '[keep-alive2] send2',packet.encode('hex') 160 | s.sendto(packet, (svr, 61440)) 161 | while True: 162 | data, address = s.recvfrom(1024) 163 | if data[0] == '\x07': 164 | break 165 | #print '[keep-alive2] recv2',data.encode('hex') 166 | tail = data[16:20] 167 | 168 | 169 | ran += random.randint(1,10) 170 | packet = keep_alive_package_builder(2,dump(ran),tail,3,False) 171 | #print '[keep-alive2] send3',packet.encode('hex') 172 | s.sendto(packet, (svr, 61440)) 173 | while True: 174 | data, address = s.recvfrom(1024) 175 | if data[0] == '\x07': 176 | break 177 | #print '[keep-alive2] recv3',data.encode('hex') 178 | tail = data[16:20] 179 | print "[keep-alive] keep-alive loop was in daemon." 180 | i = 3 181 | 182 | while True: 183 | try: 184 | keep_alive1(SALT,package_tail,password,server) 185 | print '[keep-alive2] send' 186 | ran += random.randint(1,10) 187 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 188 | #print('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 189 | #print '[keep_alive2] send',str(i),packet.encode('hex') 190 | s.sendto(packet, (svr, 61440)) 191 | data, address = s.recvfrom(1024) 192 | #print '[keep_alive2] recv',data.encode('hex') 193 | tail = data[16:20] 194 | #print('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 195 | 196 | ran += random.randint(1,10) 197 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 198 | #print('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 199 | s.sendto(packet, (svr, 61440)) 200 | #print('[keep_alive2] send',str(i+1),packet.encode('hex')) 201 | data, address = s.recvfrom(1024) 202 | #print('[keep_alive2] recv',data.encode('hex')) 203 | tail = data[16:20] 204 | #print('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 205 | i = (i+2) % 0xFF 206 | time.sleep(20) 207 | except: 208 | pass 209 | 210 | def checksum(s): 211 | ret = 1234 212 | for i in re.findall('....', s): 213 | ret ^= int(i[::-1].encode('hex'), 16) 214 | ret = (1968 * ret) & 0xffffffff 215 | return struct.pack('= 5 and UNLIMITED_RETRY == False : 282 | print('[login] exception occured.') 283 | sys.exit(1) 284 | else: 285 | continue 286 | 287 | print('[login] login Success') 288 | return data[23:39] 289 | #return data[-22:-6] 290 | 291 | def keep_alive1(salt,tail,pwd,svr): 292 | foo = struct.pack('!H',int(time.time())%0xFFFF) 293 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 294 | data += tail 295 | data += foo + '\x00\x00\x00\x00' 296 | print '[keep_alive1] send'#data.encode('hex')) 297 | 298 | s.sendto(data, (svr, 61440)) 299 | while True: 300 | data, address = s.recvfrom(1024) 301 | if data[0] == '\x07': 302 | break 303 | else: 304 | print '[keep-alive1]recv/not expected'#data.encode('hex') 305 | #print('[keep-alive1] recv',data.encode('hex')) 306 | 307 | def empty_socket_buffer(): 308 | #empty buffer 309 | print('starting to empty socket buffer') 310 | try: 311 | while True: 312 | data, address = s.recvfrom(1024) 313 | #print 'recived sth unexcepted',data.encode('hex') 314 | if s == '': 315 | break 316 | except: 317 | # get exception means it has done. 318 | print('exception in empty_socket_buffer') 319 | pass 320 | print('emptyed') 321 | 322 | 323 | def main(): 324 | global server,username,password,host_name,host_os,dhcp_server,mac,hexip,host_ip 325 | ''' 326 | print("Username:") 327 | username=raw_input() 328 | print("Password:") 329 | password=raw_input() 330 | print("Host_ip:") 331 | host_ip=raw_input() 332 | mac=randomMAC() 333 | ''' 334 | print("Use randomMAC to Auth...."+hex(mac)) 335 | hexip=socket.inet_aton(host_ip) 336 | #host_ip=ip 337 | host_name = "est-pc" 338 | host_os = "DrcomGoAway" #default is 8089D 339 | dhcp_server = "0.0.0.0" 340 | #mac = 0xE0DB55BAE012 341 | #it is a mac in programme and it may crush with other users so I use randMAC to avoid it 342 | loginpart() 343 | 344 | def loginpart(): 345 | global package_tail 346 | while True: 347 | try: 348 | package_tail = login(username, password, server) 349 | except loginException: 350 | continue 351 | #print('package_tail',package_tail.encode('hex')) 352 | keeppart() 353 | 354 | def keeppart(): 355 | #empty_socket_buffer() 356 | #empty_socket_buffer() 357 | keep_alive2(SALT,package_tail,password,server) 358 | 359 | 360 | if __name__ == "__main__": 361 | try_socket() 362 | version() 363 | #get_randmac() 364 | #get_conf() 365 | main() 366 | 367 | 368 | -------------------------------------------------------------------------------- /custom/drcom-generic-debug-u62.py: -------------------------------------------------------------------------------- 1 | # 1.Please edit this file in editors which supports UNIX files if you are in Windows OS 2 | # 2.tested pass in v0.8 u62R0 3 | # 3.edit basic configuration first. 4 | # 4.if you can use it to access Internet stablely, contacting administrators. 5 | # else contacting administrators with drcom_client.log 6 | 7 | import socket, struct, time 8 | from hashlib import md5 9 | import sys 10 | import urllib2 11 | 12 | class ChallengeException (Exception): 13 | def __init__(self): 14 | pass 15 | 16 | class LoginException (Exception): 17 | def __init__(self): 18 | pass 19 | 20 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 21 | s.bind(("0.0.0.0", 61440)) 22 | 23 | s.settimeout(3) 24 | SALT = '' 25 | UNLIMITED_RETRY = True 26 | EXCEPTION = False 27 | DEBUG = True 28 | # basic configuration 29 | server = "192.168.100.150" # Auth server ip 30 | username = "" 31 | password = "" 32 | host_name = "LIYUANYUAN" 33 | host_os = "8089D" 34 | host_ip = "10.30.22.17" # your ip, the server wouldn't check this, so it's a nonsense 35 | dhcp_server = "0.0.0.0" 36 | mac = 0xb888e3051680 37 | 38 | def log(*args, **kwargs): 39 | s = ' '.join(args) 40 | print s 41 | with open('drcom_client.log','a') as f: 42 | f.write(s + '\n') 43 | 44 | def challenge(svr,ran): 45 | while True: 46 | t = struct.pack(">5)) 81 | return ret 82 | 83 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 84 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 85 | if first : 86 | data += '\x0f\x27' 87 | else: 88 | data += '\xdc\02' 89 | data += '\x2f\x12' + '\x00' * 6 90 | data += tail 91 | data += '\x00' * 4 92 | #data += struct.pack("!H",0xdc02) 93 | if type == 3: 94 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 95 | #CRC 96 | # edited on 2014/5/12, filled zeros to checksum 97 | # crc = packet_CRC(data+foo) 98 | crc = '\x00' * 4 99 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 100 | data += crc + foo + '\x00' * 8 101 | else: #packet type = 1 102 | data += '\x00' * 16 103 | return data 104 | 105 | def packet_CRC(s): 106 | ret = 0 107 | for i in re.findall('..', s): 108 | ret ^= struct.unpack('>h', i)[0] 109 | ret &= 0xFFFF 110 | ret = ret * 0x2c7 111 | return ret 112 | 113 | def keep_alive2(*args): 114 | #first keep_alive: 115 | #number = number (mod 7) 116 | #status = 1: first packet user sended 117 | # 2: first packet user recieved 118 | # 3: 2nd packet user sended 119 | # 4: 2nd packet user recieved 120 | # Codes for test 121 | tail = '' 122 | packet = '' 123 | svr = server 124 | import random 125 | ran = random.randint(0,0xFFFF) 126 | ran += random.randint(1,10) 127 | # 2014/10/15 add by latyas, maybe svr sends back a file packet 128 | svr_num = 0 129 | packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1,True) 130 | while True: 131 | log('[keep-alive2] send1',packet.encode('hex')) 132 | s.sendto(packet, (svr, 61440)) 133 | data, address = s.recvfrom(1024) 134 | if data.startswith('\x07\x00\x28\x00') or data.startswith('\x07' + chr(svr_num) + '\x28\x00'): 135 | break 136 | elif data[0] == '\x07' and data[2] == '\x10': 137 | log('[keep-alive2] recv file, resending..') 138 | svr_num = svr_num + 1 139 | packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1, False) 140 | else: 141 | log('[keep-alive2] recv1/unexpected',data.encode('hex')) 142 | log('[keep-alive2] recv1',data.encode('hex')) 143 | 144 | ran += random.randint(1,10) 145 | packet = keep_alive_package_builder(svr_num, dump(ran),'\x00'*4,1,False) 146 | log('[keep-alive2] send2',packet.encode('hex')) 147 | s.sendto(packet, (svr, 61440)) 148 | while True: 149 | data, address = s.recvfrom(1024) 150 | if data[0] == '\x07': 151 | svr_num = svr_num + 1 152 | break 153 | else: 154 | log('[keep-alive2] recv2/unexpected',data.encode('hex')) 155 | log('[keep-alive2] recv2',data.encode('hex')) 156 | tail = data[16:20] 157 | 158 | 159 | ran += random.randint(1,10) 160 | packet = keep_alive_package_builder(svr_num,dump(ran),tail,3,False) 161 | log('[keep-alive2] send3',packet.encode('hex')) 162 | s.sendto(packet, (svr, 61440)) 163 | while True: 164 | data, address = s.recvfrom(1024) 165 | if data[0] == '\x07': 166 | svr_num = svr_num + 1 167 | break 168 | else: 169 | log('[keep-alive2] recv3/unexpected',data.encode('hex')) 170 | log('[keep-alive2] recv3',data.encode('hex')) 171 | tail = data[16:20] 172 | log("[keep-alive2] keep-alive2 loop was in daemon.") 173 | 174 | i = svr_num 175 | while True: 176 | try: 177 | ran += random.randint(1,10) 178 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 179 | #log('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 180 | log('[keep_alive2] send',str(i),packet.encode('hex')) 181 | s.sendto(packet, (svr, 61440)) 182 | data, address = s.recvfrom(1024) 183 | log('[keep_alive2] recv',data.encode('hex')) 184 | tail = data[16:20] 185 | #log('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 186 | 187 | ran += random.randint(1,10) 188 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 189 | #log('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 190 | s.sendto(packet, (svr, 61440)) 191 | log('[keep_alive2] send',str(i+1),packet.encode('hex')) 192 | data, address = s.recvfrom(1024) 193 | log('[keep_alive2] recv',data.encode('hex')) 194 | tail = data[16:20] 195 | #log('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 196 | i = (i+2) % 0xFF 197 | time.sleep(20) 198 | keep_alive1(*args) 199 | except: 200 | pass 201 | 202 | 203 | import re 204 | def checksum(s): 205 | ret = 1234 206 | for i in re.findall('....', s): 207 | ret ^= int(i[::-1].encode('hex'), 16) 208 | ret = (1968 * ret) & 0xffffffff 209 | return struct.pack(' 222 | data += '\00'*4 #your ipaddress 2 223 | data += '\00'*4 #your ipaddress 3 224 | data += '\00'*4 #your ipaddress 4 225 | data += md5sum(data + '\x14\x00\x07\x0b')[:8] #md53 226 | data += '\x01' #ipdog 227 | data += '\x00'*4 #delimeter 228 | data += host_name.ljust(32, '\x00') 229 | data += '\x08\x08\x08\x08' #primary dns: 8.8.8.8 230 | data += ''.join([chr(int(i)) for i in dhcp_server.split('.')]) #DHCP server 231 | data += '\x00\x00\x00\x00' #secondary dns:0.0.0.0 232 | data += '\x00' * 8 #delimeter 233 | data += '\x94\x00\x00\x00' # unknow 234 | data += '\x05\x00\x00\x00' # os major 235 | data += '\x01\x00\x00\x00' # os minor 236 | data += '\x28\x0a\x00\x00' # OS build 237 | data += '\x02\x00\x00\x00' #os unknown 238 | data += host_os.ljust(32,'\x00') 239 | data += '\x00' * 96 240 | #data += '\x01' + host_os.ljust(128, '\x00') 241 | #data += '\x0a\x00\x00'+chr(len(pwd)) # \0x0a represents version of client, algorithm: DRCOM_VER + 100 242 | #data += ror(md5sum('\x03\x01'+salt+pwd), pwd) 243 | data += '\x0a\x00' # for u64, \x1a\x00 244 | data += '\x02\x0c' 245 | data += checksum(data+'\x01\x26\x07\x11\x00\x00'+dump(mac)) 246 | data += '\x00\x00' #delimeter 247 | data += dump(mac) 248 | data += '\x00' # auto logout / default: False 249 | data += '\x00' # broadcast mode / default : False 250 | data += '\xe9\x13' #unknown, filled numbers randomly =w= 251 | 252 | log('[mkpkt]',data.encode('hex')) 253 | return data 254 | 255 | def login(usr, pwd, svr): 256 | import random 257 | global SALT 258 | 259 | i = 0 260 | while True: 261 | salt = challenge(svr,time.time()+random.randint(0xF,0xFF)) 262 | SALT = salt 263 | packet = mkpkt(salt, usr, pwd, mac) 264 | log('[login] send',packet.encode('hex')) 265 | s.sendto(packet, (svr, 61440)) 266 | data, address = s.recvfrom(1024) 267 | log('[login] recv',data.encode('hex')) 268 | log('[login] packet sent.') 269 | if address == (svr, 61440): 270 | if data[0] == '\x04': 271 | log('[login] loged in') 272 | break 273 | else: 274 | continue 275 | else: 276 | if i >= 5 and UNLIMITED_RETRY == False : 277 | log('[login] exception occured.') 278 | sys.exit(1) 279 | else: 280 | continue 281 | 282 | log('[login] login sent') 283 | #0.8 changed: 284 | return data[23:39] 285 | #return data[-22:-6] 286 | 287 | def keep_alive1(salt,tail,pwd,svr): 288 | foo = struct.pack('!H',int(time.time())%0xFFFF) 289 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 290 | data += tail 291 | data += foo + '\x00\x00\x00\x00' 292 | log('[keep_alive1] send',data.encode('hex')) 293 | 294 | s.sendto(data, (svr, 61440)) 295 | while True: 296 | data, address = s.recvfrom(1024) 297 | if data[0] == '\x07': 298 | break 299 | else: 300 | log('[keep-alive1]recv/not expected',data.encode('hex')) 301 | log('[keep-alive1] recv',data.encode('hex')) 302 | 303 | def empty_socket_buffer(): 304 | #empty buffer for some fucking schools 305 | log('starting to empty socket buffer') 306 | try: 307 | while True: 308 | data, address = s.recvfrom(1024) 309 | log('recived sth unexcepted',data.encode('hex')) 310 | if s == '': 311 | break 312 | except: 313 | # get exception means it has done. 314 | log('exception in empty_socket_buffer') 315 | pass 316 | log('emptyed') 317 | def main(): 318 | log("auth svr:"+server+"\nusername:"+username+"\nmac:"+str(hex(mac))) 319 | while True: 320 | try: 321 | package_tail = login(username, password, server) 322 | except LoginException: 323 | continue 324 | log('package_tail',package_tail.encode('hex')) 325 | #keep_alive1 is fucking bullshit! 326 | empty_socket_buffer() 327 | keep_alive1(SALT,package_tail,password,server) 328 | #empty_socket_buffer() 329 | keep_alive2(SALT,package_tail,password,server) 330 | if __name__ == "__main__": 331 | main() 332 | 333 | 334 | -------------------------------------------------------------------------------- /custom/drcom_d_gxnuedu.py: -------------------------------------------------------------------------------- 1 | #coding=UTF-8 2 | #test version 3 | 4 | 5 | import socket, struct, time,random,re 6 | from hashlib import md5 7 | 8 | #config 9 | server = '192.168.125.13' 10 | username='填上你的学号@cuc'#联通电信移动分别是cuc,cmc,ctc 11 | password='学号密码' 12 | CONTROLCHECKSTATUS = '\x20' 13 | ADAPTERNUM = '\x01' 14 | host_ip = '路由器的IP' 15 | IPDOG = '\x01' 16 | host_name = 'DRCOMFUCKER' 17 | PRIMARY_DNS = '202.193.160.33' 18 | dhcp_server = '0.0.0.0' 19 | AUTH_VERSION = '\x2c\x00' 20 | mac = 0x110000000007 21 | host_os = 'WINDIAOS' 22 | KEEP_ALIVE_VERSION = '\xdc\x02 23 | #config_end 24 | 25 | class ChallengeException (Exception): 26 | def __init__(self): 27 | pass 28 | 29 | class loginException (Exception): 30 | def __init__(self): 31 | pass 32 | 33 | def try_socket(): 34 | #sometimes cannot get the port 35 | global s,salt 36 | try: 37 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 38 | s.bind(("0.0.0.0", 61440)) 39 | s.settimeout(3) 40 | except: 41 | print ("."), 42 | time.sleep(0.5) 43 | print ("."), 44 | time.sleep(0.5) 45 | print (".") 46 | time.sleep(0.5) 47 | print ("...reopen") 48 | time.sleep(10) 49 | main() 50 | else: 51 | SALT= '' 52 | 53 | UNLIMITED_RETRY = True 54 | EXCEPTION = False 55 | 56 | def get_randmac(): 57 | mac = [ 0x00, 0x16, 0x3e,random.randint(0x00, 0x7f),random.randint(0x00, 0xff),random.randint(0x00, 0xff) ] 58 | return ''.join(map(lambda x: "%02x" % x, mac)) 59 | #print randomMAC() 60 | 61 | def version(): 62 | print ("DrCOM Auth Router for GDUFE") 63 | 64 | 65 | def challenge(svr,ran): 66 | while True: 67 | t = struct.pack(">5)) 102 | return ret 103 | 104 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 105 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 106 | data += KEEP_ALIVE_VERSION+'\x2f\x12' + '\x00' * 6 107 | data += tail 108 | data += '\x00' * 4 109 | #data += struct.pack("!H",0xdc02) 110 | if type == 3: 111 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 112 | #use double keep in main to keep online .Ice 113 | crc = '\x00' * 4 114 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 115 | data += crc + foo + '\x00' * 8 116 | else: #packet type = 1 117 | data += '\x00' * 16 118 | return data 119 | 120 | def packet_CRC(s): 121 | ret = 0 122 | for i in re.findall('..', s): 123 | ret ^= struct.unpack('>h', i)[0] 124 | ret &= 0xFFFF 125 | ret = ret * 0x2c7 126 | return ret 127 | 128 | 129 | 130 | def keep_alive2(*args): 131 | tail = '' 132 | packet = '' 133 | svr = server 134 | ran = random.randint(0,0xFFFF) 135 | ran += random.randint(1,10) 136 | 137 | packet = keep_alive_package_builder(0,dump(ran),'\x00'*4,1,True) 138 | #packet = keep_alive_package_builder(0,dump(ran),dump(ran)+'\x22\x06',1,True) 139 | print ('[keep-alive2] send1')#packet.encode('hex') 140 | while True: 141 | s.sendto(packet, (svr, 61440)) 142 | data, address = s.recvfrom(1024) 143 | if data.startswith('\x07'): 144 | break 145 | else: 146 | print ('[keep-alive2] recv/unexpected',data.encode('hex')) 147 | continue 148 | ran += random.randint(1,10) 149 | packet = keep_alive_package_builder(1,dump(ran),'\x00'*4,1,False) 150 | #print '[keep-alive2] send2',packet.encode('hex') 151 | s.sendto(packet, (svr, 61440)) 152 | while True: 153 | data, address = s.recvfrom(1024) 154 | if data[0] == '\x07': 155 | break 156 | #print '[keep-alive2] recv2',data.encode('hex') 157 | tail = data[16:20] 158 | 159 | 160 | ran += random.randint(1,10) 161 | packet = keep_alive_package_builder(2,dump(ran),tail,3,False) 162 | #print '[keep-alive2] send3',packet.encode('hex') 163 | s.sendto(packet, (svr, 61440)) 164 | while True: 165 | data, address = s.recvfrom(1024) 166 | if data[0] == '\x07': 167 | break 168 | #print '[keep-alive2] recv3',data.encode('hex') 169 | tail = data[16:20] 170 | print ("[keep-alive] keep-alive loop was in daemon.") 171 | i = 3 172 | 173 | while True: 174 | try: 175 | keep_alive1(SALT,package_tail,password,server) 176 | print '[keep-alive2] send' 177 | ran += random.randint(1,10) 178 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 179 | #print('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 180 | #print '[keep_alive2] send',str(i),packet.encode('hex') 181 | s.sendto(packet, (svr, 61440)) 182 | data, address = s.recvfrom(1024) 183 | #print '[keep_alive2] recv',data.encode('hex') 184 | tail = data[16:20] 185 | #print('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 186 | 187 | ran += random.randint(1,10) 188 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 189 | #print('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 190 | s.sendto(packet, (svr, 61440)) 191 | #print('[keep_alive2] send',str(i+1),packet.encode('hex')) 192 | data, address = s.recvfrom(1024) 193 | #print('[keep_alive2] recv',data.encode('hex')) 194 | tail = data[16:20] 195 | #print('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 196 | i = (i+2) % 0xFF 197 | time.sleep(20) 198 | except: 199 | pass 200 | 201 | def checksum(s): 202 | ret = 1234 203 | for i in re.findall('....', s): 204 | ret ^= int(i[::-1].encode('hex'), 16) 205 | ret = (1968 * ret) & 0xffffffff 206 | return struct.pack('= 5 and UNLIMITED_RETRY == False : 273 | print('[login] exception occured.') 274 | sys.exit(1) 275 | else: 276 | continue 277 | 278 | print('[login] login Success') 279 | return data[23:39] 280 | #return data[-22:-6] 281 | 282 | def keep_alive1(salt,tail,pwd,svr): 283 | foo = struct.pack('!H',int(time.time())%0xFFFF) 284 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 285 | data += tail 286 | data += foo + '\x00\x00\x00\x00' 287 | print '[keep_alive1] send'#data.encode('hex')) 288 | 289 | s.sendto(data, (svr, 61440)) 290 | while True: 291 | data, address = s.recvfrom(1024) 292 | if data[0] == '\x07': 293 | break 294 | else: 295 | print '[keep-alive1]recv/not expected'#data.encode('hex') 296 | #print('[keep-alive1] recv',data.encode('hex')) 297 | 298 | def empty_socket_buffer(): 299 | #empty buffer 300 | print('starting to empty socket buffer') 301 | try: 302 | while True: 303 | data, address = s.recvfrom(1024) 304 | #print 'recived sth unexcepted',data.encode('hex') 305 | if s == '': 306 | break 307 | except: 308 | # get exception means it has done. 309 | print('exception in empty_socket_buffer') 310 | pass 311 | print('emptyed') 312 | 313 | 314 | 315 | def main(): 316 | global server,username,password,host_name,host_os,dhcp_server,mac,hexip,host_ip 317 | hexip=socket.inet_aton(host_ip) 318 | #host_ip=ip 319 | host_name = "est-pc" 320 | host_os = "8089D" #default is 8089D 321 | dhcp_server = "0.0.0.0" 322 | #mac = 0xE0DB55BAE012 323 | #it is a mac in programme and it may crush with other users so I use randMAC to avoid it 324 | loginpart() 325 | 326 | def loginpart(): 327 | global package_tail 328 | while True: 329 | try: 330 | package_tail = login(username, password, server) 331 | except loginException: 332 | continue 333 | #print('package_tail',package_tail.encode('hex')) 334 | keeppart() 335 | 336 | def keeppart(): 337 | #empty_socket_buffer() 338 | #empty_socket_buffer() 339 | keep_alive2(SALT,package_tail,password,server) 340 | 341 | 342 | if __name__ == "__main__": 343 | try_socket() 344 | version() 345 | #get_conf() 346 | main() 347 | 348 | 349 | -------------------------------------------------------------------------------- /custom/drcom_d_version.py: -------------------------------------------------------------------------------- 1 | #coding=UTF-8 2 | #test version 3 | #Licensed under the GPL 4 | #thx all authors before 5 | 6 | 7 | import socket, struct, time,sys,urllib2,random,re,uuid 8 | from hashlib import md5 9 | 10 | #config 11 | server = '10.1.1.10' 12 | username='' 13 | password='' 14 | CONTROLCHECKSTATUS = '\x20' 15 | ADAPTERNUM = '\x03' 16 | host_ip = '10.50.23.19' 17 | IPDOG = '\x01' 18 | host_name = 'DRCOMFUCKER' 19 | PRIMARY_DNS = '202.102.192.68' 20 | dhcp_server = '10.50.23.254' 21 | AUTH_VERSION = '\x22\x00' 22 | mac = 0x20689df3d066 23 | host_os = 'WINDIAOS' 24 | KEEP_ALIVE_VERSION = '\xdc\x02' 25 | #config_end 26 | 27 | def try_socket(): 28 | #sometimes cannot get the port 29 | global s,salt 30 | try: 31 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 32 | s.bind(("0.0.0.0", 61440)) 33 | s.settimeout(3) 34 | except: 35 | i=0 36 | print ">Error!<" 37 | print">Cannot get the right port,this programm may cannot auth right<" 38 | print">Wait for 5 seconds<" 39 | time.sleep(5) 40 | else: 41 | SALT= '' 42 | 43 | 44 | 45 | UNLIMITED_RETRY = True 46 | EXCEPTION = False 47 | 48 | 49 | def version(): 50 | print "=====================================================================" 51 | print "DrCOM Auth Router for 3.5+" 52 | print "Version Apr.6.d" 53 | print "with keep-alive1&keep-alive2" 54 | print "=====================================================================" 55 | 56 | 57 | def challenge(svr,ran): 58 | while True: 59 | t = struct.pack(">5)) 91 | return ret 92 | 93 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 94 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 95 | if first : 96 | data += '\x0f\x27' 97 | else: 98 | data += KEEP_ALIVE_VERSION 99 | data += '\x2f\x12' + '\x00' * 6 100 | data += tail 101 | data += '\x00' * 4 102 | #data += struct.pack("!H",0xdc02) 103 | if type == 3: 104 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 105 | #use double keep in main to keep online .Ice 106 | crc = '\x00' * 4 107 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 108 | data += crc + foo + '\x00' * 8 109 | else: #packet type = 1 110 | data += '\x00' * 16 111 | return data 112 | 113 | def packet_CRC(s): 114 | ret = 0 115 | for i in re.findall('..', s): 116 | ret ^= struct.unpack('>h', i)[0] 117 | ret &= 0xFFFF 118 | ret = ret * 0x2c7 119 | return ret 120 | 121 | 122 | 123 | def keep_alive2(*args): 124 | tail = '' 125 | packet = '' 126 | svr = server 127 | ran = random.randint(0,0xFFFF) 128 | ran += random.randint(1,10) 129 | 130 | packet = keep_alive_package_builder(0,dump(ran),'\x00'*4,1,True) 131 | #packet = keep_alive_package_builder(0,dump(ran),dump(ran)+'\x22\x06',1,True) 132 | print '[keep-alive2] send1'#packet.encode('hex') 133 | while True: 134 | s.sendto(packet, (svr, 61440)) 135 | data, address = s.recvfrom(1024) 136 | if data.startswith('\x07'): 137 | break 138 | else: 139 | continue 140 | #print '[keep-alive2] recv/unexpected',data.encode('hex') 141 | #print '[keep-alive2] recv1',data.encode('hex') 142 | 143 | ran += random.randint(1,10) 144 | packet = keep_alive_package_builder(1,dump(ran),'\x00'*4,1,False) 145 | #print '[keep-alive2] send2',packet.encode('hex') 146 | s.sendto(packet, (svr, 61440)) 147 | while True: 148 | data, address = s.recvfrom(1024) 149 | if data[0] == '\x07': 150 | break 151 | #print '[keep-alive2] recv2',data.encode('hex') 152 | tail = data[16:20] 153 | 154 | 155 | ran += random.randint(1,10) 156 | packet = keep_alive_package_builder(2,dump(ran),tail,3,False) 157 | #print '[keep-alive2] send3',packet.encode('hex') 158 | s.sendto(packet, (svr, 61440)) 159 | while True: 160 | data, address = s.recvfrom(1024) 161 | if data[0] == '\x07': 162 | break 163 | #print '[keep-alive2] recv3',data.encode('hex') 164 | tail = data[16:20] 165 | print "[keep-alive] keep-alive loop was in daemon." 166 | i = 3 167 | 168 | while True: 169 | try: 170 | keep_alive1(SALT,package_tail,password,server) 171 | print '[keep-alive2] send' 172 | ran += random.randint(1,10) 173 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 174 | #print('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 175 | #print '[keep_alive2] send',str(i),packet.encode('hex') 176 | s.sendto(packet, (svr, 61440)) 177 | data, address = s.recvfrom(1024) 178 | #print '[keep_alive2] recv',data.encode('hex') 179 | tail = data[16:20] 180 | #print('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 181 | 182 | ran += random.randint(1,10) 183 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 184 | #print('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 185 | s.sendto(packet, (svr, 61440)) 186 | #print('[keep_alive2] send',str(i+1),packet.encode('hex')) 187 | data, address = s.recvfrom(1024) 188 | #print('[keep_alive2] recv',data.encode('hex')) 189 | tail = data[16:20] 190 | #print('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 191 | i = (i+2) % 0xFF 192 | time.sleep(20) 193 | except: 194 | pass 195 | 196 | def checksum(s): 197 | ret = 1234 198 | for i in re.findall('....', s): 199 | ret ^= int(i[::-1].encode('hex'), 16) 200 | ret = (1968 * ret) & 0xffffffff 201 | return struct.pack('= 5 and UNLIMITED_RETRY == False : 268 | print('[login] exception occured.') 269 | sys.exit(1) 270 | else: 271 | continue 272 | 273 | print('[login] login Success') 274 | return data[23:39] 275 | #return data[-22:-6] 276 | 277 | def keep_alive1(salt,tail,pwd,svr): 278 | foo = struct.pack('!H',int(time.time())%0xFFFF) 279 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 280 | data += tail 281 | data += foo + '\x00\x00\x00\x00' 282 | print '[keep_alive1] send'#data.encode('hex')) 283 | 284 | s.sendto(data, (svr, 61440)) 285 | while True: 286 | data, address = s.recvfrom(1024) 287 | if data[0] == '\x07': 288 | break 289 | else: 290 | print '[keep-alive1]recv/not expected'#data.encode('hex') 291 | #print('[keep-alive1] recv',data.encode('hex')) 292 | 293 | def empty_socket_buffer(): 294 | #empty buffer 295 | print('starting to empty socket buffer') 296 | try: 297 | while True: 298 | data, address = s.recvfrom(1024) 299 | #print 'recived sth unexcepted',data.encode('hex') 300 | if s == '': 301 | break 302 | except: 303 | # get exception means it has done. 304 | print('exception in empty_socket_buffer') 305 | pass 306 | print('emptyed') 307 | 308 | 309 | def check_online(): 310 | try: 311 | check_online = urllib2.urlopen('http://www.baidu.com') 312 | foo=check_online.read() 313 | except: 314 | print "Network line Err,check the line...Hit the return" 315 | raw_input() 316 | else: 317 | if '10.1.1.10' in foo: 318 | print "Not Online,try to auth" 319 | raw_input() 320 | else: 321 | print "Already online,Hit the return" 322 | raw_input() 323 | sys.exit(0) 324 | 325 | 326 | 327 | def main(): 328 | global hexip,host_ip 329 | #host_ip=socket.gethostbyname(socket.gethostname()) 330 | hexip=socket.inet_aton(host_ip) 331 | dhcp_server = "0.0.0.0" 332 | #mac = 0xE0DB55BAE012 333 | #it is a mac in programme and it may crush with other users so I use randMAC to avoid it 334 | loginpart() 335 | 336 | def loginpart(): 337 | global package_tail 338 | while True: 339 | try: 340 | package_tail = login(username, password, server) 341 | except loginException: 342 | continue 343 | #print('package_tail',package_tail.encode('hex')) 344 | keeppart() 345 | 346 | def keeppart(): 347 | #empty_socket_buffer() 348 | keep_alive1(SALT,package_tail,password,server) 349 | keep_alive2(SALT,package_tail,password,server) 350 | 351 | 352 | if __name__ == "__main__": 353 | try_socket() 354 | version() 355 | #get_conf() 356 | main() 357 | 358 | 359 | -------------------------------------------------------------------------------- /custom/drcom_d_中国民航大学.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import socket, struct, time 4 | from hashlib import md5 5 | import sys 6 | import os 7 | import random 8 | 9 | # CONFIG 10 | server = "192.168.100.251" 11 | username = " 12 | password = " 13 | host_ip = "10.5.155.177" 14 | host_name = "fuyumi" 15 | host_os = "Windows 8.1" 16 | dhcp_server = "0.0.0.0" 17 | mac = 0xb63d020c60fd 18 | CONTROLCHECKSTATUS = '\x20' 19 | ADAPTERNUM = '\x01' 20 | KEEP_ALIVE_VERSION = '\xd4\x02' 21 | AUTH_VERSION = '\x09\x00' 22 | IPDOG = '\x01' 23 | # CONFIG_END 24 | 25 | class ChallengeException (Exception): 26 | def __init__(self): 27 | pass 28 | 29 | class LoginException (Exception): 30 | def __init__(self): 31 | pass 32 | 33 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 34 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 35 | s.bind(("0.0.0.0", 52431)) 36 | 37 | s.settimeout(3) 38 | SALT = '' 39 | IS_TEST = True 40 | # IS_TEST = False 41 | # specified fields based on version 42 | CONF = "/etc/drcom.conf" 43 | if IS_TEST: 44 | CONF = '' 45 | UNLIMITED_RETRY = True 46 | EXCEPTION = False 47 | DEBUG = False #log saves to file 48 | LOG_PATH = '/var/log/drcom_client.log' 49 | if IS_TEST: 50 | DEBUG = True 51 | LOG_PATH = 'drcom_client.log' 52 | 53 | 54 | def log(*args, **kwargs): 55 | s = ' '.join(args) 56 | s = time.strftime("%Y-%m-%d %X", time.localtime()) + s 57 | print s 58 | if 0: 59 | with open(LOG_PATH,'a') as f: 60 | f.write(s + '\n') 61 | 62 | def challenge(svr,ran): 63 | while True: 64 | t = struct.pack(">5)) 99 | return ret 100 | 101 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 102 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 103 | if first : 104 | data += '\x0f\x27' 105 | else: 106 | data += KEEP_ALIVE_VERSION 107 | data += '\x2f\x12' + '\x00' * 6 108 | data += tail 109 | data += '\x00' * 4 110 | #data += struct.pack("!H",0xdc02) 111 | if type == 3: 112 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 113 | #CRC 114 | # edited on 2014/5/12, filled zeros to checksum 115 | # crc = packet_CRC(data+foo) 116 | crc = '\x00' * 4 117 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 118 | data += crc + foo + '\x00' * 8 119 | else: #packet type = 1 120 | data += '\x00' * 16 121 | return data 122 | 123 | def packet_CRC(s): 124 | ret = 0 125 | for i in re.findall('..', s): 126 | ret ^= struct.unpack('>h', i)[0] 127 | ret &= 0xFFFF 128 | ret = ret * 0x2c7 129 | return ret 130 | 131 | def keep_alive2(*args): 132 | #first keep_alive: 133 | #number = number (mod 7) 134 | #status = 1: first packet user sended 135 | # 2: first packet user recieved 136 | # 3: 2nd packet user sended 137 | # 4: 2nd packet user recieved 138 | # Codes for test 139 | tail = '' 140 | packet = '' 141 | svr = server 142 | ran = random.randint(0,0xFFFF) 143 | ran += random.randint(1,10) 144 | # 2014/10/15 add by latyas, maybe svr sends back a file packet 145 | svr_num = 0 146 | packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1,True) 147 | while True: 148 | #log('[keep-alive2] send1',packet.encode('hex')) 149 | try: 150 | s.sendto(packet, (svr, 61440)) 151 | data, address = s.recvfrom(1024) 152 | except: 153 | continue 154 | #log('[keep-alive2] recv1',data.encode('hex')) 155 | if data.startswith('\x07\x00\x28\x00') or data.startswith('\x07' + chr(svr_num) + '\x28\x00'): 156 | break 157 | elif data[0] == '\x07' and data[2] == '\x10': 158 | log('[keep-alive2] recv file, resending..') 159 | svr_num = svr_num + 1 160 | packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1, False) 161 | else: 162 | log('[keep-alive2] recv1/unexpected',data.encode('hex')) 163 | #log('[keep-alive2] recv1',data.encode('hex')) 164 | 165 | ran += random.randint(1,10) 166 | packet = keep_alive_package_builder(svr_num, dump(ran),'\x00'*4,1,False) 167 | #log('[keep-alive2] send2',packet.encode('hex')) 168 | s.sendto(packet, (svr, 61440)) 169 | while True: 170 | try: 171 | data, address = s.recvfrom(1024) 172 | except: 173 | s.sendto(packet, (svr, 61440)) 174 | continue 175 | if data[0] == '\x07': 176 | svr_num = svr_num + 1 177 | break 178 | else: 179 | log('[keep-alive2] recv2/unexpected',data.encode('hex')) 180 | #log('[keep-alive2] recv2',data.encode('hex')) 181 | tail = data[16:20] 182 | 183 | 184 | ran += random.randint(1,10) 185 | packet = keep_alive_package_builder(svr_num,dump(ran),tail,3,False) 186 | #log('[keep-alive2] send3',packet.encode('hex')) 187 | s.sendto(packet, (svr, 61440)) 188 | while True: 189 | try: 190 | data, address = s.recvfrom(1024) 191 | except: 192 | s.sendto(packet, (svr, 61440)) 193 | continue 194 | if data[0] == '\x07': 195 | svr_num = svr_num + 1 196 | break 197 | else: 198 | log('[keep-alive2] recv3/unexpected',data.encode('hex')) 199 | # log('[keep-alive2] recv3',data.encode('hex')) 200 | tail = data[16:20] 201 | log("[keep-alive2] keep-alive2 loop was in daemon.") 202 | 203 | i = svr_num 204 | while True: 205 | try: 206 | ran += random.randint(1,10) 207 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 208 | #log('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 209 | log('[keep_alive2] send',str(i),packet.encode('hex')) 210 | s.sendto(packet, (svr, 61440)) 211 | data, address = s.recvfrom(1024) 212 | log('[keep_alive2] recv',data.encode('hex')) 213 | tail = data[16:20] 214 | #log('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 215 | 216 | ran += random.randint(1,10) 217 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 218 | #log('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 219 | s.sendto(packet, (svr, 61440)) 220 | log('[keep_alive2] send',str(i+1),packet.encode('hex')) 221 | data, address = s.recvfrom(1024) 222 | log('[keep_alive2] recv',data.encode('hex')) 223 | tail = data[16:20] 224 | #log('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 225 | i = (i+2) % 0xFF 226 | time.sleep(5) 227 | keep_alive1(*args) 228 | except: 229 | pass 230 | 231 | 232 | import re 233 | def checksum(s): 234 | ret = 1234 235 | for i in re.findall('....', s): 236 | ret ^= int(i[::-1].encode('hex'), 16) 237 | ret = (1968 * ret) & 0xffffffff 238 | return struct.pack(' 251 | data += '\00'*4 #your ipaddress 2 252 | data += '\00'*4 #your ipaddress 3 253 | data += '\00'*4 #your ipaddress 4 254 | data += md5sum(data + '\x14\x00\x07\x0b')[:8] #md53 255 | data += IPDOG 256 | data += '\x00'*4 #delimeter 257 | data += host_name.ljust(32, '\x00') 258 | data += '\x08\x08\x08\x08' #primary dns: 8.8.8.8 259 | data += ''.join([chr(int(i)) for i in dhcp_server.split('.')]) #DHCP server 260 | data += '\x00\x00\x00\x00' #secondary dns:0.0.0.0 261 | data += '\x00' * 8 #delimeter 262 | data += '\x94\x00\x00\x00' # unknow 263 | data += '\x05\x00\x00\x00' # os major 264 | data += '\x01\x00\x00\x00' # os minor 265 | data += '\x28\x0a\x00\x00' # OS build 266 | data += '\x02\x00\x00\x00' #os unknown 267 | data += host_os.ljust(32,'\x00') 268 | data += '\x00' * 96 269 | #data += '\x01' + host_os.ljust(128, '\x00') 270 | #data += '\x0a\x00\x00'+chr(len(pwd)) # \0x0a represents version of client, algorithm: DRCOM_VER + 100 271 | #data += ror(md5sum('\x03\x01'+salt+pwd), pwd) 272 | data += AUTH_VERSION 273 | data += '\x02\x0c' 274 | data += checksum(data+'\x01\x26\x07\x11\x00\x00'+dump(mac)) 275 | data += '\x00\x00' #delimeter 276 | data += dump(mac) 277 | data += '\x00' # auto logout / default: False 278 | data += '\x00' # broadcast mode / default : False 279 | data += '\xe9\x13' #unknown, filled numbers randomly =w= 280 | 281 | log('[mkpkt]',data.encode('hex')) 282 | return data 283 | 284 | def login(usr, pwd, svr): 285 | import random 286 | global SALT 287 | 288 | i = 0 289 | while True: 290 | salt = challenge(svr,time.time()+random.randint(0xF,0xFF)) 291 | SALT = salt 292 | packet = mkpkt(salt, usr, pwd, mac) 293 | log('[login] send',packet.encode('hex')) 294 | try: 295 | s.sendto(packet, (svr, 61440)) 296 | data, address = s.recvfrom(1024) 297 | except: 298 | continue 299 | log('[login] recv',data.encode('hex')) 300 | log('[login] packet sent.') 301 | if address == (svr, 61440): 302 | if data[0] == '\x04': 303 | log('[login] loged in') 304 | break 305 | else: 306 | continue 307 | else: 308 | if i >= 5 and UNLIMITED_RETRY == False : 309 | log('[login] exception occured.') 310 | sys.exit(1) 311 | else: 312 | continue 313 | 314 | log('[login] login sent') 315 | #0.8 changed: 316 | return data[23:39] 317 | #return data[-22:-6] 318 | 319 | def keep_alive1(salt,tail,pwd,svr): 320 | foo = struct.pack('!H',int(time.time())%0xFFFF) 321 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 322 | data += tail 323 | data += foo + '\x00\x00\x00\x00' 324 | log('[keep_alive1] send',data.encode('hex')) 325 | 326 | s.sendto(data, (svr, 61440)) 327 | while True: 328 | try: 329 | data, address = s.recvfrom(1024) 330 | except: 331 | s.sendto(data, (svr, 61440)) 332 | continue 333 | if data[0] == '\x07': 334 | break 335 | else: 336 | log('[keep-alive1]recv/not expected',data.encode('hex')) 337 | log('[keep-alive1] recv',data.encode('hex')) 338 | 339 | def empty_socket_buffer(): 340 | #empty buffer for some fucking schools 341 | log('starting to empty socket buffer') 342 | try: 343 | while True: 344 | data, address = s.recvfrom(1024) 345 | log('recived sth unexpected',data.encode('hex')) 346 | if s == '': 347 | break 348 | except: 349 | # get exception means it has done. 350 | log('exception in empty_socket_buffer') 351 | pass 352 | log('emptyed') 353 | def daemon(): 354 | with open('/var/run/jludrcom.pid','w') as f: 355 | f.write(str(os.getpid())) 356 | 357 | def main(): 358 | if not IS_TEST: 359 | daemon() 360 | execfile(CONF, globals()) 361 | log("auth svr:"+server+"\nusername:"+username+"\npassword:"+password+"\nmac:"+str(hex(mac))) 362 | while True: 363 | try: 364 | package_tail = login(username, password, server) 365 | except LoginException: 366 | continue 367 | log('package_tail',package_tail.encode('hex')) 368 | #keep_alive1 is fucking bullshit! 369 | empty_socket_buffer() 370 | keep_alive1(SALT,package_tail,password,server) 371 | keep_alive2(SALT,package_tail,password,server) 372 | if __name__ == "__main__": 373 | while True: 374 | main() 375 | 376 | 377 | -------------------------------------------------------------------------------- /custom/drcom_d_广东财经大学.py: -------------------------------------------------------------------------------- 1 | #coding=UTF-8 2 | #test version 3 | 4 | 5 | import socket, struct, time,random,re 6 | from hashlib import md5 7 | 8 | #config 9 | server = '58.62.247.115' 10 | username='' 11 | password='' 12 | CONTROLCHECKSTATUS = '\x20' 13 | ADAPTERNUM = '\x04' 14 | host_ip = '172.31.37.194' 15 | IPDOG = '\x01' 16 | host_name = 'DRCOMFUCKER' 17 | PRIMARY_DNS = '202.96.128.166' 18 | dhcp_server = '222.202.171.33' 19 | AUTH_VERSION = '\x7f\x7f' #maximize version for continuous update 20 | mac = 0xfc15b4ff0125 21 | host_os = 'Linux' 22 | KEEP_ALIVE_VERSION = '\xdc\x02' 23 | 24 | #config_end 25 | 26 | class ChallengeException (Exception): 27 | def __init__(self): 28 | pass 29 | 30 | class loginException (Exception): 31 | def __init__(self): 32 | pass 33 | 34 | def try_socket(): 35 | #sometimes cannot get the port 36 | global s,salt 37 | try: 38 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 39 | s.bind(("0.0.0.0", 61440)) 40 | s.settimeout(3) 41 | except: 42 | print ("."), 43 | time.sleep(0.5) 44 | print ("."), 45 | time.sleep(0.5) 46 | print (".") 47 | time.sleep(0.5) 48 | print ("...reopen") 49 | time.sleep(10) 50 | main() 51 | else: 52 | SALT= '' 53 | 54 | UNLIMITED_RETRY = True 55 | EXCEPTION = False 56 | 57 | def get_randmac(): 58 | mac = [ 0x00, 0x16, 0x3e,random.randint(0x00, 0x7f),random.randint(0x00, 0xff),random.randint(0x00, 0xff) ] 59 | return ''.join(map(lambda x: "%02x" % x, mac)) 60 | #print randomMAC() 61 | 62 | def version(): 63 | print ("DrCOM Auth Router for GDUFE") 64 | 65 | 66 | def challenge(svr,ran): 67 | while True: 68 | t = struct.pack(">5)) 103 | return ret 104 | 105 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 106 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 107 | data += KEEP_ALIVE_VERSION+'\x2f\x12' + '\x00' * 6 108 | data += tail 109 | data += '\x00' * 4 110 | #data += struct.pack("!H",0xdc02) 111 | if type == 3: 112 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 113 | #use double keep in main to keep online .Ice 114 | crc = '\x00' * 4 115 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 116 | data += crc + foo + '\x00' * 8 117 | else: #packet type = 1 118 | data += '\x00' * 16 119 | return data 120 | 121 | def packet_CRC(s): 122 | ret = 0 123 | for i in re.findall('..', s): 124 | ret ^= struct.unpack('>h', i)[0] 125 | ret &= 0xFFFF 126 | ret = ret * 0x2c7 127 | return ret 128 | 129 | 130 | 131 | def keep_alive2(*args): 132 | tail = '' 133 | packet = '' 134 | svr = server 135 | ran = random.randint(0,0xFFFF) 136 | ran += random.randint(1,10) 137 | 138 | packet = keep_alive_package_builder(0,dump(ran),'\x00'*4,1,True) 139 | #packet = keep_alive_package_builder(0,dump(ran),dump(ran)+'\x22\x06',1,True) 140 | print ('[keep-alive2] send1')#packet.encode('hex') 141 | while True: 142 | s.sendto(packet, (svr, 61440)) 143 | data, address = s.recvfrom(1024) 144 | if data.startswith('\x07'): 145 | break 146 | else: 147 | print ('[keep-alive2] recv/unexpected',data.encode('hex')) 148 | continue 149 | ran += random.randint(1,10) 150 | packet = keep_alive_package_builder(1,dump(ran),'\x00'*4,1,False) 151 | #print '[keep-alive2] send2',packet.encode('hex') 152 | s.sendto(packet, (svr, 61440)) 153 | while True: 154 | data, address = s.recvfrom(1024) 155 | if data[0] == '\x07': 156 | break 157 | #print '[keep-alive2] recv2',data.encode('hex') 158 | tail = data[16:20] 159 | 160 | 161 | ran += random.randint(1,10) 162 | packet = keep_alive_package_builder(2,dump(ran),tail,3,False) 163 | #print '[keep-alive2] send3',packet.encode('hex') 164 | s.sendto(packet, (svr, 61440)) 165 | while True: 166 | data, address = s.recvfrom(1024) 167 | if data[0] == '\x07': 168 | break 169 | #print '[keep-alive2] recv3',data.encode('hex') 170 | tail = data[16:20] 171 | print ("[keep-alive] keep-alive loop was in daemon.") 172 | i = 3 173 | 174 | while True: 175 | try: 176 | keep_alive1(SALT,package_tail,password,server) 177 | print '[keep-alive2] send' 178 | ran += random.randint(1,10) 179 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 180 | #print('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 181 | #print '[keep_alive2] send',str(i),packet.encode('hex') 182 | s.sendto(packet, (svr, 61440)) 183 | data, address = s.recvfrom(1024) 184 | #print '[keep_alive2] recv',data.encode('hex') 185 | tail = data[16:20] 186 | #print('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 187 | 188 | ran += random.randint(1,10) 189 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 190 | #print('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 191 | s.sendto(packet, (svr, 61440)) 192 | #print('[keep_alive2] send',str(i+1),packet.encode('hex')) 193 | data, address = s.recvfrom(1024) 194 | #print('[keep_alive2] recv',data.encode('hex')) 195 | tail = data[16:20] 196 | #print('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 197 | i = (i+2) % 0xFF 198 | time.sleep(20) 199 | except: 200 | pass 201 | 202 | def checksum(s): 203 | ret = 1234 204 | for i in re.findall('....', s): 205 | ret ^= int(i[::-1].encode('hex'), 16) 206 | ret = (1968 * ret) & 0xffffffff 207 | return struct.pack('= 5 and UNLIMITED_RETRY == False : 274 | print('[login] exception occured.') 275 | sys.exit(1) 276 | else: 277 | continue 278 | 279 | print('[login] login Success') 280 | return data[23:39] 281 | #return data[-22:-6] 282 | 283 | def keep_alive1(salt,tail,pwd,svr): 284 | foo = struct.pack('!H',int(time.time())%0xFFFF) 285 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 286 | data += tail 287 | data += foo + '\x00\x00\x00\x00' 288 | print '[keep_alive1] send'#data.encode('hex')) 289 | 290 | s.sendto(data, (svr, 61440)) 291 | while True: 292 | data, address = s.recvfrom(1024) 293 | if data[0] == '\x07': 294 | break 295 | else: 296 | print '[keep-alive1]recv/not expected'#data.encode('hex') 297 | #print('[keep-alive1] recv',data.encode('hex')) 298 | 299 | def empty_socket_buffer(): 300 | #empty buffer 301 | print('starting to empty socket buffer') 302 | try: 303 | while True: 304 | data, address = s.recvfrom(1024) 305 | #print 'recived sth unexcepted',data.encode('hex') 306 | if s == '': 307 | break 308 | except: 309 | # get exception means it has done. 310 | print('exception in empty_socket_buffer') 311 | pass 312 | print('emptyed') 313 | 314 | 315 | 316 | def main(): 317 | global server,username,password,host_name,host_os,dhcp_server,mac,hexip,host_ip 318 | hexip=socket.inet_aton(host_ip) 319 | #host_ip=ip 320 | host_name = "est-pc" 321 | host_os = "8089D" #default is 8089D 322 | dhcp_server = "0.0.0.0" 323 | #mac = 0xE0DB55BAE012 324 | #it is a mac in programme and it may crush with other users so I use randMAC to avoid it 325 | loginpart() 326 | 327 | def loginpart(): 328 | global package_tail 329 | while True: 330 | try: 331 | package_tail = login(username, password, server) 332 | except loginException: 333 | continue 334 | #print('package_tail',package_tail.encode('hex')) 335 | keeppart() 336 | 337 | def keeppart(): 338 | #empty_socket_buffer() 339 | #empty_socket_buffer() 340 | keep_alive2(SALT,package_tail,password,server) 341 | 342 | 343 | if __name__ == "__main__": 344 | try_socket() 345 | version() 346 | #get_conf() 347 | main() 348 | 349 | 350 | -------------------------------------------------------------------------------- /custom/drcom_d_衡水学院.py: -------------------------------------------------------------------------------- 1 | #coding=UTF-8 2 | 3 | #适用于衡水学院校园网,已通过测试 4 | #在下面需要输入帐号信息的地方输入账号等信息 5 | #有问题请联系littledongdong@foxmail.com 6 | #最后编辑时间:2017-2-22 10:14:51 7 | #by Dong 8 | 9 | import socket, struct, time,random,re 10 | from hashlib import md5 11 | 12 | #config 13 | server = '192.168.114.11' 14 | username=''#引号内输入校园网账号(学号) 15 | password=''#引号内输入校园网密码 16 | CONTROLCHECKSTATUS = '\x20' 17 | ADAPTERNUM = '\x04' 18 | host_ip = ''#引号内输入本机IP地址(可在Dr.COM客户端查看) 19 | IPDOG = '\x01' 20 | host_name = 'DRCOMFUCKER' 21 | PRIMARY_DNS = '222.222.222.222' 22 | dhcp_server = '192.168.103.254' 23 | AUTH_VERSION = '\x21\x00' 24 | mac = 0x001c4209e63c 25 | host_os = 'WINDIAOS' 26 | KEEP_ALIVE_VERSION = '\xdc\x02' 27 | #config_end 28 | 29 | class ChallengeException (Exception): 30 | def __init__(self): 31 | pass 32 | 33 | class loginException (Exception): 34 | def __init__(self): 35 | pass 36 | 37 | def try_socket(): 38 | #sometimes cannot get the port 39 | global s,salt 40 | try: 41 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 42 | s.bind(("0.0.0.0", 61440)) 43 | s.settimeout(3) 44 | except: 45 | print ("."), 46 | time.sleep(0.5) 47 | print ("."), 48 | time.sleep(0.5) 49 | print (".") 50 | time.sleep(0.5) 51 | print ("...reopen") 52 | time.sleep(10) 53 | main() 54 | else: 55 | SALT= '' 56 | 57 | UNLIMITED_RETRY = True 58 | EXCEPTION = False 59 | 60 | def get_randmac(): 61 | mac = [ 0x00, 0x16, 0x3e,random.randint(0x00, 0x7f),random.randint(0x00, 0xff),random.randint(0x00, 0xff) ] 62 | return ''.join(map(lambda x: "%02x" % x, mac)) 63 | #print randomMAC() 64 | 65 | def version(): 66 | print ("DrCOM Auth Router for GDUFE") 67 | 68 | 69 | def challenge(svr,ran): 70 | while True: 71 | t = struct.pack(">5)) 106 | return ret 107 | 108 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 109 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 110 | data += KEEP_ALIVE_VERSION+'\x2f\x12' + '\x00' * 6 111 | data += tail 112 | data += '\x00' * 4 113 | #data += struct.pack("!H",0xdc02) 114 | if type == 3: 115 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 116 | #use double keep in main to keep online .Ice 117 | crc = '\x00' * 4 118 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 119 | data += crc + foo + '\x00' * 8 120 | else: #packet type = 1 121 | data += '\x00' * 16 122 | return data 123 | 124 | def packet_CRC(s): 125 | ret = 0 126 | for i in re.findall('..', s): 127 | ret ^= struct.unpack('>h', i)[0] 128 | ret &= 0xFFFF 129 | ret = ret * 0x2c7 130 | return ret 131 | 132 | 133 | 134 | def keep_alive2(*args): 135 | tail = '' 136 | packet = '' 137 | svr = server 138 | ran = random.randint(0,0xFFFF) 139 | ran += random.randint(1,10) 140 | 141 | packet = keep_alive_package_builder(0,dump(ran),'\x00'*4,1,True) 142 | #packet = keep_alive_package_builder(0,dump(ran),dump(ran)+'\x22\x06',1,True) 143 | print ('[keep-alive2] send1')#packet.encode('hex') 144 | while True: 145 | s.sendto(packet, (svr, 61440)) 146 | data, address = s.recvfrom(1024) 147 | if data.startswith('\x07'): 148 | break 149 | else: 150 | print ('[keep-alive2] recv/unexpected',data.encode('hex')) 151 | continue 152 | ran += random.randint(1,10) 153 | packet = keep_alive_package_builder(1,dump(ran),'\x00'*4,1,False) 154 | #print '[keep-alive2] send2',packet.encode('hex') 155 | s.sendto(packet, (svr, 61440)) 156 | while True: 157 | data, address = s.recvfrom(1024) 158 | if data[0] == '\x07': 159 | break 160 | #print '[keep-alive2] recv2',data.encode('hex') 161 | tail = data[16:20] 162 | 163 | 164 | ran += random.randint(1,10) 165 | packet = keep_alive_package_builder(2,dump(ran),tail,3,False) 166 | #print '[keep-alive2] send3',packet.encode('hex') 167 | s.sendto(packet, (svr, 61440)) 168 | while True: 169 | data, address = s.recvfrom(1024) 170 | if data[0] == '\x07': 171 | break 172 | #print '[keep-alive2] recv3',data.encode('hex') 173 | tail = data[16:20] 174 | print ("[keep-alive] keep-alive loop was in daemon.") 175 | i = 3 176 | 177 | while True: 178 | try: 179 | keep_alive1(SALT,package_tail,password,server) 180 | print '[keep-alive2] send' 181 | ran += random.randint(1,10) 182 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 183 | #print('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 184 | #print '[keep_alive2] send',str(i),packet.encode('hex') 185 | s.sendto(packet, (svr, 61440)) 186 | data, address = s.recvfrom(1024) 187 | #print '[keep_alive2] recv',data.encode('hex') 188 | tail = data[16:20] 189 | #print('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 190 | 191 | ran += random.randint(1,10) 192 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 193 | #print('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 194 | s.sendto(packet, (svr, 61440)) 195 | #print('[keep_alive2] send',str(i+1),packet.encode('hex')) 196 | data, address = s.recvfrom(1024) 197 | #print('[keep_alive2] recv',data.encode('hex')) 198 | tail = data[16:20] 199 | #print('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 200 | i = (i+2) % 0xFF 201 | time.sleep(20) 202 | except: 203 | pass 204 | 205 | def checksum(s): 206 | ret = 1234 207 | for i in re.findall('....', s): 208 | ret ^= int(i[::-1].encode('hex'), 16) 209 | ret = (1968 * ret) & 0xffffffff 210 | return struct.pack('= 5 and UNLIMITED_RETRY == False : 277 | print('[login] exception occured.') 278 | sys.exit(1) 279 | else: 280 | continue 281 | 282 | print('[login] login Success') 283 | return data[23:39] 284 | #return data[-22:-6] 285 | 286 | def keep_alive1(salt,tail,pwd,svr): 287 | foo = struct.pack('!H',int(time.time())%0xFFFF) 288 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 289 | data += tail 290 | data += foo + '\x00\x00\x00\x00' 291 | print '[keep_alive1] send'#data.encode('hex')) 292 | 293 | s.sendto(data, (svr, 61440)) 294 | while True: 295 | data, address = s.recvfrom(1024) 296 | if data[0] == '\x07': 297 | break 298 | else: 299 | print '[keep-alive1]recv/not expected'#data.encode('hex') 300 | #print('[keep-alive1] recv',data.encode('hex')) 301 | 302 | def empty_socket_buffer(): 303 | #empty buffer 304 | print('starting to empty socket buffer') 305 | try: 306 | while True: 307 | data, address = s.recvfrom(1024) 308 | #print 'recived sth unexcepted',data.encode('hex') 309 | if s == '': 310 | break 311 | except: 312 | # get exception means it has done. 313 | print('exception in empty_socket_buffer') 314 | pass 315 | print('emptyed') 316 | 317 | 318 | 319 | def main(): 320 | global server,username,password,host_name,host_os,dhcp_server,mac,hexip,host_ip 321 | hexip=socket.inet_aton(host_ip) 322 | #host_ip=ip 323 | host_name = "est-pc" 324 | host_os = "8089D" #default is 8089D 325 | dhcp_server = "0.0.0.0" 326 | #mac = 0xE0DB55BAE012 327 | #it is a mac in programme and it may crush with other users so I use randMAC to avoid it 328 | loginpart() 329 | 330 | def loginpart(): 331 | global package_tail 332 | while True: 333 | try: 334 | package_tail = login(username, password, server) 335 | except loginException: 336 | continue 337 | #print('package_tail',package_tail.encode('hex')) 338 | keeppart() 339 | 340 | def keeppart(): 341 | #empty_socket_buffer() 342 | #empty_socket_buffer() 343 | keep_alive2(SALT,package_tail,password,server) 344 | 345 | 346 | if __name__ == "__main__": 347 | try_socket() 348 | version() 349 | #get_conf() 350 | main() 351 | 352 | 353 | -------------------------------------------------------------------------------- /custom/drcom_for_dlnu_520(x).py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import socket, struct, time 4 | from hashlib import md5 5 | import sys 6 | import os 7 | import random 8 | 9 | # CONFIG 10 | server = '172.16.192.111' 11 | username='' 12 | password='' 13 | CONTROLCHECKSTATUS = '\x00' 14 | ADAPTERNUM = '\x00' 15 | host_ip = '0.210.30.0' 16 | IPDOG = '\x00' 17 | host_name = 'DRCOMFUCKER' 18 | PRIMARY_DNS = '0.0.0.0' 19 | dhcp_server = '0.0.0.0' 20 | AUTH_VERSION = '\x20\x1a' 21 | mac = 0xb888e3051680 22 | host_os = 'WINDIAOS' 23 | KEEP_ALIVE_VERSION = '\xdc\x02' 24 | # CONFIG_END 25 | 26 | nic_name = '' #Indicate your nic, e.g. 'eth0.2'.nic_name 27 | bind_ip = '0.0.0.0' 28 | 29 | class ChallengeException (Exception): 30 | def __init__(self): 31 | pass 32 | 33 | class LoginException (Exception): 34 | def __init__(self): 35 | pass 36 | 37 | def bind_nic(): 38 | try: 39 | import fcntl 40 | def get_ip_address(ifname): 41 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 42 | return socket.inet_ntoa(fcntl.ioctl( 43 | s.fileno(), 44 | 0x8915, # SIOCGIFADDR 45 | struct.pack('256s', ifname[:15]) 46 | )[20:24]) 47 | return get_ip_address(nic_name) 48 | except ImportError as e: 49 | print('Indicate nic feature need to be run under Unix based system.') 50 | return '0.0.0.0' 51 | except IOError as e: 52 | print(nic_name + 'is unacceptable !') 53 | return '0.0.0.0' 54 | finally: 55 | return '0.0.0.0' 56 | 57 | if nic_name != '': 58 | bind_ip = bind_nic() 59 | 60 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 61 | # s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 62 | s.bind((bind_ip, 61440)) 63 | 64 | s.settimeout(3) 65 | SALT = '' 66 | IS_TEST = True 67 | # specified fields based on version 68 | CONF = "/etc/drcom.conf" 69 | UNLIMITED_RETRY = True 70 | EXCEPTION = False 71 | DEBUG = False #log saves to file 72 | LOG_PATH = '/var/log/drcom_client.log' 73 | if IS_TEST: 74 | DEBUG = True 75 | LOG_PATH = 'drcom_client.log' 76 | 77 | 78 | def log(*args, **kwargs): 79 | s = ' '.join(args) 80 | print s 81 | if DEBUG: 82 | with open(LOG_PATH,'a') as f: 83 | f.write(s + '\n') 84 | 85 | def challenge(svr,ran): 86 | while True: 87 | t = struct.pack(">5)) 122 | # return ret 123 | 124 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 125 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 126 | if first : 127 | data += '\x0f\x27' 128 | else: 129 | data += KEEP_ALIVE_VERSION 130 | data += '\x2f\x12' + '\x00' * 6 131 | data += tail 132 | data += '\x00' * 4 133 | #data += struct.pack("!H",0xdc02) 134 | if type == 3: 135 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 136 | #CRC 137 | # edited on 2014/5/12, filled zeros to checksum 138 | # crc = packet_CRC(data+foo) 139 | crc = '\x00' * 4 140 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 141 | data += crc + foo + '\x00' * 8 142 | else: #packet type = 1 143 | data += '\x00' * 16 144 | return data 145 | 146 | # def packet_CRC(s): 147 | # ret = 0 148 | # for i in re.findall('..', s): 149 | # ret ^= struct.unpack('>h', i)[0] 150 | # ret &= 0xFFFF 151 | # ret = ret * 0x2c7 152 | # return ret 153 | 154 | def keep_alive2(*args): 155 | #first keep_alive: 156 | #number = number (mod 7) 157 | #status = 1: first packet user sended 158 | # 2: first packet user recieved 159 | # 3: 2nd packet user sended 160 | # 4: 2nd packet user recieved 161 | # Codes for test 162 | tail = '' 163 | packet = '' 164 | svr = server 165 | ran = random.randint(0,0xFFFF) 166 | ran += random.randint(1,10) 167 | # 2014/10/15 add by latyas, maybe svr sends back a file packet 168 | svr_num = 0 169 | packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1,True) 170 | while True: 171 | log('[keep-alive2] send1',packet.encode('hex')) 172 | s.sendto(packet, (svr, 61440)) 173 | data, address = s.recvfrom(1024) 174 | log('[keep-alive2] recv1',data.encode('hex')) 175 | if data.startswith('\x07\x00\x28\x00') or data.startswith('\x07' + chr(svr_num) + '\x28\x00'): 176 | break 177 | elif data[0] == '\x07' and data[2] == '\x10': 178 | log('[keep-alive2] recv file, resending..') 179 | svr_num = svr_num + 1 180 | packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1, False) 181 | else: 182 | log('[keep-alive2] recv1/unexpected',data.encode('hex')) 183 | #log('[keep-alive2] recv1',data.encode('hex')) 184 | 185 | ran += random.randint(1,10) 186 | packet = keep_alive_package_builder(svr_num, dump(ran),'\x00'*4,1,False) 187 | log('[keep-alive2] send2',packet.encode('hex')) 188 | s.sendto(packet, (svr, 61440)) 189 | while True: 190 | data, address = s.recvfrom(1024) 191 | if data[0] == '\x07': 192 | svr_num = svr_num + 1 193 | break 194 | else: 195 | log('[keep-alive2] recv2/unexpected',data.encode('hex')) 196 | log('[keep-alive2] recv2',data.encode('hex')) 197 | tail = data[16:20] 198 | 199 | 200 | ran += random.randint(1,10) 201 | packet = keep_alive_package_builder(svr_num,dump(ran),tail,3,False) 202 | log('[keep-alive2] send3',packet.encode('hex')) 203 | s.sendto(packet, (svr, 61440)) 204 | while True: 205 | data, address = s.recvfrom(1024) 206 | if data[0] == '\x07': 207 | svr_num = svr_num + 1 208 | break 209 | else: 210 | log('[keep-alive2] recv3/unexpected',data.encode('hex')) 211 | log('[keep-alive2] recv3',data.encode('hex')) 212 | tail = data[16:20] 213 | log("[keep-alive2] keep-alive2 loop was in daemon.") 214 | 215 | i = svr_num 216 | while True: 217 | try: 218 | ran += random.randint(1,10) 219 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 220 | #log('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 221 | log('[keep_alive2] send',str(i),packet.encode('hex')) 222 | s.sendto(packet, (svr, 61440)) 223 | data, address = s.recvfrom(1024) 224 | log('[keep_alive2] recv',data.encode('hex')) 225 | tail = data[16:20] 226 | #log('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 227 | 228 | ran += random.randint(1,10) 229 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 230 | #log('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 231 | s.sendto(packet, (svr, 61440)) 232 | log('[keep_alive2] send',str(i+1),packet.encode('hex')) 233 | data, address = s.recvfrom(1024) 234 | log('[keep_alive2] recv',data.encode('hex')) 235 | tail = data[16:20] 236 | #log('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 237 | i = (i+2) % 0xFF 238 | time.sleep(20) 239 | keep_alive1(*args) 240 | except: 241 | pass 242 | 243 | 244 | import re 245 | def checksum(s): 246 | ret = 1234 247 | for i in re.findall('....', s): 248 | ret ^= int(i[::-1].encode('hex'), 16) 249 | ret = (1968 * ret) & 0xffffffff 250 | return struct.pack(' 263 | data += '\00'*4 #your ipaddress 2 264 | data += '\00'*4 #your ipaddress 3 265 | data += '\00'*4 #your ipaddress 4 266 | data += md5sum(data + '\x14\x00\x07\x0b')[:8] #md53 267 | data += IPDOG 268 | data += '\x00'*4 #delimeter 269 | data += host_name.ljust(32, '\x00') 270 | data += ''.join([chr(int(i)) for i in PRIMARY_DNS.split('.')]) #primary dns 271 | data += ''.join([chr(int(i)) for i in dhcp_server.split('.')]) #DHCP server 272 | data += '\x00\x00\x00\x00' #secondary dns:0.0.0.0 273 | data += '\x00' * 8 #delimeter 274 | data += '\x94\x00\x00\x00' # unknow 275 | data += '\x05\x00\x00\x00' # os major 276 | data += '\x01\x00\x00\x00' # os minor 277 | data += '\x28\x0a\x00\x00' # OS build 278 | data += '\x02\x00\x00\x00' #os unknown 279 | data += host_os.ljust(32,'\x00') 280 | data += '\x00' * 96 281 | #data += '\x01' + host_os.ljust(128, '\x00') 282 | #data += '\x0a\x00\x00'+chr(len(pwd)) # \0x0a represents version of client, algorithm: DRCOM_VER + 100 283 | #data += ror(md5sum('\x03\x01'+salt+pwd), pwd) 284 | data += AUTH_VERSION 285 | data += '\x02\x0c' 286 | data += checksum(data+'\x01\x26\x07\x11\x00\x00'+dump(mac)) 287 | data += '\x00\x00' #delimeter 288 | data += dump(mac) 289 | data += '\x00' # auto logout / default: False 290 | data += '\x00' # broadcast mode / default : False 291 | data += '\xe9\x13' #unknown, filled numbers randomly =w= 292 | 293 | log('[mkpkt]',data.encode('hex')) 294 | return data 295 | 296 | def login(usr, pwd, svr): 297 | import random 298 | global SALT 299 | 300 | i = 0 301 | while True: 302 | salt = challenge(svr,time.time()+random.randint(0xF,0xFF)) 303 | SALT = salt 304 | packet = mkpkt(salt, usr, pwd, mac) 305 | log('[login] send',packet.encode('hex')) 306 | s.sendto(packet, (svr, 61440)) 307 | data, address = s.recvfrom(1024) 308 | log('[login] recv',data.encode('hex')) 309 | log('[login] packet sent.') 310 | if address == (svr, 61440): 311 | if data[0] == '\x04': 312 | log('[login] loged in') 313 | break 314 | else: 315 | log('[login] login failed.') 316 | if IS_TEST: 317 | time.sleep(3) 318 | else: 319 | time.sleep(30) 320 | continue 321 | else: 322 | if i >= 5 and UNLIMITED_RETRY == False : 323 | log('[login] exception occured.') 324 | sys.exit(1) 325 | else: 326 | continue 327 | 328 | log('[login] login sent') 329 | #0.8 changed: 330 | return data[23:39] 331 | #return data[-22:-6] 332 | 333 | def keep_alive1(salt,tail,pwd,svr): 334 | foo = struct.pack('!H',int(time.time())%0xFFFF) 335 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 336 | data += tail 337 | data += foo + '\x00\x00\x00\x00' 338 | log('[keep_alive1] send',data.encode('hex')) 339 | 340 | s.sendto(data, (svr, 61440)) 341 | while True: 342 | data, address = s.recvfrom(1024) 343 | if data[0] == '\x07': 344 | break 345 | else: 346 | log('[keep-alive1]recv/not expected',data.encode('hex')) 347 | log('[keep-alive1] recv',data.encode('hex')) 348 | 349 | def empty_socket_buffer(): 350 | #empty buffer for some fucking schools 351 | log('starting to empty socket buffer') 352 | try: 353 | while True: 354 | data, address = s.recvfrom(1024) 355 | log('recived sth unexpected',data.encode('hex')) 356 | if s == '': 357 | break 358 | except: 359 | # get exception means it has done. 360 | log('exception in empty_socket_buffer') 361 | pass 362 | log('emptyed') 363 | def daemon(): 364 | with open('/var/run/jludrcom.pid','w') as f: 365 | f.write(str(os.getpid())) 366 | 367 | def main(): 368 | if not IS_TEST: 369 | daemon() 370 | execfile(CONF, globals()) 371 | log("auth svr:"+server+"\nusername:"+username+"\npassword:"+password+"\nmac:"+str(hex(mac))) 372 | log(bind_ip) 373 | while True: 374 | try: 375 | package_tail = login(username, password, server) 376 | except LoginException: 377 | continue 378 | log('package_tail',package_tail.encode('hex')) 379 | #keep_alive1 is fucking bullshit! 380 | empty_socket_buffer() 381 | keep_alive1(SALT,package_tail,password,server) 382 | keep_alive2(SALT,package_tail,password,server) 383 | if __name__ == "__main__": 384 | main() 385 | -------------------------------------------------------------------------------- /custom/heau-drcom.py: -------------------------------------------------------------------------------- 1 | # 1.Please edit this file in editors which supports UNIX files if you are in Windows OS 2 | # 2.tested pass in v0.8 u62R0 3 | # 3.edit basic configuration first. 4 | # 4.if you can use it to access Internet stablely, contacting administrators. 5 | # else contacting administrators with drcom_client.log 6 | 7 | import socket, struct, time 8 | from hashlib import md5 9 | import sys 10 | import urllib2 11 | 12 | class ChallengeException (Exception): 13 | def __init__(self): 14 | pass 15 | 16 | class LoginException (Exception): 17 | def __init__(self): 18 | pass 19 | 20 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 21 | s.bind(("0.0.0.0", 61440)) 22 | 23 | s.settimeout(3) 24 | SALT = '' 25 | UNLIMITED_RETRY = True 26 | EXCEPTION = False 27 | DEBUG = True 28 | # basic configuration 29 | server = "10.0.108.3" # Auth server ip 30 | username = "学号" 31 | password = "密码" 32 | host_name = "WINDOWS 8" 33 | host_os = "WINDOWS" 34 | host_ip = "172.28.27.127" # your ip, the server wouldn't check this, so it's a nonsense 35 | dhcp_server = "172.28.27.1" 36 | mac = 0x20cf305061b9 37 | 38 | def log(*args, **kwargs): 39 | s = ' '.join(args) 40 | print s 41 | 42 | def challenge(svr,ran): 43 | while True: 44 | t = struct.pack(">5)) 79 | return ret 80 | 81 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 82 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 83 | if first : 84 | data += '\x0f\x27' 85 | else: 86 | data += '\xdc\02' 87 | data += '\x2f\x12' + '\x00' * 6 88 | data += tail 89 | data += '\x00' * 4 90 | #data += struct.pack("!H",0xdc02) 91 | if type == 3: 92 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 93 | #CRC 94 | # edited on 2015/2/19, filled zeros to checksum 95 | # crc = packet_CRC(data+foo) 96 | crc = '\x00' * 4 97 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 98 | data += crc + foo + '\x00' * 8 99 | else: #packet type = 1 100 | data += '\x00' * 16 101 | return data 102 | 103 | def packet_CRC(s): 104 | ret = 0 105 | for i in re.findall('..', s): 106 | ret ^= struct.unpack('>h', i)[0] 107 | ret &= 0xFFFF 108 | ret = ret * 0x2c7 109 | return ret 110 | 111 | def keep_alive2(*args): 112 | #first keep_alive: 113 | #number = number (mod 7) 114 | #status = 1: first packet user sended 115 | # 2: first packet user recieved 116 | # 3: 2nd packet user sended 117 | # 4: 2nd packet user recieved 118 | # Codes for test 119 | tail = '' 120 | packet = '' 121 | svr = server 122 | import random 123 | ran = random.randint(0,0xFFFF) 124 | ran += random.randint(1,10) 125 | # 2014/10/15 add by latyas, maybe svr sends back a file packet 126 | svr_num = 0 127 | packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1,True) 128 | while True: 129 | log('[keep-alive2] send1',packet.encode('hex')) 130 | s.sendto(packet, (svr, 61440)) 131 | data, address = s.recvfrom(1024) 132 | if data.startswith('\x07\x00\x28\x00') or data.startswith('\x07' + chr(svr_num) + '\x28\x00'): 133 | break 134 | elif data[0] == '\x07' and data[2] == '\x10': 135 | log('[keep-alive2] recv file, resending..') 136 | svr_num = svr_num + 1 137 | packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1, False) 138 | else: 139 | log('[keep-alive2] recv1/unexpected',data.encode('hex')) 140 | log('[keep-alive2] recv1',data.encode('hex')) 141 | 142 | ran += random.randint(1,10) 143 | packet = keep_alive_package_builder(svr_num, dump(ran),'\x00'*4,1,False) 144 | log('[keep-alive2] send2',packet.encode('hex')) 145 | s.sendto(packet, (svr, 61440)) 146 | while True: 147 | data, address = s.recvfrom(1024) 148 | if data[0] == '\x07': 149 | svr_num = svr_num + 1 150 | break 151 | else: 152 | log('[keep-alive2] recv2/unexpected',data.encode('hex')) 153 | log('[keep-alive2] recv2',data.encode('hex')) 154 | tail = data[16:20] 155 | 156 | 157 | ran += random.randint(1,10) 158 | packet = keep_alive_package_builder(svr_num,dump(ran),tail,3,False) 159 | log('[keep-alive2] send3',packet.encode('hex')) 160 | s.sendto(packet, (svr, 61440)) 161 | while True: 162 | data, address = s.recvfrom(1024) 163 | if data[0] == '\x07': 164 | svr_num = svr_num + 1 165 | break 166 | else: 167 | log('[keep-alive2] recv3/unexpected',data.encode('hex')) 168 | log('[keep-alive2] recv3',data.encode('hex')) 169 | tail = data[16:20] 170 | log("[keep-alive2] keep-alive2 loop was in daemon.") 171 | 172 | i = svr_num 173 | while True: 174 | try: 175 | ran += random.randint(1,10) 176 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 177 | #log('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 178 | log('[keep_alive2] send',str(i),packet.encode('hex')) 179 | s.sendto(packet, (svr, 61440)) 180 | data, address = s.recvfrom(1024) 181 | log('[keep_alive2] recv',data.encode('hex')) 182 | tail = data[16:20] 183 | #log('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 184 | 185 | ran += random.randint(1,10) 186 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 187 | #log('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 188 | s.sendto(packet, (svr, 61440)) 189 | log('[keep_alive2] send',str(i+1),packet.encode('hex')) 190 | data, address = s.recvfrom(1024) 191 | log('[keep_alive2] recv',data.encode('hex')) 192 | tail = data[16:20] 193 | #log('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 194 | i = (i+2) % 0xFF 195 | time.sleep(20) 196 | keep_alive1(*args) 197 | except: 198 | pass 199 | 200 | 201 | import re 202 | def checksum(s): 203 | ret = 1234 204 | for i in re.findall('....', s): 205 | ret ^= int(i[::-1].encode('hex'), 16) 206 | ret = (1968 * ret) & 0xffffffff 207 | return struct.pack(' 220 | data += '\00'*4 #your ipaddress 2 221 | data += '\00'*4 #your ipaddress 3 222 | data += '\00'*4 #your ipaddress 4 223 | data += md5sum(data + '\x14\x00\x07\x0b')[:8] #md53 224 | data += '\x01' #ipdog 225 | data += '\x00'*4 #delimeter 226 | data += host_name.ljust(32, '\x00') 227 | data += '\x08\x08\x08\x08' #primary dns: 8.8.8.8 228 | data += ''.join([chr(int(i)) for i in dhcp_server.split('.')]) #DHCP server 229 | data += '\x00\x00\x00\x00' #secondary dns:0.0.0.0 230 | data += '\x00' * 8 #delimeter 231 | data += '\x94\x00\x00\x00' # unknow 232 | data += '\x05\x00\x00\x00' # os major 233 | data += '\x01\x00\x00\x00' # os minor 234 | data += '\x28\x0a\x00\x00' # OS build 235 | data += '\x02\x00\x00\x00' #os unknown 236 | data += host_os.ljust(32,'\x00') 237 | data += '\x00' * 96 238 | #data += '\x01' + host_os.ljust(128, '\x00') 239 | #data += '\x0a\x00\x00'+chr(len(pwd)) # \0x0a represents version of client, algorithm: DRCOM_VER + 100 240 | #data += ror(md5sum('\x03\x01'+salt+pwd), pwd) 241 | data += '\x1a\x00' # for u64, \x1a\x00 242 | data += '\x02\x0c' 243 | data += checksum(data+'\x01\x26\x07\x11\x00\x00'+dump(mac)) 244 | data += '\x00\x00' #delimeter 245 | data += dump(mac) 246 | data += '\x00' # auto logout / default: False 247 | data += '\x00' # broadcast mode / default : False 248 | data += '\xe9\x13' #unknown, filled numbers randomly =w= 249 | 250 | log('[mkpkt]',data.encode('hex')) 251 | return data 252 | 253 | def login(usr, pwd, svr): 254 | import random 255 | global SALT 256 | 257 | i = 0 258 | while True: 259 | salt = challenge(svr,time.time()+random.randint(0xF,0xFF)) 260 | SALT = salt 261 | packet = mkpkt(salt, usr, pwd, mac) 262 | log('[login] send',packet.encode('hex')) 263 | s.sendto(packet, (svr, 61440)) 264 | data, address = s.recvfrom(1024) 265 | log('[login] recv',data.encode('hex')) 266 | log('[login] packet sent.') 267 | if address == (svr, 61440): 268 | if data[0] == '\x04': 269 | log('[login] loged in') 270 | break 271 | else: 272 | continue 273 | else: 274 | if i >= 5 and UNLIMITED_RETRY == False : 275 | log('[login] exception occured.') 276 | sys.exit(1) 277 | else: 278 | continue 279 | 280 | log('[login] login sent') 281 | #0.8 changed: 282 | return data[23:39] 283 | #return data[-22:-6] 284 | 285 | def keep_alive1(salt,tail,pwd,svr): 286 | foo = struct.pack('!H',int(time.time())%0xFFFF) 287 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 288 | data += tail 289 | data += foo + '\x00\x00\x00\x00' 290 | log('[keep_alive1] send',data.encode('hex')) 291 | 292 | s.sendto(data, (svr, 61440)) 293 | while True: 294 | data, address = s.recvfrom(1024) 295 | if data[0] == '\x07': 296 | break 297 | else: 298 | log('[keep-alive1]recv/not expected',data.encode('hex')) 299 | log('[keep-alive1] recv',data.encode('hex')) 300 | 301 | def empty_socket_buffer(): 302 | #empty buffer for some fucking schools 303 | log('starting to empty socket buffer') 304 | try: 305 | while True: 306 | data, address = s.recvfrom(1024) 307 | log('recived sth unexcepted',data.encode('hex')) 308 | if s == '': 309 | break 310 | except: 311 | # get exception means it has done. 312 | log('exception in empty_socket_buffer') 313 | pass 314 | log('emptyed') 315 | def main(): 316 | log("auth svr:"+server+"\nusername:"+username+"\nmac:"+str(hex(mac))) 317 | while True: 318 | try: 319 | package_tail = login(username, password, server) 320 | except LoginException: 321 | continue 322 | log('package_tail',package_tail.encode('hex')) 323 | #keep_alive1 is fucking bullshit! 324 | empty_socket_buffer() 325 | keep_alive1(SALT,package_tail,password,server) 326 | #empty_socket_buffer() 327 | keep_alive2(SALT,package_tail,password,server) 328 | if __name__ == "__main__": 329 | main() 330 | -------------------------------------------------------------------------------- /custom/ppp_esc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cp /lib/netifd/proto/ppp.sh /lib/netifd/proto/ppp.sh_bak 3 | sed -i '/proto_run_command/i username=`echo -e "$username"`' /lib/netifd/proto/ppp.sh 4 | sed -i '/proto_run_command/i password=`echo -e "$password"`' /lib/netifd/proto/ppp.sh 5 | -------------------------------------------------------------------------------- /custom/pppoe.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | server="127.0.0.1" 4 | 5 | while(1) 6 | do 7 | echo "Test connectivity to auth server" 8 | ping -c1 $server 9 | if [ $? != 0 ] 10 | then 11 | echo "ping failed, retry" 12 | else 13 | echo "OK" 14 | break 15 | fi 16 | done 17 | 18 | exec python /usr/bin/drcom-pppoe.py 19 | -------------------------------------------------------------------------------- /custom/湖南信息职业技术学院_d.py: -------------------------------------------------------------------------------- 1 | #coding=UTF-8 2 | #test version 3 | #Licensed under the AGPLv3 4 | #thx all authors before 5 | 6 | 7 | import socket, struct, time,random,re 8 | from hashlib import md5 9 | 10 | #config 11 | server = '172.17.0.253' 12 | username='' 13 | password='' 14 | CONTROLCHECKSTATUS = '\x20' 15 | ADAPTERNUM = '\x03' 16 | host_ip = '10.24.1.39' 17 | IPDOG = '\x01' 18 | host_name = 'DRCOMFUCKER' 19 | PRIMARY_DNS = '58.20.127.170' 20 | dhcp_server = '172.17.199.2' 21 | AUTH_VERSION = '\x23\x00' 22 | mac = 0x2aaa06436a60 23 | host_os = 'WINDIAOS' 24 | KEEP_ALIVE_VERSION = '\x0f\x27' 25 | 26 | #config_end 27 | 28 | class ChallengeException (Exception): 29 | def __init__(self): 30 | pass 31 | 32 | class loginException (Exception): 33 | def __init__(self): 34 | pass 35 | 36 | def try_socket(): 37 | #sometimes cannot get the port 38 | global s,salt 39 | try: 40 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 41 | s.bind(("0.0.0.0", 61440)) 42 | s.settimeout(3) 43 | except: 44 | print ".", 45 | time.sleep(0.5) 46 | print ".", 47 | time.sleep(0.5) 48 | print "." 49 | time.sleep(0.5) 50 | print "...reopen" 51 | time.sleep(10) 52 | sys.exit(0) 53 | else: 54 | SALT= '' 55 | 56 | UNLIMITED_RETRY = True 57 | EXCEPTION = False 58 | 59 | def get_randmac(): 60 | mac = [ 0x00, 0x16, 0x3e,random.randint(0x00, 0x7f),random.randint(0x00, 0xff),random.randint(0x00, 0xff) ] 61 | return ''.join(map(lambda x: "%02x" % x, mac)) 62 | #print randomMAC() 63 | 64 | def version(): 65 | print "=====================================================================" 66 | print "DrCOM Auth Router for u6x" 67 | print "with keep-alive1&keep-alive2" 68 | print "=====================================================================" 69 | 70 | 71 | 72 | 73 | def challenge(svr,ran): 74 | while True: 75 | t = struct.pack(">5)) 110 | return ret 111 | 112 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 113 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 114 | data += '\xd8\x02\x2f\x12' + '\x00' * 6 115 | data += tail 116 | data += '\x00' * 4 117 | #data += struct.pack("!H",0xdc02) 118 | if type == 3: 119 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 120 | #use double keep in main to keep online .Ice 121 | crc = '\x00' * 4 122 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 123 | data += crc + foo + '\x00' * 8 124 | else: #packet type = 1 125 | data += '\x00' * 16 126 | return data 127 | 128 | def packet_CRC(s): 129 | ret = 0 130 | for i in re.findall('..', s): 131 | ret ^= struct.unpack('>h', i)[0] 132 | ret &= 0xFFFF 133 | ret = ret * 0x2c7 134 | return ret 135 | 136 | 137 | 138 | def keep_alive2(*args): 139 | tail = '' 140 | packet = '' 141 | svr = server 142 | ran = random.randint(0,0xFFFF) 143 | ran += random.randint(1,10) 144 | 145 | packet = keep_alive_package_builder(0,dump(ran),'\x00'*4,1,True) 146 | #packet = keep_alive_package_builder(0,dump(ran),dump(ran)+'\x22\x06',1,True) 147 | print '[keep-alive2] send1'#packet.encode('hex') 148 | while True: 149 | s.sendto(packet, (svr, 61440)) 150 | data, address = s.recvfrom(1024) 151 | if data.startswith('\x07'): 152 | break 153 | else: 154 | continue 155 | #print '[keep-alive2] recv/unexpected',data.encode('hex') 156 | #print '[keep-alive2] recv1',data.encode('hex') 157 | 158 | ran += random.randint(1,10) 159 | packet = keep_alive_package_builder(1,dump(ran),'\x00'*4,1,False) 160 | #print '[keep-alive2] send2',packet.encode('hex') 161 | s.sendto(packet, (svr, 61440)) 162 | while True: 163 | data, address = s.recvfrom(1024) 164 | if data[0] == '\x07': 165 | break 166 | #print '[keep-alive2] recv2',data.encode('hex') 167 | tail = data[16:20] 168 | 169 | 170 | ran += random.randint(1,10) 171 | packet = keep_alive_package_builder(2,dump(ran),tail,3,False) 172 | #print '[keep-alive2] send3',packet.encode('hex') 173 | s.sendto(packet, (svr, 61440)) 174 | while True: 175 | data, address = s.recvfrom(1024) 176 | if data[0] == '\x07': 177 | break 178 | #print '[keep-alive2] recv3',data.encode('hex') 179 | tail = data[16:20] 180 | print "[keep-alive] keep-alive loop was in daemon." 181 | i = 3 182 | 183 | while True: 184 | try: 185 | keep_alive1(SALT,package_tail,password,server) 186 | print '[keep-alive2] send' 187 | ran += random.randint(1,10) 188 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 189 | #print('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 190 | #print '[keep_alive2] send',str(i),packet.encode('hex') 191 | s.sendto(packet, (svr, 61440)) 192 | data, address = s.recvfrom(1024) 193 | #print '[keep_alive2] recv',data.encode('hex') 194 | tail = data[16:20] 195 | #print('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 196 | 197 | ran += random.randint(1,10) 198 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 199 | #print('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 200 | s.sendto(packet, (svr, 61440)) 201 | #print('[keep_alive2] send',str(i+1),packet.encode('hex')) 202 | data, address = s.recvfrom(1024) 203 | #print('[keep_alive2] recv',data.encode('hex')) 204 | tail = data[16:20] 205 | #print('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 206 | i = (i+2) % 0xFF 207 | time.sleep(20) 208 | except: 209 | pass 210 | 211 | def checksum(s): 212 | ret = 1234 213 | for i in re.findall('....', s): 214 | ret ^= int(i[::-1].encode('hex'), 16) 215 | ret = (1968 * ret) & 0xffffffff 216 | return struct.pack('= 5 and UNLIMITED_RETRY == False : 283 | print('[login] exception occured.') 284 | sys.exit(1) 285 | else: 286 | continue 287 | 288 | print('[login] login Success') 289 | return data[23:39] 290 | #return data[-22:-6] 291 | 292 | def keep_alive1(salt,tail,pwd,svr): 293 | foo = struct.pack('!H',int(time.time())%0xFFFF) 294 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 295 | data += tail 296 | data += foo + '\x00\x00\x00\x00' 297 | print '[keep_alive1] send'#data.encode('hex')) 298 | 299 | s.sendto(data, (svr, 61440)) 300 | while True: 301 | data, address = s.recvfrom(1024) 302 | if data[0] == '\x07': 303 | break 304 | else: 305 | print '[keep-alive1]recv/not expected'#data.encode('hex') 306 | #print('[keep-alive1] recv',data.encode('hex')) 307 | 308 | def empty_socket_buffer(): 309 | #empty buffer 310 | print('starting to empty socket buffer') 311 | try: 312 | while True: 313 | data, address = s.recvfrom(1024) 314 | #print 'recived sth unexcepted',data.encode('hex') 315 | if s == '': 316 | break 317 | except: 318 | # get exception means it has done. 319 | print('exception in empty_socket_buffer') 320 | pass 321 | print('emptyed') 322 | 323 | 324 | def check_online(): 325 | try: 326 | check_online = urllib2.urlopen('http://www.baidu.com') 327 | foo=check_online.read() 328 | except: 329 | print "Network line Err,check the line...Hit the return" 330 | raw_input() 331 | else: 332 | if '10.1.1.10' in foo: 333 | print "Not Online,try to auth" 334 | raw_input() 335 | else: 336 | print "Already online,Hit the return" 337 | raw_input() 338 | sys.exit(0) 339 | 340 | 341 | 342 | def main(): 343 | global server,username,password,host_name,host_os,dhcp_server,mac,hexip,host_ip 344 | hexip=socket.inet_aton(host_ip) 345 | #host_ip=ip 346 | host_name = "est-pc" 347 | host_os = "8089D" #default is 8089D 348 | dhcp_server = "0.0.0.0" 349 | #mac = 0xE0DB55BAE012 350 | #it is a mac in programme and it may crush with other users so I use randMAC to avoid it 351 | loginpart() 352 | 353 | def loginpart(): 354 | global package_tail 355 | while True: 356 | try: 357 | package_tail = login(username, password, server) 358 | except loginException: 359 | continue 360 | #print('package_tail',package_tail.encode('hex')) 361 | keeppart() 362 | 363 | def keeppart(): 364 | #empty_socket_buffer() 365 | #empty_socket_buffer() 366 | keep_alive2(SALT,package_tail,password,server) 367 | 368 | 369 | if __name__ == "__main__": 370 | try_socket() 371 | version() 372 | #get_conf() 373 | main() 374 | 375 | 376 | -------------------------------------------------------------------------------- /custom/长沙保险职业学院_u6x.py: -------------------------------------------------------------------------------- 1 | #coding=UTF-8 2 | #test version 3 | #Licensed under the GPL 4 | #thx all authors before 5 | 6 | 7 | import socket, struct, time,sys,urllib2,random,re,uuid 8 | from hashlib import md5 9 | 10 | #config 11 | server = '119.39.32.154' 12 | username='' 13 | password='' 14 | CONTROLCHECKSTATUS = '\x20' 15 | ADAPTERNUM = '\x01' 16 | host_ip = '1.1.1.1' 17 | IPDOG = '\x01' 18 | host_name = 'DRCOMFUCKER' 19 | PRIMARY_DNS = '58.20.125.163' 20 | dhcp_server = '42.48.21.1' 21 | AUTH_VERSION = '\x23\x00' 22 | mac = 0x0016ecbf06ba 23 | host_os = 'WINDIAOS' 24 | KEEP_ALIVE_VERSION = '\x0f\x27' 25 | 26 | #config_end 27 | 28 | class ChallengeException (Exception): 29 | def __init__(self): 30 | pass 31 | 32 | class loginException (Exception): 33 | def __init__(self): 34 | pass 35 | 36 | def try_socket(): 37 | #sometimes cannot get the port 38 | global s,salt 39 | try: 40 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 41 | s.bind(("0.0.0.0", 61440)) 42 | s.settimeout(3) 43 | except: 44 | print ".", 45 | time.sleep(0.5) 46 | print ".", 47 | time.sleep(0.5) 48 | print "." 49 | time.sleep(0.5) 50 | print "...reopen" 51 | time.sleep(10) 52 | sys.exit(0) 53 | else: 54 | SALT= '' 55 | 56 | UNLIMITED_RETRY = True 57 | EXCEPTION = False 58 | 59 | def get_randmac(): 60 | mac = [ 0x00, 0x16, 0x3e,random.randint(0x00, 0x7f),random.randint(0x00, 0xff),random.randint(0x00, 0xff) ] 61 | return ''.join(map(lambda x: "%02x" % x, mac)) 62 | #print randomMAC() 63 | 64 | def version(): 65 | print "=====================================================================" 66 | print "DrCOM Auth Router for u6x" 67 | print "powered by Ice and thx all authors before" 68 | print "Version 0.4.1 with mac & ip en beta" 69 | print "with keep-alive1&keep-alive2" 70 | print "=====================================================================" 71 | 72 | 73 | 74 | 75 | def challenge(svr,ran): 76 | while True: 77 | t = struct.pack(">5)) 112 | return ret 113 | 114 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 115 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 116 | data += '\xd8\02\x2f\x12' + '\x00' * 6 117 | data += tail 118 | data += '\x00' * 4 119 | #data += struct.pack("!H",0xdc02) 120 | if type == 3: 121 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 122 | #use double keep in main to keep online .Ice 123 | crc = '\x00' * 4 124 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 125 | data += crc + foo + '\x00' * 8 126 | else: #packet type = 1 127 | data += '\x00' * 16 128 | return data 129 | 130 | def packet_CRC(s): 131 | ret = 0 132 | for i in re.findall('..', s): 133 | ret ^= struct.unpack('>h', i)[0] 134 | ret &= 0xFFFF 135 | ret = ret * 0x2c7 136 | return ret 137 | 138 | 139 | 140 | def keep_alive2(*args): 141 | tail = '' 142 | packet = '' 143 | svr = server 144 | ran = random.randint(0,0xFFFF) 145 | ran += random.randint(1,10) 146 | 147 | packet = keep_alive_package_builder(0,dump(ran),'\x00'*4,1,True) 148 | #packet = keep_alive_package_builder(0,dump(ran),dump(ran)+'\x22\x06',1,True) 149 | print '[keep-alive2] send1'#packet.encode('hex') 150 | while True: 151 | s.sendto(packet, (svr, 61440)) 152 | data, address = s.recvfrom(1024) 153 | if data.startswith('\x07'): 154 | break 155 | else: 156 | continue 157 | #print '[keep-alive2] recv/unexpected',data.encode('hex') 158 | #print '[keep-alive2] recv1',data.encode('hex') 159 | 160 | ran += random.randint(1,10) 161 | packet = keep_alive_package_builder(1,dump(ran),'\x00'*4,1,False) 162 | #print '[keep-alive2] send2',packet.encode('hex') 163 | s.sendto(packet, (svr, 61440)) 164 | while True: 165 | data, address = s.recvfrom(1024) 166 | if data[0] == '\x07': 167 | break 168 | #print '[keep-alive2] recv2',data.encode('hex') 169 | tail = data[16:20] 170 | 171 | 172 | ran += random.randint(1,10) 173 | packet = keep_alive_package_builder(2,dump(ran),tail,3,False) 174 | #print '[keep-alive2] send3',packet.encode('hex') 175 | s.sendto(packet, (svr, 61440)) 176 | while True: 177 | data, address = s.recvfrom(1024) 178 | if data[0] == '\x07': 179 | break 180 | #print '[keep-alive2] recv3',data.encode('hex') 181 | tail = data[16:20] 182 | print "[keep-alive] keep-alive loop was in daemon." 183 | i = 3 184 | 185 | while True: 186 | try: 187 | keep_alive1(SALT,package_tail,password,server) 188 | print '[keep-alive2] send' 189 | ran += random.randint(1,10) 190 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 191 | #print('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 192 | #print '[keep_alive2] send',str(i),packet.encode('hex') 193 | s.sendto(packet, (svr, 61440)) 194 | data, address = s.recvfrom(1024) 195 | #print '[keep_alive2] recv',data.encode('hex') 196 | tail = data[16:20] 197 | #print('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 198 | 199 | ran += random.randint(1,10) 200 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 201 | #print('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 202 | s.sendto(packet, (svr, 61440)) 203 | #print('[keep_alive2] send',str(i+1),packet.encode('hex')) 204 | data, address = s.recvfrom(1024) 205 | #print('[keep_alive2] recv',data.encode('hex')) 206 | tail = data[16:20] 207 | #print('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 208 | i = (i+2) % 0xFF 209 | time.sleep(20) 210 | except: 211 | pass 212 | 213 | def checksum(s): 214 | ret = 1234 215 | for i in re.findall('....', s): 216 | ret ^= int(i[::-1].encode('hex'), 16) 217 | ret = (1968 * ret) & 0xffffffff 218 | return struct.pack('= 5 and UNLIMITED_RETRY == False : 285 | print('[login] exception occured.') 286 | sys.exit(1) 287 | else: 288 | continue 289 | 290 | print('[login] login Success') 291 | return data[23:39] 292 | #return data[-22:-6] 293 | 294 | def keep_alive1(salt,tail,pwd,svr): 295 | foo = struct.pack('!H',int(time.time())%0xFFFF) 296 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 297 | data += tail 298 | data += foo + '\x00\x00\x00\x00' 299 | print '[keep_alive1] send'#data.encode('hex')) 300 | 301 | s.sendto(data, (svr, 61440)) 302 | while True: 303 | data, address = s.recvfrom(1024) 304 | if data[0] == '\x07': 305 | break 306 | else: 307 | print '[keep-alive1]recv/not expected'#data.encode('hex') 308 | #print('[keep-alive1] recv',data.encode('hex')) 309 | 310 | def empty_socket_buffer(): 311 | #empty buffer 312 | print('starting to empty socket buffer') 313 | try: 314 | while True: 315 | data, address = s.recvfrom(1024) 316 | #print 'recived sth unexcepted',data.encode('hex') 317 | if s == '': 318 | break 319 | except: 320 | # get exception means it has done. 321 | print('exception in empty_socket_buffer') 322 | pass 323 | print('emptyed') 324 | 325 | 326 | def check_online(): 327 | try: 328 | check_online = urllib2.urlopen('http://www.baidu.com') 329 | foo=check_online.read() 330 | except: 331 | print "Network line Err,check the line...Hit the return" 332 | raw_input() 333 | else: 334 | if '10.1.1.10' in foo: 335 | print "Not Online,try to auth" 336 | raw_input() 337 | else: 338 | print "Already online,Hit the return" 339 | raw_input() 340 | sys.exit(0) 341 | 342 | 343 | 344 | def main(): 345 | global server,username,password,host_name,host_os,dhcp_server,mac,hexip,host_ip 346 | hexip=socket.inet_aton(host_ip) 347 | #host_ip=ip 348 | host_name = "est-pc" 349 | host_os = "8089D" #default is 8089D 350 | dhcp_server = "0.0.0.0" 351 | #mac = 0xE0DB55BAE012 352 | #it is a mac in programme and it may crush with other users so I use randMAC to avoid it 353 | loginpart() 354 | 355 | def loginpart(): 356 | global package_tail 357 | while True: 358 | try: 359 | package_tail = login(username, password, server) 360 | except loginException: 361 | continue 362 | #print('package_tail',package_tail.encode('hex')) 363 | keeppart() 364 | 365 | def keeppart(): 366 | #empty_socket_buffer() 367 | #empty_socket_buffer() 368 | keep_alive2(SALT,package_tail,password,server) 369 | 370 | 371 | if __name__ == "__main__": 372 | try_socket() 373 | version() 374 | #get_conf() 375 | main() 376 | 377 | 378 | -------------------------------------------------------------------------------- /custom/长沙联通.py: -------------------------------------------------------------------------------- 1 | # This version has passed the test. 2 | 3 | import socket, struct, time 4 | from hashlib import md5 5 | import sys 6 | import os 7 | 8 | class ChallengeException (Exception): 9 | def __init__(self): 10 | pass 11 | 12 | class LoginException (Exception): 13 | def __init__(self): 14 | pass 15 | 16 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 17 | s.bind(("0.0.0.0", 61440)) 18 | 19 | s.settimeout(3) 20 | SALT = '' 21 | UNLIMITED_RETRY = True 22 | EXCEPTION = False 23 | DEBUG = True 24 | # basic configuration 25 | server = "58.20.127.106" # Auth server ip 26 | username = "" 27 | password = "" 28 | host_name = "LIYUANYUAN" 29 | host_os = "8089D" 30 | host_ip = "119.39.42.28" # your ip, the server wouldn't check this, so it's a nonsense 31 | dhcp_server = "119.39.42.1" 32 | mac = 0xf8a963a2f70f 33 | 34 | def log(*args, **kwargs): 35 | s = ' '.join(args) 36 | print s 37 | with open('drcom_client.log','a') as f: 38 | f.write(s + '\n') 39 | 40 | def challenge(svr,ran): 41 | while True: 42 | t = struct.pack(">5)) 77 | return ret 78 | 79 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 80 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 81 | data += '\xd8\02' 82 | data += '\x2f\x12' + '\x00' * 6 83 | data += tail 84 | data += '\x00' * 4 85 | #data += struct.pack("!H",0xdc02) 86 | if type == 3: 87 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 88 | #CRC 89 | # edited on 2014/5/12, filled zeros to checksum 90 | # crc = packet_CRC(data+foo) 91 | crc = '\x00' * 4 92 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 93 | data += crc + foo + '\x00' * 8 94 | else: #packet type = 1 95 | data += '\x00' * 16 96 | return data 97 | 98 | def packet_CRC(s): 99 | ret = 0 100 | for i in re.findall('..', s): 101 | ret ^= struct.unpack('>h', i)[0] 102 | ret &= 0xFFFF 103 | ret = ret * 0x2c7 104 | return ret 105 | 106 | def keep_alive2(*args): 107 | #first keep_alive: 108 | #number = number (mod 7) 109 | #status = 1: first packet user sended 110 | # 2: first packet user recieved 111 | # 3: 2nd packet user sended 112 | # 4: 2nd packet user recieved 113 | # Codes for test 114 | tail = '' 115 | packet = '' 116 | svr = server 117 | import random 118 | ran = random.randint(0,0xFFFF) 119 | ran += random.randint(1,10) 120 | # 2014/10/15 add by latyas, maybe svr sends back a file packet 121 | svr_num = 0 122 | while True: 123 | packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1,True) 124 | log('[keep-alive2] send1',packet.encode('hex')) 125 | s.sendto(packet, (svr, 61440)) 126 | data, address = s.recvfrom(1024) 127 | if data.startswith('\x07\x00\x28\x00'): 128 | break 129 | elif data[0] == '\x07' and data[2] == '\x10': 130 | log('[keep-alive2] recv file, resending..') 131 | svr_num = svr_num + 1 132 | else: 133 | log('[keep-alive2] recv1/unexpected',data.encode('hex')) 134 | log('[keep-alive2] recv1',data.encode('hex')) 135 | 136 | ran += random.randint(1,10) 137 | packet = keep_alive_package_builder(svr_num, dump(ran),'\x00'*4,1,False) 138 | log('[keep-alive2] send2',packet.encode('hex')) 139 | s.sendto(packet, (svr, 61440)) 140 | while True: 141 | data, address = s.recvfrom(1024) 142 | if data[0] == '\x07': 143 | svr_num = svr_num + 1 144 | break 145 | else: 146 | log('[keep-alive2] recv2/unexpected',data.encode('hex')) 147 | log('[keep-alive2] recv2',data.encode('hex')) 148 | tail = data[16:20] 149 | 150 | 151 | ran += random.randint(1,10) 152 | packet = keep_alive_package_builder(svr_num,dump(ran),tail,3,False) 153 | log('[keep-alive2] send3',packet.encode('hex')) 154 | s.sendto(packet, (svr, 61440)) 155 | while True: 156 | data, address = s.recvfrom(1024) 157 | if data[0] == '\x07': 158 | svr_num = svr_num + 1 159 | break 160 | else: 161 | log('[keep-alive2] recv3/unexpected',data.encode('hex')) 162 | log('[keep-alive2] recv3',data.encode('hex')) 163 | tail = data[16:20] 164 | log("[keep-alive2] keep-alive2 loop was in daemon.") 165 | 166 | i = svr_num 167 | while True: 168 | try: 169 | ran += random.randint(1,10) 170 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 171 | #log('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 172 | log('[keep_alive2] send',str(i),packet.encode('hex')) 173 | s.sendto(packet, (svr, 61440)) 174 | data, address = s.recvfrom(1024) 175 | log('[keep_alive2] recv',data.encode('hex')) 176 | tail = data[16:20] 177 | #log('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 178 | 179 | ran += random.randint(1,10) 180 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 181 | #log('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 182 | s.sendto(packet, (svr, 61440)) 183 | log('[keep_alive2] send',str(i+1),packet.encode('hex')) 184 | data, address = s.recvfrom(1024) 185 | log('[keep_alive2] recv',data.encode('hex')) 186 | tail = data[16:20] 187 | #log('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 188 | i = (i+2) % 0xFF 189 | time.sleep(20) 190 | keep_alive1(*args) 191 | except: 192 | pass 193 | 194 | 195 | import re 196 | def checksum(s): 197 | ret = 1234 198 | for i in re.findall('....', s): 199 | ret ^= int(i[::-1].encode('hex'), 16) 200 | ret = (1968 * ret) & 0xffffffff 201 | return struct.pack(' 214 | data += '\xc0\xa8\xbf\x01' #your ipaddress 2 215 | data += '\00'*4 #your ipaddress 3 216 | data += '\00'*4 #your ipaddress 4 217 | data += md5sum(data + '\x14\x00\x07\x0b')[:8] #md53 218 | data += '\x01' #ipdog 219 | data += '\x00'*4 #delimeter 220 | data += host_name.ljust(32, '\x00') 221 | data += '\xc0\xa8\x09\x01' #primary dns: 8.8.8.8 222 | data += ''.join([chr(int(i)) for i in dhcp_server.split('.')]) #DHCP server 223 | data += '\x3a\x14\x7f\xee' #secondary dns:0.0.0.0 224 | data += '\x00' * 8 #delimeter 225 | data += '\x94\x00\x00\x00' # unknow 226 | data += '\x06\x00\x00\x00' # os major 227 | data += '\x01\x00\x00\x00' # os minor 228 | data += '\xb0\x1d\x00\x00' # OS build 229 | data += '\x02\x00\x00\x00' #os unknown 230 | data += host_os.ljust(32,'\x00') 231 | data += '\x00' * 96 232 | #data += '\x01' + host_os.ljust(128, '\x00') 233 | #data += '\x0a\x00\x00'+chr(len(pwd)) # \0x0a represents version of client, algorithm: DRCOM_VER + 100 234 | #data += ror(md5sum('\x03\x01'+salt+pwd), pwd) 235 | data += '\x22\x00' # for u64, \x1a\x00 236 | data += '\x02\x0c' 237 | data += checksum(data+'\x01\x26\x07\x11\x00\x00'+dump(mac)) 238 | data += '\x00\x00' #delimeter 239 | data += dump(mac) 240 | data += '\x00' # auto logout / default: False 241 | data += '\x00' # broadcast mode / default : False 242 | data += '\x5b\x88' #unknown, filled numbers randomly =w= 243 | 244 | log('[mkpkt]',data.encode('hex')) 245 | return data 246 | 247 | def login(usr, pwd, svr): 248 | import random 249 | global SALT 250 | 251 | i = 0 252 | while True: 253 | salt = challenge(svr,time.time()+random.randint(0xF,0xFF)) 254 | SALT = salt 255 | packet = mkpkt(salt, usr, pwd, mac) 256 | log('[login] send',packet.encode('hex')) 257 | s.sendto(packet, (svr, 61440)) 258 | data, address = s.recvfrom(1024) 259 | log('[login] recv',data.encode('hex')) 260 | log('[login] packet sent.') 261 | if address == (svr, 61440): 262 | if data[0] == '\x04': 263 | log('[login] loged in') 264 | break 265 | else: 266 | continue 267 | else: 268 | if i >= 5 and UNLIMITED_RETRY == False : 269 | log('[login] exception occured.') 270 | sys.exit(1) 271 | else: 272 | continue 273 | 274 | log('[login] login sent') 275 | #0.8 changed: 276 | return data[23:39] 277 | #return data[-22:-6] 278 | 279 | def keep_alive1(salt,tail,pwd,svr): 280 | foo = struct.pack('!H',int(time.time())%0xFFFF) 281 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 282 | data += tail 283 | data += foo 284 | log('[keep_alive1] send',data.encode('hex')) 285 | 286 | s.sendto(data, (svr, 61440)) 287 | while True: 288 | data, address = s.recvfrom(1024) 289 | if data[0] == '\x07': 290 | break 291 | else: 292 | log('[keep-alive1]recv/not expected',data.encode('hex')) 293 | log('[keep-alive1] recv',data.encode('hex')) 294 | 295 | def empty_socket_buffer(): 296 | #empty buffer for some fucking schools 297 | log('starting to empty socket buffer') 298 | try: 299 | while True: 300 | data, address = s.recvfrom(1024) 301 | log('recived sth unexcepted',data.encode('hex')) 302 | if s == '': 303 | break 304 | except: 305 | # get exception means it has done. 306 | log('exception in empty_socket_buffer') 307 | pass 308 | log('emptyed') 309 | def main(): 310 | log("auth svr:"+server+"\nusername:"+username+"\nmac:"+str(hex(mac))) 311 | while True: 312 | try: 313 | package_tail = login(username, password, server) 314 | except LoginException: 315 | continue 316 | log('package_tail',package_tail.encode('hex')) 317 | #keep_alive1 is fucking bullshit! 318 | empty_socket_buffer() 319 | keep_alive1(SALT,package_tail,password,server) 320 | #empty_socket_buffer() 321 | keep_alive2(SALT,package_tail,password,server) 322 | if __name__ == "__main__": 323 | try: 324 | main() 325 | except: 326 | os.system("pause") 327 | 328 | -------------------------------------------------------------------------------- /drcom_d_config.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Dec 03 23:45:49 2014 4 | Last Modified: 2016/10/19 12:13 5 | @author: latyas 6 | """ 7 | 8 | from binascii import hexlify 9 | import re 10 | 11 | def hexed(s): 12 | ret = '' 13 | for i in s: 14 | ret += '\\x' + hex(ord(i))[2:].rjust(2, '0') 15 | return ret 16 | 17 | filename = '3.pcapng' 18 | f = open(filename, 'rb') 19 | text = f.read() 20 | offset = re.search('\xF0\x00\xF0\x00[\x00-\xFF]{4}[\x03\x07]\x01', text).start() + 8 21 | #print hexlify(text[offset:offset+330]) 22 | #print hexlify(text[offset:offset+338]) 23 | # print text[offset+334:offset+338].encode('hex') 24 | if re.match('\x00\x00[\x00-\xFF]{2}', text[offset+334:offset+338]): 25 | ror_version = True 26 | else : 27 | ror_version = False 28 | # print ror_version 29 | username_len = ord(text[offset+3]) - 20 30 | username = text[offset+20:offset+20+username_len] 31 | print 'server = \'%s\'' % '.'.join([str(ord(i)) for i in text[offset-12:offset-8]]) 32 | print 'username=\'%s\'' % username 33 | print 'password=\'\'' 34 | print 'CONTROLCHECKSTATUS = \'%s\'' % hexed(text[offset+56]) 35 | print 'ADAPTERNUM = \'%s\'' % hexed(text[offset+57]) 36 | print 'host_ip = \'%s\'' % '.'.join(map(lambda x: str(ord(x)), text[offset+81:offset+85])) 37 | print 'IPDOG = \'%s\'' % hexed(text[offset+105]) 38 | print 'host_name = \'%s\'' % 'GILIGILIEYE' 39 | print 'PRIMARY_DNS = \'%s\'' % '.'.join(map(lambda x: str(ord(x)), text[offset+142:offset+146])) 40 | print 'dhcp_server = \'%s\'' % '.'.join(map(lambda x: str(ord(x)), text[offset+146:offset+150])) 41 | print 'AUTH_VERSION = \'%s\'' % hexed(text[offset+310:offset+312]) 42 | if ror_version: 43 | print 'mac = 0x%s' % hexlify(text[offset+328:offset+334]) 44 | else: 45 | print 'mac = 0x%s' % hexlify(text[offset+320:offset+326]) 46 | print 'host_os = \'%s\'' % 'NOTE7' 47 | 48 | KEEP_ALIVE_VERSION = [i for i in re.findall('\xf0\x00\xf0\x00....\x07.\x5c\x28\x00\x0b\x01(..)', text) if i != '\x0f\x27'][0] 49 | print 'KEEP_ALIVE_VERSION = \'%s\'' % hexed(KEEP_ALIVE_VERSION) 50 | print 'ror_version = %s ' % ror_version -------------------------------------------------------------------------------- /drcom_p_config.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Dec 03 23:45:49 2014 4 | 5 | @author: latyas 6 | """ 7 | 8 | from binascii import hexlify 9 | import re 10 | 11 | def hexed(s): 12 | ret = '' 13 | for i in s: 14 | ret += '\\x' + hex(ord(i))[2:].rjust(2, '0') 15 | return ret 16 | 17 | filename = 'drp.pcapng' 18 | f = open(filename, 'rb') 19 | text = f.read() 20 | offset = re.search('\x07[\x00-\xFF]\x60\x00\x03\x00', text).start() 21 | #print hexlify(text[offset:offset+330]) 22 | print 'server = \'%s\'' % '.'.join([str(ord(i)) for i in text[offset-12:offset-8]]) 23 | print 'pppoe_flag = \'%s\'' % hexed(text[offset+19]) 24 | keep_alive2_flag = re.search('\x07.\x5c\x28\x00\x0b\x03(.)\x02', text).group(1) 25 | #print hexlify(text[offset:offset+330]) 26 | print 'keep_alive2_flag = \'%s\'' % hexed(keep_alive2_flag) 27 | -------------------------------------------------------------------------------- /images/pppoe1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcoms/drcom-generic/698b3f50321d3dbc2abffd6692da79afc44ce47f/images/pppoe1.jpg -------------------------------------------------------------------------------- /images/pppoe2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcoms/drcom-generic/698b3f50321d3dbc2abffd6692da79afc44ce47f/images/pppoe2.jpg -------------------------------------------------------------------------------- /latest-pppoe-python3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | import socket 4 | import struct 5 | import time 6 | import sys 7 | import random 8 | import os 9 | import hashlib 10 | import binascii 11 | 12 | # CONFIG 13 | server = '172.30.1.80' 14 | pppoe_flag = b'\x2a' 15 | keep_alive2_flag = b'\xdc' 16 | # CONFIG_END 17 | 18 | host_ip = server 19 | IS_TEST = True 20 | CONF = "/etc/drcom.conf" 21 | DEBUG = False #log saves to file 22 | if IS_TEST: 23 | CONF = '' 24 | DEBUG = True 25 | LOG_PATH = 'drcom_client.log' 26 | 27 | def log(*args, **kwargs): 28 | s = ' '.join(args) 29 | if 'pkt' in kwargs and DEBUG == True: 30 | s += '\n\tpacket:' + binascii.hexlify(kwargs['pkt']) 31 | print(s) 32 | if DEBUG: 33 | with open(LOG_PATH,'a') as f: 34 | try: 35 | f.write(s) 36 | f.write('\n') 37 | except: 38 | f.write('FUCK WINDOWS' + '\n') 39 | def dump(n): 40 | s = '%x' % n 41 | if len(s) & 1: 42 | s = '0' + s 43 | return binascii.unhexlify(bytes(s, 'ascii')) 44 | 45 | # def gbk2utf8(string): 46 | # try: 47 | # import platform 48 | # if platform.uname()[0] != 'Windows': 49 | # return string.decode('gb2312').encode().decode() 50 | # else: 51 | # return string.decode('gb2312') 52 | # except Exception as e: 53 | # return 'You have witnessed too much...' 54 | 55 | def gen_crc(data, encrypt_type): 56 | DRCOM_DIAL_EXT_PROTO_CRC_INIT = 20000711 57 | ret = '' 58 | if encrypt_type == 0: 59 | # 加密方式无 60 | return struct.pack(' luci已无人维护,请谨慎使用 4 | 5 | 当前root文件夹下为D版本,将luci存储的参数实现转换为py文件可获取的格式(默认位置在/etc/config/drcoom.conf下),增加判断开启与关闭drcom控制脚本,依赖环境依然是python-mini,若手动覆盖安装python-mini后,运行时出现提示libz.so文件确实,请自行寻找并添加到/usr/lib文件夹下,并建立相应的软连接。 6 | 7 | 8 | 这里提供一个NEWIFI-mini的固件,添加python-mini和drcom以及该目录下的LuCI界面(暂包括:K1、K2、niwifi-mini) 9 | 10 | * 链接: https://pan.baidu.com/s/1qYaTTgC 11 | * 密码:6sgp 12 | 13 | 其他版本如果要自行添加可以参照以下方法(以P版本作大体介绍)。 14 | 15 | 16 | 首先修改 `root/usr/lib/lua/luci/model/cbi/drcom.lua`,在末尾处添加 17 | 18 | pppoe_flag = s:option(Value, "pppoe_flag", translate("pppoe_flag")) 19 | keep_alive2_flag = s:option(Value, "keep_alive2_flag", translate("keep_alive2_flag")) 20 | 21 | 此处修改是添加必要的参数设置方式。 22 | 23 | 24 | 接下来修改 `root/etc/config/drcom`,在其末尾添加 25 | 26 | option pppoe_flag '\x2a' 27 | option keep_alive2_flag '\xdc' 28 | 29 | 此处参数可以不做修改,待调整后在luci图形界面再作相关修改; 30 | 31 | 32 | 接下来修改`root/bin/transdrcom`,在相应末尾部位添加 33 | 34 | tmp_pppoe_flag="pppoe_flag = '$(uci get drcom.@drcom[0].pppoe_flag)'" 35 | tmp_keep_alive2_flag="keep_alive2_flag = '$(uci get drcom.@drcom[0].keep_alive2_flag)'" 36 | echo "$tmp_pppoe_flag" >> "$curdir" 37 | echo "$tmp_keep_alive2_flag" >> "$curdir" 38 | 39 | 最后将P版本的`latest-wired-pppoe.py`文件移动到`root/bin`文件夹下,并重命名为drcom,修改赋予执行权限。 40 | 41 | 以上修改完成之后,windows下直接通过winscp上传root目录下文件到根目录覆盖即可;linux下使用scp命令上传覆盖。 42 | -------------------------------------------------------------------------------- /openwrt/root/bin/drcom: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Copyright (c) 2014-2016, latyas 3 | # Edit by Sui 4 | # -*- coding: utf-8 -*- 5 | import socket, struct, time 6 | from hashlib import md5 7 | import sys 8 | import os 9 | import random 10 | 11 | execfile('/etc/config/drcom.conf',globals()) 12 | nic_name = '' #Indicate your nic, e.g. 'eth0.2'.nic_name 13 | bind_ip = '0.0.0.0' 14 | 15 | class ChallengeException (Exception): 16 | def __init__(self): 17 | pass 18 | 19 | class LoginException (Exception): 20 | def __init__(self): 21 | pass 22 | 23 | def bind_nic(): 24 | try: 25 | import fcntl 26 | def get_ip_address(ifname): 27 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 28 | return socket.inet_ntoa(fcntl.ioctl( 29 | s.fileno(), 30 | 0x8915, # SIOCGIFADDR 31 | struct.pack('256s', ifname[:15]) 32 | )[20:24]) 33 | return get_ip_address(nic_name) 34 | except ImportError as e: 35 | print('Indicate nic feature need to be run under Unix based system.') 36 | return '0.0.0.0' 37 | except IOError as e: 38 | print(nic_name + 'is unacceptable !') 39 | return '0.0.0.0' 40 | finally: 41 | return '0.0.0.0' 42 | 43 | if nic_name != '': 44 | bind_ip = bind_nic() 45 | 46 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 47 | # s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 48 | s.bind((bind_ip, 61440)) 49 | 50 | s.settimeout(3) 51 | SALT = '' 52 | UNLIMITED_RETRY = True 53 | EXCEPTION = False 54 | 55 | def log(*args, **kwargs): 56 | s = ' '.join(args) 57 | print s 58 | 59 | def challenge(svr,ran): 60 | while True: 61 | t = struct.pack(">5)) 96 | # return ret 97 | 98 | def keep_alive_package_builder(number,random,tail,type=1,first=False): 99 | data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) 100 | if first : 101 | data += '\x0f\x27' 102 | else: 103 | data += KEEP_ALIVE_VERSION 104 | data += '\x2f\x12' + '\x00' * 6 105 | data += tail 106 | data += '\x00' * 4 107 | #data += struct.pack("!H",0xdc02) 108 | if type == 3: 109 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip 110 | #CRC 111 | # edited on 2014/5/12, filled zeros to checksum 112 | # crc = packet_CRC(data+foo) 113 | crc = '\x00' * 4 114 | #data += struct.pack("!I",crc) + foo + '\x00' * 8 115 | data += crc + foo + '\x00' * 8 116 | else: #packet type = 1 117 | data += '\x00' * 16 118 | return data 119 | 120 | # def packet_CRC(s): 121 | # ret = 0 122 | # for i in re.findall('..', s): 123 | # ret ^= struct.unpack('>h', i)[0] 124 | # ret &= 0xFFFF 125 | # ret = ret * 0x2c7 126 | # return ret 127 | 128 | def keep_alive2(*args): 129 | #first keep_alive: 130 | #number = number (mod 7) 131 | #status = 1: first packet user sended 132 | # 2: first packet user recieved 133 | # 3: 2nd packet user sended 134 | # 4: 2nd packet user recieved 135 | # Codes for test 136 | tail = '' 137 | packet = '' 138 | svr = server 139 | ran = random.randint(0,0xFFFF) 140 | ran += random.randint(1,10) 141 | # 2014/10/15 add by latyas, maybe svr sends back a file packet 142 | svr_num = 0 143 | packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1,True) 144 | while True: 145 | log('[keep-alive2] send1',packet.encode('hex')) 146 | s.sendto(packet, (svr, 61440)) 147 | data, address = s.recvfrom(1024) 148 | log('[keep-alive2] recv1',data.encode('hex')) 149 | if data.startswith('\x07\x00\x28\x00') or data.startswith('\x07' + chr(svr_num) + '\x28\x00'): 150 | break 151 | elif data[0] == '\x07' and data[2] == '\x10': 152 | log('[keep-alive2] recv file, resending..') 153 | svr_num = svr_num + 1 154 | packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1, False) 155 | else: 156 | log('[keep-alive2] recv1/unexpected',data.encode('hex')) 157 | #log('[keep-alive2] recv1',data.encode('hex')) 158 | 159 | ran += random.randint(1,10) 160 | packet = keep_alive_package_builder(svr_num, dump(ran),'\x00'*4,1,False) 161 | log('[keep-alive2] send2',packet.encode('hex')) 162 | s.sendto(packet, (svr, 61440)) 163 | while True: 164 | data, address = s.recvfrom(1024) 165 | if data[0] == '\x07': 166 | svr_num = svr_num + 1 167 | break 168 | else: 169 | log('[keep-alive2] recv2/unexpected',data.encode('hex')) 170 | log('[keep-alive2] recv2',data.encode('hex')) 171 | tail = data[16:20] 172 | 173 | 174 | ran += random.randint(1,10) 175 | packet = keep_alive_package_builder(svr_num,dump(ran),tail,3,False) 176 | log('[keep-alive2] send3',packet.encode('hex')) 177 | s.sendto(packet, (svr, 61440)) 178 | while True: 179 | data, address = s.recvfrom(1024) 180 | if data[0] == '\x07': 181 | svr_num = svr_num + 1 182 | break 183 | else: 184 | log('[keep-alive2] recv3/unexpected',data.encode('hex')) 185 | log('[keep-alive2] recv3',data.encode('hex')) 186 | tail = data[16:20] 187 | log("[keep-alive2] keep-alive2 loop was in daemon.") 188 | 189 | i = svr_num 190 | while True: 191 | try: 192 | ran += random.randint(1,10) 193 | packet = keep_alive_package_builder(i,dump(ran),tail,1,False) 194 | #log('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) 195 | log('[keep_alive2] send',str(i),packet.encode('hex')) 196 | s.sendto(packet, (svr, 61440)) 197 | data, address = s.recvfrom(1024) 198 | log('[keep_alive2] recv',data.encode('hex')) 199 | tail = data[16:20] 200 | #log('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) 201 | 202 | ran += random.randint(1,10) 203 | packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) 204 | #log('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) 205 | s.sendto(packet, (svr, 61440)) 206 | log('[keep_alive2] send',str(i+1),packet.encode('hex')) 207 | data, address = s.recvfrom(1024) 208 | log('[keep_alive2] recv',data.encode('hex')) 209 | tail = data[16:20] 210 | #log('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) 211 | i = (i+2) % 0xFF 212 | time.sleep(20) 213 | keep_alive1(*args) 214 | except: 215 | pass 216 | 217 | 218 | import re 219 | def checksum(s): 220 | ret = 1234 221 | for i in re.findall('....', s): 222 | ret ^= int(i[::-1].encode('hex'), 16) 223 | ret = (1968 * ret) & 0xffffffff 224 | return struct.pack(' 237 | data += '\00'*4 #your ipaddress 2 238 | data += '\00'*4 #your ipaddress 3 239 | data += '\00'*4 #your ipaddress 4 240 | data += md5sum(data + '\x14\x00\x07\x0b')[:8] #md53 241 | data += IPDOG 242 | data += '\x00'*4 #delimeter 243 | data += host_name.ljust(32, '\x00') 244 | data += ''.join([chr(int(i)) for i in PRIMARY_DNS.split('.')]) #primary dns 245 | data += ''.join([chr(int(i)) for i in dhcp_server.split('.')]) #DHCP server 246 | data += '\x00\x00\x00\x00' #secondary dns:0.0.0.0 247 | data += '\x00' * 8 #delimeter 248 | data += '\x94\x00\x00\x00' # unknow 249 | data += '\x05\x00\x00\x00' # os major 250 | data += '\x01\x00\x00\x00' # os minor 251 | data += '\x28\x0a\x00\x00' # OS build 252 | data += '\x02\x00\x00\x00' #os unknown 253 | data += host_os.ljust(32,'\x00') 254 | data += '\x00' * 96 255 | #data += '\x01' + host_os.ljust(128, '\x00') 256 | #data += '\x0a\x00\x00'+chr(len(pwd)) # \0x0a represents version of client, algorithm: DRCOM_VER + 100 257 | #data += ror(md5sum('\x03\x01'+salt+pwd), pwd) 258 | data += AUTH_VERSION 259 | data += '\x02\x0c' 260 | data += checksum(data+'\x01\x26\x07\x11\x00\x00'+dump(mac)) 261 | data += '\x00\x00' #delimeter 262 | data += dump(mac) 263 | data += '\x00' # auto logout / default: False 264 | data += '\x00' # broadcast mode / default : False 265 | data += '\xe9\x13' #unknown, filled numbers randomly =w= 266 | 267 | log('[mkpkt]',data.encode('hex')) 268 | return data 269 | 270 | def login(usr, pwd, svr): 271 | import random 272 | global SALT 273 | 274 | i = 0 275 | while True: 276 | salt = challenge(svr,time.time()+random.randint(0xF,0xFF)) 277 | SALT = salt 278 | packet = mkpkt(salt, usr, pwd, mac) 279 | log('[login] send',packet.encode('hex')) 280 | s.sendto(packet, (svr, 61440)) 281 | data, address = s.recvfrom(1024) 282 | log('[login] recv',data.encode('hex')) 283 | log('[login] packet sent.') 284 | if address == (svr, 61440): 285 | if data[0] == '\x04': 286 | log('[login] loged in') 287 | break 288 | else: 289 | log('[login] login failed.') 290 | if IS_TEST: 291 | time.sleep(3) 292 | else: 293 | time.sleep(30) 294 | continue 295 | else: 296 | if i >= 5 and UNLIMITED_RETRY == False : 297 | log('[login] exception occured.') 298 | sys.exit(1) 299 | else: 300 | continue 301 | 302 | log('[login] login sent') 303 | #0.8 changed: 304 | return data[23:39] 305 | #return data[-22:-6] 306 | 307 | def keep_alive1(salt,tail,pwd,svr): 308 | foo = struct.pack('!H',int(time.time())%0xFFFF) 309 | data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' 310 | data += tail 311 | data += foo + '\x00\x00\x00\x00' 312 | log('[keep_alive1] send',data.encode('hex')) 313 | 314 | s.sendto(data, (svr, 61440)) 315 | while True: 316 | data, address = s.recvfrom(1024) 317 | if data[0] == '\x07': 318 | break 319 | else: 320 | log('[keep-alive1]recv/not expected',data.encode('hex')) 321 | log('[keep-alive1] recv',data.encode('hex')) 322 | 323 | def empty_socket_buffer(): 324 | #empty buffer for some fucking schools 325 | log('starting to empty socket buffer') 326 | try: 327 | while True: 328 | data, address = s.recvfrom(1024) 329 | log('recived sth unexpected',data.encode('hex')) 330 | if s == '': 331 | break 332 | except: 333 | # get exception means it has done. 334 | log('exception in empty_socket_buffer') 335 | pass 336 | log('emptyed') 337 | 338 | def main(): 339 | log("auth svr:"+server+"\nusername:"+username+"\npassword:"+password+"\nmac:"+str(hex(mac))) 340 | log(bind_ip) 341 | while True: 342 | try: 343 | package_tail = login(username, password, server) 344 | except LoginException: 345 | continue 346 | log('package_tail',package_tail.encode('hex')) 347 | #keep_alive1 is fucking bullshit! 348 | empty_socket_buffer() 349 | keep_alive1(SALT,package_tail,password,server) 350 | keep_alive2(SALT,package_tail,password,server) 351 | if __name__ == "__main__": 352 | main() 353 | -------------------------------------------------------------------------------- /openwrt/root/bin/transdrcom: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright (c) 2014 OpenWrt 3 | # Copyright (c) 2016 Sui 4 | curdir=/etc/config/drcom.conf 5 | touch $curdir 6 | tmp_server="server = '$(uci get drcom.@drcom[0].server)'" 7 | tmp_username="username = '$(uci get drcom.@drcom[0].username)'" 8 | tmp_password="password = '$(uci get drcom.@drcom[0].password)'" 9 | tmp_host_name="host_name = '$(uci get drcom.@drcom[0].host_name)'" 10 | tmp_host_os="host_os = '$(uci get drcom.@drcom[0].host_os)'" 11 | tmp_host_ip="host_ip = '$(uci get drcom.@drcom[0].host_ip)'" 12 | tmp_dhcp_server="dhcp_server = '$(uci get drcom.@drcom[0].dhcp_server)'" 13 | tmp_mac="mac = $(uci get drcom.@drcom[0].mac)" 14 | tmp_PRIMARY_DNS="PRIMARY_DNS = '$(uci get drcom.@drcom[0].PRIMARY_DNS)'" 15 | tmp_AUTH_VERSION="AUTH_VERSION = '$(uci get drcom.@drcom[0].AUTH_VERSION)'" 16 | tmp_KEEP_ALIVE_VERSION="KEEP_ALIVE_VERSION = '$(uci get drcom.@drcom[0].KEEP_ALIVE_VERSION)'" 17 | tmp_CONTROLCHECKSTATUS="CONTROLCHECKSTATUS = '$(uci get drcom.@drcom[0].CONTROLCHECKSTATUS)'" 18 | tmp_ADAPTERNUM="ADAPTERNUM = '$(uci get drcom.@drcom[0].ADAPTERNUM)'" 19 | tmp_IPDOG="IPDOG = '$(uci get drcom.@drcom[0].IPDOG)'" 20 | echo $tmp_server >> $curdir 21 | echo $tmp_username >> $curdir 22 | echo $tmp_password >> $curdir 23 | echo $tmp_host_name >> $curdir 24 | echo $tmp_host_os >> $curdir 25 | echo $tmp_host_ip >> $curdir 26 | echo $tmp_dhcp_server >> $curdir 27 | echo $tmp_mac >> $curdir 28 | echo $tmp_PRIMARY_DNS >> $curdir 29 | echo $tmp_AUTH_VERSION >> $curdir 30 | echo $tmp_KEEP_ALIVE_VERSION >> $curdir 31 | echo $tmp_CONTROLCHECKSTATUS >> $curdir 32 | echo $tmp_ADAPTERNUM >> $curdir 33 | echo $tmp_IPDOG >> $curdir 34 | 35 | -------------------------------------------------------------------------------- /openwrt/root/etc/config/drcom: -------------------------------------------------------------------------------- 1 | config drcom 2 | option enable '' 3 | option server '' 4 | option username '' 5 | option password '' 6 | option host_name '' 7 | option host_os '' 8 | option host_ip '' 9 | option dhcp_server '' 10 | option mac '' 11 | option PRIMARY_DNS '' 12 | option AUTH_VERSION '' 13 | option KEEP_ALIVE_VERSION '' 14 | option CONTROLCHECKSTATUS '' 15 | option ADAPTERNUM '' 16 | option IPDOG '' 17 | -------------------------------------------------------------------------------- /openwrt/root/etc/init.d/drcom: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | # Copyright (c) 2016, Sui 3 | START=90 4 | 5 | drcom_up() 6 | { 7 | local enable 8 | config_get_bool enable $1 enable 9 | if [ $enable ]; then 10 | transdrcom 11 | drcom & 12 | sleep 5 13 | echo "Dr.COM Client is started" 14 | else 15 | stop 16 | fi 17 | } 18 | 19 | start() 20 | { 21 | sleep 10 22 | rm -rf /etc/config/drcom.conf 23 | config_load drcom 24 | config_foreach drcom_up drcom 25 | } 26 | 27 | stop() 28 | { 29 | kill -9 `ps | grep drcom | grep python | awk '{print $1}'` 30 | echo "Dr.COM Client is stopped" 31 | } 32 | 33 | restart() 34 | { 35 | stop 36 | rm -rf /etc/config/drcom.conf 37 | config_load drcom 38 | config_foreach drcom_up drcom 39 | } 40 | -------------------------------------------------------------------------------- /openwrt/root/etc/rc.d/S99drcom: -------------------------------------------------------------------------------- 1 | ../init.d/drcom -------------------------------------------------------------------------------- /openwrt/root/usr/lib/lua/luci/controller/drcom.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | # Copyright (c) 2014-2016, latyas 3 | # Edit by Sui 4 | ]]-- 5 | 6 | module("luci.controller.drcom", package.seeall) 7 | 8 | function index() 9 | 10 | if not nixio.fs.access("/etc/config/drcom") then 11 | return 12 | end 13 | 14 | local page 15 | 16 | page = entry({"admin", "services", "Dr.COM"}, cbi("drcom"), _("Dr.COM"), 45) 17 | page.i18n = "DrCOM" 18 | page.dependent = true 19 | end 20 | -------------------------------------------------------------------------------- /openwrt/root/usr/lib/lua/luci/model/cbi/drcom.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | # Copyright (c) 2014-2016, latyas 3 | # Edit by Sui 4 | ]]-- 5 | require("luci.sys") 6 | local fs = require "nixio.fs" 7 | local nixio = require "nixio" 8 | 9 | local drcom_running =(luci.sys.call("ps | grep drcom |egrep -v grep > /dev/null") == 0) 10 | local client_status 11 | 12 | if drcom_running then 13 | client_status = "客户端运行中" 14 | else 15 | client_status = "客户端未运行" 16 | end 17 | 18 | m = Map("drcom", translate("Dr.COM"), translate(client_status)) 19 | 20 | s = m:section(TypedSection, "drcom", translate("客户端配置"), 21 | translate("LuCI版本的Dr.COM配置.").. 22 | "
" 23 | ..[[
]] 24 | ..[[]] 25 | ..translate("欢迎加入本项目的讨论组(注意:需要FQ)。") 26 | ..[[]] 27 | ..[[
]] 28 | ..[[
]] 29 | ..[[]] 30 | ..translate("官方交流QQ群:318495368,欢迎加入。") 31 | ..[[]] 32 | ..[[
]] 33 | ..[[
]] 34 | ..[[]] 35 | ..translate("本项目在GitHub的项目地址。") 36 | ..[[]] 37 | ..[[
]] 38 | ..[[
]] 39 | ..[[]] 40 | ..translate("查看本页面的相关自定义修改和配置说明。") 41 | ..[[]] 42 | ..[[
]] 43 | ) 44 | s.anonymous = true 45 | 46 | enable = s:option(Flag, "enable", translate("开启Dr.com")) 47 | 48 | remote_server = s:option(Value, "server", translate("认证服务器地址")) 49 | remote_server.datatype = "ip4addr" 50 | remote_server.defaule = "192.168.1.1" 51 | 52 | username = s:option(Value, "username", translate("用户名")) 53 | username.default = "123" 54 | 55 | password = s:option(Value, "password", translate("密码")) 56 | password.datatype = "maxlength(16)" 57 | password.password = true 58 | password.default = "123" 59 | 60 | host_name = s:option(Value, "host_name", translate("主机名称")) 61 | host_name.datatype = "maxlength(32)" 62 | host_name.default = "HP" 63 | 64 | host_os = s:option(Value, "host_os", translate("主机操作系统")) 65 | host_os.datatype = "maxlength(32)" 66 | host_os.default = "DOS" 67 | 68 | host_ip = s:option(Value, "host_ip", translate("主机IP")) 69 | host_ip.datatype = "ip4addr" 70 | host_ip.default = "0.0.0.0" 71 | 72 | dhcp_server = s:option(Value, "dhcp_server", translate("DHCP服务器")) 73 | dhcp_server.datatype = "ip4addr" 74 | dhcp_server.default = "0.0.0.0" 75 | 76 | mac = s:option(Value, "mac", translate("绑定MAC地址")) 77 | mac.default = "0xaabbccddeeff" 78 | 79 | PRIMARY_DNS = s:option(Value, "PRIMARY_DNS", translate("PRIMARY_DNS")) 80 | PRIMARY_DNS.default = "114.114.114.114" 81 | 82 | AUTH_VERSION = s:option(Value, "AUTH_VERSION", translate("AUTH_VERSION")) 83 | AUTH_VERSION.default = "\x0a\x00" 84 | 85 | KEEP_ALIVE_VERSION = s:option(Value, "KEEP_ALIVE_VERSION", translate("KEEP_ALIVE_VERSION")) 86 | KEEP_ALIVE_VERSION.default = "\xdc\x02" 87 | 88 | CONTROLCHECKSTATUS = s:option(Value, "CONTROLCHECKSTATUS", translate("CONTROLCHECKSTATUS")) 89 | CONTROLCHECKSTATUS.default = "\x20" 90 | 91 | ADAPTERNUM = s:option(Value, "ADAPTERNUM", translate("ADAPTERNUM")) 92 | ADAPTERNUM.default = "\x01" 93 | 94 | IPDOG = s:option(Value, "IPDOG", translate("IPDOG")) 95 | IPDOG.default = "\x01" 96 | 97 | local apply = luci.http.formvalue("cbi.apply") 98 | if apply then 99 | io.popen("/etc/init.d/drcom restart") 100 | end 101 | 102 | return m 103 | -------------------------------------------------------------------------------- /tests/drcom_d.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | -- drcom lua version with dhcp 4 | -- depend lua with double int32, luasocket, lua-md5 5 | -- author: fuyumi 6 | -- dirty and unfinished 7 | 8 | local socket = require('socket') 9 | local md5 = require('md5') 10 | local udp = socket.udp() 11 | local server = '119.39.30.18' 12 | local port = 61440 13 | udp:settimeout(5) 14 | udp:setsockname('*', port) 15 | udp:setpeername(server, port) 16 | 17 | -- server = '119.39.30.18' 18 | username = 'abc@defg' 19 | password = 'hijk' 20 | CONTROLCHECKSTATUS = '20' 21 | ADAPTERNUM = '01' 22 | host_ip = '6e35d852' 23 | IPDOG = '01' 24 | host_name = 'fuyumi' 25 | -- PRIMARY_DNS = '58.20.127.238' 26 | -- dhcp_server = '110.53.216.1' 27 | AUTH_VERSION = '2600' 28 | mac = '1c872c478e3b' 29 | host_os = 'Windows 10' 30 | KEEP_ALIVE_VERSION = 'd802' 31 | 32 | function bin_xor(x, y) 33 | local z = 0 34 | for i = 0, 63 do 35 | if (x % 2 == 0) then 36 | if ( y % 2 == 1) then 37 | y = y - 1 38 | z = z + 2 ^ i 39 | end 40 | else 41 | x = x - 1 42 | if (y % 2 == 0) then 43 | z = z + 2 ^ i 44 | else 45 | y = y - 1 46 | end 47 | end 48 | y = y / 2 49 | x = x / 2 50 | end 51 | return z 52 | end 53 | 54 | function num2hex(num) 55 | local hexstr = '0123456789abcdef' 56 | local s = '' 57 | while num > 0 do 58 | local mod = math.fmod(num, 16) 59 | s = string.sub(hexstr, mod+1, mod+1) .. s 60 | num = math.floor(num / 16) 61 | end 62 | if s == '' then s = '0' end 63 | return s 64 | end 65 | 66 | function random(a, b) 67 | math.randomseed(tostring(os.time()):reverse():sub(1, 6)) 68 | return math.random(a, b) 69 | end 70 | 71 | function dump() 72 | -- body 73 | end 74 | 75 | function challenge() 76 | ran = random(1, 255) 77 | udp:send(string.char(01,02,ran,09,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00)) 78 | data = udp:receive(1024) 79 | if string.byte(data) == 02 then 80 | return string.sub(data, 5, 8) 81 | else 82 | assert(print(), 'error for receiving') 83 | end 84 | end 85 | 86 | function mkptk(salt, usr, pwd, mac) 87 | data1 = string.char(03,01,00) .. string.char(string.len(usr) + 20) 88 | data2 = md5.sum(string.char(03,01) .. salt .. pwd) 89 | data3 = string.sub(usr .. string.rep(string.char(0), 36), 1, 36) 90 | data4 = string.char(('0x' .. CONTROLCHECKSTATUS) + 0) .. string.char(('0x' .. ADAPTERNUM) + 0) 91 | f1 = num2hex(string.byte(data2,1))..num2hex(string.byte(data2,2))..num2hex(string.byte(data2,3))..num2hex(string.byte(data2,4))..num2hex(string.byte(data2,5))..num2hex(string.byte(data2,6)) 92 | f2 = bin_xor((('0x'..f1) + 0), (('0x'..mac) + 0)) 93 | f3 = string.sub(('000000' .. num2hex(f2)), -12) 94 | f4 = string.char(('0x'..(string.sub(f3,1,2)))+0)..string.char(('0x'..(string.sub(f3,3,4)))+0)..string.char(('0x'..(string.sub(f3,5,6)))+0)..string.char(('0x'..(string.sub(f3,7,8)))+0)..string.char(('0x'..(string.sub(f3,9,10)))+0)..string.char(('0x'..(string.sub(f3,11,12)))+0) 95 | data5 = f4 96 | data6 = md5.sum(string.char(01) .. pwd .. salt .. string.char(0,0,0,0)) 97 | data7 = string.char(01) .. string.char(8,8,8,8) --issue 98 | data8 = string.rep(string.char(0), 12) 99 | data9 = string.sub(md5.sum((data1 .. data2 .. data3 .. data4 .. data5 .. data6 .. data7 .. data8) .. string.char(20, 00, 07, 11)), 1, 8) 100 | data10 = string.char(('0x' .. IPDOG) + 0) .. string.char(0,0,0,0) 101 | data11 = string.sub(host_name .. string.rep(string.char(0), 32), 1, 32) 102 | data12 = string.char(8,8,8,8) .. string.char(8,8,8,8) 103 | data13 = string.char(0,0,0,0,0,148,0,0,0,96,0,0,0,1,0,0,0,177,29,0,0,2,0,0,0) 104 | data14 = string.sub(host_os .. string.rep(string.char(0), 32), 1, 32) 105 | data15 = string.rep(string.char(0), 96) 106 | data16 = string.char(('0x' .. string.sub(AUTH_VERSION, 1, 2)) + 0) ..string.char(('0x' .. string.sub(AUTH_VERSION, 3, 4)) + 0) 107 | data17 = string.char(2,12) 108 | data18 = nil --checksum 109 | data19 = string.char(0,0) 110 | data20 = dump() 111 | data21 = string.char(0,0,0,0) 112 | data = data1 .. data2 .. data3 .. data4 .. data5 .. data6 .. data7 .. data8 .. data9 .. data10 113 | data = data .. data11 .. data11 .. data12 .. data13 ..data14 .. data15 .. data16 .. data17 114 | data = data .. data18 .. data19 .. data20 .. data21 115 | udp:send(data) 116 | end 117 | 118 | salt = challenge() 119 | -- print(string.byte(salt),1,100) 120 | -- udp:send(salt) 121 | mkptk(salt, username, password, mac) 122 | -------------------------------------------------------------------------------- /tests/fake_svr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import socket 4 | import re 5 | 6 | # CONFIG 7 | server = '192.168.1.14' 8 | username = 'a' 9 | password = 'a' 10 | host_name = 'LIYUANYUAN' 11 | host_os = '8089D' 12 | host_ip = '10.30.22.17' 13 | PRIMARY_DNS = '114.114.114.114' 14 | dhcp_server = '0.0.0.0' 15 | mac = 0xb888e3051680 16 | CONTROLCHECKSTATUS = '\x20' 17 | ADAPTERNUM = '\x01' 18 | KEEP_ALIVE_VERSION = '\xDC\x02' 19 | AUTH_VERSION = '\x0A\x00' 20 | IPDOG = '\x01' 21 | ror_version = False 22 | # CONFIG_END 23 | 24 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 25 | s.bind(('192.168.1.14', 61440)) 26 | s.settimeout(30) 27 | test_svr = ('192.168.1.11', 61440) 28 | print('##### Server is listening. #####') 29 | 30 | def receive_challenge(challenge_seed, MM): 31 | data, addr = s.recvfrom(1024) 32 | if addr == test_svr: 33 | print('> Received: ' + data.encode('hex')) 34 | if (re.match('\x01\x02[\x00-\xFF]{3}[\x00]{15}', data)): 35 | print('>>> Challenge packet received.') 36 | seed = data[2:4] 37 | s.sendto('\x02\x01' + seed + challenge_seed + '\x00' * 12 + ''.join([chr(int(i)) for i in host_ip.split('.')]) + '\xF0\x00' + MM + '\x00' * 34, test_svr) 38 | return 1 39 | else: 40 | print('>>> Unknown packet in challenge.') 41 | return 0 42 | else: 43 | print('>>> Not match.') 44 | return 0 45 | 46 | def receive_loginpkt(challenge_seed, Auth_Information): 47 | data, addr = s.recvfrom(1024) 48 | print('> Received: ' + data.encode('hex')) 49 | if (data.encode('hex') == '030100153821896b162d58752557b27a03d322ff610000000000000000000000000000000000000000000000000000000000000000000000200180a96a6e00adba973cf02d13d29a8eec6605e2e8d780010a1e1611000000000000000000000000486c558f1a339aa001000000004c495955414e5955414e000000000000000000000000000000000000000000007272727200000000000000000000000000000000940000000500000001000000280a00000200000038303839440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00020c803256d60000b888e30516800000e913'): 50 | print('>>> Login packet received.') 51 | s.sendto('\x04\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00' + Auth_Information + '\xB0\x05\x00\x03\x01\x00', test_svr) 52 | s.sendto('\x4D\x3A\x04\xD5\x68\x74\x74\x70\x3A\x2F\x2F\x35\x38\x2E\x32\x30\x2E\x31\x30\x38\x2E\x31\x30\x38\x3A\x31\x30\x30\x31\x30\x2F\x6C\x67\x64\x78\x2F', test_svr) 53 | else: 54 | print('>>> Wrong authentication.') 55 | 56 | def receive_keepalive1(Auth_Information, MM): 57 | data, addr = s.recvfrom(1024) 58 | print('>>> Received: ' + data.encode('hex')) 59 | if (re.match('\xFF\x38\x21\x89\x6B\x16\x2D\x58\x75\x25\x57\xB2\x7A\x03\xD3\x22\xFF\x00\x00\x00' + Auth_Information + '[\x00-\xFF]{2}', data)): 60 | print('>>> Keepalive 1 received.') 61 | s.sendto('\x07\x01\x10\x00\x06\x00\x89\x45\x04\x38\xE2\x11\x6E\x35\xAA' + MM + '\x01\x00\x00\x00\x06' + '\x00' * 17 + '\xFF\xFF\xFF\xFF\x80\x3A\x09\x00\xFF\xFF\xFF\xFF', test_svr) 62 | 63 | def receive_keepalive2(MM, someflux): 64 | data, addr = s.recvfrom(1024) 65 | print('>>> Received: ' + data.encode('hex')) 66 | if (re.match(r'\x07[\x00-\xFF]\x28\x00\x0B\x01\x0F\x27\x2F\x12[\x00]{30}', data)): 67 | print('>>> Keepalive 2 Misc_Type_1 partA received.') 68 | # send Misc_Type file 69 | s.sendto('\x07\x00\x10\x01\x0B\x06' + KEEP_ALIVE_VERSION + '\x00' * 8 + MM, test_svr) 70 | receive_keepalive2(MM, someflux) 71 | elif (re.match(r'\x07[\x00-\xFF]\x28\x00\x0B\x01' + KEEP_ALIVE_VERSION + r'\x2F\x12[\x00]{6}[\x00-\xFF]{4}[\x00]{20}', data)): 72 | print('>>> Keepalive 2 Misc_Type_1 partB received.') 73 | # send Misc_Type 2 74 | s.sendto('\x07\x00\x28\x00\x0B\x02' + KEEP_ALIVE_VERSION + '\x2F\x12' + '\x00' * 6 + someflux + '\x00' * 20, test_svr) 75 | data, addr = s.recvfrom(1024) 76 | print('>>> Received: ' + data.encode('hex')) 77 | foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) 78 | if (re.match(r'\x07[\x00-\xFF]\x28\x00\x0B\x03' + KEEP_ALIVE_VERSION + '\x2F\x12[\x00]{6}' + someflux + r'[\x00]{8}' + foo + '[\x00]{8}', data)): 79 | print('>>> Keepalive 2 Misc_Type_3 received.') 80 | # send Misc_Type 4 81 | s.sendto('\x07\x00\x28\x00\x0B\x04' + KEEP_ALIVE_VERSION + '\x2F\x12' + '\x00' * 6 + someflux + '\x00' * 20, test_svr) 82 | print('>>> Keepalive in loop. <<<') 83 | 84 | def main(): 85 | challenge_seed = '\x52\x6C\xE4\x00' 86 | MM = '\xA8\xA6\x00\x00\x70\xCD\xA0\xA3\x00\x00\x00\x00' + KEEP_ALIVE_VERSION + '\x00\x00' 87 | Auth_Information = '\x44\x72\x63\x6F\x77\x27\x20\xCA\xED\x05\x6E\x35\xAA\x8B\x01\xFB' 88 | val = receive_challenge(challenge_seed, MM) 89 | someflux = '\x13\x38\xE2\x11' 90 | if val: 91 | receive_loginpkt(challenge_seed, Auth_Information) 92 | while 1: 93 | receive_keepalive1(Auth_Information, MM) 94 | receive_keepalive2(MM, someflux) 95 | 96 | 97 | if __name__ == '__main__': 98 | main() 99 | -------------------------------------------------------------------------------- /tests/pppoe_heartbeat_analysis.py: -------------------------------------------------------------------------------- 1 | #coding=utf8 2 | from binascii import hexlify, crc32 3 | import re 4 | import struct 5 | import md4 6 | 7 | class PPPOEHeartbeat: 8 | def __init__(self, num): 9 | self.count = num # 计数器 10 | def _make_challenge(self): 11 | data = '\x07' 12 | data += chr(self.count) 13 | data += '\x08\x00\x01\x00' 14 | data+= '\x00\x00' 15 | return data 16 | 17 | def _encrypt_md4(self, data): 18 | pass 19 | def _encrypt_md5(self, data): 20 | pass 21 | 22 | def _encrypt_sha1(self, data): 23 | pass 24 | 25 | def _netinfo_encrypt(self, data): 26 | s = '' 27 | for index, c in enumerate(data): 28 | foo = ord(c) << index & 0x07 29 | foo &= 0xFF # 去掉多余位 30 | bar = ord(c) >> (8 - (index & 0x07)) 31 | bar &= 0xFF 32 | s += chr((foo + bar) & 0xFF) 33 | return s 34 | 35 | def _DrcomCRC32(self, data, init = 0): 36 | ret = init 37 | for i in re.findall('....', data): 38 | ret ^= struct.unpack('!I', i)[0] 39 | return ret 40 | def _gen_crc(self, data, encrypt_type): 41 | DRCOM_DIAL_EXT_PROTO_CRC_INIT = 20000711 42 | ret = '' 43 | if encrypt_type == 0: 44 | # 加密方式无 45 | return struct.pack('!I',DRCOM_DIAL_EXT_PROTO_CRC_INIT) + struct.pack('!I',126) 46 | elif encrypt_type == 1: 47 | # 加密方式为 md5 48 | foo = hashlib.md5(data).digest() 49 | ret += foo[2] 50 | ret += foo[3] 51 | ret += foo[8] 52 | ret += foo[9] 53 | ret += foo[5] 54 | ret += foo[6] 55 | ret += foo[13] 56 | ret += foo[14] 57 | return ret 58 | elif encrypt_type == 2: 59 | # md4 60 | foo = md4(data) 61 | ret += foo[1] 62 | ret += foo[2] 63 | ret += foo[8] 64 | ret += foo[9] 65 | ret += foo[4] 66 | ret += foo[5] 67 | ret += foo[11] 68 | ret += foo[12] 69 | return ret 70 | elif encrypt_type == 3: 71 | # sha1 72 | foo = hashlib.sha1(data).digest() 73 | ret += foo[2] 74 | ret += foo[3] 75 | ret += foo[9] 76 | ret += foo[10] 77 | ret += foo[5] 78 | ret += foo[6] 79 | ret += foo[15] 80 | ret += foo[16] 81 | return ret 82 | 83 | def _make_heartbeat(self, sip, challenge_seed): 84 | # DrcomDialExtProtoHeader - 5 bytes 85 | """ 86 | typedef struct _tagDrcomDialExtProtoHeader 87 | { 88 | unsigned char code; 89 | unsigned char id; 90 | unsigned short length; 91 | unsigned char type; 92 | } PPPOEHEADER; 93 | """ 94 | data = '\x07' # code 95 | data += chr(self.count + 1) # id 96 | data += '\x60\x00' # length 97 | data += '\x03' # type 98 | """ 99 | struct _tagDrcomDialExtProtoLoginPacket { 100 | PPPOEHEADER header; // 5 byte 101 | 102 | #define hcode header.code // PPPoE ext = 0x07 103 | #define hid header.id // 自定义,每次不同就可以 104 | #define hlength header.length // 发送数据包的长度 105 | #define htype header.type // PPPoE = 0x03 106 | 107 | unsigned char uidlength; 108 | unsigned char mac[6]; 109 | unsigned long sip; 110 | unsigned long option; //bit0=dhcp, bit1=请求封装, bit2-7(verno) 111 | //b8=(no first),b9=有tcpipdog.dll, b10-12 选择出口线路 2006-12-18 112 | //b13(mydll mark2007-2-28), bit14-31 unuse 113 | //b14(mydll mark b15=find proxy cut line (pppoe模式2007-11-22) 114 | //bit16-31 unuse 115 | 116 | unsigned char ChallengeSeed[SEED_LEN]; 117 | unsigned long crc[2]; 118 | 119 | //account ,len 0 120 | //struct _tagDrcomDialExtProtoNetWorkInfo netinfo[MAX_DRCOM_DIAL_EXT_PROTO_NET_NUM]; 121 | //unsigned char unused[4]; 122 | }; 123 | """ 124 | data += '\x00' # uid length 125 | data += '\x00\x00\x00\x00\x00\x00' # mac 126 | data += sip # AuthHostIP 127 | data += '\x00\x62\x00\x14' # 非第一次则是 data += '\x00\x62\x00\x14' 128 | #data += struct.pack('I',0x14006200) 129 | data += challenge_seed # Challenge Seed 130 | # CRC 131 | # data += struct.pack('I',20000711) # DRCOM_DIAL_EXT_PROTO_CRC_INIT 132 | # data += '\xc7\x2f\x31\x01' 133 | data + '\x01\x31\x2f\xc7' 134 | #data += struct.pack('I',126) 135 | # data += '\x7e\x00\x00\x00' 136 | data += '\x00\x00\x00\x7e' 137 | # - DrcomDialExtProtoHeader end - 138 | """ 139 | struct _tagDrcomDialExtProtoNetWorkInfo 140 | { 141 | unsigned char mac[6]; 142 | unsigned char netmark; //dhcp mark 143 | unsigned char type; //interface type(ether,ppp) 144 | unsigned long sip; 145 | unsigned long smask; 146 | //ULONG gateway1; 147 | }; 148 | """ 149 | data += '\x00\x00\x00\x00\x00\x00' 150 | data += '\x00' 151 | data += '\x8b' 152 | data += '\xac\x2a\x14\x78' 153 | data += '\xff\xff\xff\xff' 154 | 155 | data += '\x00\xa0\x59\x06\x00\x20' 156 | data += '\x00' 157 | data += '\x03' 158 | data += '\xc0\x51\x25\x08' 159 | data += '\xff\xff\xff\x00' 160 | 161 | data += '\x00\xa0\x59\x06\x00\x01' 162 | data += '\x00' 163 | data += '\x03' 164 | data += '\xc0\x51\x2b\x08' 165 | data += '\xff\xff\xff\x00' 166 | 167 | data += '\x00\x00\x00\x00\x00\x00' 168 | data += '\x00' 169 | data += '\x00' 170 | data += '\x00\x00\x00\x00' 171 | data += '\x00\x00\x00\x00' 172 | 173 | 174 | return data 175 | def send(self): 176 | pass 177 | 178 | a = PPPOEHeartbeat(0x55) 179 | c = a._make_heartbeat('\xac\x15\x05\x0f','\xcf\x89\xa8\x03') 180 | print hexlify(c) 181 | print hex(a._DrcomCRC32(c)) 182 | print hex((a._DrcomCRC32(c)*19680126)) 183 | print hex((a._DrcomCRC32(c)*19680126) & 0xFFFFFFFF) 184 | -------------------------------------------------------------------------------- /utils/database_passcode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Copyright (c) 2015 Ice Weng # May 23 3 | # Copyright (c) 2016 Artoria2e5 # refactor, changes released under CC0 4 | """DRCOM db passcode obfuscation utils.""" 5 | import sys 6 | 7 | try: 8 | raw_input 9 | except: 10 | raw_input = input # py3 11 | 12 | codearray = [28, 57, 86, 19, 47, 76, 9, 38, 66, 95, 28, 57, 86, 18, 47, 76] 13 | 14 | def decode(s, clean=True): 15 | if s[-1] == 'a' and not clean: 16 | s = s[:-1] 17 | return ''.join(chr(_lim32(ord(c) - codearray[i])) for i, c in enumerate(s)) 18 | 19 | def encode(s, clean=False): 20 | return ''.join(chr(_lim126(ord(c) + codearray[i])) 21 | for i, c in enumerate(s)) + 'a' if not clean else '' 22 | 23 | def _lim32(num): 24 | return num if (num >= 32) else num + 126 - 31 25 | 26 | def _lim126(num): 27 | return num if (num <= 126) else num - 126 + 31 28 | 29 | if __name__ == '__main__': 30 | prompt = 'input the code you want to %s: ' 31 | argv, argc = sys.argv, len(sys.argv) 32 | if argc == 1: 33 | action = '' 34 | while action not in ['encode', 'decode']: 35 | action = raw_input('encode/decode? ') 36 | print(locals()[action](raw_input(prompt % action))) 37 | if argc == 2: 38 | if argc in ['encode', 'decode']: 39 | print(locals()[argv[1]](raw_input(prompt % argv[1]))) 40 | else: 41 | print('decode(-a$): ' + decode(argv[1])) 42 | print('encode(+a$): ' + encode(argv[1])) 43 | elif argc >= 3: 44 | if argc in ['encode', 'decode']: 45 | print('\n'.join(map(locals()[argv[1]](argv[2:])))) 46 | else: 47 | raise ValueError('bad action: not encode/decode') 48 | --------------------------------------------------------------------------------