基于百度OpenRasp的插桩浅析

渗透技巧 2年前 (2022) admin
782 0 0

点击蓝字 关注我们

前言


上一次,我们对以ASM为基础的RaspDemo进行了分析学习。由浅入深,这一次我们以百度的OpenRasp作为样例,继续探究学习RASP这一领域。

前文链接:

记一次RASP Demo分析 (qq.com)

RASP前置知识点:监控与软件攻防 (qq.com)

OpenRasp链接:https://packages.baidu.com/app/openrasp/release/

部署


安装部署这里我们就大概的讲一下流程吧,具体的步骤可以参考官网。先部署一个信息展示的服务端,然后再下载安装一个测试样例客户端,最后获取服务端的id和secret,然后下载agent端指定url,以及用上之前收集到的id和secret,指定测试样例客户端目录就可以完成监控和与服务端的连接同步。

正题


打开下载下来的目录,第一个进入眼帘的是一个RaspInstaller.jar,拖到jd-gui中查看。从 名字中,我们也基本可以判断这是一个安装用的jar。

基于百度OpenRasp的插桩浅析


这里我们先找一下这个jar的入口,可以看到是App,打开看了一下,先是判断一下要进行步骤是install还是uninstall,之后判断操作系统和服务,然后创建相应的目录以及将文件放置进去,并写入环境变量和修改配置。

基于百度OpenRasp的插桩浅析

基于百度OpenRasp的插桩浅析

基于百度OpenRasp的插桩浅析

基于百度OpenRasp的插桩浅析

基于百度OpenRasp的插桩浅析

之前我们知道,agent可以通过javaagent这个参数进行启动插桩。其实还有另一个操作可以进行插桩,就是利用JVM的attach API通过进程pid进行远程加载。这里面有一个类Attacher就完成了这个操作,当指定pid这个arg后,就通过了远程加载的方式进行了插桩,也不用重启服务。

基于百度OpenRasp的插桩浅析

通过上面图片的内容,我们可以知道,当启动agent的时候,最开始启动的是rasp.jar这个包,所以我们继续分析这个包的内容。拿到包,先看一下MF配置,发现Agent是这个包的入口。

基于百度OpenRasp的插桩浅析


这里我们先看一下premain,这里调用了init方法,先是用addJarToBootstrap加载目录到 BootstrapClassLoader 的ClassPath下,为后续hook做准备,不然有一些类例如java.io.File不能hook。

基于百度OpenRasp的插桩浅析


之后ModuleLoader加载rasp-engine.jar这个包。

基于百度OpenRasp的插桩浅析

这里按照之前的步骤,找到了EngineBoot,可以看到这里进行了两个初始化。JsPluginManager和CheckerManager。

基于百度OpenRasp的插桩浅析


JsPluginManager在这里我们可以看到当没有指定id和secret的时候,会调用更新插件和文件监控的功能。

基于百度OpenRasp的插桩浅析

基于百度OpenRasp的插桩浅析


接下来会调用CheckerManager的初始化方法,可以看到这是一个enum枚举类型的类,用循环的方式导入各个type.

基于百度OpenRasp的插桩浅析



type如下

基于百度OpenRasp的插桩浅析


接下来就是调用initTransformer(inst),这里定义的是CustomClassTransformer这个类对象,会自动调用addAnnotationHook()这个方法,之后扫描包下有@HookAnnotation的类,然后再进行一个配置的读取,读取一些类的忽略,当两者判断完,就进行类的添加。

基于百度OpenRasp的插桩浅析

基于百度OpenRasp的插桩浅析

基于百度OpenRasp的插桩浅析


然后再调用retransform,调用全部已经加载的类,这里还会进行一个class的一个判断,判断这个是不是需要hook的类,如果是,则追加。这里因为CustomClassTransformer继承自ClassFileTransformer,当类被加载的时候,会自动调用transform函数。

基于百度OpenRasp的插桩浅析

基于百度OpenRasp的插桩浅析


这里再调用之前扫描得到this.hooks字段,对放进来的类进行一个判断,如果是则调用 transformClass这个方法,从而调用hookMethod

基于百度OpenRasp的插桩浅析


这里我们以DeserializationHook为例子,可以看到这边调用了DeserializationHook的checkDeserializationClass方法,在入口之前利用javassist进行了插桩。

基于百度OpenRasp的插桩浅析



这边以DeserializationHook为例,学习分析一下实现逻辑。进入HookHandler的doCkeck方法,如果开启了hook,则继续调用doRealCheckWithoutRequest这个方法,接着调用CheckerManager.check。

基于百度OpenRasp的插桩浅析

基于百度OpenRasp的插桩浅析

基于百度OpenRasp的插桩浅析

这边继续往上翻,会发现调用的是AbstractChecker的chek方法,之后就是根据各个方法类的checkParam进行检测了,如果检测成功,则给isBlock赋值为true进行拦截了。

基于百度OpenRasp的插桩浅析


这里以XssChecker的checkParam方法进行分析学习,可以看出这里是以正则匹配作为一个检测。

基于百度OpenRasp的插桩浅析

这次大概的把openrasp的一些调用流程做了一个学习,但是感觉对于这个产品的原理的认识还是不够充分,还是需要继续学习分析其背后的检测原理和一些调度。感觉非常幸运能有百度openrasp这样的开源产品可以用来作为RASP学习的一个机会。最后再放一下之前那篇文章中写到的RASP一个流程的思路吧:

在有类被ClassLoader加载时候,会把该类的字节码先交给类ClassTransformer的 transform方法处理,该方法通过配置文件判断该类是否为我们需要hook的类,如果是则交给ASM或JAVASSIST类进行处理,当触发了我们需要hook的类,我们会在方法的开头或者结尾插入进入检测函数的字节码。把hook好的字节码返回,从而载入虚拟机。


原文始发于微信公众号(Th0r安全):基于百度OpenRasp的插桩浅析

版权声明:admin 发表于 2022年3月16日 上午9:31。
转载请注明:基于百度OpenRasp的插桩浅析 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...