吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8317|回复: 101
收起左侧

[Web逆向] 【嶺上開花】油猴实战劫持人脸识别

    [复制链接]
李恒道 发表于 2023-1-8 02:29
本帖最后由 李恒道 于 2023-1-8 02:45 编辑

感谢
感谢涛之雨大佬在我失恋的日子里看我特别痛苦所以用我的支付宝花呗请我吃饭
害得我一边忍受失恋的折磨一边打工还上次的日料钱
在此我不得不说一句
码头拎搞吧,给你置办卡地亚,2023,祝我涛神名满天下
前文

其实封包过明显更简单但是我就是要补出来环境
我要魔改出来一个自动答题过人脸的变态考试专版APP
嘿,就是玩
图片.png
目标

某起

开始

首先点击按钮提示 图片.png
直接源代码里搜索一下
图片.png
发现通过m.f判断
因为是webpack打包,往上找m
图片.png
m来自ba39
直接打断往里追或者搜索ba39都可以
找到了函数,前方的n.d是webpack的环境定义头,直接忽略,发现m.f的f来自于i
图片.png
我们继续找i
图片.png
发现i来自763d
继续找763d
发现这个函数的f取决于变量d
图片.png
而d在下方,默认为假,下方有两个赋值d的,一个是函数,一个是直接调用,我们先忽略函数,直接看调用的s

调用一下打个断点往里追
找到了
[JavaScript] 纯文本查看 复制代码
 function s(e) {
            var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}
              , n = arguments.length > 2 ? arguments[2] : void 0;
            o((function(i) {
                i.callHandler(e, t, (function(e) {
                    var t = e;
                    if ("string" == typeof e)
                        try {
                            t = JSON.parse(e)
                        } catch (e) {}
                    n && n(t)
                }
                ))
            }
            ))
        }

e是调用事件名,t是变量,n是回调函数
我们调用了o来回调执行函数,那我们去看看o
[JavaScript] 纯文本查看 复制代码
        function o(e) {
            if (window.WebViewJavascriptBridge)
                e(window.WebViewJavascriptBridge);
            else if (i()) {
                if (window.WVJBCallbacks)
                    return window.WVJBCallbacks.push(e),
                    !1;
                window.WVJBCallbacks = [e];
                var t = document.createElement("iframe");
                t.style.display = "none",
                t.src = "wvjbscheme://__BRIDGE_LOADED__",
                document.documentElement.appendChild(t),
                setTimeout((function() {
                    document.documentElement.removeChild(t)
                }
                ), 0)
            } else
                a() && document.addEventListener("WebViewJavascriptBridgeReady", (function() {
                    e(window.WebViewJavascriptBridge)
                }
                ), !1)
        }

这里可以看到在检测各种桥,我们来搞个最基本的
window.WebViewJavascriptBridge吧
调用e(window.WebViewJavascriptBridge);会把我们的函数传进去
去回调
[JavaScript] 纯文本查看 复制代码
                i.callHandler(e, t, (function(e) {
                    var t = e;
                    if ("string" == typeof e)
                        try {
                            t = JSON.parse(e)
                        } catch (e) {}
                    n && n(t)
                }

那我们就需要实现callHandler函数,检测是否是getRuntimeEnvironment
如果是的话就去回调第三个参数,第三个参数是个函数,接受一个e
我们应该传入一个对象
然后会对n传入这个对象
n则是
[JavaScript] 纯文本查看 复制代码
(function(e) {
            d = "app" === e.platform
        }
        )

代表我们传入的对象必须包含platform,并且是app
开始
直接上油猴
[JavaScript] 纯文本查看 复制代码
window.WebViewJavascriptBridge = {
    callHandler: (name, obj, callback) => {
       xxxxx
       防恶意利用删除代码
       balabala

    }
}

就会发现我们已经过了APP功能性检测

目前已经在网页模拟出来了我们的APP环境
我们可以在最后调用标明一个
console.log('遇到未处理的事件'+name+')
来看我们到底需要补什么环境函数和数据
第一个碰到的就是genSign
但是问题来了
网页本身就可以计算sign,难道我们要再使用脚本实现一遍吗?
为什么不开脚本好好的,开了脚本却要自己实现一遍?
我们翻一下堆栈,发现了一个有意思的爆出错误

这里可以看到调用genSign之前设置了一个定时器,到时间就触发一个自定义错误
那上方肯定有一个try函数
往上继续找堆栈,果然找到了

如果调用genSign函数到时还没有返回
就直接触发异常让catch抓到错误然后走原来的网页逻辑
那我们不需要处理genSign,直接在callHandler检测到并且返回一个undefined即可

开始分析摄像头

然后我们分析摄像头触发一下按钮发现调用了examPushSign事件

翻一下堆栈,发现使用了t.image

除此以外一个没动
我们抓个包看看提交的参数是什么%2F9j%2F4AAQSkZJRgABAQEAAQABAAD%2F2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj%2F2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj%2FwAARCAKAAoADASIAAhEBAxEB%2F8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL%2F8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWW
很明显是一个url编码掉的,再解码看看/9j/4AAQSkZJRgABAQEAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAKAAoADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWW这种带/ 数字和连续HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBg的字符,很难不让人联想到是base64转了图片
我们尝试复制粘贴一下
随便找个
https://tool.chinaz.com/tools/imgtobase
然后在这个图片前加个data:image/jpeg;base64,表示是一个base64图片,发现直接解码成功!
那我们基本就理清他的回调逻辑了,油猴上比较简单,我们可以直接打开一个文件选择器,接受图片之后base64掉传回给网页
理论建立完毕
实战开始

补充


其实可以在callHandle里手动触发错误,关于这个的处理方案就当作一个小想法了~因为比较无关紧要

我们继续
当点击按钮触发摄像头拍照后
直接回调文件选择
这里我就干脆封出来一个函数
获取到file对象之后转成base64,去掉前缀,然后回调callback
这里没用promise是因为原来的WebViewJavascriptBridge不是一个async对象,我们保持一致
[JavaScript] 纯文本查看 复制代码
function receivePicture(callback){
    let input=document.createElement('input');
    input.setAttribute('type', 'file');
    input.setAttribute('multiple', 'multiple');
    input.accept="image/*"
    input.addEventListener('change',(e)=>{
        const file=e.target.files[0]
        const reader = new FileReader();
        reader.addEventListener('load', ()=> {
            callback(reader.result.replace('data:image/jpeg;base64,',""))
        });
        reader.readAsDataURL(file);

    })
    input.click()
}

然后直接些对应的调用
收到base64之后包装一下返回去
[JavaScript] 纯文本查看 复制代码
        if(name==='examPushSign'){
            receivePicture(xxxxx)
            return
        }

我们接下来测试一下效果

开始选择文件

顺便来一张极限竞速
图片.png

图片.png


结语

有时候不得不感叹
精神小伙里我代码写的好
程序员里我又是最精神的那一批
属实赢了两拨:赢麻了
撒花~







免费评分

参与人数 42威望 +1 吾爱币 +66 热心值 +40 收起 理由
zuodini + 2 + 1 谢谢@Thanks!
guomanmin + 1 + 1 话说两位大佬能帮我看看有个网站也是要人脸,解决后有奖
RiiiickSandes + 1 + 1 我很赞同!
LuckyDouer + 1 + 1 热心回复!
无敌小王 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
李佑辰 + 1 我很赞同!
wrndlb + 1 + 1 内容的最后一张图挺好,是我的了
jamessteed + 1 + 1 谢谢@Thanks!
jyz5201314 + 1 + 1 用心讨论,共获提升!
笙若 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
yp17792351859 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Koardor + 1 秦始皇摸高压线-嬴麻了!
朕来打江山 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lyhfree92 + 1 + 1 我很赞同!
风烟丶残梦 + 1 + 1 哥哥nb!
极地企鹅 + 1 + 1 我很赞同!
莫奇 + 1 + 1 我很赞同!
逆向学习 + 1 + 1 我很赞同!
baoyanchen + 1 + 1
ct268gh + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
我已经蓝屏 + 1 + 1 热心回复!
lhr349 + 1 + 1 我很赞同!
leweishang + 1 + 1 热心回复!
LightswornSnow + 1 + 1 用心讨论,共获提升!
学习打败高富帅 + 1 + 1 用心讨论,共获提升!
djkzhengjun + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
RuinMirror + 1 + 1 热心回复!
52shuqi + 1 + 1 鼓励转贴优秀软件安全工具和文档!
Arcticlyc + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
78zhanghao87 + 1 我很赞同!
chengdragon + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
白醋柚子茶 + 1 + 1 用心讨论,共获提升!
笨笨家的唯一 + 1 + 1 我很赞同!
sxlixiaoyang + 2 + 1 win-win!~~
zanaa007 + 1 + 1 用心讨论,共获提升!
辰某 + 2 + 1 用心讨论,共获提升!
yyb414 + 1 + 1 热心回复!
sam喵喵 + 1 谢谢@Thanks!
正己 + 4 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
三滑稽甲苯 + 2 + 1 用心讨论,共获提升!
tigerxiao + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
涛之雨 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

涛之雨 发表于 2023-1-8 07:44

写的不错,问一下,
这个对象怎么收到?

列明 发表于 2023-1-8 09:41
涛神问:这个对象怎么收到?
我问:你还发对象么?
我再说:下一个请务必发给我!
 楼主| 李恒道 发表于 2023-1-8 13:57
涛之雨 发表于 2023-1-8 07:44

写的不错,问一下,![]()
这个对象怎么收到?


JS会判断WebViewJavascriptBridge是否存在,然后尝试调用callHandler来使用app功能
我们直接实现一下
window.WebViewJavascriptBridge = {
    callHandler: (name, obj, callback) => {
       xxxxx
       防恶意利用删除代码
       balabala
 
    }
}
就可以接收到网页的各种回调事件
knight0531 发表于 2023-1-8 08:33
这个需要人脸识别才能考试的app真是够差劲的,非得强制认证一下,但是里面的题不还是度娘解决,感觉就是留痕。拜读楼主帖子,受益匪浅,还得抓紧补充知识,要不跟不上楼主步伐......
78zhanghao87 发表于 2023-1-8 14:10
厉害,这种混淆过的代码怎么看懂的?
whg118 发表于 2023-1-8 03:53
加紧学习基础知识了,不然跟不上节奏
fengxu 发表于 2023-1-8 04:55
厉害厉害,请你一下
lvkeqin 发表于 2023-1-8 06:51
软件名:牢底坐穿。很刑
nmkj888 发表于 2023-1-8 07:33
流弊Plus,比修改摄像头底层协议,用视频图片替换还牛
Helsing9527 发表于 2023-1-8 07:39
我靠,向大佬致敬
ct268gh 发表于 2023-1-8 08:21
本帖最后由 ct268gh 于 2023-1-8 08:23 编辑

是chinaedu那个吗,想看看大佬的自动答题怎么做的
danding 发表于 2023-1-8 08:25
这个可不可以逆向思维干票大的
tzblue 发表于 2023-1-8 08:32
劫持人脸识别……
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-25 14:26

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表