最近開始學習網絡安全和系統安全,接觸到了很多新術語、新方法和新工具,作為一名初學者,感覺安全領域涉及的知識好廣、好雜,但同時也非常有意思。這系列文章是作者學習安全過程中的總結和探索,我們一起去躺過那些坑、跨過那些洞、守住那些站,真心希望文章對您有所幫助,感謝您的閱讀和關注。
黑客第一篇文章將分享獲取主機信息,利用注冊表獲取主機名及USB歷史痕跡、回收站文件等,這些知識廣泛應用于電子取證、Web滲透和攻擊溯源領域,并且USB歷史痕跡是本文的亮點。希望這篇基礎文章對您有所幫助,更希望大家提高安全意識,學會相關防范,也歡迎大家討論。娜璋AI安全之家于2020年8月18日開通,將專注于和安全技術,主要分享Web滲透、系統安全、CVE復現、威脅情報分析、人工智能、大數據分析、惡意代碼檢測等文章。真心想把自己近十年的所學所做所感分享出來,與大家一起進步。
聲明:本人堅決反對利用教學方法進行惡意攻擊的行為,一切錯誤的行為必將受到嚴懲,綠色網絡需要我們共同維護,更推薦大家了解技術背后的原理,更好地進行安全防護。雖然作者是一名安全小白c返回注冊表值是否存在,但會保證每一篇文章都會很用心地撰寫,希望這些基礎性文章對你有所幫助,在安全路上一起前行。
文章目錄:
一.獲取主機信息
WMI( ) 是一項核心的管理技術,WMI模塊可用于獲取內部信息。WMI作為一種規范和基礎結構,通過它可以訪問、配置、管理和監視幾乎所有的資源,比如用戶可以在遠程計算機器上啟動一個進程;設定一個在特定日期和時間運行的進程;遠程啟動計算機;獲得本地或遠程計算機的已安裝程序列表;查詢本地或遠程計算機的事件日志等等。
本文使用獲取系統上相關的信息可以使用WMI接口c返回注冊表值是否存在,安裝調用PIP工具即可。
下面的代碼是獲取主機相關信息。
import wmi
import os
import socket
w = wmi.WMI()
#獲取電腦使用者信息
for CS in w.Win32_ComputerSystem():
#print(CS)
print("電腦名稱: %s" %CS.Caption)
print("使用者: %s" %CS.UserName)
print("制造商: %s" %CS.Manufacturer)
print("系統信息: %s" %CS.SystemFamily)
print("工作組: %s" %CS.Workgroup)
print("機器型號: %s" %CS.model)
print("")
#獲取操作系統信息
for OS in w.Win32_OperatingSystem():
#print(OS)
print("操作系統: %s" %OS.Caption)
print("語言版本: %s" %OS.MUILanguages)
print("系統位數: %s" %OS.OSArchitecture)
print("注冊人: %s" %OS.RegisteredUser)
print("系統驅動: %s" %OS.SystemDevice)
print("系統目錄: %s" %OS.SystemDirectory)
print("")
#獲取電腦IP和MAC信息
for address in w.Win32_NetworkAdapterConfiguration(ServiceName = "e1dexpress"):
#print(address)
print("IP地址: %s" % address.IPAddress)
print("MAC地址: %s" % address.MACAddress)
print("網絡描述: %s" % address.Description)
print("")
#獲取電腦CPU信息
for processor in w.Win32_Processor():
#print(processor)
print("CPU型號: %s" % processor.Name.strip())
print("CPU核數: %s" % processor.NumberOfCores)
print("")
#獲取BIOS信息
for BIOS in w.Win32_BIOS():
#print(BIOS)
print("使用日期: %s" %BIOS.Description)
print("主板型號: %s" %BIOS.SerialNumber)
print("當前語言: %s" %BIOS.CurrentLanguage)
print("")
#獲取內存信息
for memModule in w.Win32_PhysicalMemory():
totalMemSize = int(memModule.Capacity)
print("內存廠商: %s" %memModule.Manufacturer)
print("內存型號: %s" %memModule.PartNumber)
print("內存大小: %.2fGB" %(totalMemSize/1024**3))
print("")
#獲取磁盤信息
for disk in w.Win32_DiskDrive():
diskSize = int(disk.size)
print("磁盤名稱: %s" %disk.Caption)
print("硬盤型號: %s" %disk.Model)
print("磁盤大小: %.2fGB" %(diskSize/1024**3))
#獲取顯卡信息
for xk in w.Win32_VideoController():
print("顯卡名稱: %s" %xk.name)
print("")
#獲取計算機名稱和IP
hostname = socket.gethostname()
ip = socket.gethostbyname(hostname)
print("計算機名稱: %s" %hostname)
print("IP地址: %s" %ip)
輸出結果如下圖所示:
二.獲取注冊表信息1.注冊表基本結構
注冊表()是系統中一個重要的數據庫,它用于存儲有關應用程序、用戶和系統信息。注冊表的結構就像一顆樹,樹的頂級節點(hive)不能添加、修改和刪除,如下圖所示是注冊表的頂級節點。
在C#中對注冊表進行操作,需要引用命名空間using .Win32。
注冊表中常用的數據類型有:
2.注冊表基本操作
注冊表操作主要調用擴展包。官方文檔如下:
基本操作函數如下:
(1) 創建操作
例如在下創建鍵,其中我們最常用的是在\這個鍵下創建程序產品鍵,保存一些程序的配置在注冊表中。如果中沒有鍵,則會先創建這個鍵及其子鍵,如果存在就不會重寫。
運行結果如下:
(2) 檢索鍵值操作
在下面新建一個值yxz,內容為“hello na”,然后編寫代碼讀取相關的內容。
輸出結果如下圖所示:
(3) 創建鍵值操作
創建鍵值代碼如下,但會提示: [ 5] 拒絕訪問錯誤。
(4) 刪除鍵值操作
成功刪除鍵值,如下圖所示。
(5) 其他操作
3.獲取用戶賬戶信息
獲取用戶名稱的代碼如下:
執行結果如下,我們可以通過讀取含有Users字段的數據,從而間接獲取用戶賬戶信息。
C:\Users\xiuzhang
三.獲取回收站內容
為什么我們要去獲取回收站文件呢?因為很多情況下調查取證需要獲取遠程目標的歷史痕跡,回收站是重要的一個目標。在操作系統中,回收站是一個專門用來存放被刪除文件的特色文件夾。
在使用FAT文件系統的系統中,回收站目錄通常是C:\;在 、 XP在內支持的NTFS操作系統中,C:\;在 Vista和中,回收站目錄是C:\$.Bin。如下圖所示,回收站中包含兩個文件,分別位于桌面和D盤目錄。
第一步,檢測回收站目錄是否存在。
操作系統輸出結果如下所示:
第二步,找到回收站之后,檢測其中的內容,如下圖所示,字符串SID與用戶賬戶名是對應的,比如1001結尾的SID。
第三步,編寫代碼獲取回收站文件夾所在目錄。
輸出結果如下圖所示:
第四步,用將用戶的SID關聯起來,使用注冊表將SID轉化為一個準確的用戶名。
編寫一個函數來將每一個SID轉化為用戶名,這個函數將打開注冊便檢查鍵值,找到其值并從中找到用戶名。
如下圖所示,用戶名為“”。
第五步,獲取回收站所有內容,完整代碼如下。
輸出結果如下圖所示:
對應的回收站內容如下,但非常可惜獲取的值無法對應,why?后續作者會繼續深入挖掘。
如果我們想把文件刪除到回收站,又怎么解決呢?刪除文件一般使用os.,但這樣是直接刪除文件,不刪到回收站的,那么想刪除文件到回收站怎么辦?
(1) 安裝擴展包(含)。
(2) 調用函數實現刪除文件至回收站。
在的文件中定義了一個名為的外殼函數,用它可以實現各種文件操作,如文件的拷貝、刪除、移動等,該函數使用起來非常簡單,它只有一個指向結構的參數。
最終效果如下圖所示,可以看到.rb文件被成功刪除。
注意,注冊表操作可能會遇到“: [ 5] 拒絕訪問”問題,我們需要設置.exe用戶名完全控制,并且用管理員方式打開即可解決。
四.獲取U盤痕跡
這部分我認為是本文最大的亮點。在系統中,當一個USB移動存儲設備插入時,就會在注冊表中留下痕跡。當移動設備插入計算機時,即插即用管理器PnP(Plug and Play)接受該事件,并且在USB設備的固件( )中查詢有關該設備的描述信息(廠商、型號、序列號等)。當設備被識別后,在注冊表中創建一個新的鍵值:
在這個鍵值下,會看到類似下面的結構子鍵,該子鍵代表設備類標示符,用來標識設備的一個特定類。
其中,子鍵中"###"代表區域由PnP管理器依據在USB設備描述符中獲取的數據填寫。如下圖所示:
注意需要判斷值為disk,即為磁盤的子項,光盤為cdrom。
如果使用工具可以看見USB設備描述內容,其中的信息都是相互對應的。設備類ID一旦建立,就需要建立一個特定唯一的UID,它可以把具有同一設備類標識的多個存儲設備區分。
完整實現代碼如下:
# encoding:utf-8
from winreg import *
import sys
usb_name = []
uid_flag = []
usb_path = []
#連接注冊表根鍵 以HKEY_LOCAL_MACHINE為例
regRoot = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
#檢索子項
subDir = r"SYSTEM\CurrentControlSet\Enum\USBSTOR"
#獲取指定目錄下所有鍵的控制
keyHandle = OpenKey(regRoot, subDir)
#獲取該目錄下所有鍵的個數(0-下屬鍵個數 1-當前鍵值個數)
count = QueryInfoKey(keyHandle)[0]
print(count)
#窮舉USBSTOR鍵獲取鍵名
for i in range(count):
subKeyName = EnumKey(keyHandle, i)
subDir_2 = r'%s\%s' % (subDir, subKeyName)
#print(subDir_2)
#根據獲取的鍵名拼接之前的路徑作為參數 獲取當前鍵下所屬鍵的控制
keyHandle_2 = OpenKey(regRoot, subDir_2)
num = QueryInfoKey(keyHandle_2)[0]
#遍歷子鍵內容
for j in range(num):
subKeyName_2 = EnumKey(keyHandle_2, j)
#print(subKeyName_2)
result_path = r'%s\%s' % (subDir_2, subKeyName_2)
#獲取具體鍵值內容并判斷Service為disk
keyHandle_3 = OpenKey(regRoot, result_path)
numKey = QueryInfoKey(keyHandle_3)[1]
for k in range(numKey):
#獲取USB名稱
name, value, type_ = EnumValue(keyHandle_3, k)
if(('Service' in name) and ('disk'in value)):
value,type_ = QueryValueEx(keyHandle_3,'FriendlyName')
usb = value
uid = subKeyName_2
path = "USBSTOR" + "\\" + subKeyName + "\\" + subKeyName_2
print(usb)
print(uid)
print(path)
print("")
#關閉鍵值
CloseKey(keyHandle)
CloseKey(regRoot)
輸出的USB記錄鍵名如下圖所示,包括三星、金盾、等U盤或硬盤型號。
其中對應的注冊表信息如下圖所示,即是輸出的USB名稱“ 2.0 USB ”,UID序號為“0105&0”,搜索的(服務)為disk(磁盤)的選項。
簡單總結:
個人感覺這方面的資料真心很少,文章博客也少,所以看起來操作似乎很簡單,但真正實現起來還是令人深思的。然后就是其實存儲USB記錄的還有很多鍵值,如
接下來我想要完成的就是如何把這些鍵值聯系起來,似乎要通過,同時怎樣獲取時間,怎樣正確刪除這些信息都值得深究。
五.總結
這篇文章真的花費了一些精力,希望您喜歡。同時感覺自己要學習的知識好多,也有好多大神臥虎藏龍,開源分享。作為初學者,我們可能有差距,不論你之前是什么方向,是什么工作,是什么學歷,是大學大專中專,亦或是高中初中,只要你喜歡安全,喜歡滲透,就朝著這個目標去努力吧!有差距不可怕,我們需要的是去縮小差距,去戰斗,況且這個學習的歷程真的很美,安全真的有意思。但切勿去做壞事,我們需要的是白帽子,是維護我們的網絡,安全路上共勉。
最后,真誠地感謝您關注“娜璋之家”公眾號,也希望我的文章能陪伴你成長,希望在技術路上不斷前行。文章如果對你有幫助、有感悟,就是對我最好的回報,且看且珍惜!再次感謝您的關注,也請幫忙宣傳下“娜璋之家”,哈哈~初來乍到,還請多多指教。
日日思君不見君,共看夕陽落。
(By:娜璋之家公眾號 2020-09-05 夜于武漢)
參考文獻: