工具名叫CyberChef,包含了常见的文本、压缩、代码格式化、网络请求、加解密、证书和秘钥、编解码等功能。项目的自我介绍:The Cyber Swiss Army Knife – a web app for encryption, encoding, compression and data analysis。

github地址:https://github.com/gchq/CyberChef
在线地址:https://gchq.github.io/CyberChef
在线地址2:https://icyberchef.com/

下面是几个简单的演示:

  • 1. 将一段文本进行BASE64编码;
  • 2. 计算文件MD5;
  • 3.1. 对文本进行流水线批处理(Hack一个游戏存档)
  • 3.2. 更复杂的流程(查看实时天气)

1. 将一段文本进行BASE64编码

网页的主界面有四个区域,左侧是操作列表工具箱;中间一栏是数据加工流程的编排界面,从左侧挑选需要的操作并按设想的顺序组织出一条流水线,点击下面的BAKE按钮可以执行批处理任务,也可以勾选Auto Bake,这样页面会在有任何修改的时候自动执行处理任务;右侧上方是输入框(支持文本输入和文件输入),右侧下方是输出框。

2. 计算MD5,支持上传文件作为输入

3.1 文本内容流水线处理(批处理命令)

先介绍一个网页版的放置游戏:https://static.oschina.net/trytry/cityinc 。

这个游戏的流程是购买不同的建筑进行生产,更高级的建筑每次生产需要的耗时更长,收益可以用来购买各种建筑的加速包,也可以用来购买更多数量的建筑。游戏本身虽然非常无聊,但因为它的存档文件是一套JSON,支持游戏进度导出和导入,用来做演示和验证非常方便直观。下面借助Hack这个游戏的过程来介绍CyberChef的工作流编排。

首先是它的游戏记录,导出的时候会得到一串BASE64编码内容,所以先从添加一个 From Base64操作(步骤1)开始。

网页中提到的兼容代码,在解码过这段BASE64内容以后,可以发现就是一个简单的url encode处理,所以接下来就是url decode操作(添加 URL Decode,操作2)

看得出来,这是一份包含了所有游戏数据的json格式存档,为了便于查看可以临时美化一下,等后面实际用的时候删掉(添加一条Json Beautify,属于Code dity分类)。

这个存档里的键名含义比较好猜。游戏里一共有10类建筑,保存在key名为build的数组里,每个build对象包含了数量(num)、收益倍率(multiplier)、生产速度倍率(speedMultiplier)、当前生产进度(curPercent)、是否在生产(inProgress)、是否自动生产(auto)、下次奖励的达成条件(nextGoal)、总收益占比(curRevenue)。

build数据修改如下(全部都是正则文本替换,第1, 2, 4, 5都是一次性设置即可,第3条可以重复设置,代表跳过本轮生产过程直接完成生产):

1. 每个建筑数量均改为200(动作3)

2. 全部自动生产(动作4,false改true)

3. 生产进度改为99.99%,让生产在下一秒瞬间完成(动作5)

4. 500倍建造加速(动作6,这两处修改可以使用相同的查询词)

5. 500倍收益倍率(动作6,这两处修改可以使用相同的查询词)

然后是存档里的happiness对象,包含了支持率数据,游戏设定超过80%支持率可以得到额外的收益,但是会随着时间往下掉,也改成99.99%(动作7,可以每次都修改成99.99%,维持在最高支持率)。

存档里的settings对象包含了CityName,改个新名字就叫The Citadel(动作8,也是一次性修改操作),并且打开城市名字的修改按钮(动作9)。

curMoney猜测代表的是当前账户余额,改成10亿(动作10)。

curCitizen代表当前人口,不知道有什么用,为了演示改成10000(动作11)。

以下是修改之前的数据:

存档改完以后还需要转成游戏支持的存档格式,所以添加url encode(动作12),和To Base64(动作13),最终就得到了可以直接导入的存档文本(把临时添加的json美化删掉)。

使用流程:

1. 切换到游戏的设置界面,复制当前存档文本;

2. 粘贴到CyberChef的Input框中,复制Output中的任务结果;

3. 返回游戏,粘贴到“导入”文本框,点击“导入”。

最终效果

借助CyberChef工具,一行代码都不用写,很轻松就能把数据按要求处理完成。

作为对比,下面是实现这套流程的代码(其实也不复杂):


if (txtInput.TextLength < 1) return;

//base64转文本,结果是url encode,需要urldecode一下
string strUrlEncode = Encoding.ASCII.GetString(Convert.FromBase64String(txtInput.Text));
string plain = HttpUtility.UrlDecode(strUrlEncode);

//建筑数量
string result = Regex.Replace(plain, "(?<=\"num\":)\\d+", "200");

//自动生产
result = Regex.Replace(result, "(?<=\"auto\":)false", "true");

//本轮生产进度
result = Regex.Replace(result, "(?<=\"curPercent\":)[0-9.]+", "99.9999");

//所有倍率数值改为500倍
result = Regex.Replace(result, "(?<=ultiplier\":)[0-9.]+", "500");

//支持率改满100%
result = Regex.Replace(result, "(?<=\"sliderValue\":)[0-9.]+", "99.9999");

//修改城市名字
result = Regex.Replace(result, "(?<=\\\"cityName\\\":\\\")[^\"]+", "The Citadel");

//打开开关,允许修改城市名字
result = result.Replace("\"allowEditCityName\":false", "\"allowEditCityName\":true");

//修改金额为10亿
result = Regex.Replace(result, "(?<=\"curMoney\":)[0-9.]+", "1000000000");

//人口修改为1万人
result = Regex.Replace(result, "(?<=\"curCitizen\":)\\d+", "10000");

string strEncodeOut = HttpUtility.UrlEncode(result);
string output = Convert.ToBase64String(Encoding.ASCII.GetBytes(strEncodeOut));

3.2 获取当地的实时天气

思路:根据IP地址查询归属地,根据归属地调用天气预报接口,数据提取和展示。

需要提前说明一下:Register捕获的是正则表达式组,可以将每个希望捕获的内容都拆成单独的Register,也可以合并写到一个表达式里。下面的示例中,因为省份和城市固定是一前一后的顺序所以合在了一起,其它变量因为不能确定先后顺序,所以单独写对应的正则表达式组。

(1). HTTP Request,先查自己的IP地址
Method: Get, URL: https://chenxin.info/ip

(2). Register,把上一步的结果保存到变量R0
表达式:([\s\S]*) 得到变量R0,保存的是IP地址。

(3). HTTP Request,调用高德的接口,根据IP查看归属地,其实这个接口不传ip的话可以直接返回归属地,为了演示功能,特地做了(1)(2)两步多余的操作。
Get,https://restapi.amap.com/v3/ip?ip=$R0&output=json&key=1c2f4efa377e93ed8448f8b86223c937 

(4). Register,从(3)的结果里提取城市代码adcode
表达式:(?<=\”adcode\”:\”)(\d+) 得到变量R1,保存的是城市代码

(5). HTTP Request,调用高德的接口,根据城市代码查询实时天气
Get, https://restapi.amap.com/v3/weather/weatherInfo?city=$R1&key=1c2f4efa377e93ed8448f8b86223c937

(6). Register, 提取省份保存到R2变量,城市保存到R3变量
表达式:(?<=\”province\”:\”)([^”]+)\”,\”city\”:\”([^”]+)\” 

(7). Register, 提取天气,保存到R4变量
表达式:(?<=weather\”:\”)([^”]+)

(8). Register,提取温度,保存到R5变量
表达式:(?<=temperature\”:\”)(\d+)

(9). Register, 提取湿度,保存到R6变量
表达式:(?<=humidity\”:\”)(\d+)

(10). Register, 提取风向,保存到R7变量
表达式:(?<=winddirection\”:\”)([^”]+)

(11). Register,提取风力,保存到R8变量
表达式:(?<=windpower\”:\”)([^”]+)

(12). Register,提取时间,保存到R9变量
表达式:(?<=reporttime\”:\”)([^”]+)

(13). Find / Replace,采用查找全部内容,并且替换成按格式拼接的文本的方式输出最终结果
Find:.+
Replace:我的IP: $R0\r\n所在地:$R2 $R3 实时天气:\r\n$R4, $R5 度, 湿度 $R6%\r\n风向风力: $R7 风 $R8 级\r\n汇报时间: $R9

最后再加点料,整点活

(14). Base64编码
(15). gzip压缩
(16). ToHex
(17). 字节数组反序
(18). 将上一步得到的字节数组作为像素点转成灰度Bitmap(彩色图片要求字节长度是通道数的整倍数,RGB3倍,ARGB4倍,诸如此类),最终就得到了加密过的天气预报信息。祝大家玩得开心。

分类: articles