[SHCTF]easyLogin 出题小记

admin 2025年2月6日20:16:28评论2 views字数 3472阅读11分34秒阅读模式

[SHCTF]easyLogin 出题小记

附上源码,感兴趣的师傅可以看看
https://github.com/SHangwendada/SHCTF-easyLogin/tree/main

方法1:

改机APP直接改,梭哈。

方法2:

[SHCTF]easyLogin 出题小记

直接看主体逻辑,其实就是发送了Username以及password还有passticket,username和password都给我们了,但是passticket并没有给我们,因此需要去逆向,首先根据下面Toast的代码告诉了我们这个可能和设备有关,这个时候需要考虑的验证是否新设备是否使用到设备id之类的。

[SHCTF]easyLogin 出题小记

getPassticket注册于easyLogin,那么我们需要使用IDA直接分析easyLogin。

这里我的设备为Arm64 因此我分析的为arm64-v8a,(注意不同设备接下来的操作可能不尽相同,但是原理逻辑基本一致)。

函数列表中没有发现Jni_Onload,可以确定为静态注册,静态注册直接搜索函数名字就好了:

[SHCTF]easyLogin 出题小记

这里需要注意参数类型变换,可能需要手动更改:

[SHCTF]easyLogin 出题小记

[SHCTF]easyLogin 出题小记

可以发现这里有输出Device ID的字样。

[SHCTF]easyLogin 出题小记

那么根据提示,我们的主要目标就是替换掉这个device id。

查看一下数据包:

[SHCTF]easyLogin 出题小记

可以发现passticket上传的并不是设备id,二十哈希之后的设备id,并且显然不是md5值。

这个时候要么分析这个passticket 要么 复现这个哈希算法。

[SHCTF]easyLogin 出题小记

看到这里基本也不会有想去逆向哈希算法的思路了。

只有调试或者FridaHook了,但是程序存在hook检测。

主要看init Array段中的一些内容:

[SHCTF]easyLogin 出题小记

创建了两个线程:

[SHCTF]easyLogin 出题小记

检测IDA的我们不用看,直接撸检测frida的:

[SHCTF]easyLogin 出题小记

比较了本地和系统的libc中 signal 的前8个字符是否一致,不一致则认为被hook,这里hook点可以在v13==v12。

[SHCTF]easyLogin 出题小记

修改他们的比较结果即可,这里值的注意的是由于时机问题可以直接hook pthread_create来hook这个点位。

function passAnti1() {
Interceptor.attach(Module.getExportByName(null, "pthread_create"), {
onEnter: function (args) {
this.funAddr = args[2];
var instruction = Instruction.parse(this.funAddr.add(0x2b4));
if (instruction.mnemonic === "cmp") {
Interceptor.attach(this.funAddr.add(0x2b4), {
onEnter: function (args) {
this.context.x25 = this.context.x24;
}
});
}
},
onLeave: function (retval) {

console.log("pthread_create returned");
}
});
}

或者重定向fread:

function hook_memcmp_addr() {
//hook反调试
var memcmp_addr = Module.findExportByName("libc.so", "fread");
if (memcmp_addr !== null) {
// console.log("fread address: ", memcmp_addr);
Interceptor.attach(memcmp_addr, {
onEnter: function (args) {
this.buffer = args[0]; // 保存 buffer 参数
this.size = args[1]; // 保存 size 参数
this.count = args[2]; // 保存 count 参数
this.stream = args[3]; // 保存 FILE* 参数
},
onLeave: function (retval) {
// console.log(this.count.toInt32());
if (this.count.toInt32() == 8) {
Memory.writeByteArray(this.buffer, [0x50, 0x00, 0x00, 0x58, 0x00, 0x02, 0x1f, 0xd6]);
retval.replace(8); // 填充前8字节
// console.log(hexdump(this.buffer));
}
}
});
} else {
console.log("Error: memcmp function not found in libc.so");
}
}

最后我们的脚本还需要注意时机,这里给出完整的重定向的代码:

function hook_memcmp_addr() {
var memcmp_addr = Module.findExportByName("libc.so", "fread");
if (memcmp_addr !== null) {
Interceptor.attach(memcmp_addr, {
onEnter: function (args) {
this.buffer = args[0];
this.size = args[1];
this.count = args[2];
this.stream = args[3];
},
onLeave: function (retval) {
if (this.count.toInt32() == 8) {
Memory.writeByteArray(this.buffer, [0x50, 0x00, 0x00, 0x58, 0x00, 0x02, 0x1f, 0xd6]);
retval.replace(8);
}
}
});
} else {
console.log("Error: memcmp function not found in libc.so");
}
}

function NativeHook() {
var base = Module.getBaseAddress("libeasylogin.so");
console.log("[Base]->", base);

Interceptor.attach(base.add(0x1F250), {
onEnter: function (args) {
try {
var originalStr = this.context.x0.readCString();
console.log("Original x0:", originalStr);
var newValue = "a24256ec5983b4a8";

if (newValue.length <= originalStr.length) {
Memory.writeUtf8String(this.context.x0, newValue);

console.log("Modified x0:", this.context.x0.readCString());
} else {
console.warn("New string is longer than the original. Skipping write to avoid overflow.");
}
} catch (e) {
console.error("Error modifying x0 content:", e);
}
}
});
}

function Hookdlopenext() {
hook_memcmp_addr();
var dlopen = Module.findExportByName(null, "android_dlopen_ext");
Interceptor.attach(dlopen, {
onEnter: function (args) {
var filePath = args[0].readCString();
console.log("[android_dlopen_ext] -> ", filePath);
if (filePath.indexOf("libeasylogin") != -1) {
this.isCanHook = true;
}
}, onLeave: function (retValue) {
if (this.isCanHook) {
this.isCanHook = false;
NativeHook();
}
}
})
}

setImmediate(Hookdlopenext);

本题没有标准解,师傅们可以打开思维,需求更多的破解方式,体会Re的乐趣。

[SHCTF]easyLogin 出题小记

看雪ID:Shangwendada

https://bbs.kanxue.com/user-home-979679.htm

*本文为看雪论坛优秀文章,由 Shangwendada 原创,转载请注明来自看雪社区

原文始发于微信公众号(看雪学苑):[SHCTF]easyLogin 出题小记

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月6日20:16:28
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   [SHCTF]easyLogin 出题小记http://cn-sec.com/archives/3706257.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息