├── .gitignore ├── Cargo.toml ├── README.md ├── docs ├── index.html └── index.js └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "xor" 3 | version = "0.1.0" 4 | authors = ["Jonir Rings "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | rayon = "1.4.1" 11 | 12 | [profile.release] 13 | opt-level = 'z' 14 | lto = true 15 | codegen-units = 1 16 | panic = 'abort' 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 思路 2 | 1. 寻找备份页面URL的参数,从而进入备份页面 3 | 1. 备份配置文件 4 | 1. 解密配置文件,得到账号密码 5 | # tewa-708e破解流程 6 | 1. 光猫上插入u盘,fat32文件系统。 7 | 1. 常规用户登陆http://192.168.1.1:8080 8 | 1. 切换到 管理-设备管理 9 | 1. 浏览器进入调试模式,在console处,从top切换到MD_Device_user.html 10 | 1. 在console内执行 11 | ``` 12 | `http://192.168.1.1:8080/usbbackup.cmd?action=backupeble&sessionKey=${sessionKey}` 13 | ``` 14 | 1. 注意反引号属于代码的一部分,得到一个url,打开之后点击备份(如果不可点击,审查元素然后删除disabled) 15 | 1. **如果上述方式执行失败**,根据[KoolShare](https://koolshare.cn/forum.php?mod=redirect&goto=findpost&ptid=166510&pid=2227183)坛友的做法也可以尝试执行下列代码 16 | ```js 17 | usbsubarea = { 18 | selectedIndex: 0, 19 | value: "never_mind...", 20 | options:[ 21 | {value: "usb1_1"} 22 | ] 23 | }; 24 | 25 | btnApply(); 26 | ``` 27 | 1. 如果都失败,请参考[相近型号破解的思路](#其他几个相近型号的破解)和[#2](https://github.com/jonirrings/xor/issues/2) 28 | 1. 在u盘内得到ctce8_TEWA-708E.cfg文件 29 | 1. 使用[routerpassview](http://www.nirsoft.net/utils/router_password_recovery.html)或者[附件的xor](https://github.com/jonirrings/xor/releases)解密, 使用方法参考[#4](https://github.com/jonirrings/xor/issues/4) 30 | 1. 直接使用[网页](https://jonirrings.github.io/xor/)解密,用法参考页面说明。 31 | 1. 在解密后文件内找到TeleComAccount,下面的Password内即为超密 32 | 1. 如果需要打开telnet,超级用户登陆后,打开 http://192.168.1.1:8080/enableTelnet.html 即可启用telnet 33 | 34 | # 关于本项目 35 | 备份的cfg文件只是被简单地 `byte ^ 0xff` 处理过,所以根据`xor`的特性,再次计算就能得到原始数据。 36 | 37 | # 编译 38 | 有rust环境的话,直接`cargo run -- cfg文件`就行。 39 | 没有环境的话,直接下载[release页面](https://github.com/jonirrings/xor/releases)已经编译好的执行文件,然后`cmd`内执行`xor cfg文件`就行。 40 | 41 | # 其他几个相近型号的破解 42 | 关于tewa-1000e, tewa-800e之类的型号,将console内执行那一步的url改一下,可以参考[#2](https://github.com/jonirrings/xor/issues/2): 43 | 1. 在`MD_Device_user.html`里面找到的`backupeble`这个关键字 44 | 1. 找到跟`session`相关的参数,手动拼凑有效的url 45 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | TEWA-708e/1000e配置文件转换 9 | 10 | 11 | 12 | 13 | 14 |

此页面仅在Chrome/Firefox/Edge/Safari下测试过,不保证其他浏览器下的兼容性,不保证错误文件的转换效果。

15 |

本页面不会收集数据,不信自己看源码,反正也没几行,哈哈哈!

16 |

用法:选择配置文件,点击转换,然后在代码区里面找TeleComAccount

17 |
18 | 22 | 23 |
24 |
25 | 26 |
27 | 28 | -------------------------------------------------------------------------------- /docs/index.js: -------------------------------------------------------------------------------- 1 | function convert(buffer) { 2 | const u8array = new Uint8Array(buffer) 3 | const plainBuffer = u8array.map(u=>u^0xff); 4 | return new TextDecoder("utf-8").decode(plainBuffer); 5 | } 6 | 7 | function getFile(form) { 8 | const formData = new FormData(form); 9 | return formData.get('config-file'); 10 | } 11 | 12 | function getCipher(file) { 13 | const reader = new FileReader(); 14 | reader.onload = function (e) { 15 | const cipherBuffer = e.target.result; 16 | const plainText = convert(cipherBuffer); 17 | code.innerHTML = formatXml(plainText); 18 | } 19 | reader.readAsArrayBuffer(file); 20 | } 21 | 22 | function formatXml(string) { 23 | return Prism.highlight(string, Prism.languages.xml, 'xml'); 24 | } 25 | 26 | function onSubmit(e) { 27 | e.preventDefault(); 28 | const file = getFile(e.target); 29 | if (!file || file.size < 1) { 30 | alert('请先选择文件'); 31 | return; 32 | } 33 | getCipher(file); 34 | // get file 35 | // convert file 36 | // format xml 37 | } 38 | 39 | const form = document.getElementById('config-form'); 40 | form.addEventListener('submit', onSubmit); 41 | const code = document.getElementById('result'); -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::io::{Read, Write}; 2 | use std::fs::OpenOptions; 3 | use rayon::prelude::*; 4 | 5 | fn main() { 6 | let input = std::env::args().nth(1); 7 | let output = std::env::args().nth(2); 8 | match (input, output) { 9 | (Some(i), Some(o)) => { 10 | xor(i, o); 11 | } 12 | (Some(i), None) => { 13 | let mut o = i.clone(); 14 | o.push_str(".xml"); 15 | xor(i, o) 16 | } 17 | _ => { 18 | println!("missing parameter!"); 19 | println!("usage:"); 20 | println!("\txor input_file output_file"); 21 | } 22 | } 23 | } 24 | 25 | fn xor(i: String, o: String) { 26 | let input_file = OpenOptions::new().read(true).open(i); 27 | if let Err(err) = input_file { 28 | println!("{}", err); 29 | return; 30 | } 31 | let output_file = OpenOptions::new().write(true).create(true).open(o); 32 | if let Err(err) = output_file { 33 | println!("{}", err); 34 | return; 35 | } 36 | if let (Ok(mut input), Ok(mut output)) = (input_file, output_file) { 37 | let mut buf = Vec::new(); 38 | if input.read_to_end(&mut buf).is_err() { 39 | println!("Reading Error!"); 40 | }; 41 | buf.par_iter_mut().for_each(|p| *p ^= 0xff); 42 | if output.write(&buf).is_err() { 43 | println!("Writing Error!"); 44 | }; 45 | } 46 | } 47 | --------------------------------------------------------------------------------