Wednesday, June 30, 2010

Echeneidae IDS 難以捉摸的Bug

我在昨天早上的測試中,發現在高度壓力測試下Echeneidae IDS會發生異常的錯誤。
IDS會卡住導致暫存封包過量,最後終止Program。

目前這個Bug我還找不出解決方法(連哪裡出錯都不知道),不過懷疑跟多核心CPU同步問題有關

Sunday, June 27, 2010

Echeneidae IDS 2 Alpha 1 Release

內容
Echeneidae IDS是一個擁有模組化規則的網路入侵檢測系統(只檢測不防禦,沒有Firewall的功能),每個規則都為一個Python Module,被載入後可以透過繼承modrule.rule和其他通用模組進行封包的取得和分析。

每個規則模組都為獨立Process,因此如果一個模組出現異常導致關閉,不會影響到其他規則
並且由於為多個獨立Process,所以在多核心CPU上可以發揮平行運算的效能(核心捕捉封包的模組設計上盡量減少了多個Process存取同一個資源時所造成的等待)

目前已完成的基本模組有封包解析模組(modfilter.py,目前已能解析Ethernet II、ARP、IPv4、TCP)、IPv4碎片重組(modipfrag.py)、計時模組(define.py中,由於受限於GIL,可能不是很準)

核心C Extension Module已經盡量提升效能了,不過礙於Python本身是直譯式語言的關係,效能問題頗嚴重,不過在多核CPU上可以藉由平行運算的優勢來改善一些

測試
目前內建測試規則有兩個,偵測Port Scan和紀錄TCP連線,至於規則的寫法,之後會有說明文件(有興趣的人可以直接去研究rule資料夾下的ruleX.py,裡面的都是標準寫法)

需要Winpcap和Python 3.1.2才能運行(Python 3.1.2必須是32bit版本,OS是64bit沒關係)
執行資料夾下的echeneidae.py,輸入網卡代號選擇網卡,Echeneidae IDS便開始運作,將偵測結果顯示在螢幕上

注意,由於會有一個緩衝用的檔案packet.swap,會占用610MB的硬碟空間,建議在1G以上硬碟空間執行,另外建議不要在中文目錄下執行

目前測試Intel CPU單核 雙核 四核都能正常運作,以測正常運作作業系統有Windows 7 32bit和下面(是我目前能測的,不代表其他Windows OS不能運作)

Windows XP SP3 32bit

Windows Server 2003 SP2 32bit

Windows Server 2008 R2 64bit





Thursday, June 24, 2010

Echeneidae IDS 顛倒架構 & IPv4 碎片重組模組

IP碎片重組一直是Echeneidae IDS中重要的部分,顯然也是個大問題。
我從開發早期就開始構思IP碎片重組模組,不過直到今天我才真正的實踐了它。

從前天開始著力於開發它時,才發現原本的封包解析架構並不適合它,應該說架構上顛倒了。
原本架構在OSI 7模型中,是由下到上,由最底層開始解析。但是接觸IP碎片重組後,發現我對TCP封包的理解有所錯誤(TCP和UDP之類的應該是可以由一個或多個IP封包組成),因此我做了一個重大的決定,重新改寫解析架構,改為由上往下,TCP解析時可以要求多個IP封包傳回,進行重組

不幸的是,我今天連續遇到了兩個極為奇怪又簡單的Bug,分別是陣列少加了[XXX]和多了一個break; ,我都透過逐步檢查才找到並解決它,當然過程耗費了數個小時,是令人抓狂的一件事(尤其在找到那一剎那,才發覺自己浪費了多少時間)

不過令人高興的是,IPv4碎片重組模組已經順利的通過了由8000多片碎片組成的TCP封包測試,對於數小時的Debug來說,是個不錯的結果

圖中 TCP test [192, 168, 2, 3]:-19513 -> [192, 168, 2, 254]:71 為碎片重組規則偵測結果

Sunday, June 20, 2010

Windows Event的一些小地方

為了讓Echeneidae IDS能有更高的效能,所以必須用一些奇怪的方式使用Event這個同步物件,當然也必須更深入了解它的特性


CreateEvent中的bManualReset可以設定這個Event是要
手動用ResetEven設回未標記狀態(nonsignaled state),還是在經過WaitForSingleObject
之類的等待API後,自動設回未標記狀態(nonsignaled state),這其中有些有趣的問題


auto-reset
如果多個Process同時在等待一個Event,Event被設定為auto-reset
那麼當Event被標記時,會怎樣呢?


答案是,其中一個等待會被釋放,然後又被設回未標記狀態,其它的等待還是繼續等待


manual-reset
一樣是多個Process在等待一個Event,這次Event被設為手動設回未標記狀態,當Event被標記時,所有的等待都會釋放

Windows 為了改變使用者(使用管理員權限 -> 使用一般User權限) 所做的設計

我認為,Linux很大一部分的安全性來自於系統不允許使用者預設使用Root操作系統(很多資料也極力不建議這麼做),但是Windows絕大部分使用者還是使用管理員權限操作系統,導致許多惡意程式獲得過高的權限破壞系統

深入 Windows 核心 - Windows Internals - 第五版中,有提到不少關於Windows的安全性設計(作者顯然用一大章節才粗略的描述了概觀),其中也寫到了Windows UAC跟為了相容性而作的虛擬化設計

Windows UAC其實設計上有一個很大的功能,在於方便使用者在一般User下於必要時刻取得適當權限(e.g. 管理員權限),Windows 7一般User安全性有清楚的提及,我認為比起Linux在需要Root權限情況下所設計的詢問機制友善多了

相容用的虛擬化技術是為了相容一些被設計以管理員權限執行的軟體(大部分是如此,微軟現在也在將"以一般User權限角度設計軟體"的觀念推廣給軟體設計者),由於這些軟體本來預料中是會被以管理員權限執行的,所以也會做出許多一般User權限被阻止的行為(e.g. 寫檔案到C:\WINDOWS資料夾下),微軟為了相容這些軟體,會將這些被阻止的操作轉向到當前User的一個資料夾下(登錄檔則放在當前User的一個特殊Key下),就像是一個SandBox,軟體還是可以照常運作(它以為它操作成功了),但是又不會危害到Windows所建立的安全架構

不過虛擬化技術只在32bit有效,微軟認為64bit是個全新的開始,所以並沒有做這項相容設計

不過這目前看起來,大部分的使用者還是以管理員帳戶來操作系統

Friday, June 18, 2010

提升Echeneidae IDS 同步處理效能

一個星期以來,我不斷著力於提升關於同步存取的效能問題,它是蠻大的一個Delay部分

放棄了標準的 Mutex鎖住資源方法(取得Mutex,把其他的Process都停下來),改用InterlockedXXX系列API搭配巧妙的設計來解決這個令人頭痛的問題(能改善效能的原因,我在Windows API Mutex 與 Yourself SpinLock中有說明)


在經過不斷的思考後(大部分時間都是邊休閒邊思考),今天在一個下午的小憩時終於想出了所有問題的解決方法,並且順利的實作出來

其中除了用到了InterlockedXXX以外,還使用了CPU內建的同步機制(同一塊記憶體,Read&Write 不會衝突,http://developer.intel.com/Assets/PDF/manual/253668.pdf的第八章節有清楚的提及,希望AMD CPU也有相同設計)來減少API的呼叫,加快速度
幸運的,僅經過一次Bug的修改,Program便順利的運作了,在壓力測試下也有不錯的表現

P4 3.2G  200KB\s下載流量下有穩定的表現


Thursday, June 17, 2010

深入 Windows 核心 - Windows Internals - 第五版

今天拿到了

Windows® Internals: Including Windows Server 2008 and Windows Vista, Fifth Edition

這本好書的中文翻譯版

封面還是一樣,一支廣為人知的手電筒
譯者翻譯的還不算太差,不過把一些專有名詞翻譯了,這樣在網路上找資料時比較不方便
比之前拿到的另一本翻譯書好多了,那本書的翻譯常常讓人不知所措

Monday, June 14, 2010

AT&Tx86ASM lock前綴 更快的SpinLock

為了要在GCC上編譯我的Program,Program中的內嵌ASM必須改用AT&T規範的ASM來寫

很明顯的,AT&T ASM與Intel ASM有非常大的不同,暫存器前必須加上%前綴很快的就像Python判斷式不需要加( )成為我的噩夢

在克服%前綴問題後,開始實作SpinLock

以指令cmpxchg代替了Windows API的InterlockedCompareExchange,它的特色我在前面的文章InterlockedCompareExchange 鎖上 比較 交換有提過了


就在我將lock前綴(讓CPU存取同步)加到cmpxchg時,一個麻煩的錯誤發生了Invalid lock sequence,MSDN的解釋同樣令人困惑不解(對這我並不感到意外,這種事情常發生)。
就在嘗試各種方法來解決這個不了解的錯誤時,發現到VC++同樣ASM(lock cmpxchg),竟然沒有問題。於是我開始比對VC++跟GCC編譯出來到底有何不同。很快的,發現lock cmpxchg中的目標數不能為暫存器,具體原因還不清楚,目前確定直接傳入記憶體位址是個不錯的主意。


我會遇上這個問題的原因就更加曲折了,來自於對AT&T ASM的不了解。
AT&T ASM在傳入外部C變數時(ASM內嵌在C Program中),必須透過一個input operands來告訴編譯器傳入哪些變數,並且可指定編譯器要如何傳入。
不幸的是,我將它指定為"以暫存器形式傳入",並且將它傳到lock cmpxchg的目標數,錯誤就因此發生。解決辦法只要將它指定為"以記憶體位址形式傳入",就能簡單的解決此問題。


為了解決這個錯誤,我花了一個小時的時間,並更加了解AT&T ASM
實作SpinLock後,測試速度時又給了我另一個驚喜
它比之前透過InterlockedCompareExchange的版本快了大概30%,更加印證了之前的這篇文章Windows API Mutex 與 Yourself SpinLock所說的,透過自己實作有時會比呼叫Windows API來的快。


主要的等待並取得Lock代碼

typedef struct _lock{
    unsigned long lock;
}lock;





static void WaitLock(void* pLock){
    lock* pWaitlock;

    pWaitlock=(lock*)pLock;
    __asm__ __volatile__("WaitLoop:;"
                         "movl $0,%%eax;"
                         "movl $1,%%edx;"
                         "lock;cmpxchgl %%edx,%0;"
                         "jz WaitRet;"
                         "rep;nop;"
                         "jnz WaitLoop;"
                         "WaitRet:;"
                         :
                         :"m"(pWaitlock->lock)
                         :"eax","edx","memory");

    return;
}

Saturday, June 12, 2010

Echeneidae IDS Logo

使用SVG向量繪圖

Windows API Mutex 與 Yourself SpinLock

Windows API因為安全、相容、穩定性等等,往往必須經過許多檢查、判斷、呼叫,需要使用不少的時間才能達到真正的目的

今天照著Linux源碼片段,嘗試自己實現一個SpinLock提供同不存取共用資源的功能

void GetSpinLock(unsigned long* plock){
    GetSpinLock_Loop:
if(InterlockedCompareExchange(plock,1,0)==0){
return;
    }else{
__asm{
            rep nop
jmp GetSpinLock_Loop
        }
    }


    return;
}
void ReleaseSpinLock(unsigned long* plock){
  *plock=0;

  return;
}

並且做了個測試,比較具有同樣功能的Windows Mutex
測試中,兩個Process都嘗試存取同一塊記憶體,並且將當中的數值+1
在測試結果中發現到,使用Windows Mutex所需的時間幾乎是自己實現的簡單SpinLock的12倍

所以下次如果有使用一些簡單功能的API,不妨試試看自己實現它,可能會發現意想不到的驚喜!

InterlockedCompareExchange 鎖上 比較 交換

我決定在Echeneidae IDS上使用一種全新的Queue架構,增加Queue Manager的彈性與效能(諷刺的是,儘管我不斷在Python C Extension部分使用各種極端的方法提升效能,Python本身其實才是效能的最大問題)

在這個架構中,我決定要盡量減少許多封裝型的同步API(Synchronization API)的使用
e.g.

原因在於它們往往需要通過Windows內部許多的機制來解決同步問題,如此一來需要占用一小段時間

為了使用簡單的同步API達成同步問題,我嘗試大量採用InterlockedXXXXXX系列API
它們透過CPU的指令集中的lock對總線進行控制,讓CPU在執行這行指令時,不會被打斷(不管是中斷還是多核CPU問題),解決同步問題

我認為InterlockedCompareExchange給我不少幫助,它可以先將目標資料跟比對資料比對後,如果相等,則將取代資料存入目標資料中,反之沒有動作

如此一來,當兩個Thread會同時搶著修改一個資源時,可以在資源加入一個Status標誌,表示當前是否有人已經先占用,如果發現它等於未被人占用狀態值,則將它修改為占用狀態值,並且進行處理,InterlockedCompareExchange剛好可以將上述兩個動作合在一個指令完成,並且透過lock的保護,確保不會兩個Thread不會同時檢查跟修改Status標誌


Wednesday, June 9, 2010

Process的Integrity Level設定

Windows中有一個Integrity Level設計,不同Level的Process之間的溝通會有所限制
設定方法是先取得一個Process的Token(可以直接從自己的Process用DuplicateTokenEx複製一個來用),透過SetTokenInformation的TokenIntegrityLevel來進行設定,使用CreateProcessAsUser使用這個Token建立Process

值得一提的是,TOKEN_MANDATORY_LABEL結構中SID_AND_ATTRIBUTES的SID要被指定為Integrity Level SID,以Windows Vista和Windows 7來說

  1. System Level:S-1-16-16384
  2. High Level:S-1-16-12288
  3. Medium Level:S-1-16-8192
  4. Low Level:S-1-16-4096
  5. Untrusted Level:S-1-16-0
一個經過Integrity Level設定的Process,被指定為Low Level

相關文件:http://msdn.microsoft.com/en-us/library/bb625960.aspx
PS:

文件中的Starting a process at low integrity範例,它的Low Integrity Level SID


WCHAR wszIntegritySid[20] = L"S-1-16-1024";


似乎是錯誤的,正確應為S-1-16-4096

Monday, June 7, 2010

Windows Vista之後的AssignProcessToJobObject

今天因為一個極為奇怪的的問題困擾著我
當我嘗試呼叫 AssignProcessToJobObject 目標Process放進經過權限設定的Job時,不幸的傳回了System Error Code 5(ERROR_ACCESS_DENIED),並且困擾著我


在嘗試過多種方法後,決定透過網路來取得此問題的解決方案
幸運的,也有人遇到了此問題並有熱心人士提供了解答(原始資料)。原來在Vista之後,Windows為了解決相容性問題,Program Compatibility Assistant會在程式執行時將它自動加入到一個Job中,由於一個Process只能被加入到一個Job中,導致我的程式呼叫AssignProcessToJobObject失敗


從這張圖可以很明確的看到,就算是一個在普通不過的程式,也會被自動加入到一個特殊的Job中
解決方法:

  1. 可以在CreateProcess的CreationFlags加入CREATE_BREAKAWAY_FROM_JOB,這麼一來,Program Compatibility Assistant就不會將Process加入到Job中
  2. 透過一個Manifest檔指示Program Compatibility Assistant不要加Process加入到Job中
  3. 可以使用cmd.exe來執行你的Process,這樣也不會被加入到Job中

Sunday, June 6, 2010

ImpersonateLoggedOnUser 與 Mr. Scruff

今天終於發現了ImpersonateLoggedOnUser這個對我的程式極為關鍵的API

MSDN:
The ImpersonateLoggedOnUser function lets the calling thread impersonate the security context of a logged-on user. 


它簡單的解決了我呼叫CreateProcessWithLogonW後,無法取得該Process的Token問題(會出現操作不允許錯誤),原因應該在於CreateProcessWithLogonW後的Process運行在另一個User下,所以無法去OpenProcessToken它,不過透過ImpersonateLoggedOnUser模仿(Impersonate)該User的 security context 就解決了此問題


就在今天,我從Windows範例音樂中的Kalimba這首歌開始尋找,找到了Mr. Scruff這位DJ兼插畫家,他的專輯封面立刻吸引了我,簡單有力的線條,帶給人十分簡單又活潑的感覺,就像他的音樂帶給人的感受


不像很多電子音樂,他使用豐富的元素混音,讓人不會有呆版單調的感覺,我喜愛的另一位電子音樂團體Daft Punk正有此特色


Mr. Scruff個人網站:http://www.mrscruff.com/showscreen.php?site_id=9&screentype=site&screenid=9


使用CreateProcessWithLogonW讓程式啟動在另一個User(ACLUser1),而不是原來的User(user)




經過特殊權限設定的a.txt,讓ACLUser1只能讀取它




當notepad.exe嘗試寫入a.txt時,引發了權限錯誤




透過ImpersonateLoggedOnUser+OpenProcessToken得來的Token,Remove掉了notepad.exe的所有Privilege(如SeShutdownPrivilege,我想應該沒有人會使用notepad來關閉電腦吧)




希望ImpersonateLoggedOnUser和Mr. Scruff帶給你的感覺和我一樣,簡單

Saturday, June 5, 2010

Windows 7一般User安全性

昨天裝完Windows 7後,由於最近研究了一些Windows內建安全機制,所以試著使用內建安全機制

Windows 7裝完後預設為管理員帳戶,所以我將它設了密碼後,另外建立一個一般User帳戶,UAC Level調到最高(總是提醒跟詢問)

發現到使用一般User帳戶登入後,使用上其實沒有什麼大問題,但是仔細觀察Windows對登錄檔和檔案所設定的安全權限,就會發現到當Windows 7登錄一般User後,其實很多重要的系統檔案和登錄檔都受到了保護

e.g.
C:\Windows整個資料夾下所有檔案都只能讀取跟執行,無法寫入、重新命名等等
C:\Program Files資料夾也是如此
系統碟大部分重要檔案都受到保護

登錄檔除了HKEY_CURRENT_USER外,大部分都只有讀取權限,所以自動啟動病毒、映像劫持等等也無法破壞你的電腦(HKEY_CURRENT_USER下雖然有自動啟動登錄檔,但是每個User的HKEY_CURRENT_USER都是個別獨立的,所以只要從別的帳戶登入,自動起動病毒便無效)

當一般User執行某些動作需要管理員權限時,便會出現盾牌圖示


點選後,會出現輸入系統管理員密碼對話方塊,這有點像Linux的 Sudo概念

基本上像是安裝軟體,只要你輸入管理員密碼,Windows會自動讓它取得適當權限,確保安裝操作正常

另一件有趣的事是:如果你用系統管理員身分執行一個程式
Windows其實會使用系統管理員帳戶來執行它

e.g. 記事本以系統管理員身分執行,在工作管理員中就可以看到,notepad.exe的執行User是"test"(我的系統管理員帳號),而不是我現在登入的"user"


我認為就像Linux一樣,Linux預設是不讓你用Root登錄系統的,因為太危險了

Windows雖然預設是用系統管理員登入,但是自己可以建立一般User並使用它,這樣系統的安全性會增加不少

Echeneidae IDS 成功移植到Python 3.1

昨天因為在電腦上新裝了Windows 7(P4+1G RAM),想說要一切更新,所以裝上了Python 3.1

相較於Pyhon 2.6,Python 3.1有許多地方不同,最令我驚訝的的是,Pyhont 3.1連C Extension部分都做了更改,入口函式名稱也有所不同,另外就是,原本Python 2.6

4/2 預設是整數,也就是2

到了Pyhton 3.0

4/2預設為浮點數 2.0

導致原本使用 / 代替 >> 的做法無效,需要全部修改

PS:在Python中很奇怪的是,用*和/作位元運算比用<< 和 >> 還要快,而且快不少

不過最令人欣慰的是,Echeneidae IDS+Winpcap捕捉封包 在Windows 7上運作良好