星 - 逆向
type: channel
link: https://blog.hoshi.tech/tag/%E9%80%86%E5%90%91/
items: Nikke拆包解密记录
items: 记录Hackergame 2022参与经历
items: 记录下初次参加CTF的经历 - Hackergame 2021
items: 解密明日方舟的数据信息 - 远古版本0.7.8
items: 提取宝石研物语的Live2D - 远古1.0版本
items: 尝试修复iOS ArcaeaCountdownScore - 版本3.6.0

Nikke拆包解密记录
type: item
date: 2022-11-09T06:26:00+00:00
description: 0x0 背景最近一个新二游Nikke正式开服了，由于某种原因在各群各站传的沸沸扬扬。玩这个游戏的冲什么来懂得都懂，实际玩了一下后发现也就只有模型和剧情值得一览。这不得解解包，四舍五入通下关。主要文章是分析完之后补写，实际分析过程是动调静态一起上的。0x1 寻找解密方法查看AssetBundle可以发现Header被修改。正常应该为UnityFS + 1 byte版本号 + 5.x.x.2021.3.9f1 + 2 bytes AB大小等。而Nikke修改后的Header为NKAB + 不明 + GoddessofVictory等。且观察发现并非简单的将信息移动，那就需要分析看看了。起手il2cppdumper后直接在dump.cs中搜索关键词NKAB就能够定位到相关方法，这个字符串在类名中包含，并且很贴心的只出现了一次：// Namespace: UnityEngine.ResourceManagement.ResourceProviders internal enum NKBundleEncryptionMode // TypeDefIndex: 25907 { // Fields public ushort value__; // 0x0 public const NKBundleEncryptionMode Default = 0; } // Namespace: UnityEngine.ResourceManagement.ResourceProviders public class NKABStreamProcessorWithSeek : IDataConverter // TypeDefIndex: 25908 { public Stream CreateReadStream(Stream input, string id) { } public Stream CreateWriteStream(Stream input, string id) { } public void .ctor() { } } // Namespace: UnityEngine.ResourceManagement.ResourceProviders internal class NKAssetBundleStream : Stream // TypeDefIndex: 25909 { // Fields [CompilerGenerated] private readonly Stream <baseStream>k__BackingField; // 0x28 [CompilerGenerated] private readonly NKBundleHeader k__BackingField; // 0x30 [CompilerGenerated] private readonly Aes <AES>k__BackingField; // 0x38 [CompilerGenerated] private ICryptoTransform <transform>k__BackingField; // 0x40 [CompilerGenerated] private byte[] <encryptedBuffer>k__BackingField; // 0x48 [CompilerGenerated] private byte[] <plainBuffer>k__BackingField; // 0x50 [CompilerGenerated] private readonly string <Name>k__BackingField; // 0x58 [CompilerGenerated] private bool <Disposed>k__BackingField; // 0x60 // Properties protected Stream baseStream { get; } public NKBundleHeader Header { get; } protected Aes AES { get; } protected ICryptoTransform transform { get; set; } protected byte[] encryptedBuffer { get; set; } protected byte[] plainBuffer { get; set; } protected string Name { get; } protected bool Disposed { get; set; } public override bool CanRead { get; } public override b…

记录Hackergame 2022参与经历
type: item
date: 2022-10-29T05:49:00+00:00
description: 0x0 背景弃坑Arcaea一年多了，周六还是偶然打开某arc群时还是发现几个大佬在发 Hackergame 2021排名截图。真巧，今年也来玩一玩。不过现在变身成为打工人后空闲时间只顾着咸鱼了，花了一上午挑了一些简单的题目做完后直接摆烂了......0x1 题目签到众所周知本题应该不难，上来是需要在限定时间内手写2022并通过识别后提交。打开HTML源码看到是Vue写的，第一时间就是修改时间限制。但往下翻翻发现提交函数直接拼接了识别结果。果然还是想难了.....随便提交一个结果后将传参改为?result=2022即可。flag{HappyHacking2022-1a3d895fa6}猫咪问答 Pro Max参考历年题目，考察信息搜索能力。中国科学技术大学 NEBULA 战队（USTC NEBULA）是于何时成立的喵？直接Google搜索USTC NEBULA成立时间得知为2017-03。2022 年 9 月，中国科学技术大学学生 Linux 用户协会（LUG @ USTC）在科大校内承办了软件自由日活动。除了专注于自由撸猫的主会场之外，还有一些和技术相关的分会场（如闪电演讲 Lightning Talk）。其中在第一个闪电演讲主题里，主讲人于 slides 中展示了一张在 GNOME Wayland 下使用 Wayland 后端会出现显示问题的 KDE 程序截图，请问这个 KDE 程序的名字是什么？Google LUG @ USTC GNOME Wayland 可找到并下载Slides，截图在第15页，注意一条菜单项叫Configure Kdenlive，那程序名就很明显了。22 年坚持，小 C 仍然使用着一台他从小用到大的 Windows 2000 计算机。那么，在不变更系统配置和程序代码的前提下，Firefox 浏览器能在 Windows 2000 下运行的最后一个大版本号是多少？Google Windows 2000可得12你知道 PwnKit（CVE-2021-4034）喵？据可靠谣传，出题组的某位同学本来想出这样一道类似的题，但是发现 Linux 内核更新之后居然不再允许 argc 为 0 了喵！那么，请找出在 Linux 内核 master 分支（torvalds/linux.git）下，首个变动此行为的 commit 的 hash 吧喵！找到此仓库torvalds/linux: Linux kernel source tree (github.com)并搜索CVE-2021-4034可得dcd46d897adb70d63e025f175a00a89797d31a43通过监视猫咪在键盘上看似乱踩的故意行为，不出所料发现其秘密连上了一个 ssh 服务器，终端显示 ED25519 key fingerprint is MD5:e4:ff:65:d7:be:5d:c8:44:1d:89:6b:50:f5:50:a0:ce.，你知道猫咪在连接什么域名吗？直接GoogleMD5:e4:ff:65:d7:be:5d:c8:44:1d:89:6b:50:f5:50:a0:ce可以在第二页找到ssh.log — Book of Zeek (git/master)此页面。在#outbound-movement中可发现连接的IP地址为205.166.94.16。直接访问看邮箱域名可得sdf.org。中国科学技术大学可以出校访问国内国际网络从而允许云撸猫的“网络通”定价为 20 元一个月是从哪一天正式实行的？Google中国科学技术大学 网络通 20元可以找到关于实行新的网络费用分担办法的通知-中国科学技术大学 (ustc.edu.cn)此页面。得知旧的费用分担办法已经为20元一个月。使用关键词网络费用分担办法的通知 2003年在Google没搜到结果，百度居然给了结果关于实行新的网络费用分担办法的通知 (ustc.edu.cn)。由文件可知2003-03-01flag1：flag{meowexammeow_772b498346fe0925_1e02f422c8}flag2：flag{meowexamfullymeowed!_6c159adddb7f171b_8f2fb889d9}家目录里的秘密用过rclone，知道配置文件默认在.config下，翻了下发现Code也在这个目录，一顿翻找找到user\.config\Code\User\History\2f23f721\DUGV.c文件。这才知道原来VSCode有保存历史文件。然后想到直接全文检索flag其实更容易定位到......说回rclone，此前尝试写世纪互联版OneDrive的实现时有研究过rclone。知道rclone将明文密码”加密“后保存。这次打开配置文件后可以看出ft…

记录下初次参加CTF的经历 - Hackergame 2021
type: item
date: 2021-10-29T18:24:00+00:00
description: 0x0 背景弃坑Arcaea一段时间了，在Hackergame 2021结束的最后两天偶然打开某arc群时发现几个大佬这几天隔段时间就往群里丢一张分数及排名截图，翻翻记录发现某张图上截到了 Hackergame 2021的字样。搜了搜是中国科学技术大学第八届信息安全大赛，卧槽，看起来非常有趣。那么菜鸡空闲时间里的第一次安全游戏之旅就开始了...还是怀念大学时的空闲时间啊，可以花时间边学边解。现在只能等下班后挤出点时间解题了，加入又太晚，只能挑很容易看出头绪的 - 即人数多的题目解答了。0x1 题目签到打开题目我是一脸懵逼的，意味わかんない。万幸官方有提示参考历年签到题，挨个看了看都是提交某个值获取到某个flag，再看看QA才知道游戏玩法。结合题意和返回的时间可知页数跟字符串有关。Hackergame 2021 比赛进行期间的任何一页获取当前时间的Timestamp转到对应页即可。flag{HappyHacking2021-0af061d136}进制十六——参上阅读完文字觉得老哥们个个都是人才，说话又有趣......看图答题，抹掉区域的十六进制对应回ASCII即可flag{Y0U_SH0U1D_kn0w_H0W_t0_C0nv3rt_HEX_to_TexT}去吧！追寻自由的电波北约音标字母 - 维基百科，自由的百科全书 (wikipedia.org)其实我是用Potplayer慢放听了好一会儿才听出来，我也知道是因为现代的播放器自动保持声调导致的，但是懒得开au降调，硬是听出来了。直到后来水群的时候，发现关闭声音滤镜就不会保持声调了，才知道是真的好听。flag{phoneticab}猫咪问答 Pro Max第一题2017 年，中科大信息安全俱乐部（SEC@USTC）并入中科大 Linux 用户协会（USTCLUG）。目前，信息安全俱乐部的域名（sec.ustc.edu.cn）已经无法访问，但你能找到信息安全俱乐部的社团章程在哪一天的会员代表大会上通过的吗？看到域名已经无法访问第一反应就是去Wayback Machine (archive.org)找，输入链接打开跳转到主页就能找到社团章程链接打开，第一行就是通过日期。第二题中国科学技术大学 Linux 用户协会在近五年多少次被评为校五星级社团Google 中国科学技术大学 Linux 用户协会 五星级社团 第一条官方简介里就提到了为了表彰其出色表现，协会于 2011 年 5 月被评为中国科学技术大学优秀学生社团，于 2012 年 5 月、2013 年 5 月及 2014 年 5 月分别被评为中国科学技术大学四星级学生社团，并于 2015 年 5 月、2017 年 7 月、2018 年 9 月、2019 年 8 月及 2020 年 9 月被评为中国科学技术大学五星级学生社团。值得一提的是，居然还搜到了一个相关知乎问题中国科学技术大学 Linux 用户协会在近五年多少次被评为校五星级社团？ - 知乎 (zhihu.com)，这位童鞋企图请求场外援助可还行。第三题「中国科学技术大学 Linux 用户协会位于西区图书馆的活动室门口的牌子上“LUG @ USTC”下方的小字是？」直接Google中国科学技术大学 Linux 用户协会 西区图书馆翻翻看有官方发布的新闻，标题为西区图书馆新活动室启用。第四题「在 SIGBOVIK 2021 的一篇关于二进制 Newcomb-Benford 定律的论文中，作者一共展示了多少个数据集对其理论结果进行验证？」Google sigbovik 2021 newcomb-benford即可找到PDF，下载后找到对应文章，作者有提到We converted all ofthe data points to their binary representations, and plottedthe relative frequency of the leading digits. The figures areshown in Figs. 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, and 14in the appendix4.数一数即得到答案。第五题「不严格遵循协议规范的操作着实令人生厌，好在 IETF 于 2021 年成立了 Protocol Police 以监督并惩戒所有违背 RFC 文档的行为个体。假如你发现了某位同学可能违反了协议规范，根据 Protocol Police 相关文档中规定的举报方法，你应该将你的举报信发往何处？」根据题意Google IETF Protocol Police report找到rfc8962，下翻找到Reporting OffensesSend all your reports of p…

解密明日方舟的数据信息 - 远古版本0.7.8
type: item
date: 2021-07-19T15:02:00+00:00
description: [scode type="red"]免责声明：本文仅为博主安全研究学习记录，强烈反对参考本文内容进行不正当用途，包括但不限于作弊行为等。请后果自负。[/scode][scode type="yellow"]此文为补写，意为记录，重新分析也是用回远古版本安装包，应该已不适用于目前版本游戏[/scode]0x0 背景2019年5月跟着群友入坑了明日方舟（于2019年11月左右弃坑），顺手拆了CG和立绘（Perfare佬yyds）。后来突发奇想想做个多游戏抽卡模拟器（剧透：咕了）。素材已经到位，接着就是卡池数据了，得想个办法拆出游戏数据，总不能期期手动跟进卡池更新吧？于是说干就干，打开资源文件夹，发现在\AB\Android\gamedata\excel目录下有gacha_table.ab文件，这就是卡池数据了。丢进AssetStudio，点开gacha_table就发现全是看不懂的数据，导出后为gacha_table.bytes。没办法，只能分析下是怎么解密数据的了。注：本文为补写，按照回忆重新开始分析，与文中不同的时当时是直接搜索加密相关关键词直接找到几个解密类Hook的。0x1 寻找解密方法游戏基于UnityEngine引擎且使用了il2cpp。按部就班掏出Il2CppDumper加载libil2cpp.so及assets\bin\Data\Managed\Metadata\global-metadata.dat，然后丢IDA分析并加载dump出的IDA python脚本。（值得一提（？）的是，ARM和ARMv7架构对应lib中libil2cpp.so是完全相同的。仅有少量第三方库存在差异。）与此同时使用dnSpy加载dump出的dummy dll寻找到可疑目标类Torappu.GachaDB，其继承自Torappu.DB.ConstTable -> SingletonAbstractTable -> AbstractTable。跳转到Torappu.DB，好家伙，疑似3个加解密方法：第一个应是Json密文的序列化及反序列化、第二个是很明显的AES加解密，第一次接触RijndaelManaged类还是在崩坏学园2里、而第三个看着像是基于随机种子的加解密。查看DBLoader.LoadTable()方法，伪代码：int __fastcall DBLoader__LoadTable(int a1, _DWORD *abstractTable) { int v3; // r1 int result; // r0 int isProdMode; // r0 int *tableConfig; // r1 int converter; // r5 int v8; // r0 int v9; // r0 if ( !byte_3023ECE ) { sub_26B1D18(15387); byte_3023ECE = 1; } if ( !abstractTable ) goto LABEL_13; v3 = (*(int (__fastcall **)(_DWORD *, _DWORD))(*abstractTable + 212))( abstractTable, *(_DWORD *)(*abstractTable + 216)); result = 1; if ( v3 ) return result; isProdMode = AbstractTable__get_isProdMode(1); tableConfig = abstractTable + 3; if ( isProdMode ) tableConfig = abstractTable + 4; if ( !*tableConfig ) { LABEL_13: v9 = ((int (*)(void))loc_26E73D0)(); return CryptUtils__CalculateMD5FromFileOrEmpty(v9); } converter = ConverterFactory__Create(*tableConfig, *(_DWORD *)(*tableConfig + 20)); v8 = Class_Torappu_DB_DBLoader; if ( (*(_BYTE *)(Class_Torappu_DB_DBLoader + 178) & 1) != 0 && !*(_DWORD *)(Class_Torappu_DB_DBLoader + 96) ) v8 = il2cpp_runtime_class_init_0(); return DBLoader___DoLoadTable(v8, abstractTable, converte…

提取宝石研物语的Live2D - 远古1.0版本
type: item
date: 2021-07-18T05:44:00+00:00
description: [scode type="yellow"]此文为补写，意为记录，已不适用于目前版本游戏[/scode]0x0 故事那是2017年... 突然两张GIF刷爆了我加的多个群组。 大伙们都是LSP了，看到这哪还顶得住，纷纷开始寻找原游戏出处。然后发现是TapTap中还未上架的游戏《宝石研物语》，这还不得感觉关注一波？于是游戏关注度飞涨。然后...不太妙的感觉...不过不碍事，游戏关注持续增加。一直到上线后一度挤爆服务器，后续多天也经常维护。至于玩家们最关注的Live2D，则不出意外的惨遭和谐，掀裙子的动画直接消失了。这哪能忍，那么就尝试看看资源文件，是否真的删掉了动画还是仅不播放此动画了。0x1 资源解密解压安装包，assets\res\下有live2d文件夹。好耶，点开模型配置文件model.json！...坏耶，被加密了，再看看动作文件，贴图文件等，发现全部被加密，且文件头为都为gemtrade。结合这游戏是Cocos2d-Lua开发的，盲猜一波是xxtea加密（?）。掏出IDA，加载libcocos2dlua.so，定位到cocos2d::FileUtils::getDataFromFile（），伪代码：cocos2d::Data *__fastcall cocos2d::FileUtils::getDataFromFile(cocos2d::Data *a1, cocos2d::FileUtils *a2, int a3, _BYTE *a4) { int v8; // r2 int v10[8]; // [sp+0h] [bp-20h] BYREF cocos2d::Data::Data(a1); v8 = *(_DWORD *)a2; v10[1] = (int)a1; v10[0] = (int)off_CD734C60; (*(void (__fastcall **)(cocos2d::FileUtils *, int, int *))(v8 + 28))(a2, a3, v10); if ( !cocos2d::Data::isNull(a1) ) *a4 = cocos2d::FileUtils::decodeData(a2, a1); return a1; }发现多了一个FileUtils::decodeData()方法，那么它应该就是目标了，此方法中调用FileUtils::decodeBuffer()紧接着FileUtils::decodeXOR()，伪代码：char *__fastcall cocos2d::FileUtils::decodeXOR(cocos2d::FileUtils *this, unsigned __int8 *a2, int a3, int *a4) { unsigned int v8; // r4 int v9; // r5 int v10; // r8 int v11; // r0 unsigned int v12; // r6 unsigned int v13; // r8 unsigned int v14; // r10 unsigned int v15; // r5 char *v16; // r11 int v17; // r0 __int16 v18; // r12^2 char *v19; // r3 unsigned int v20; // r0 unsigned int v21; // r2 if ( a3 <= 19 ) return 0; v8 = memcmp(&unk_CD6C15E8, a2, 8u); if ( v8 ) return 0; v9 = cocos2d::FileUtils::char2uint(this, a2, 8); v10 = cocos2d::FileUtils::char2uint(this, a2, 12); v11 = cocos2d::FileUtils::char2uint(this, a2, 16); v12 = (unsigned int)(v11 + v10) >> 1; v13 = (unsigned int)(v10 - v11) >> 1; v14 = a3 - 20; *a4 = v14; v15 = v9 - v12 * v13; v16 = (char *)malloc(v14); memcpy(v16, a2 + 20, v14); while ( 1 ) { v17 = cocos2d::FileUtils::char2uint(this, (unsigned __int8 *)v16, v8); v18 = HIWORD(v17) ^ HIWORD(v15); v16[v8] = v17 ^ …

尝试修复iOS ArcaeaCountdownScore - 版本3.6.0
type: item
date: 2021-07-17T10:11:00+00:00
description: [scode type="yellow"]本文于完成2个月后凭回忆补写并重新配图，且博主并未学过C系语言，难免会有错漏，请见谅[/scode][scode type="lblue"]博主使用设备为iPad Pro 10.5（2017）架构为ARM64，文中所有修改都针对ARM64[/scode][scode type="red"]免责声明：本文禁止转载，仅为博主安全研究学习记录，强烈反对参考本文内容进行不正当用途，包括但不限于作弊行为等。请后果自负。[/scode]0x0 前言由大佬 esterTion 编写的iOS插件 ArcaeaCountdownScore 用于lowiro制作的音游Arcaea。此插件的作用是将游戏分数计算改为倒计分制，即开局满分，产生每个far或者lost时分数递减。这种计分制度对我这种菜鸡即为有用，可以更容易的提前许多预估出本局打歌是否可以达到理想的分数并选择继续还是重试。而616截止至目前（写文时3.6.4）都没有推出具有此功能的搭档。不幸的是，插件在很久前就失效了，表现为什么反应都没有，而鸽王一直都没有更新，我也一直在等待。此时的我并未加入任何音游相关的群组。直至616推出了3.6.0版本更新，此版本中在请求头中新增了X-Random-Challenge字段来验证请求，与此相关的代码逆出来看着简直像一坨shit。于是我想尝试加入一些音游群组向大佬们取经。进入一些群组后才发现原来 esterTion已然弃坑许久（具体原因可参见其B站动态），那么大佬们不再维护ArcaeaCountdownScore，就只能自己撸起袖子上了。。。小知识：616在iOS 3.6.0版本请求头中同时也加入了X-Client-Certificate-Subject-CN以及EnableObfuseCheck，而安卓则在后续版本中加入趣事：616在iOS 3.6.0版本中意外（？）打包进了Algo.zip0x1 方法注入拿到 ArcaeaCountdownScore 源码后首先看看hook的方法：ArcUtil_calculateScore = (unsigned long)MSFindSymbol(NULL, "__ZN7ArcUtil14calculateScoreEiiiii");::aru:blood2:: 怪不得没有任何反应了，iOS二进制文件中已经没有了符号，插件无从找起，方法都没有被替换，当然什么反应都没有了。那么当务之急就是找到新的方法位置进行hook。iOS中没有符号了，那么掏出安卓版3.6.0的二进制想办法对比定位。找到ArcUtil::calculateScore()，然后按x寻找其xref引用，可见一堆调用了calculateScore()的方法。接下来就是在这些方法中找出可以用于在iOS二进制中搜索的信息，由于我之前就有看过OnlineManager::submitScoreInternal()方法，并且此方法中也调用了calculateScore()，所以直接选择从此方法入手。伪代码： v133 = std::string::append((int)&v550, "&score=", 7u); v134 = *(_OWORD *)v133; v553 = *(void **)(v133 + 16); v552 = v134; *(_QWORD *)(v133 + 8) = 0LL; *(_QWORD *)(v133 + 16) = 0LL; *(_QWORD *)v133 = 0LL; v135 = (std::__ndk1 *)ArcUtil::calculateScore( (ArcUtil *)*(unsigned int *)(a4 + 32), *(_DWORD *)(a4 + 28), *(_DWORD *)(a4 + 24), *(_DWORD *)(a4 + 20), *(_DWORD *)(a4 + 28) + *(_DWORD *)(a4 + 32) + *(_DWORD *)(a4 + 24), *(_BYTE *)(a4 + 132)); std::to_string(v135, v136);可以看到调用calculateScore()方法前有个字符串拼接，其中部分字符串为&score=，那么就可以在iOS的二进制中搜索此字符串：找到后查找其引用进入的即为OnlineManager::submitScoreInternal()方法（如果使用其他引用进行查找发现多个调用，则需要对比找到其在iOS中对应方法），伪代码： v72 = std::string::append(&v328, "&score="); v73 = *(_OWORD *)v72; v331 = *(_QWO…