首页
社区
课程
招聘
dll注入lsass失败,求方法或工具
发表于: 2014-6-23 13:18 5342

dll注入lsass失败,求方法或工具

2014-6-23 13:18
5342
因为本机上装了360还有瑞星,注入dll到lsass总是失败。
求一个加载工具能注入一个测试用的dll到lsass进程。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 45
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
DLL注入工具

注入在Windows平台上很常见,一般分为两类:二进制代码注入和动态连接库(DLL)注入。二进制代码注入指的是将SHELLCODE一类的数据放入远程进程并在本地进程中启动远程进程使其开始运作。DLL注入指的是以二进制代码注入为基础,在远程进程中运行加载动态链接库(DLL)的代码,使其运作加载DLL。DLL注入以二进制代码注入为基础,但是实现的功能比二进制代码丰富,在测试过程中,对深入观察和修改程序行为具有不可替代的作用。本文以下将以DLL注入为主阐述注入SMSS进程的方法。
       SMSS是会话进程,它是Windows中一个很特殊的进程,作用是管理子系统并且初始系统化变量的进程。在Windows操作系统中,有许多进程可以进行DLL注入,包括系统级进程lsass.exe(管理登录),CSRSS.EXE,除了SYSTEM、IDLE和SMSS没有关于其注入方面的资料。由于SYSTEM实质是Windows内核进程(NTOSKRNL),IDLE是闲置进程,这两个都是系统虚拟出来的进程,不存在注入的可能性,但是SMSS属于后于SYSTEM和IDLE创建的进程,其也有模块加载,因此SMSS在注入上存在理论可能性,不过实现起来十分困难。
       传统注入方式,使用的是函数CreateRemoteThread在远程进程(需要注入的进程)里面去启动一个新线程执行加载DLL,但是SMSS却不能使用这类方法:
(1)因为它是在系统初始化后由SYSTEM创建,其实是一个内核进程,而且它创键CSRSS.exe,所以即使是利用DuplicateHandle都找不到它的进程句柄以进行操作。
(2)CreateRemoteThread是一个kernel32.dll中的函数,而SMSS中除了ntdll.dll导出的函数以外,就没有其它函数可以使用了。而CreateRemoteThread函数不能使用。
  由于SMSS不能选择用CreateRemoteThread,因此选用测试使用一种别的方法,函数补丁法,其原理如图1所示:

  函数补丁法的设计思路是:通过远程读写内存,注入一段ShellCode,但并非是利用CreateRemoteThread启动一个新线程来执行它,而是利用继续写远程进程内存的方式,改变远程进程一些必调函数的入口或者IAT,函数在运行的时候,就会自动调用我们事先准备的ShellCode实现DLL的加载。
       由于CreateRemoteThread函数无法使用,因此只能采用由ntdll.dll导出的LdrLoadDll去加载DLL从而实现。因为这个函数才是LoadLibraryExW的实现者,以下是测试成功的注入代码:

__asm
    {
       pushad
       pushfd        //  保护现场

       //这些还原代码由外部进行初始化
       mov    eax,0xEEEEEEEE
       mov    bl,0xFF           //存五个字节的内容
       mov    edx,0xDDDDDDDD    //存需要写东西的地址
       mov    [edx],eax
       mov    byte ptr [edx+4],bl

       //这些代码最后会重新初始化的
       mov    eax,fs:[0x30]
       mov    eax,dword ptr [eax+0x0c] //  Ldr : _PEB_LDR_DATA
       mov    eax,dword ptr [eax+0x1c] //  InInitializationOrderModuleList : _LIST_ENTRY
       mov    eax,dword ptr [eax+0x08] //  EntryInProgress
       mov    edi,eax                     //  edi = ntdll.dll首地址
       mov    eax,dword ptr [edi+3ch]     //  eax = PE首部
       mov    edx,dword ptr [eax+edi+78h]
       add    edx,edi                     //  edx = 引出表地址
       mov    ecx,dword ptr [edx+18h]     //  ecx = 输出函数的个数(NumberOfNames)
       mov    ebx,dword ptr [edx+20h]   
       add    ebx,edi                     //  ebx = 函数名地址(AddressOfNames)

    SEARCH:
       dec    ecx
       mov    esi,[ebx+ecx*4]
       add    esi,edi
      
       mov    eax,0x4c72644c
       cmp    [esi],eax         //  比较'LdrL'
       jne    SEARCH

       mov    eax,0x4464616f
       cmp    [esi+4],eax          //  比较'oadD'
       jne    SEARCH

       cmp    word ptr [esi+8],0x6c6c     //  比较'll'
       jne    SEARCH

       //  如果是LdrLoadDll(表明地址已找到)
       mov    ebx,dword ptr [edx+24h]
       add    ebx,edi                     //  ebx = 序号数组的地址

       mov    ecx,dword ptr [ebx+ecx*2]   //  ecx = 计算出序号值
       and    ecx,0x0000ffff
       mov    ebx,dword ptr [edx+1ch]   
       add    ebx,edi                     //  ebx = 函数地址起始位置
       mov    eax,dword ptr [ebx+ecx*4]  
       add    eax,edi                  //  eax = 利用序号值,得出LdrLoadDll的地址

//LdrLoadDllLdrLoadDll(NULL, 0, &uni_input, &hHandle);

       //  先存入UNISTRING的值到内存中
       push   0x00000000
       push   0x006C006C
       push   0x0064002E
       push   0x00740073
       push   0x00650074
       mov    edx,esp    //edx = UNISTRING的数据
      
       //  预留存储空间
       sub    esp,0x0c
       mov    dword ptr [esp+4],0x00120010    //10 00 12 00 (UNICODE前面两个字符)
       mov    [esp+8],edx
       xor    ecx,ecx
       mov    [esp],ecx      //初始化OUT指针

       push   esp //PHANDLE  ModuleHandle
       mov    ebx,esp
       add    ebx,8
       push   ebx //PUNICODE_STRING ModuleFileName
       push   0   //ULONG       Flags
       push   0   //PWCHAR   PathToFile
       call   eax

       //  维持平衡
       add    esp,0x20   //0xc+5*4=32
      
       popfd
       popad         //  还原现场
    }  

    __asm
    {
       _emit  0x90  
       _emit  0x90
       _emit  0x90  
       _emit  0x90
       _emit  0x90   //  需要还原原始代码,5个字节最好
      
       _emit  0xE9  
        _emit 0x90
        _emit 0x90      
        _emit 0x90      
        _emit 0x90
    }

  前面说到,SMSS本来就是一个由内核创建的进程,它本身也就不支持在Win32下运行,所以DLL也必须是特殊的写法才行,Native的。为了验证注入SMSS的成功性,我把system32下面的sfcfiles.dll改名为test.dll,然后再一次重复试验,可以成功注入,如图2所示:

  由此得出结论是,通过设计的测试流程,SMSS通过函数补丁的方式,注入加载DLL。
2014-6-23 13:54
0
雪    币: 215
活跃值: (90)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
我想是不是可以通过驱动的帮助注入dll到lsass进程。
2014-6-23 15:59
0
雪    币: 215
活跃值: (90)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
找到一个参考文章。。。
“  一旦定位LSASS进程,就可以通过减去ActiveProcessLinks偏移值,从而得到LSASS与第一个EPROCESS结构的偏移值。
    下一步就是把shell code拷贝到目标内存空间。起先我打算把代码存放在PEB;以前,PEB总是被映射到0x7ffdf000,但在XP SP2中PEB的映射地址是随机的。虽然可以通过0xFFDFF000->0x18->0x30找到PEB,但我们有更好的选择:把代码存放到内核-用户-共享内存区域,通常被称为SharedUserData。0xFFDF0000处是一个可写的内存区域,在那里可以保存我们的代码。这个内存区域是从用户域被标记为只读的0x7FFE0000处映射而来的,这个映射在所有的平台上都一样,所以这是个不错的选择。 由于在这个区域的内存对所有进程来来说都是可读的,所以必要把地址空间切换到目标进程,可以直接从内核把代码写入到0xFFDF0000+0x800。当排队一个用户模式APC时,把0x7FFE0000+0x800作为参数。

见:Windows远程内核漏洞注入http://www.pediy.com/kssd/pediy07/pediy7-780.htm
2014-6-25 09:59
0
游客
登录 | 注册 方可回帖
返回
//