首页
社区
课程
招聘
[原创]不用导出任何函数的DLL劫持注入,完美!
发表于: 2017-3-13 15:48 39553

[原创]不用导出任何函数的DLL劫持注入,完美!

2017-3-13 15:48
39553

.

最近在写SOCKS5代理,用的是LSP.代理成功了,但是因为LSP模块没办法隐藏,各种三方模块啊

删除PE头,强制删除文件,游戏都会闪退


想来想去,就想到这个法子,HOOK LdrLoadDll返回的模块句柄

把返回句柄替换成真实的DLL句柄,这种劫持的方式好处就是不用任何导出函数

不管什么是DLL劫持都可以,只要你能替换原来的DLL,LSP也挺方便的,哈哈哈


不过这种lsp劫持注入,只能用API HOOK来完成 SOCKS5代理

基本框架已经测试通过,抽空来分享一下劫持注入部分的代码


首先是HOOK部分

本来之前用的是inlinehook,XP测试的,弄成功了发现XP WIN7 WIN10中的HOOK地址汇编代码不一样,

而HOOK地址中 只有三个字节,所以就想到了用VEH来HOOK,只需要修改一个字节就行了


然后是处理HOOK部分:


因为RET的时候堆栈各种参数跟函数入口的时候都是一样了,

所以这里的HOOK函数(NewLdrLoadDll)直接跟LdrLoadDll一样就行了

先判断LdrLoadDll返回的句柄是不是自己的,如果是,说明我们的DLLMain函数执行完成,要返回了

然后把返回的句柄替换成被劫持的DLL

然后还原HOOK地址,完成我们想要的操作(比如内存注入自己,创建独立的工作线程),

最后卸载自身模块,不留痕迹


卸载模块部分:


因为DLL不能自己Free自己,所以申请一块独立的内存,使用线程来卸载自己

测试的时候,发现hookLdrLoadDll(false),竟然不能删除VEH,导致线程不能卸载模块

然后把删除VEH也添加到了线程中处理


写着写着shellcode,发现好烦啊,都是用od写好汇编代码,复制数据出来

再RtlCopyMemory修改shellcode参数

因为这个特别烦,就是撸了几把LOL,

回来就写了个shellcode组装的函数 shellcodeAppend()

看着用起来挺方便,拿出来个大家瞧瞧


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 2
支持
分享
打赏 + 6.00雪花
打赏次数 2 雪花 + 6.00
 
赞赏  aabiaobiao   +5.00 2019/01/31 老哥可以认识下吗 我私信你哦
赞赏  CCkicker   +1.00 2017/06/19
最新回复 (37)
雪    币: 0
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
2
String拥有一个特殊点叫:String对象的内容不可改变! 在调用诸如String对象的replace()等方法时,不是在原Sting对象的基础上改变对象内容,而是创建了一个新的String对象把调用的方法后返回的结果放在这个新的String对象中 代码示例如下: String str3 = "LOVO JAVA"; str3.replaceAll("JAVA", "J2EE"); 打印输出:LOVO JAVA System.out.println(str3; String str3 = "LOVO JAVA"; String str = str3.replaceAll("JAVA", "J2EE"); 打印输出:LOVO J2EE System.out.println(str); 开发工具不全的朋友,可jiaqun163201006
2017-3-13 16:15
0
雪    币: 4
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
可以使用在注入的dll中开启一个线程使用FreeLibraryAndExitThread函数, 释放dll. 直接退出线程, 释放dll 并且不返回!
2017-3-13 17:17
0
雪    币: 8
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
能不能把源码附件发上来呀
2017-3-13 18:24
0
雪    币: 7553
活跃值: (5392)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
Handjay 可以使用在注入的dll中开启一个线程使用FreeLibraryAndExitThread函数, 释放dll. 直接退出线程, 释放dll 并且不返回!
这个真的可以吗,线程没退出,DLL模块能Free掉?
2017-3-13 19:20
0
雪    币: 221
活跃值: (2326)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
能不能把源码附件发上来呀
2017-3-15 08:20
0
雪    币: 3738
活跃值: (3872)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
先马后看!
2017-3-15 20:25
0
雪    币: 83
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
只需要独立的内存就可以free自己
2017-3-15 21:09
0
雪    币: 31
活跃值: (87)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
9
Mark,感谢分享
2017-3-15 22:08
0
雪    币: 703
活跃值: (327)
能力值: (RANK:380 )
在线值:
发帖
回帖
粉丝
10
可以挂内存查询,不解释
2017-3-15 23:04
0
雪    币: 878
活跃值: (737)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
赞个,mark
2017-3-15 23:44
0
雪    币: 12702
活跃值: (4304)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
学习一下~~谢谢
2017-3-16 02:37
0
雪    币: 187
活跃值: (112)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
mark,收藏
2017-3-16 09:41
0
雪    币: 7553
活跃值: (5392)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
kvllz 可以挂内存查询,不解释[em_19]
他扫描内存块是有条件限制的,最简单的就是PE头,去掉PE头大部分的就很安全了,易语言除外
2017-3-16 13:00
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
内存加载自身代码能不能给个,找不到。
2017-3-16 14:31
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
挺巧妙~~~
2017-3-16 21:57
0
雪    币: 496
活跃值: (286)
能力值: ( LV13,RANK:400 )
在线值:
发帖
回帖
粉丝
17

哦, 楼主还要Hook pLdrLoadDll

我这有个更巧妙的方法,直接替换moudle list就行了,抽空我写篇文章


https://gist.github.com/tishion/96272231c54a42862569

/**
 ** tishion#163.com
 ** 2016-01-28 18:52:34
 **/
PLDR_DATA_TABLE_ENTRY GetModuleEntryInLoadOrderModuleList(HMODULE hMod)
{
 PPEB pPeb = NULL;
 // Get the base address of PEB struct
 __asm
 {
  push eax
  mov eax, fs:[0x30]
  mov pPeb, eax
  pop eax
 }
 // Get pointer value of PEB_LDR_DATA
 PPEB_LDR_DATA pLdr = pPeb->Ldr;
 // And get header of the InLoadOrderModuleList
 PLIST_ENTRY pHeaderOfModuleList = &(pLdr->InLoadOrderModuleList);
 if (pHeaderOfModuleList->Flink == pHeaderOfModuleList)
 {
  // Something was wrong
  return NULL;
 }
 PLDR_DATA_TABLE_ENTRY pEntry = NULL;
 PLIST_ENTRY pCur = pHeaderOfModuleList->Flink;
 // Find Entry of the fake module
 do
 {
  pEntry = CONTAINING_RECORD(pCur, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
  // Ok, got it
  if (pEntry->BaseAddress == hMod)
  {
   break;
  }
  pEntry = NULL;
  pCur = pCur->Flink;
 } while (pCur != pHeaderOfModuleList);
 return pEntry;
}
/**
 ** Replace the return value of LoadLibrary
 **
 **/
BOOL LoadFogModule(HMODULE hModule, LPCTSTR pOrigiModPath)
{
 // First, we must get the Entry of the fake module
 PLDR_DATA_TABLE_ENTRY pEntryOfFakeMod = GetModuleEntryInLoadOrderModuleList(hModule);
 
 // Then, load the original module
 HMODULE hOrigiMod = ::LoadLibrary(pOrigiModPath);
 if (NULL != pEntryOfFakeMod && NULL != hOrigiMod)
 {
  // Now we need to find the Entry of the original module
  PLDR_DATA_TABLE_ENTRY pEntryOfOrigiMod = GetModuleEntryInLoadOrderModuleList(hOrigiMod);
  /*
   * Tish is the key statement which will replace the return value of LoadLibrary.
   * At the end of LoadLibrary, it will return the base address which get from the entry of fake module.
   * And then the process will import all the functions and variables it needs according to the base address.
   * Because we have replaced the address with the base address of real original module,
   * so it will work well, that is to say the process can get all valid imported functions and variables
   * from the original module.
   */
  pEntryOfFakeMod->BaseAddress = pEntryOfOrigiMod->BaseAddress;
  // Then we must remove the fake module entry from all the module list, or it will lead the process crash
  // remove it from InLoadOrderModuleList
  pEntryOfFakeMod->InLoadOrderModuleList.Blink->Flink = pEntryOfFakeMod->InLoadOrderModuleList.Flink;
  pEntryOfFakeMod->InLoadOrderModuleList.Flink->Blink = pEntryOfFakeMod->InLoadOrderModuleList.Blink;
  // remove it from InInitializationOrderModuleList
  pEntryOfFakeMod->InInitializationOrderModuleList.Blink->Flink = pEntryOfFakeMod->InInitializationOrderModuleList.Flink;
  pEntryOfFakeMod->InInitializationOrderModuleList.Flink->Blink = pEntryOfFakeMod->InInitializationOrderModuleList.Blink;
  // remove it from InMemoryOrderModuleList
  pEntryOfFakeMod->InMemoryOrderModuleList.Blink->Flink = pEntryOfFakeMod->InMemoryOrderModuleList.Flink;
  pEntryOfFakeMod->InMemoryOrderModuleList.Flink->Blink = pEntryOfFakeMod->InMemoryOrderModuleList.Blink;
  return TRUE;
 }
 return FALSE;


2017-3-17 16:58
0
雪    币: 22
活跃值: (453)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18

ls的地址打不开!

2017-3-17 20:06
0
雪    币: 496
活跃值: (286)
能力值: ( LV13,RANK:400 )
在线值:
发帖
回帖
粉丝
19
靴子 ls的地址打不开!
可能国内被墙了。。
2017-3-18 09:10
0
雪    币: 7553
活跃值: (5392)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
20
tishion 哦, 楼主还要Hook pLdrLoadDll我这有个更巧妙的方法,直接替换moudle list就行了,抽空我写篇文章https://gist.github.com/tishi ...
大神到处有啊
2017-3-18 14:47
0
雪    币: 7553
活跃值: (5392)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
21
清明雨 内存加载自身代码能不能给个,找不到。
http://m.pediy.com/showthread.php?t=203910
2017-3-18 14:55
0
雪    币: 1036
活跃值: (1311)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
22
赞个 好思路
2017-3-20 10:09
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
学习下看不懂哈
2017-3-21 10:39
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
楼主 看你帖子貌似你也在搞dxf 请教一下关于过木马加载有什么办法吗
2017-3-30 09:38
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
我用lsp劫持没出现三方啊?
2017-5-29 10:14
0
游客
登录 | 注册 方可回帖
返回
//