• 添加新的Hook点
    • Java版本
      • 添加hook点
      • 添加检测类型
      • 构造参数并进入checker
    • PHP 版本
      • 新增hook点

    添加新的Hook点

    Java版本

    添加hook点

    根据自己的hook点在com.baidu.openrasp.hook包中添加一个继承自AbstractClassHook的类,并实现getTypeisClassMatched两个方法进行hook点的匹配,并在hookMethod方法中的内部类的onMethodEnte方法和onMethodExit方法进行hook点前后的逻辑插入,具体代码如下:

    1. package com.baidu.openrasp.hook;
    2. import com.baidu.openrasp.HookHandler;
    3. import javassist.CannotCompileException;
    4. import javassist.CtClass;
    5. import javassist.NotFoundException;
    6. import java.io.IOException;
    7. /**
    8. * 自定义hook点继承自AbstractClassHook
    9. */
    10. public class MyHook extends AbstractClassHook {
    11. /**
    12. * 返回自定义的hook点类型名称
    13. */
    14. @Override
    15. public String getType() {
    16. return "string_replace";
    17. }
    18. @Override
    19. protected void hookMethod(CtClass ctClass) throws IOException, CannotCompileException, NotFoundException {
    20. /*
    21. * 获取要插入函数开始的代码
    22. * 参数 "$0,$1,$2" 表示获取带插入函数的 this,第一个参数以及第二个参数
    23. * 然后用获取的参数调用HookHandler.checkStringReplaceEnter这个静态方法
    24. * 最后三个参数代表HookHandler.checkStringReplaceEnter方法的参数类型
    25. */
    26. String srcBefore = getInvokeStaticSrc(HookHandler.class, "checkStringReplaceEnter",
    27. "$0,$1,$2", String.class, String.class, String.class);
    28. // 在String.replace函数开始的地方,插入刚才获取的代码片段,第三个个参数为函数签名信息
    29. insertBefore(ctClass, "replace", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", srcBefore);
    30. /*
    31. * 获取要插入函数结束的代码
    32. * 参数 "$_" 代表获取待插入函数的返回值
    33. * 最后用获取的内容调用HookHandler.checkStringReplaceExit这个静态方法
    34. */
    35. String srcAfter = getInvokeStaticSrc(HookHandler.class, "checkStringReplaceExit", "$_", String.class);
    36. /*
    37. * 在String.replace函数结束的地方,插入刚才获取的代码片段,第三个个参数为函数签名信息
    38. * 最后一个参数为true代表在异常退出的地方异常会插入响应的代码段
    39. */
    40. insertAfter(ctClass, "replace", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", srcAfter, true);
    41. }
    42. /**
    43. * 匹配需要hook的类名
    44. */
    45. @Override
    46. public boolean isClassMatched(String className) {
    47. return "java.lang.String".equals(className);//该hook点hook的是java.lang.String类
    48. }
    49. }

    将如上实现的hook点加入com.baidu.openrasp.transformer.CustomClassTransformer的构造方法中,实现字节码的转换,代码如下:

    1. public CustomClassTransformer() {
    2. hooks = new HashSet<AbstractClassHook>();
    3. addHook(new MyHook()); // 将hook点加入transformer
    4. }

    添加检测类型

    在 com.baidu.openrasp.plugin.checker.CheckParameter 中添加相应的检测类型

    1. public enum Type {
    2. // 添加相应的检测类型,checker使用JsChecker代表该hook点的参数使用js插件检测
    3. // 除了JsChecker之外还可以根据com.baidu.openrasp.plugin.checker包下面的其他checker进行自定义checker
    4. // 第一个参数是检测类型名称,第二个是检测使用的checker
    5. REPLACE("replace", new JsChecker()),
    6. String name;
    7. Checker checker;
    8. Type(String name, Checker checker) {
    9. this.name = name;
    10. this.checker = checker;
    11. }
    12. @Override
    13. public String toString() {
    14. return name;
    15. }
    16. }

    构造参数并进入checker

    编写hook点中调用的 HookHandler.checkStringReplaceEnterHookHandler.checkStringReplaceExit 方法,来实现具体的检测逻辑,检测逻辑中可以调用js插件,示例如下:

    1. public static void checkStringReplaceEnter(String str,String regex,String replacement){
    2. // 如下是构造参数并进入checker的操作
    3. // 构造参数
    4. HashMap<String, Object> param = new HashMap<String, Object>();
    5. param.put("str",str);
    6. param.put("regex", regex);
    7. param.put("replacement", replacement);
    8. // 进入第三步中设置的checker,第一个参数是检测类型名称,第二个参数是检测参数map
    9. doCheck(CheckParameter.Type.REPLACE, param);
    10. }

    参考资料

    • Javassist 框架参考文档: javassist

    PHP 版本

    新增hook点

    假设我们要新增hook_class下的hook_function方法,其对应的检测类型为hook_type,则新增HOOK过程如下:

    • 在hook文件夹下新建新增hook点对应文件,建议命名方式为openrasp_hook_class.cc,同时将其添加至config.m4config.w32
    • 引入openrasp_hook.h,根据业务需求,选择合适的HOOK方式:前置HOOK(PRE_HOOK_FUNCTION_EX),后置HOOK(POST_HOOK_FUNCTION_EX)以及前后同时HOOK(HOOK_FUNCTION_EX),根据选择的HOOK方式合理定义前置处理函数及后置处理函数,形如:
    1. #include "openrasp_hook.h"
    2. HOOK_FUNCTION_EX(hook_function, hook_class, hook_type);
    3. void pre_hook_class_hook_function_hook_type(OPENRASP_INTERNAL_FUNCTION_PARAMETERS)
    4. {
    5. //do something
    6. ...
    7. }
    8. void post_hook_class_hook_function_hook_type(OPENRASP_INTERNAL_FUNCTION_PARAMETERS)
    9. {
    10. //do something
    11. ...
    12. }