關於32位程序在64位系統下運行中須要注意的重定向問題(有圖,很清楚)

0x00 前言


最近學習了Stuart@ukstufus的文章《Persistence Architecture Matters》,恰巧解決了我以前遇到過的一個問題,理清了文件和註冊表重定向中須要注意的細節windows

你們在學習的過程當中不免也會碰到,因此在此分享一下。api

《Persistence Architecture Matters》的連接:
https://labs.mwrinfosecurity.com/blog/persistence-architecture-matters/bash

0x01 消失的註冊表鍵值


OS:Win8x64
開發環境:VS2008ide

一、編寫程序寫入註冊表

代碼以下:函數

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測試

如圖spa

Alt text

二、獲取寫入的鍵值

編寫批處理文件來得到寫入的結果code

批處理內容以下:blog

1
REG query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v "test" >>result.txt

在本地右鍵直接執行批處理文件

但是,批處理執行後沒法輸出寫入的鍵值

0x02 消失的文件


一、編寫程序寫入文件

代碼以下:

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

如圖

Alt text

二、獲取寫入的文件

批處理內容以下:

1
dir c:\windows\system32\ test .txt >>result.txt

在本地右鍵直接執行批處理文件

一樣,批處理沒法輸出寫入的文件內容

0x03 緣由分析


一、重定向

自xp系統開始,64位的系統引入了新技術:文件重定向和註冊表重定向
這個技術是爲了在64位系統下將32位程序和64程序分離開
在64位平臺上運行32位程序的模擬器被稱爲WOW64
WOW64全稱爲"Windows 32 on Windows 64"

二、註冊表重定向

在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文件

三、文件重定向

一樣,文件系統也存在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

解決方法:

一、修改調用的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

成功得到鍵值

如圖

Alt text

注:
也可結合使用Wow64DisableWow64FsRedirectionWow64RevertWow64FsRedirection關閉和開啓重定向,以此來跳太重定向,寫入64位的註冊表

二、修改批處理,查詢重定向後的註冊表鍵值(驗證結論用)

不修改原程序,默認讓其寫入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\

一、修改批處理

32位程序生成的文件實際位置爲C:\Windows\SysWOW64\test.txt

因此批處理對應的內容以下:

1
dir C:\Windows\SysWOW64\ test .txt >>result.txt

二、補充

(1)以前遇到過的一個問題:

在測試Security Support Provider的時候就存在這個問題:
http://drops.wooyun.org/tips/12518

使用32位的程序將mimikatz.dll上傳至域控(Server2008x64)的c:\windows\system32\下

因爲重定向的緣故mimikatz.dll實際的上傳位置爲C:\Windows\SysWOW64,所以致使測試失敗

解決方法:

  1. 文件的複製路徑改成c:\windows\Sysnative
  2. 換用批處理實現複製功能,不會存在重定向問題

(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的分享。解決了個人問題,也讓我有了更清楚的認識。

更多學習資料:

本文由三好學生原創並首發於烏雲drops,轉載請註明

http://drops.wooyun.org/tips/14831

相關文章
相關標籤/搜索