关于32位程序在64位系统下运行中需要注意的重定向问题(有图,很清楚)
Posted 朝闻道
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于32位程序在64位系统下运行中需要注意的重定向问题(有图,很清楚)相关的知识,希望对你有一定的参考价值。
0x00 前言
最近学习了Stuart@ukstufus的文章《Persistence Architecture Matters》,恰巧解决了我之前遇到过的一个问题,理清了文件和注册表重定向中需要注意的细节
大家在学习的过程中难免也会碰到,所以在此分享一下。
《Persistence Architecture Matters》的链接:
https://labs.mwrinfosecurity.com/blog/persistence-architecture-matters/
0x01 消失的注册表键值
OS:Win8x64
开发环境:VS2008
1、编写程序写入注册表
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include <atlbase.h> int main( int argc, char *argv[]) { LPCTSTR lpSubKey = "Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run" ; HKEY hKey; DWORD dwDisposition = REG_OPENED_EXISTING_KEY; LONG lRet = ::RegCreateKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition); if (ERROR_SUCCESS != lRet) { return 0; } char szModuleName[MAX_PATH] = { 0 }; ::GetModuleFileNameA(NULL, szModuleName, MAX_PATH); lRet = ::RegSetValueEx(hKey, "test" , NULL, REG_SZ, ( BYTE *)szModuleName, strlen (szModuleName) + 1); if (ERROR_SUCCESS != lRet) printf ( "RegSetValueEx error!\\n" ); else printf ( "[+] RegSetValueEx Success!\\n" ); ::RegCloseKey(hKey); return 0; } |
编译平台设置为Win32
以管理员权限运行后会向HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run
写入键值test
如图
2、获取写入的键值
编写批处理文件来获得写入的结果
批处理内容如下:
1
|
REG query "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "test" >>result.txt |
在本地右键直接执行批处理文件
可是,批处理执行后无法输出写入的键值
0x02 消失的文件
1、编写程序写入文件
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
#include <stdio.h> void main() { char *temp= "test" ; FILE * fp; fp= fopen ( "c:\\\\windows\\\\system32\\\\test.txt" , "a+" ); if (fp==0) return ; fwrite (temp, strlen (temp),1,fp); printf ( "[+] Write Success!\\n" ); fclose (fp); } |
编译平台设置为Win32
以管理员权限运行后会向c:\\windows\\system32\\
写入文件test.txt
如图
2、获取写入的文件
批处理内容如下:
1
|
dir c:\\windows\\system32\\ test .txt >>result.txt |
在本地右键直接执行批处理文件
同样,批处理无法输出写入的文件内容
0x03 原因分析
1、重定向
自xp系统开始,64位的系统引入了新技术:
文件重定向和注册表重定向
这个技术是为了在64位系统下将32位程序和64程序分离开
在64位平台上运行32位程序的模拟器被称为WOW64
WOW64全称为"Windows 32 on Windows 64"
2、注册表重定向
在X64系统里面,一些特殊的注册表键会被分为2个独立的部分
(1)32位程序对注册表某些位置的操作存在重定向
比如对HKLM/Software访问,会被WOW64重定向至HKLM/Software/Wow6432Node
具体存在重定向的注册表位置可参考如下链接:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa384253(v=vs.85).aspx
(2)64位程序对注册表的操作不存在重定向
(3)补充
HKLM/Software/Wow6432Node下保存的均为32位程序的注册表信息
如果在HKLM\\Software\\Wow6432Node\\Microsoft\\CurrentVersion\\Run
添加启动项来运行dll,系统默认会执行32位的rundll32.exe(路径为:c:\\windows\\SysWOW64\\rundll32.exe)来加载dll,加载的dll必须是32位(如果是64位会出错)
当然,如果在HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run
添加启动项来运行dll,则默认为64位rundll32.exe,加载64位dll文件
3、文件重定向
同样,文件系统也存在2个独立的部分
(1)32位程序对%systemroot%/system32
的操作存在重定向
32位文件会被重定向到%systemroot%/SysWOW64
(2)64位程序对文件操作不存在重定向
(3)补充
%systemroot%/SysWOW64下的都为32位程序,在里面可以找到32位的cmd、calc等
基于以上的分析,整理出了如下操作注册表键值和文件系统的方法
0x04 找回注册表键值
解决思路:
32位程序写注册表的操作会被重定向到HKLM\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run
而在本地执行批处理默认会调用64位的程序,不会被重定向,查询的位置为HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run
解决方法:
1、修改调用的api参数,跳过重定向,使32位程序去访问64位的注册表
在调用函数RegCreateKeyEx创建注册表项时,对其第六个参数REGSAM samDesired设置中添加参数KEY_WOW64_64KEY
即KEY_ALL_ACCES
改为KEY_ALL_ACCESS | KEY_WOW64_64KEY
这样就会跳过重定向,最终写入的位置为HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run
修改后的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include "stdafx.h" #include <atlbase.h> int main( int argc, char *argv[]) { LPCTSTR lpSubKey = "Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run" ; HKEY hKey; DWORD dwDisposition = REG_OPENED_EXISTING_KEY; LONG lRet = ::RegCreateKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, NULL, NULL, REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS | KEY_WOW64_64KEY, NULL, &hKey, &dwDisposition); if (ERROR_SUCCESS != lRet) { printf ( "RegCreateKeyEx error!\\n" ); return 0; } char szModuleName[MAX_PATH] = { 0 }; ::GetModuleFileNameA(NULL, szModuleName, MAX_PATH); lRet = ::RegSetValueEx(hKey, "test" , NULL, REG_SZ, ( BYTE *)szModuleName, strlen (szModuleName) + 1); if (ERROR_SUCCESS != lRet) printf ( "RegSetValueEx error!\\n" ); else printf ( "[+] RegSetValueEx Success!\\n" ); ::RegCloseKey(hKey); return 0; } |
再次执行批处理
1
|
REG query "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "test" >>result.txt |
成功获得键值
如图
注:
也可结合使用Wow64DisableWow64FsRedirection
和Wow64RevertWow64FsRedirection
关闭和开启重定向,以此来跳过重定向,写入64位的注册表
2、修改批处理,查询重定向后的注册表键值(验证结论用)
不修改原程序,默认让其写入HKLM\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run
修改批处理文件查询重定向后的注册表键值,代码为:
1
|
REG query "HKLM\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run" /v "test" |
在本地右键执行后可成功获得键值
注:
实际测试的过程中很少能够在本地右键执行批处理,所以该方法仅作验证思路
通常情况下,32位的程序执行批处理文件也会存在重定向的问题。
0x05 找回文件
解决思路:
同样,32位程序写入c:\\windows\\system32\\
的操作会被重定向到c:\\windows\\SysWOW64\\
32位程序如果需要访问真正的c:\\windows\\system32\\
,可访问c:\\windows\\Sysnative\\
1、修改批处理
32位程序生成的文件实际位置为C:\\Windows\\SysWOW64\\test.txt
所以批处理对应的内容如下:
1
|
dir C:\\Windows\\SysWOW64\\ test .txt >>result.txt |
2、补充
(1)之前遇到过的一个问题:
在测试Security Support Provider的时候就存在这个问题:
http://drops.wooyun.org/tips/12518
使用32位的程序将mimikatz.dll上传至域控(Server2008x64)的c:\\windows\\system32\\下
由于重定向的缘故mimikatz.dll实际的上传位置为C:\\Windows\\SysWOW64,因此导致测试失败
解决方法:
- 文件的复制路径改为c:\\windows\\Sysnative
- 换用批处理实现复制功能,不会存在重定向问题
(2)可供测试32位和64位程序区别的小方法:
32位cmd:
1
|
C:\\Windows\\SysWOW64\\cmd.exe |
64位cmd:
1
|
c:\\windows\\system32\\cmd.exe |
分别执行写注册表和写文件的操作,重定向的细节显而易见
写注册表:
1
|
reg add "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "test" |
查询注册表:
1
2
|
REG query "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "test" REG query "HKLM\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run" /v "test" |
写文件:
1
|
copy test .txt c:\\windows\\system32\\ test .txt |
查找文件:
1
2
3
|
dir c:\\windows\\system32\\ test .txt dir C:\\Windows\\SysWOW64\\ test .txt dir C:\\Windows\\Sysnative\\ test .txt |
0x06 小结
32位程序在64系统下执行的时候,如果有对注册表和文件的操作,重定向的细节必须考虑。
对注册表操作:
访问HKLM\\Software\\
的实际路径为HKLM\\Software\\Wow6432Node\\
对文件操作:
访问c:\\windows\\Sysnative\\
的实际路径为 c:\\windows\\system32\\
访问c:\\windows\\system32\\
的实际路径为 c:\\windows\\SysWOW64\\
引用Stuart@ukstufus文章中的两幅图,能够帮助大家更清晰的认识其中的细节。
感谢Stuart@ukstufus的分享。解决了我的问题,也让我有了更清楚的认识。
更多学习资料:
- https://msdn.microsoft.com/en-us/library/windows/desktop/aa384232(v=vs.85).aspx
- https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx
本文由三好学生原创并首发于乌云drops,转载请注明
http://drops.wooyun.org/tips/14831
以上是关于关于32位程序在64位系统下运行中需要注意的重定向问题(有图,很清楚)的主要内容,如果未能解决你的问题,请参考以下文章