關於32位程式在64位系統下執行中需要注意的重定向問題
0x00 前言
[email protected] Architecture Matters》,恰巧解決了我之前遇到過的一個問題,理清了檔案和登錄檔重定向中需要注意的細節
大家在學習的過程中難免也會碰到,所以在此分享一下。
《Persistence Architecture Matters》的連結:
https://labs.mwrinfosecurity.com/blog/persistence-architecture-matters/
0x01 消失的登錄檔鍵值
OS:Win8x64
開發環境:VS2008
1、編寫程式寫入登錄檔
程式碼如下:
#!cpp
#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、獲取寫入的鍵值
編寫批處理檔案來獲得寫入的結果
批處理內容如下:
#!bash
REG query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v "test" >>result.txt
在本地右鍵直接執行批處理檔案
可是,批處理執行後無法輸出寫入的鍵值
0x02 消失的檔案
1、編寫程式寫入檔案
程式碼如下:
#!cpp
#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、獲取寫入的檔案
批處理內容如下:
#!bash
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
修改後的程式碼如下:
#!cpp
#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;
}
再次執行批處理
#!bash
REG query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v "test" >>result.txt
成功獲得鍵值
如圖
注:
也可結合使用Wow64DisableWow64FsRedirection
和Wow64RevertWow64FsRedirection
關閉和開啟重定向,以此來跳過重定向,寫入64位的登錄檔
2、修改批處理,查詢重定向後的登錄檔鍵值(驗證結論用)
不修改原程式,預設讓其寫入HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run
修改批處理檔案查詢重定向後的登錄檔鍵值,程式碼為:
#!bash
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
所以批處理對應的內容如下:
#!bash
dir C:\Windows\SysWOW64\test.txt >>result.txt
2、補充
(1)之前遇到過的一個問題:
在測試Security Support Provider的時候就存在這個問題:
/tips/?id=12518
使用32位的程式將mimikatz.dll上傳至域控(Server2008x64)的c:\windows\system32\下
由於重定向的緣故mimikatz.dll實際的上傳位置為C:\Windows\SysWOW64,因此導致測試失敗
解決方法:
- 檔案的複製路徑改為c:\windows\Sysnative
- 換用批處理實現複製功能,不會存在重定向問題
(2)可供測試32位和64位程式區別的小方法:
32位cmd:
#!bash
C:\Windows\SysWOW64\cmd.exe
64位cmd:
#!bash
c:\windows\system32\cmd.exe
分別執行寫登錄檔和寫檔案的操作,重定向的細節顯而易見
寫登錄檔:
#!bash
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v "test"
查詢登錄檔:
#!bash
REG query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v "test"
REG query "HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run" /v "test"
寫檔案:
#!bash
copy test.txt c:\windows\system32\test.txt
查詢檔案:
#!bash
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\
[email protected],能夠幫助大家更清晰的認識其中的細節。
[email protected],也讓我有了更清楚的認識。
更多學習資料:
- 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,轉載請註明
相關文章
- 教育直播系統搭建需要注意的問題2020-04-07
- 關於程式碼如何執行的五個問題2023-12-25
- 關於 Angular Universal 應用執行時需要 Browser API 的問題2023-02-18AngularAPI
- 關於 SAP Spartacus 重定向部分外部 url 到後臺系統的問題2022-11-06
- 關於 AppCrawler 執行過程中的幾個小問題2020-07-22APP
- [提問交流]在Apache下重定向問題 /login 重定向到 /home/passport/login 有問題2019-05-11ApachePassport
- equals中關於空格需要注意的地方2018-05-20
- 關於js執行緒問題的解讀2018-12-28JS執行緒
- 關於物件導向的方法並行執行的問題2024-07-13物件並行
- 電磁流量計在使用需要注意的問題2020-12-21
- 啟明雲端分享|關於sigmastar SSD201/SSD202D核心板在使用中需要注意的問題2021-10-12AST
- 04.關於執行緒你必須知道的8個問題(下)2023-01-01執行緒
- vue中需要注意的問題總結(上)2018-04-17Vue
- 關於在執行java連線MongoDB時遇到的連線超時問題2018-11-06JavaMongoDB
- Parallel Desktop 中執行 Win10 系統的目錄問題2020-05-14ParallelWin10
- 關於使用JupyterNotebook執行程式碼執行到一半會閃退的問題2022-01-02行程
- 有個關於多執行緒的識別問題2020-05-08執行緒
- 使用 sendBeacon 需要注意的問題2023-02-10
- 03.關於執行緒你必須知道的8個問題(中)2022-12-26執行緒
- 關於我寫的python 金融量化盤後分析系統執行出現的一些問題2020-12-30Python
- 關於 Android studio 在xml中不提示的問題2019-01-09AndroidXML
- CentOS 7系統中執行yum命令失敗問題的排查方法2020-08-25CentOS
- 關於debian系統下使用vi編輯語法不高亮的問題2020-12-29
- windows10系統限制應用程式在集合中執行的方法2018-07-28Windows
- 關於mes系統硬體配置問題2020-04-16
- 面試中關於多執行緒同步,你必須要思考的問題2019-07-24面試執行緒
- J2SE - 關於SimpleDateFonnat的執行緒安全問題2018-05-18執行緒
- 10個需要注意的SQL問題2023-09-20SQL
- 關於如何解決IDEA中同一個src下多個類中之一執行時自動報錯其他類中的問題導致想要執行的類無法正常執行的問題的解決思路2024-08-18Idea
- 關於《深入理解計算機系統》 程式碼是怎麼執行的2018-09-27計算機
- 開發陪診程式專案需要注意問題2023-04-27
- 【ansible】關於ansible執行過程中載入環境變數問題2020-10-03變數
- 執行緒問題2(注意例項變數)2020-04-05執行緒變數
- win系統伺服器在使用過程中需要注意什麼2023-03-17伺服器
- 程式設計中對於檔案路徑應該注意的問題2019-01-08程式設計
- Linux中重定向應注意的事情2023-05-08Linux
- 關於如何系統提升自己專業能力的問題?2021-11-25
- 關於重定向2023-05-01