phoenix Fire Wall (鳳凰防火牆)原理分析

來源:互聯網
上載者:User

phoenix防火牆原理

 

 

應用程式層原理

Winsock 2 服務提供者介面(SPI)為應用程式提供服務。
SPI的體繫結構為:
(協議層次)
Winsock 2 API -> WS2_32.DLL -> SPI -> Transport ,Layered Protocol, SPI -> BaseProtocol

 

(Winsock 2 結構)
Winsock 2 Application -> Winsock 2 API -> Winsock 2 DLL -> Winsock 2 Transport Function SPI -> Transport Service Provider

分層服務提供者將自己安裝到Winsock目錄中的基礎提供者上面,截取來自應用程式的 Winsock API 呼叫。
使用者建立通訊端時,通訊端建立函數會在Winsock目錄中尋找合適的協議,然後調用此協議的提供者匯出的函數完成各種功能。

 

安裝LSP 的過程是:
1、先安裝一個分層協議,然後安裝協議鏈; WSCInstallProvider
2、重新為目錄排序 WSCWriteProviderOrder

移除LSP 使用 WSCDeinstallProvider

 

具體編寫 LSP 的過程是,匯出 WSPStartup函數,在這個函數裡面修改 WSPPROC_TABLE 指向的 Winsock 2 API 函數的地址,指向自己的函數.

 

 

 

驅動層原理

NDIS 網路驅動程式為網路驅動抽象了網路硬體,為上層驅動抽象了管理硬體的下層驅動。

Transport Driver Interface (TDI)
|
NDIS Interface
|
NetCard

中介層驅動位於微連接埠驅動和傳輸驅動之間,是基於鏈路層和網路層之間的驅動。
中介層驅動的主要用途之一是過濾網路封包,它能夠截獲所有的網路資料包。

 

PassThru 是 DDK 內建的中介層例子,
在 PassThru中,有 4 處封包是可以截獲的。
MPSend
MPSendPackets
PTReceive
PTReceivePacket

 

擷取網路資料包的函數是 NdisQueryBufferSafe ,網路資料包在系統內部使用 NDIS_BUFFER 類型的鏈表格儲存體,取出資料包後根據過濾規則檢查,允許的就推進到下一層,不允許的直接丟棄。

-----------------------------------------------

程式碼分析:

phoenixFW 一共有 3 個模組 :
phoenixFW.exe phoenixLSP.dll passthru.sys

phoenixLSP.dll匯出WSPStartup,WSPStartup儲存下層提供者的函數表,修改Winsock API 函數的地址

g_NextProcTable = *lpProcTable;
 lpProcTable->lpWSPSocket = WSPSocket;
 lpProcTable->lpWSPCloseSocket = WSPCloseSocket;
 lpProcTable->lpWSPBind = WSPBind;
 lpProcTable->lpWSPAccept = WSPAccept;
 lpProcTable->lpWSPConnect = WSPConnect;
 lpProcTable->lpWSPSendTo = WSPSendTo; 
 lpProcTable->lpWSPRecvFrom = WSPRecvFrom;

 

TCP向外發起串連使用 connect函數,connect使用WSPConnect,
WSPConnect
{
 //根據規則檢查是否允許串連到遠程主機
 //如果允許通過,直接調用原來的下層函數,否則直接返回SOCKET_ERROR
 return g_NextProcTable.lpWSPConnect
}
接受串連使用 accept,accept調用WSPAccept;

 

UDP 向外發包使用 sendto,sendto調用WSPSendTo
接收UDP封包的函數 recvfrom調用WSPRecvFrom

 

phoenixLSP.dll使用 #pragma指令設定共用記憶體,用來和主模組 phoenixFW.exe進行通訊

#pragma data_seg(".initdata")
HWND   g_hPhoenixWnd = NULL;   // 主視窗控制代碼
int   g_nWorkMode = PF_PASS_ALL;  // 工作模式
#pragma data_seg()

#pragma bss_seg(".uinitdata")
RULE_ITEM  g_Rule[MAX_RULE_COUNT];      // 應用程式層規則
ULONG   g_RuleCount;
QUERY_SESSION g_QuerySession[MAX_QUERY_SESSION];   // 向主程式發送會話詢問時使用
SESSION   g_SessionBuffer[MAX_SESSION_BUFFER];  // 向主程式發送會話資訊時使用
TCHAR   g_szPhoenixFW[MAX_PATH];     // 記錄主程式路徑
#pragma bss_seg()

extern TCHAR g_szCurrentApp[MAX_PATH];

每當一個應用程式調用 Winsock 2 API,就會自動載入phoenixLSP.dll,此時記錄下這個進程的路徑
 case DLL_PROCESS_ATTACH:
  {
   // 取得主模組的名稱
   ::GetModuleFileName(NULL, g_szCurrentApp, MAX_PATH);
  }

data_seg 和 bss_seg 段,無論多少進程載入這個DLL ,都只有1份,也就是說只要1個模組修改這些內容,其他模組都會改變。

phoenixLSP.dll 匯出一個函數,用來修改 data_seg 和 bss_seg 段
__declspec(dllexport) int __stdcall PLSPIoControl(struct LSP_IO_CONTROL *pIoControl, int nType);
int __stdcall PLSPIoControl(struct LSP_IO_CONTROL *pIoControl, int nType)
{
 switch(nType)
 {
 case IO_CONTROL_SET_RULE_FILE:   // 設定應用程式層規則
  break;
 case IO_CONTROL_SET_WORK_MODE:   // 設定工作模式
  break;
 case IO_CONTROL_GET_WORK_MODE:   // 擷取工作模式
  break;
 case IO_CONTROL_SET_PHOENIX_INSTANCE: // 設定主模組資訊
  break;
 case IO_CONTROL_GET_SESSION:   // 擷取一個會話
  break;
 case IO_CONTROL_SET_QUERY_SESSION:  // 返回DLL詢問的結果
  break;
 case IO_CONTROL_GET_QUERY_SESSION:  // 擷取發出詢問的會話
  break;
 }
 return 0;
}
phoenixLSP.dll檢查應用程式的許可權後,根據規則,如果找到規則,直接按規則處理,否則 PostMessage 到phoenixFW.exe 詢問該如何操作;

phoenixFW.exe 使用 class CPIOControl 來和phoenixLSP.dll通訊,用來改變其中的data_seg 和 bss_seg 段。

 

passthru.sys 使用鏈表來儲存規則內容

// 過濾規則
typedef struct _PassthruFilter
{
 USHORT protocol;  // 使用的協議

 //驅動程式中不方便操作 TCHAR 類型的字串,所以改為 ULONG 類型
 ULONG SourceIpFrom;
 ULONG SourceIpTo;
 ULONG DestIpFrom;
 ULONG DestIpTo;

 USHORT sourcePort;  // 源連接埠號碼
 USHORT destinationPort; // 目的連接埠號碼
 
 BOOLEAN bDrop;   // 是否丟棄此封包

}PassthruFilter, *PPassthruFilter;

// 過濾規則列表
typedef struct _PassthruFilterList
{
 PassthruFilter filter;
 struct _PassthruFilterList *pNext;

} PassthruFilterList, *PPassthruFilterList;

 

phoenixFW.exe 使用CreateFile開啟到驅動程式所控制裝置的控制代碼 ,枚舉所有的適配器, 開啟每個控制裝置物件控制代碼,使用DeviceIoControl函數添加過濾規則
passthru 添加我們自己的派遣函數入口
DispatchTable[IRP_MJ_DEVICE_CONTROL] = DevIoControl;

DevIoControl
{
 switch(uIoControlCode)
 {
  case IOCTL_PTUSERIO_ENUMERATE: //枚舉適配器
   break;
  case IOCTL_PTUSERIO_OPEN_ADAPTER: //開啟適配器
   break;
  case IOCTL_PTUSERIO_QUERY_OID: //擷取OID
  case IOCTL_PTUSERIO_SET_OID:  //設定OID
   break;
  default:
   return FltDevIoControl(pDeviceObject, pIrp); //處理其他控制命令
 }
}

FltDevIoControl
{
 switch(uIoControlCode)
 {
 case IOCTL_PTUSERIO_QUERY_STATISTICS:  // 擷取網路活動狀態
  break;
 case IOCTL_PTUSERIO_RESET_STATISTICS:  // 重設網路活動狀態
  break;
 case IOCTL_PTUSERIO_ADD_FILTER:    // 添加一個過濾規則
  break;
 case IOCTL_PTUSERIO_CLEAR_FILTER:   // 清除過濾規則
  break;
 }
}

對於發送單個封包的函數
MPSend
{
     if(!FltFilterSendPacket(pAdapt,Packet,TRUE))
   {
    //
    // 如果拒絕的話,就欺騙上層,說已經發送成功了(雖然並沒有真正地發送)
    //
    return NDIS_STATUS_SUCCESS;
   }
}

FltFilterSendPacket
{
  FltReadPacketData
  bPass =FltCheckFilterRules
  return bPass;
}

FltReadPacketData
{
  //使用NdisQueryBufferSafe 擷取網路封包鏈表中的資料 Ethheader + IPheader + TCP/UDP header +淨額
}

FltCheckFilterRules
{
  //根據過濾規則檢查這個網路封包的源IP,目的IP,源連接埠,目的連接埠
  //因為這裡得到的IP都是網路位元組序,所以要轉換成本機位元組序,來判斷是否在我們指定的IP範圍內,如192.168.1.2-192.168.1.254
  #define NTOHL(val,x,y,m,n)  (((val) & (x)) << 24)|  /
 ((((val) & (y))>> 8) << 16)|  /
 ((((val) & (m))>> 16) << 8)|  /
 (((val) & (n)) >> 24)

 int x,y,m,n;
 x=0xff;
 y=0xff << 8;
 m=0xff << 16;
 n=0xff << 24;
  ipSource=pIpHdr->ipSource;
  ipSource=NTOHL(ipSource,x,y,m,n);
  //因為在phoenixFW.exe 中設定的源IP 目的IP 預設是發送封包時的順序,所以當接收封包時,要把規則中的源IP 和封包中的目的IP 進行比較
 
  return !pFilterList->filter.bDrop;
}
MPSendPackets
PtReceive
{
  bPass = FltFilterReceive
 if(!bPass)
 {
 // 拒絕這個封包
 Status = NDIS_STATUS_SUCCESS;
  break;
 }
}

FltFilterReceive
{
  bPass = FltCheckFilterRules
  return bPass;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.