关于个人防火墙的真相
原文作者:MaD?
原文標題:The truth aboutpersonal firewalls
電子郵件:mad-factor@mail.ru
作者國籍:俄羅斯
聲明:1、本人翻譯水平有限,有不當之請大家理解。如部分看不懂可以和原文對照。
??? ???? ?? 2、歡迎轉載,但請不要漏掉原文作者和翻譯者的信息。
??? ???? ?? 3、歡迎大家指出我翻譯中的錯誤,我好改正。
內容:
??? ????有多種方式來保護你的計算機免受惡意軟件的侵害,比如軟件防火墻,病毒和Rootkit檢 測軟件等。所有這些防護軟件都基于一些眾所周知而幾乎沒有改進的技術,而且這些技術你也許已經知道,繼承這些技術的安全產品也是不完善的。這樣的后果通常 是可怕的。然而這些安全公司卻天真的認為他們的產品是最先進的,包含了最新的特性,是用戶必備的。但是只要你透過他們的華麗的外衣就會看到,他們的Bug和錯誤甚至比你在學校的設計還要多。雖說生產一款產品首要的是好而強有力的廣告。但沉重的廣告和糟糕的測試結合在一起能向用戶展示一些產品所謂的強大嗎,能使其產生一種強烈的購買欲望嗎?當然不行。
??? ????保護你的個人電腦免受外部的和內部的第三者的攻擊是一個好主意。一些保護你的PC遠離木馬和間諜軟件“啟發(fā)式”的方法好像真在工作。如果他們工作的話,付30到50美元就能獲得實時的保護和更新的確是個非常好的想法。可惜,他們不能。
??? ????首先我想為我糟糕的英語道歉。我們的討論將會涉及以下產品:
??? ?????? ZoneAlarm Firewall 6.x
??? ?????? Outpost Firewall 3.x and 4.x
?? ?? ???? Look'n'Stop Firewall 2.0
??? ?????? Kerio Firewall 4.3
??? ?????? Sygate Firewall 5.6
??? ?????? Jetico Firewall 1.0
??? ?????? PortsLock Firewall 1.9
?? ?? ???? Tiny Firewall 6.5
??? ?????? Norton Internet Security 8.0
??? ?????? Comodo Firewall 2.4
??? ?????? OnlineArmor Firewall 2.1
??? ????個人軟件防火墻的保護有2種基本級別:NDIS(網絡驅動接口規(guī)范)和TDI(傳輸數據接口)。NDIS級是建立在TCP/IP棧的基礎上的,在這個級別上的保護能阻止基于TCP/IP棧BUG的攻擊,甚至你不用更新你的棧;他也能防御許多電子欺騙,洪水攻擊和分布式拒絕服務攻擊。沒有使用NDIS技術的防火墻自然變成了局外人。失敗者有PortsLock防火墻, Norton Internet Security, Comodo防火墻?等。你真的愿意為PortsLock防火墻付35歐元嗎,他甚至不能抵御低級別的TCP/IP攻擊。或者為Comodo付79美元?為你的系統(tǒng)感到悲哀。真正的防火墻是基于NDIS級的。基于NDIS有兩種不同的保護方法。第一種是NDIS-hooking保護。主要方法是HooksNdisRegisterProtocol()/NdisOpenAdapter()。當NDIS協(xié)議試圖被注冊時或是正要綁定某個適配器時,防火墻將接到通知。在防火墻正在HOOK NDIS_PROTOCOL_BLOCK andNDIS_OPEN_BLOCK的句柄的這個關鍵時刻,并且當系統(tǒng)想要發(fā)送或接收數據包時,防火墻將會被通知當這些發(fā)生的時候。防火墻正試圖安裝他們的鉤子時是有趣的時候,幾乎每個防火墻都是hook NDIS_PROTOCOL_BLOCK的句柄,但是Sygate, Kerio?和Jetico等除外,他們是HOOK NDIS_PROTOCOL_CHARACTERISTICS的句柄,而不是調用真正的NdisRegisterProtocol(),在那之后他們又移動到原來的句柄。更安全嗎?對嗎?正是,防火墻應該獨立工作,與多少協(xié)議被注冊和多少被綁定無關。是的,每個防火墻都支持這個。例如,當ZoneAlarm正在hook一個句柄時,他是分配一個無分頁的內存并且放入以下幾條指令。
pop????????eax????????;?58
push????????HookData????;?68?XX?XX?XX?XX
push????????eax????????;?50
jmp????????HookedHandler????;?E9?XX?XX?XX?XX
??? ????然后,他寫一些重要的信息在其他內存片,調用HookData和所有在NDIS_PROTOCOL_BLOCK中被hook的句柄:
??? ???
OpenAdapterCompleteHandler
CloseAdapterCompleteHandler
BindAdapterHandler
UnbindAdapterHandler
??? ????在NDIS_OPEN_BLOCK中的:
??? ???
??? SendHandler
??? ReceiveHandler
??? ReceivePacketHandler
??? SendPacketsHandler
??? ????對NDIS_PROTOCOL_BLOCK象下面這樣:
??? ???
??? VOID HookedOpenAdapterComplete(
??? ???PVOID HookData,
??? ??? INNDIS_HANDLE? ProtocolBindingContext,
??? ??? INNDIS_STATUS? Status,
?? ?? ? INNDIS_STATUS? OpenErrorStatus
??? );
??? ???真正的OpenAdapterComplete()?句柄被放在這:[HookData + 0x770]
??? ???
??? VOID HookedCloseAdapterComplete(
??? ???PVOID HookData,
??? ??? INNDIS_HANDLE? ProtocolBindingContext,
??? ??? INNDIS_STATUS? Status
??? );
??? ???真正的CloseAdapterComplete()?句柄被放在這:[HookData + 0x774]
???????
??? VOID HookedBindAdapter(
??? ???PVOID HookData,
??? ???OUT PNDIS_STATUS Status,
??? ??? INNDIS_HANDLE? BindContext,
??? ??? INPNDIS_STRING? DeviceName,
?? ?? ? INPVOID? SystemSpecific1,
??? ??? INPVOID? SystemSpecific2
??? );
??? ???真正的BindAdapter()?句柄被放在這:[HookData + 0x764]
? ???
?? VOID HookedUnbindAdapter(
??? ???PVOID HookData,
??? ???OUT PNDIS_STATUS? Status,
??? ??? INNDIS_HANDLE? ProtocolBindingContext,
??? ??? INNDIS_HANDLE? UnbindContext
??? );
??? ????真正的UnbindAdapter()??句柄被放在這:?[HookData + 0x768]
??? ??? For NDIS_OPEN_BLOCK:
?? VOIDHookedSend(
??? ???PVOID HookData,
??? ??? INNDIS_HANDLE? NdisBindingHandle,
??? ???IN? PNDIS_PACKET? Packet
??? );
??? ???真正的Send()??句柄被放在這:?[HookData + 0x1A4]
????
?VOID? HookedReceive(
??? ???PVOID HookData,
??? ???IN? NDIS_HANDLE????????????ProtocolBindingContext,
??? ???IN?NDIS_HANDLE????????????MacReceiveContext,
??? ???IN?PVOID??????????????????HeaderBuffer,
??? ???IN?UINT???????????????????HeaderBufferSize,
?? ?? ?IN?PVOID??????????????????LookAheadBuffer,
??? ???IN?UINT???????????????????LookaheadBufferSize,
??? ???IN?UINT???????????????????PacketSize
??? );
??? ???真正的Receive()?句柄被放在這:?[HookData + 0x4D0]
?VOID HookedReceivePacket(
??? ???PVOID HookData,
??? ???IN?NDIS_HANDLE????????????ProtocolBindingContext,
??? ???IN?PNDIS_PACKET???????????Packet
);
??? ???真正的ReceivePacket()?句柄被放在這:?[HookData + 0x570]
VOID HookedSendPackets(
??? ???PVOID HookData,
?? ?? ? INNDIS_HANDLE?????????????MiniportAdapterContext,
??? ??? INPPNDIS_PACKET???????????PacketArray,
?? ?? ? INUINT????????????????????NumberOfPackets
);
??? ???真正的SendPackets()??句柄被放在這:? [HookData+2E4h]
??? ????可憐的ZoneAlarm,這是如此的簡單對于獲取真實的句柄并恢復他。
??? ????我說過,每個防火墻都支持多數的注冊協(xié)議。事實上,并不是每個。Sygate認為,保持關于協(xié)議和公開包的所有信息在他的.data段中已經足夠了。不幸是個壞主意。他的句柄HOOK方式比ZoneAlarm簡單,但是說明哪些內存將被分配的指令被?放在Sygate的驅動Teefer.sys中:
???pop???????eax??????? ; 58
???push??????? HookData??? ; 68XX XX XX XX
???push???????eax??????? ; 50
???jmp??????? FakeHandler??? ;E9 XX XX XX XX
??? ??? HookData也是放在.data中的。Sygate總共能HOOK576個句柄(包括協(xié)議和開放塊句柄)。于是,大約有40-50個NDIS_PROTOCOL_BLOCK和NDIS_OPEN_BLOCK能被Hook(不要忘記幾個開放塊能被附加到一個協(xié)議塊)。大概40-50塊已經足夠了,但那樣的代碼實在是個糟糕的設計,給緩沖區(qū)溢出打了個招呼。
??? ????我有另外一個好例子,是關于關于多么有必要知道怎樣Hook和hook多少。那些來自Kerio防火墻小組的家伙不知道這些。作為一個好的防火墻,設置HOOK在?NdisRegisterProtocol(), NdisDeregisterProtocol(), NdisOpenAdapter(),NdisCloseAdapter()?等函數并且HOOK句柄。就像我說的,Kerio只是hook NDIS_PROTOCOL_CHARACTERISTICS的句柄并且僅僅調用NdisRegisterProtocol()函數,但他不將句柄移回NDIS_PROTOCOL_CHARACTERISTICS。這會怎樣?未公開的特性?我不這樣認為,恰恰是粗心的編碼和對內核標準和架構的誤解。另一個好的例子是,Kerio團隊不知道任何關于NDIS的開發(fā),事實就是這樣,他們甚至不知道怎樣去HOOK。Kerio防火墻HOOK在NDIS_PROTOCOL_CHARACTERISTICS里:
??? OpenAdapterCompleteHandler
???CloseAdapterCompleteHandler
????并這樣hook NDIS_OPEN_BLOCK:
??? SendHandler
??? SendPacketsHandler
??? ????不是太多?剛好。他能被用來繞過他的NDIS保護,并發(fā)送一個包給TCP/IP棧。你雖然已經按了“阻止所有”按鈕,但仍然能在本地嗅探器下看到進來的數據包。我可不喜歡像Kerio防火墻假裝的那樣假裝自己受保護的時候,再去嗅探器下看數據包。從另一個方面來說,Outpost防火墻,喜歡在NDIS_PROTOCOL_BLOCK中hook更多的句柄:
??? OpenAdapterCompleteHandler
??? SendCompleteHandler
???TransferDataCompleteHandler
??? RequestCompleteHandler
??? ReceiveHandler
??? StatusHandler
??? ReceivePacketHandler
??? BindAdapterHandler
??? UnbindAdapterHandler
??? ????在?NDIS_OPEN_BLOCK中:
??? ??? Outpost4.0:
??? SendCompleteHandler
???TransferDataCompleteHandler
??? ReceiveHandler
??? ReceivePacketHandler
??? StatusHandler
??? ?? Outpost 3.x:
??? SendHandler
??? TransferDataHandler
??? SendCompleteHandler
???TransferDataCompleteHandler
??? ReceiveHandler
???RequestCompleteHandler
??? ReceivePacketHandler
??? SendPacketsHandler
??? StatusHandler
??? ???他的句柄調用和防火墻之間的代碼是非常有趣的:
??? call???ImCode??????? ; E8 XX XX XX XX
????
???? For Outpost3.x:
???pop???????eax??????? ; 58
???push???????[eax]??????? ; FF30??????? Pushing the real handler
???pushad???????????????; 60
???push???????[eax+4]??????? ; FF 70 04
???push??????? [esp+28h]??? ; FF74 24 28??? Pushing return address
???jmp???????[eax+8]??????? ; FF 60 08
??? For Outpost 4.0:
???pop???????eax??????? ; 58
???add??????? eax,3??????? ; 83 C0 03???Missing three zero bytes after call
???push???????[eax]??????? ; FF30??????? Pushing the real handler
???pushad???????????????; 60
???push???????[eax+4]??????? ; FF 70 04
???push??????? [esp+28h]??? ; FF74 24 28??? Pushing return address
???jmp???????[eax+8]??????? ; FF 60 08
??? ???像我們看到的那樣,那不是一個問題對于卸載所有的HOOK并立即獲取系統(tǒng)控制權。如果你厭煩了這中間的匯編代碼,他們通常是能夠轉換成普通C代碼的,我能向你展示一些來自Tiny防火墻團隊有趣的東西,他假裝是真正的安全,并且向我們展示了很多的hook:
??? NdisOpenAdapter
??? NdisCloseAdapter
??? NdisInitializeWrapper
??? NdisTerminateWrapper
??? NdisMRegisterMiniport
???NdisIMRegisterLayeredMiniport
??? NdisRegisterProtocol
??? NdisMSetAttributesEx
??? NdisRegisterMac
???NdisIMAssociateMiniport
???NdisClOpenAddressFamily
???NdisCmRegisterAddressFamily
???NdisMCmRegisterAddressFamily
??? NdisMCoSendComplete
??? ???哦,看起來很優(yōu)秀,也真是很優(yōu)秀的樣子,他們試圖對這些函數做一個結合HOOK通過設置跳轉到他們的句柄。我不喜歡“結合”,知道為什么嗎?那不是因為他難以實現或是有些指令很難“結合”(理論上可行,實踐上未必,我不認為在真正函數的開端那樣做可行)。主要的原因是那樣不安全。Rootkit開發(fā)者使用他是因為那是一種獲取控制權的簡單的方式,但不要試圖把他用作安全軟件中,就像用恐怖份子的方法對付恐怖分子一樣。還有要說的是,我沒有發(fā)現任何線程安全和多處理器安全的代碼。再一次失敗。當你在“結合”某些代碼的時候,你需要確信沒有一個線程、沒有一個CPU在運行這些代碼。
??? ??? Tiny防火墻為每個HOOK句柄申請內存,并拷貝這些C函數在開端和結尾:
???push???????ebp???????????????????; 55
???mov??????? ebp,esp???????????????; 8B EC
???sub??????? esp,XXh???????????????; 83 EC XX
???mov??????? byte ptr [ebp-1],XXh??????????? ; C6 45FF XX
???mov??????? dword ptr [ebp-8],HookedHandler??? ; C7 45 F8 XX XX XX XX
??? <...>
???push??????? RealHandler
???call??????? [ebp-8]
???mov??????? esp, ebp
???pop??????? ebp
???ret??????? XXh
??? ???于是這就變的相當簡單,對于從新句柄偏移0xD去獲得真的句柄。對所有的句柄,Tiny都是拷貝上面的代碼。
??? hook在NDIS_PROTOCOL_BLOCK中:
??? SendCompleteHandler
??? StatusHandler
??? Hooked?在?NDIS_OPEN_BLOCK中:
??? TransferDataHandler
??? SendCompleteHandler
???TransferDataCompleteHandler
??? ReceiveHandler
??? ReceivePacketHandler
??? StatusHandler
??? ???需要說的是,有些防火墻變聰明了,如果他們被別人hook的時候,他們會試圖恢復他們的hook。例如,Outpost防火墻就檢測這個并監(jiān)視他們的hook,但僅僅像指針的安全那樣。也許他們不認為會有剪接戲法?Outpost小組不知道,白帽子Sygate防火墻也能恢復他們的hook,但他恢復的僅僅是NDIS_OPEN_BLOCK.SendHandler和?NDIS_OPEN_BLOCK.SendPacketsHandler。那是奇怪的,因為因為他們hook了很多NDIS_PROTOCOL_BLOCK中的句柄:
??? OpenAdapterCompleteHandler
???CloseAdapterCompleteHandler
???TransferDataCompleteHandler
??? ReceiveHandler
??? StatusHandler
????和?NDIS_OPEN_BLOCK?的hook:
??? SendHandler
??? TransferDataHandler
???TransferDataCompleteHandler
??? ReceiveHandler
??? ReceivePacketHandler
??? SendPacketsHandler
??? StatusHandler
??? ???只有幾種防火墻用中間層NDIS驅動來做NDIS級的保護。這是一個聰明的解決方案。例如,Look’n’Stop?和?Outpost 2008?防火墻用IM NDIS驅動。Outpost好的改進是在去年。但是現在繞過防火墻變的容易使因為沒有HOOK,沒有伎倆和沒有任何未公布的特性被使用。現在你能粉碎所有的IM NDIS防火墻只是繞過他們。不需要擾亂防火墻接受和發(fā)送包的句柄,你也不用向他們發(fā)送包。總之,使用IM NDIS驅動是好的,眾所周知的,已公布的,一個正確的保護系統(tǒng)不受外部攻擊的方法。
??? ????像你可能看到的那樣,技術各個防火墻的技術是相似的,思路甚至能被盜用并且沒有人會說你盜用了一個想法。好的方式是透過表面創(chuàng)新你的產品。不需去思考,不用產生想法,去反匯編、調試并且對它感興趣。第二種主級別的防火墻基于TDI,傳輸數據接口能為內核傳輸協(xié)議棧提供更高級別的訪問。Afd.sys,能解析winsock,經由tdi.sys(TDI層,上面層說過)與Windows TCP/IP棧(tcpip.sys)通信。于是,又幾種方式和地方去安裝hook并監(jiān)視你的程序和網絡通信。設置你的保護最好的地方正是在tcpip.sys設備,它能在協(xié)議棧的最上層解釋執(zhí)行:
??? ??? DeviceIp
??? ??? DeviceTcp
??? ??? DeviceUdp
??? ???DeviceIPMULTICAST
??? ???DeviceRawIp
??? ????好的,你甚至能通過/Device/RawIp來戲弄一些人。對于阻止程序的一個訪問網絡的請求最好的方式(公開
的方式,也是重要的),是附加到這些設備上并監(jiān)視他們。幾乎所有的防火墻都這樣做了,因為這是通知用戶陌生程序要訪問網絡的好方法。例如,Look’n’Stop附加他的設備到tcpip.sys設備:
??? ???DevicePcaTcpFilter -> DeviceTcp
??? ???DevicePcaUdpFilter -> DeviceUdp
??? ???DevicePcaRawIpFilter -> DeviceRawIp
??? ??? /Device/Ip在那里?不是足夠的,我們需要確信,所有種類的連接需要被監(jiān)視,或是他們恰恰通過了這個假冒的保護。
??? ????你的看見這些設備在你的WinObj工具里:
??? ???DeviceComodoRawIpFilter
??? ???DeviceComodoUdpFilter
??? ???DeviceComodoTcpFilter
??? ???DeviceComodoIpFilter
??? ????我希望你能猜到,Comodo防火墻是附加設備到相同名字的tcpip.sys設備。
??? ??? Outpost、Kerio、Jetico?防火墻, Norton InternetSecurity僅僅附加一個無名的設備到Tcp,Udp,Ip,RawIp,沒有感興趣的事。了解設備棧結構的人應該知道拋開這些附加設備使防火墻不再提示是相當容易的。你只需要找到tcpip.sys的DRIVER_OBJECT的指針,遍歷DeviceObject列表,清空所有DEVICE_OBJECT的附加項。相當容易吧?但對對抗防火墻很有效,他們的防護程序就是在那附近。另一個脆弱防火墻的錯誤和夸大的廣告。除了附加技術外,還有另一種有趣而復雜的的技術,但對惡意軟件更有效,這就是MajorTable hook。大家都知道,當用戶態(tài)程序想與驅動交互的時候,他通知要交互驅動的I/O管理器。I/O管理器產生一個IRP,并調用DRIVER_OBJECT.MajorTable[IRP_MJ_XXX]的句柄。就在tcpip.sys這,一些防火墻僅僅hook一個IRP_MJ_XXX句柄并監(jiān)視所有調用,通過允許請求和拒絕禁止。找到一個真的句柄不是很容易,哈?幾乎每個人都認為那不可能。尋找一些被hook的句柄的主要方法是,他必須被調用然后會被發(fā)現。通過hook Int 0x01,設置TF,防火墻句柄的所有調用,我們能發(fā)現一個防火墻要調用的真的句柄。簡單,MajorTable-hooking技術被像ZoneAlarm這樣的防火墻青睞,他是這樣HOOK的:
??? IRP_MJ_CREATE
??? IRP_MJ_CLOSE
??? IRP_MJ_DEVICE_CONTROL
???IRP_MJ_INTERNAL_DEVICE_CONTROL
??? IRP_MJ_CLEANUP
??? ????另一個局部hook的失敗是,tcpip.sys僅有TCPDispatch()?和TCPDispatchInternalDeviceControl()2個IRP句柄,第一個被所有?MajorTable填充,把它從另一個句柄上移出時容易的。TCPDispatchInternalDeviceControl()你能通過使用另一個方法?(例如前面說的追蹤方法和反匯編方法)來發(fā)現。Sygate防火墻喜歡HOOK這些句柄:
??? ???IRP_MJ_CREATE
??? ??? IRP_MJ_CLOSE
??? ???IRP_MJ_DEVICE_CONTROL
??? ???IRP_MJ_INTERNAL_DEVICE_CONTROL
??? ??? PortsLock防火墻,hook所有MajorTable句柄。好主要,既不將TCPDispatch()也不將TCPDispatchInternalDeviceControl()給敵人。Tiny防火墻是hook下面的句柄。
??? ???IRP_MJ_CREATE
??? ???IRP_MJ_CLOSE
??? ??? IRP_MJ_DEVICE_CONTROL
??? ???IRP_MJ_INTERNAL_DEVICE_CONTROL
??? ???IRP_MJ_CLEANUP
??? ????對于在一個防火墻中僅有這種類型的保護是不嚴重的,你不這樣認為嗎?我認為像PortsLock防火墻,Norton Internet Security,Comodo防火墻和其他有“防火墻”這個錯誤稱號的,就像一些有著很漂亮界面的保護系統(tǒng)。惡意軟件正在變的越來越猖獗,每天都有大量的ROOTKIT杯注冊,更多老練的,先進的,比防火墻更底層的正在不斷涌現。他們試圖影響其他進程并隱匿其中。就像一個披著羊皮的狼。我談到,injection, OpenProcess()/WriteProcessMemory()/CreateRemoteThread()和一個好的shellcode或一個self-mapped模塊等都能透過防護與外部通信,而且工作的很好,也很容易編寫,所有需要好的保護而不受其侵害。系統(tǒng)服務標提供內核函數的訪問通道,他是通過調_KiSystemService,那是用用戶模式和驅動來實現的。防火墻為了阻止這些動作使系統(tǒng)保持健壯,成功地hook了打開進程、寫進程內存、創(chuàng)建遠線程、進程、文件、文件編輯等函數。防火墻喜歡做這些,例如,ZoneAlarm防火墻hook以下系統(tǒng)服務:
???? ZwConnectPort
??? ZwCreateFile
??? ZwCreateKey
??? ZwCreatePort
??? ZwCreateProcess
??? ZwCreateProcessEx
??? ZwCreateSection
??? ZwCreateWaitablePort
??? ZwDeleteFile
??? ZwDeleteKey
??? ZwDeleteValueKey
??? ZwDuplicateObject
??? ZwLoadKey
??? ZwMapViewOfSection
??? ZwOpenFile
??? ZwOpenProcess
??? ZwOpenThread
??? ZwReplaceKey
???ZwRequestWaitReplyPort
??? ZwRestoreKey
??? ZwSecureConnectPort
??? ZwSetInformationFile
??? ZwSetSystemInformation
??? ZwSetValueKey
??? ZwTerminateProcess
??? ???他監(jiān)視對注冊表,進程,驅動,文件的訪問,并阻止自己被關閉。Outpost Firewall 4 hook更多的服務:
??? ZwAssignProcessToJobObject
??? ZwClose
??? ZwCreateFile
??? ZwCreateKey
??? ZwCreateProcess
??? ZwCreateProcessEx
??? ZwCreateSymbolicLinkObject
??? ZwCreateThread
??? ZwDeleteFile
??? ZwDeleteKey
??? ZwDeleteValueKey
??? ZwLoadDriver
??? ZwMakeTemporaryObject
??? ZwOpenFile
??? ZwOpenKey
??? ZwOpenProcess
???ZwProtectVirtualMemory
??? ZwQueryDirectoryFile
??? ZwQueryKey
??? ZwQueryValueKey
??? ZwReplaceKey
??? ZwRestoreKey
??? ZwSaveKey
??? ZwSaveKeyEx
??? ZwSetInformationFile
??? ZwSetValueKey
??? ZwTerminateProcess
??? ZwTerminateThread
??? ZwUnloadDriver
??? ZwWriteVirtualMemory
??? ???但事實上他僅用了他們的一半。他不關心驅動,你能加載任何你想要的,但他hook了ZwLoadDriver。更多的hook就更好嗎?啊哈,對漏洞挖掘者來說更好。不是每個人都知道代碼的質量怎樣,它將要運行當我們調用ZwOpenKey時。我的系統(tǒng)將要藍屏嗎?另一個關于hook的例子是Kerio防火墻:
??? ZwClose
??? ZwCreateFile
??? ZwCreateKey
??? ZwCreateProcess
??? ZwCreateProcessEx
??? ZwCreateThread
??? ZwDeleteFile
??? ZwDeleteKey
??? ZwDeleteValueKey
??? ZwLoadDriver
??? ZwMapViewOfSection
??? ZwOpenFile
??? ZwOpenKey
??? ZwResumeThread
??? ZwSetInformationFile
??? ZwSetValueKey
??? ZwTerminateProcess
??? ZwWriteFile
??? ???沒看見ZwOpenProcess/ZwWriteVirtualMemory的hook。使用Kerio你能插入你想要的每個進程,包括允許的進程。Sygate所用的hook比其他的少:
??? ZwTerminateProcess
??? ZwMapViewOfSection
???ZwAllocateVirtualMemory
??? ZwCreateThread
???ZwProtectVirtualMemory
??? ZwWriteVirtualMemory
??? ???他們認為能通過hookZwWriteVirtualMemory來保護系統(tǒng)。那是有BUG的:你能打開進程,并改變一些線程的context,幾乎與?Jetico做的相同:
??? ZwConnectPort
??? ZwCreatePort
??? ZwCreateThread
??? ZwTerminateProcess
??? ZwWriteVirtualMemory
??? ???
??? ????不是很有趣。Tiny防火墻做的最有趣:
??? ZwCreateKey
??? ZwCreateSection
??? ZwOpenKey
??? ZwSetInformationProcess
??? ZwTerminateProcess
??? ???你能這樣說嗎?:這是容易的對于通過ZwWriteVirtualMemory來插入一些東西。當然,但當此惡意行為發(fā)生時,用戶將被通知。這是個愚蠢的小玩笑,對于在用戶模式下來保護,Tiny防火墻載入他的UmxSbxExw.dll?到每個進程并hook許多進程通過安裝每個函數開始的跳轉:
kernel32.dll:
CreateProcessA
CreateProcessW
CreateRemoteThread
DebugActiveProcess
FreeLibrary
GetProcAddress
LoadLibraryExW
OpenThread
TerminateProcess
TerminateThread
WriteProcessMemory
user32.dll:
BroadcastSystemMessage
BroadcastSystemMessageA
BroadcastSystemMessageExA
BroadcastSystemMessageExW
BroadcastSystemMessageW
EndTask
ExitWindowsEx
OpenClipboard
PostMessageA
PostMessageW
PostThreadMessageA
PostThreadMessageW
SendDlgItemMessageA
SendDlgItemMessageW
SendMessageA
SendMessageCallbackA
SendMessageCallbackW
SendMessageTimeoutA
SendMessageTimeoutW
SendMessageW
SendNotifyMessageA
SendNotifyMessageW
SetUserObjectSecurity
SetWindowsHookA
SetWindowsHookExA
SetWindowsHookExW
SetWindowsHookW
advapi32.dll:
AbortSystemShutdownW
AdjustTokenPrivileges
ChangeServiceConfig2A
ChangeServiceConfig2W
ChangeServiceConfigA
ChangeServiceConfigW
ControlService
CreateProcessAsUserA
CreateProcessAsUserW
CreateProcessWithLogonW
CreateServiceA
CreateServiceW
DeleteService
EnumDependentServicesA
EnumDependentServicesW
EnumServicesStatusA
EnumServicesStatusExA
EnumServicesStatusExW
EnumServicesStatusW
InitiateSystemShutdownExW
InitiateSystemShutdownW
OpenSCManagerA
OpenSCManagerW
OpenServiceA
OpenServiceW
QueryServiceConfig2A
QueryServiceConfig2W
QueryServiceConfigA
QueryServiceConfigW
QueryServiceStatus
QueryServiceStatusEx
SetFileSecurityW
SetKernelObjectSecurity
SetNamedSecurityInfoW
SetSecurityInfo
SetServiceObjectSecurity
StartServiceA
StartServiceW
??? ???哦,Tiny是個hook怪物。你能看見在kernel32.dll上的hook!WriteProcessMemory在他們的保護之下以防止被插入。Tiny防火墻團隊認為那是一個很酷的保護方式,在一些不穩(wěn)定的程序中他可能會掛掉。從那些進程中卸載掉他的Dll也不是件難事,恢復所有的函數入口就可以享受生活了。Outpost也喜歡這樣做,他加載他的wl_hook.dll到應該被保護以防止惡意軟件的每個進程。那是龐大的hook隊列:
kernel32.dll:
CreateProcessA
CreateProcessW
CreateRemoteThread
DebugActiveProcess
WinExec
ntdll.dll:
LdrLoadDll
LdrUnloadDll
NtCreateThread
NtResumeProcess
NtResumeThread
NtSetContextThread
NtSetValueKey
NtSuspendProcess
NtSuspendThread
NtTerminateProcess
NtWriteVirtualMemory
ZwCreateThread
ZwResumeProcess
ZwResumeThread
ZwSetContextThread
ZwSetValueKey
ZwSuspendProcess
ZwSuspendThread
ZwTerminateProcess
ZwWriteVirtualMemory
user32.dll:
CallNextHookEx
ChangeDisplaySettingsExA
ChangeDisplaySettingsExW
DdeConnect
DdeConnectList
DdeInitializeA
DdeInitializeW
EndTask
ExitWindowsEx
FindWindowExA
FindWindowExW
PostMessageA
PostMessageW
SendInput
SendMessageA
SendMessageCallbackA
SendMessageCallbackW
SendMessageTimeoutA
SendMessageTimeoutW
SendMessageW
SendNotifyMessageA
SendNotifyMessageW
SetForegroundWindow
SetWindowPos
SetWindowsHookExA
SetWindowsHookExW
??? ????那不是一個保護,是沒有必要的代碼。是的,他能抵制一些稀有惡意代碼,但沒有更多。一些防火墻不僅想被作為一個防火墻來使用,他們包含了一些有趣的特性像間諜軟件或rootkit的檢測程序。是的,他們工作了?,這就產生了一個印象。在遇到調試之前的幾分鐘。一些防火墻試圖監(jiān)視模塊的加載通過設置經由PsSetLoadImageNotiryRoutine()的例行檢查。Jetico Firewall, Look’n’Stop Firewall, Tiny Firewall,ZoneAlarm Firewall, Outpost Firewall是這樣做的。例如,當Outpost加載時,監(jiān)視dnsapi.dll的加載,他通知用戶一些程序試圖使用DNS服務。這將會發(fā)生,當你將要調用gethostbyname()時,dnsapi.dll?會自動加載。不是很酷。重命名dnsapi.dll到xxx.dll,加載它,找到DnsQuery_A的指針,并使用它來解析,OutPost將會關閉。這是個糟糕的方式對于在這兒的保護。幾乎在每個防火墻中,你都能發(fā)現很多無用的,無效的東西。有時,它幫助理解部分代碼或給出一個例子函數命名,甚至你能發(fā)現一些調式信息。Look’n’Stop防火墻團隊沒有區(qū)分發(fā)布版和調試版,可能那就是他們?yōu)槭裁戳粝逻@些東西在這:
??? push??? offsetasc_187DC ; "f://dev//lns//2.05.cur//tdisys//w32api.c"
???push??? offset aKegetcurren_23 ; "KeGetCurrentIrql() ==PASSIVE_LEVEL"
???call??? ds:RtlAssert
??? ????斷言在調試構建時是有用的,但不是在發(fā)布版中。Tiny防火墻有很多奇怪的格式串日志:
?.text:00011608 aNbh0x08xMac0x0 db9,'nbh:0xX mac:0xX mah:0xX ??? ???pbc:0xX',0Dh,0Ah
.text:00011608 ; DATA XREF:HookedNdisOpenAdapter+273 o
.text:00011608 db9,'med:"%s"',0Dh,0Ah
.text:00011608 db9,'drv:"%s"',0Dh,0Ah
.text:00011608 db9,'dev:"%s"',0Dh,0Ah
.text:00011608 db9,'ada:"%s"',0
.text:00011661 align 4
我認為沒人想因為這些奇怪的記錄而看見藍屏。ZoneAlarm也喜歡記錄:
.text:0001A610 aUPacketSProtoS db '%uPacket %s: Proto: %s Flags: 0xlx Src: %2u.%2u.%2u.%2u '
.text:0001A610 ; DATA XREF:sub_1A693+119 o
.text:0001A610 db 'Dest: %2u.%2u.%2u.%2u',0
他尤其喜歡記錄在發(fā)布版本中,當然。
.text:00025A84 aSFragTLxHLxPfl db '%sfrag: t=%lx h=%lx pflg=%lx subp=%lx sip=%d.%d.%d.%d dip=%'
.text:00025A84 ; DATA XREF:sub_25BAA+2D1 o
.text:00025A84 db 'd.%d.%d.%d id=%xf=%s%s%s off=%hu act=%lx',0Ah,0
我喜歡?ZoneAlarm,他給我一些函數的名字:
.text:00050250 aVsdatantVstdic db'VSDATANT:vsTdiClientRequestReceivePreProc(): FO=%p SE=%p RE#'
.text:00050250 ; DATA XREF: sub_502A6+D3o
.text:00050250 db '=%d IRP=%p :TIMEOUT(%u)',0Ah,0
Kerio防火墻團隊不包含路徑就不能生成他們的驅動:
.rdata:00433704aCProjectsNetsecuritytoolsFire db 'C:/Projects/netsecuritytools/FirewallSDK/Build.Release/4.3.'
.rdata:00433704 db'x/bin/Release/fwdrv.pdb',0
他們也這樣記錄:
.data:00434020 aFwdrvApicopyas db'FWDRV: ApiCopyAssociatedEndpoint: Local: %u.%u.%u.%u:%u Remo'
.data:00434020 ; DATA XREF:sub_401150+3B4 o
.data:00434020 db 'te:%u.%u.%u.%u:%u,SpeedIn: %u, SpeedOut: %u, PID: 0xX, A'
.data:00434020 db 'pp: [%s], Service:[%s]',0
并且真是有大量這樣的記錄:
.data:0043B1D4 aSPagedCodeCa_7 db '%s():Paged code called on IRQL %d',0
??? ???我想說的是:不要緊,你喜歡記錄多少,你應該移走這樣的垃圾記錄和垃圾代碼在發(fā)布版中。越少的代碼,越少的bug。也學下次藍屏會剛好在那些糟糕測試并綁定調試信息的代碼中。今年的首次揭幕是OnlineArmor防火墻。“Online Armor有一個非常好的機會,調者華爾茲就竊取了蘇格蘭時事通訊2008最佳軟件防火墻的榮譽稱號”?是的,在DriverVerifier下的首次測試就給我了一個藍屏。真是很有趣,他在標準檢查工具下掛掉了。?在里面你能發(fā)現IRP_MJ_DEVICE_CONTROL?句柄,那是處理所有與METHOD_NEITHER有關的IOCTLs。
??? ????你知道ProbeForRead()/ProbeForWrite()?他們甚至不檢查指針是否為空,這真是可笑,所有Windows用戶的最好保護軟件有如此多的問題。猜猜它能怎么樣?一部分16進制的代碼如下所示:
?int __stdcall DispatchDeviceControl(intDeviceObject, PIRP Irp)
{
? struct_IRP::$::$::$::$A02EC6A2CE86544F716F4825015773AC::_IO_STACK_LOCATION *Stack; //eax@1
? unsigned int Status; // edi@1
? PIRP _Irp; // esi@1
? void *InBuffer; // ecx@2
? int InBufferSize; // edi@2
? PVOID OutBuffer; // edx@2
? int OutBufferSize; // ebx@2
? int Length; // eax@3
? int ReturnLength; // [sp+8h][bp-4h]@1
? ReturnLength = 0;
? _Irp = Irp;
? Stack =Irp->Tail.Overlay.CurrentStackLocation;
? Status = 0xC00000BBu;
? if ( *(_BYTE *)Stack == 14 )
? {
??? InBuffer = (void*)*((_DWORD *)Stack + 4);
??? InBufferSize =*((_DWORD *)Stack + 2);
??? OutBuffer =Irp->UserBuffer;
??? OutBufferSize =*((_DWORD *)Stack + 1);
??? Irp = (PIRP)*((_DWORD*)Stack + 3);
??? Status =HandleRequest((int)Irp, InBuffer, InBufferSize, OutBuffer, OutBufferSize,&ReturnLength);
? }
? Length = ReturnLength;
? _Irp->IoStatus.Status =Status;
? _Irp->IoStatus.Information =Length;
? IofCompleteRequest(_Irp, 0);
? return Status;
}
int __stdcall HandleRequest(int Ioctl,void *InBuffer, int InBufferSize, void *OutBuffer, int OutBufferSize, int*ReturnLength)
{
? …
? if ( Ioctl == 0x830020EB )
? {
???sub_1484A((int)OutBuffer);
??? *v6 = 28;
??? return 0;
? }
在sub_1484A()里什么是如此的有趣?看看這里:
int __stdcall sub_1484A(int a1)
{
? int result; // eax@3
? CPPEH_RECORD ms_exc; // [sp+Ch][bp-18h]@1
? ms_exc.disabled = 0;
? if ( dword_16168 )
? {
??? memcpy((void *)a1,(const void *)dword_161A8, 0x1Cu);
? }
? else
? {
??? result = 0;
??? memset((void *)a1, 0,0x1Cu);
? }
? return result;
}
??? ???酷,在內核空間寫些東西已經沒有任何困難了,我們能制造一個DOS,甚至可以執(zhí)行代碼。我只是不想進一步發(fā)掘了,希望剩下的將被同道之一完成。如果我說的是真的話,似乎每個防火墻都能被繞過,沒有東西能做到100%的保護。Rootkit,木馬,蠕蟲和其他惡意軟件變的更加隱蔽、復雜,而且很難被發(fā)現。我不想給出任何關于選擇哪款防火墻的建議,只是要確信,你用了一個功能強大的防火墻。
轉載于:https://www.cnblogs.com/airoot/p/4131855.html
總結
以上是生活随笔為你收集整理的关于个人防火墙的真相的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用户体验设计的五个原则(转)
- 下一篇: css斜角覆盖阴影