首页
社区
课程
招聘
[原创]用伪造so的方式注入
2017-8-31 16:58 26897

[原创]用伪造so的方式注入

2017-8-31 16:58
26897

-0x1:

   20180927更新:

        1.更新了0x5 part的源码,之前的源码链接不知何时失效了,(别问了,懒,笨,还不上进,不知道啥是git)

        2.解决了某些机型,在mprotect的时候由于权限不够而导致的失败。就是在声明的时候把结构体声明到.text段就好了,具体如下



       3.emmm...另外这个源码的下载不知道啥时候又会失效,有缘再见...




0x0  前言

 

   现在很多安全插件,都会用本地文件和系统的内存进行校验,来防止修改code内存的hook


 

   或者一些其他的原因,无法注入,无法hook,又不想麻烦的编译android源码,

 

   那我要怎么办呢?

 

   用伪造so的方式注入,

 

   尤其对注入时机比较关注的玩家,这种注入方式最棒

 

   如果hook系统的so,则需要root

  

   源码在0x5部分


   若是有图片看不清,那就下载附件吧



   

-------------------------------------------------------------------

 

0x1 选择目标so文件,得到导出函数列表

 

      比如我在android 7中,想注入dex2oat来达到不可告人的目的,

 

      我需要用ida打开dex2oat,看看dex2oat都需要哪些so

 

 

      然后选择目标so文件,遵循如下几个标准,

      如果能遵守标准,注入成功的几率就大一些

 

        a.目标so的导出函数最好全部是 C 导出(不强求)

                C++的导出:_Z32register_android_hardware_CameraP7_JNIEnv

                C导出:        register_android_hardware_Camera

 

        b.导出的函数越少越好(不强求)

 

      根据上面的标准,我认为伪造libsigchain.so,最靠谱。

 

      然后需要获得libsigchain.so的导出函数列表,步骤如下

 

      linux readelf -s libsigchain.so 得到导出函数列表,

 

      或者在idaExport窗口复制粘贴。

 


 

 

      这里要说一下,如果so中的导出函数是C++格式的,那么从ida窗口复制出来的导出函数列表,

      就是不准确的

 

      这里我用 readelf -s libsigchain.so |  grep "13 "    得到libsigchain.so的导出函数列表

 


 

notepad++,处理一下文本

 

 

得到导出函数表

 

InvokeUserSignalHandler

ClaimSignalChain

UnclaimSignalChain

EnsureFrontOfChain

InitializeSignalChain

SetSpecialSignalHandlerFn

 

------------------------------------------------------------------------------

 

0x2 使用方法

 

    打开notepad++,新建文档,把导出函数表复制进去

 

    复制  __attribute__((visibility("default"))) JmpStruct

 

    用上面介绍的按住alt的方法,一次性粘贴到,导出函数列表前面

 

    并用同样的方法,在末尾把  分号“ ; ” 加上

 

 

    上面的步骤用excel也能轻松做到

 

     经过处理后,得到

 

__attribute__((section(".text"))) __attribute__((visibility("default"))) JmpStruct InvokeUserSignalHandler;

__attribute__((section(".text"))) __attribute__((visibility("default"))) JmpStruct ClaimSignalChain;

__attribute__((section(".text"))) __attribute__((visibility("default"))) JmpStruct UnclaimSignalChain;

__attribute__((section(".text"))) __attribute__((visibility("default"))) JmpStruct EnsureFrontOfChain;

__attribute__((section(".text"))) __attribute__((visibility("default"))) JmpStruct InitializeSignalChain;

__attribute__((section(".text"))) __attribute__((visibility("default"))) JmpStruct SetSpecialSignalHandlerFn;

 

     打开hook_demo.c,把上面的信息,粘贴到对应的位置

 

 

 

 

用同样的方法得到GetProcessAddress( xxxxx )

 

GetProcessAddress( InvokeUserSignalHandler );

GetProcessAddress( ClaimSignalChain );

GetProcessAddress( UnclaimSignalChain );

GetProcessAddress( EnsureFrontOfChain );

GetProcessAddress( InitializeSignalChain );

GetProcessAddress( SetSpecialSignalHandlerFn );

 

并把得到的信息,复制粘贴到,hook_demo.cmy_init(void)函数中的对应位置

 

 

并把,原始libsigchain.so,复制到/system/lib/libsigchain_me.so

 

如果要跑在Android 7上,由于android的本身的安全性的要求,还需要,把引用的so放到导入表中,具体方法参见Android.mk

 

 

----------------------------------------------------------------------------------

 

0x3 编译并替换/system/lib/libsigchain.so

    adb push进去就行了,然后重启机器,让替换生效,

    (别忘了把原始libsigchain.so,复制成/system/lib/libsigchain_me.so

 

-----------------------------------------------------------------------------------

 

0x4 原理部分

 

    先来看一段汇编代码

 

 

push {pc}   ;pc入栈(1)

push {r0}   ;r0入栈,备份r0(2)

push {pc}   ;pc入栈(3)

pop {r0}   ;(3)处的pc值赋值给r0

ldr r0,[r0,#16]  ;读取xxxxxxxr0xxxxxxx之后会被替换成函数地址

str r0,[sp,#8]  ;xxxxxxx,替换(1)处的栈中的pc

pop {r0}   ;还原r0(2)

pop {pc}   ;跳转到xxxxxxx函数开始执行

xxxxxxx    ;指向函数的地址

 

    上面的代码,执行之后,会跳转到xxxxxxx函数执行,

 

    这里假设此时的xxxxxxx,就是 原始的libsigchain.so 中的 原始函数InvokeUserSignalHandler

 

    我们在  伪造的libsigchain.so  中,导出  伪造的InvokeUserSignalHandler 函数,

 

    让伪造的InvokeUserSignalHandler在一开始就执行上面的汇编代码,

 

    那么执行之后,就自然而然的跳转到原始的InvokeUserSignalHandler中了,

 

    这样一来,我们的so也注入进去了,原始的系统函数也能得到执行,我们的目的就达到了

 

    在代码中的,JmpCode部分,就是上面的汇编

 

 

 

 

     如何伪造的InvokeUserSignalHandler函数?

 

         在代码中,我定义了一个JmpStruct结构

 

        

 

          我需要,

 

              JmpCode    赋值给    JmpStruct.code

 

            原始的InvokeUserSignalHandler地址,赋值给    JmpStruct.address

 

          然后,再在代码中,用  JmpStruct  声明  冒牌货InvokeUserSignalHandler 就好了

 


 


 

 

-----------------------------------------------------------------------------------------

 

0x5 show me the fuck code

 

链接: https://pan.baidu.com/s/1hs7WWtu 密码: 9bmy (已经失效)

链接: https://pan.baidu.com/s/1fBn8JkNtAxTcqQowC-rJPg 提取码: 94p7

 

------------------------------------------------------------------------------------------

 

0x6 如何hook  libEGL.so 中的  eglChooseConfig  函数?

 

   这部分由于工作原因,我就不能放源码了,见谅

 

   首先,我们把所有的libEGL.so的导出函数,都用JmpStruct声明,但是就是不声明eglChooseConfig

 


 

然后我们把所有的伪造的libEGL.so函数,都用GetProcessAddress填充一下,但是就是不填充eglChooseConfig

 

 


 

 

然后我们自己实现一个eglChooseConfig函数

 


 

-------------------------------------------------------------------------

 

0x7



[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2018-9-27 19:54 被zeif编辑 ,原因:
上传的附件:
收藏
点赞8
打赏
分享
打赏 + 5.00雪花
打赏次数 1 雪花 + 5.00
 
赞赏  CCkicker   +5.00 2017/09/04
最新回复 (48)
雪    币: 519
活跃值: (3759)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
龙飞雪 2017-8-31 17:08
2
0
前面有人貌似分享过这种方法,谢谢分享
雪    币: 878
活跃值: (496)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
Rprop 2017-8-31 17:42
3
0
123
雪    币: 6818
活跃值: (153)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
聖blue 2017-8-31 22:30
4
0
不错!!!!!
雪    币: 435
活跃值: (143)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qqsunqiang 2017-9-1 07:45
5
0
谢谢楼主的分享。
雪    币: 1034
活跃值: (1660)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wooyunking 2017-9-1 10:23
6
0
加精了,屌屌屌
雪    币: 215
活跃值: (372)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
magicxss 2017-9-1 11:20
7
0
6666666666
雪    币: 1535
活跃值: (695)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
开花的水管 2017-9-1 17:22
8
0
楼主6到飞起
雪    币: 241
活跃值: (226)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
ckis 2017-9-2 03:18
9
0
和win平台的dll劫持,函数转发是一个原理
雪    币: 0
活跃值: (878)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
tangsilian 2017-9-2 11:07
10
0
写的很详细    感谢分享
雪    币: 1535
活跃值: (695)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
开花的水管 2017-9-4 10:44
11
0
附件文档里是乱码?
雪    币: 547
活跃值: (504)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
zeif 2 2017-9-4 12:25
12
0
开花的水管 附件文档里是乱码?
可能是上传下载中出现问题了,我重新更新了下附件√
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wx_Allen_940613 2017-9-4 18:58
13
0
又一波小朋友被你教坏了
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
嗯呢 2017-9-5 09:14
14
0
666666666666666666
雪    币: 171
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小猫的LGH 2017-9-6 15:21
15
0
感谢楼主的分享!
雪    币: 67
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
spydh 2017-9-7 09:55
16
0
还可以这样。。。之前我都是每个导出函数都写一遍的
雪    币: 25
活跃值: (1740)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
dryzh 2017-10-21 23:03
17
0
liblog.so可以劫持不?__android前缀的如何处理?
//liblig.so
/*
__attribute__((visibility("default")))  JmpStruct  __android_log_bwrite;
__attribute__((visibility("default")))  JmpStruct  __android_log_btwrite;
__attribute__((visibility("default")))  JmpStruct  __android_log_buf_write;
__attribute__((visibility("default")))  JmpStruct  __android_log_buf_print;
__attribute__((visibility("default")))  JmpStruct  __android_log_write;
__attribute__((visibility("default")))  JmpStruct  __android_log_assert;
__attribute__((visibility("default")))  JmpStruct  __android_log_print;
__attribute__((visibility("default")))  JmpStruct  __android_log_vprint;
__attribute__((visibility("default")))  JmpStruct  __android_log_dev_availab;*/
__attribute__((visibility("default")))  JmpStruct  android_log_setPrintForma;
__attribute__((visibility("default")))  JmpStruct  android_log_processLogBuf;
__attribute__((visibility("default")))  JmpStruct  android_log_format_free;
__attribute__((visibility("default")))  JmpStruct  android_log_formatLogLine;
__attribute__((visibility("default")))  JmpStruct  android_log_printLogLine;
__attribute__((visibility("default")))  JmpStruct  android_log_processBinary;
__attribute__((visibility("default")))  JmpStruct  android_lookupEventTag;
__attribute__((visibility("default")))  JmpStruct  android_log_addFilterRule;
__attribute__((visibility("default")))  JmpStruct  android_log_addFilterStri;
__attribute__((visibility("default")))  JmpStruct  android_log_format_new;
__attribute__((visibility("default")))  JmpStruct  logprint_run_tests;
__attribute__((visibility("default")))  JmpStruct  android_log_formatFromStr;
__attribute__((visibility("default")))  JmpStruct  android_log_shouldPrintLi;
__attribute__((visibility("default")))  JmpStruct  android_closeEventTagMap;
__attribute__((visibility("default")))  JmpStruct  android_openEventTagMap;
雪    币: 547
活跃值: (504)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
zeif 2 2017-10-24 09:47
18
0
dryzh liblog.so可以劫持不?__android前缀的如何处理? //liblig.so /* __attribute__((visibility("default"))) ...
我没试过fake    liblog.so,__android系列函数有什么特殊的么?
雪    币: 2401
活跃值: (2262)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
gtict 2018-2-1 11:14
19
0
谁下载了那份代码。再发下。谢谢
雪    币: 76
活跃值: (41)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
wushaominkk 2018-2-1 16:43
20
0
看的一脸懵逼,继续学习!
雪    币: 2375
活跃值: (433)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
petersonhz 2018-2-12 03:14
21
0
楼主IDA用的哪个版本?
雪    币: 2375
活跃值: (433)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
petersonhz 2018-2-12 03:14
22
0
ckis 和win平台的dll劫持,函数转发是一个原理
把so里面的函数代码修改掉?
雪    币: 1484
活跃值: (547)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
bugchong 2018-2-13 08:48
23
0
感谢分享,写的很细致。
雪    币: 144
活跃值: (335)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
人在塔在 2018-6-28 11:51
24
0
求分享下代码 谢谢啦
雪    币: 226
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
a达拉崩吧 2018-6-29 09:10
25
0
666
游客
登录 | 注册 方可回帖
返回