線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:9364
推到 Plurk!
推到 Facebook!

Sniffer實現之用Raw Socket實現Sniffer

 
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-11-17 17:46:43 IP:220.143.xxx.xxx 未訂閱
ktop下載此文件 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=81522    Sniffer實現之用Raw Socket實現Sniffer(1)    http://www.chinaitlab.com/www/news/article_show.asp?id=31400    一. 摘要    Raw Socket: 原始套接字 可以用它來發送和接收 IP 層以上的原始資料包, 如 ICMP, TCP, UDP...    int sockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);    這樣我們就創建了一個 Raw Socket    Sniffer: 嗅探器 關於嗅探器的原理我想大多數人可能都知道 1. 把網卡置於混雜模式; 2. 捕獲數據包; 3. 分析資料包.    但具體的實現知道的人恐怕就不是那麼多了. 好, 現在讓我們用 Raw Socket 的做一個自已的 Sniffer.    二. 把網卡置於混雜模式    在正常的情況下,一個網路介面應該只回應兩種資料幀: 一種是與自己硬體位址相匹配的資料幀 一種是發向所有機器的廣播資料幀 如果要網卡接收所有通過它的資料, 而不管是不是發給它的, 那麼必須把網卡置於混雜模式. 也就是說讓它的思維混亂, 不按正常的方式工作. 用 Raw Socket 實現代碼如下:    setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag); //設置 IP 頭操作選項 bind(sockRaw, (PSOCKADDR)&addrLocal, sizeof(addrLocal); //把 sockRaw 綁定到本地網卡上 ioctlsocket(sockRaw, SIO_RCVALL, &dwValue);  //讓 sockRaw 接受所有的資料    flag 標誌是用來設置 IP 頭操作的, 也就是說要親自處理 IP 頭: bool flag = ture; addrLocal 為本地地址: SOCKADDR_IN addrLocal; dwValue 為輸入輸出參數, 為 1 時執行, 0 時取消: DWORD dwValue = 1; 沒想到這麼簡單吧?    三. 捕獲數據包    你的 sockRaw 現在已經在工作了, 可以在局域網內其他的電腦上用 Sniffer 檢測工具檢測一下, 看你的網卡是否處於混雜模式(比如 DigitalBrain 的 ARPKiller).    不能讓他白白的浪費資源啊, 抓包!    recv(sockRaw, RecvBuf, BUFFER_SIZE, 0); //接受任意數據包    #define BUFFER_SIZE 65535 char RecvBuf[BUFFER_SIZE]; 越來越發現 Sniffer 原來如此的簡單了, 這麼一個函數就已經完成抓取資料包的任務了.    四. 分析資料包    這回抓來的包和平常用 Socket 接受陌刪筒皇且換厥露? 裏面包含 IP, TCP 等原始資訊. 要分析它首先得知道這些結構. 資料包的總體結構:    ---------------------------------------------- | ip header | tcp header(or x header) | data | ----------------------------------------------    IP header structure: 4 8 16  32 bit |--------|--------|----------------|--------------------------------| | Ver  | IHL  |Type of service | Total length | |--------|--------|----------------|--------------------------------| | Identification | Flags  |  Fragment offset | |--------|--------|----------------|--------------------------------| | Time to live  | Protocol |  Header checksum | |--------|--------|----------------|--------------------------------| |  Source address | |--------|--------|----------------|--------------------------------| |  Destination address  | |--------|--------|----------------|--------------------------------| | Option + Padding  | |--------|--------|----------------|--------------------------------| | Data  | |--------|--------|----------------|--------------------------------|    TCP header structure:    16 32 bit |--------------------------------|--------------------------------| | Source port  | Destination port | |--------------------------------|--------------------------------| |  Sequence number  | |--------------------------------|--------------------------------| | Acknowledgement number  | |--------------------------------|--------------------------------| | Offset | Resrvd |U|A|P|R|S|F| Window | |--------------------------------|--------------------------------| |  Checksum  | Urgent pointer | |--------------------------------|--------------------------------| |  Option + Padding | |--------------------------------|--------------------------------| | Data  | |--------------------------------|--------------------------------|    五. 實現 Sniffer    OK! 現在都清楚了, 還等什麼. 下麵是我用 BCB6 寫的一個 Simple Sniffer 的代碼, 僅供參考. (需要在工程檔裏加入WS2_32.LIB這個檔) //*************************************************************************// //* CPP File: WMain.cpp //* Simple Sniffer by shadowstar //* http://shadowstar.126.com/ //*************************************************************************// #include  #pragma hdrstop #include #include #include #include #include "WMain.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TMainForm *MainForm; //--------------------------------------------------------------------------- __fastcall TMainForm::TMainForm(TComponent* Owner) : TForm(Owner) { WSADATA WSAData; BOOL flag = true; int nTimeout = 1000; char LocalName[16]; struct hostent *pHost; //檢查 Winsock 版本號 if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) throw Exception("WSAStartup error!"); //初始化 Raw Socket if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == INVALID_SOCKET) throw Exception("socket setup error!"); //設置IP頭操作選項 if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)) == SOCKET_ERROR) throw Exception("setsockopt IP_HDRINCL error!"); //獲取本機名 if (gethostname((char*)LocalName, sizeof(LocalName)-1) == SOCKET_ERROR) throw Exception("gethostname error!"); //獲取本地 IP 地址 if ((pHost = gethostbyname((char*)LocalName)) == NULL) throw Exception("gethostbyname error!"); addr_in.sin_addr = *(in_addr *)pHost->h_addr_list[0]; //IP addr_in.sin_family = AF_INET; addr_in.sin_port = htons(57274); //把 sock 綁定到本地地址上 if (bind(sock, (PSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR) throw Exception("bind error!"); iSortDirection = 1; } //--------------------------------------------------------------------------- __fastcall TMainForm::~TMainForm() { WSACleanup(); } //--------------------------------------------------------------------------- void __fastcall TMainForm::btnCtrlClick(TObject *Sender) { TListItem *Item; DWORD dwValue; int nIndex = 0; if (btnCtrl->Caption == "&Start") { dwValue = 1; //設置 SOCK_RAW 為SIO_RCVALL,以便接收所有的IP包 if (ioctlsocket(sock, SIO_RCVALL, &dwValue) != 0) throw Exception("ioctlsocket SIO_RCVALL error!"); bStop = false; btnCtrl->Caption = "&Stop"; lsvPacket->Items->Clear(); } else { dwValue = 0; bStop = true; btnCtrl->Caption = "&Start"; //設置SOCK_RAW為SIO_RCVALL,停止接收 if (ioctlsocket(sock, SIO_RCVALL, &dwValue) != 0) throw Exception("WSAIoctl SIO_RCVALL error!"); } while (!bStop) { if (recv(sock, RecvBuf, BUFFER_SIZE, 0) > 0) { nIndex ; ip = *(IP*)RecvBuf; tcp = *(TCP*)(RecvBuf (ip.HdrLen & IP_HDRLEN_MASK)); Item = lsvPacket->Items->Add(); Item->Caption = nIndex; Item->SubItems->Add(GetProtocolTxt(ip.Protocol)); Item->SubItems->Add(inet_ntoa(*(in_addr*)&ip.SrcAddr)); Item->SubItems->Add(inet_ntoa(*(in_addr*)&ip.DstAddr)); Item->SubItems->Add(tcp.SrcPort); Item->SubItems->Add(tcp.DstPort); Item->SubItems->Add(ntohs(ip.TotalLen)); } Application->ProcessMessages(); } } //--------------------------------------------------------------------------- AnsiString __fastcall TMainForm::GetProtocolTxt(int Protocol) { switch (Protocol) { case IPPROTO_ICMP : //1 /* control message protocol */ return PROTOCOL_STRING_ICMP_TXT; case IPPROTO_TCP : //6 /* tcp */ return PROTOCOL_STRING_TCP_TXT; case IPPROTO_UDP : //17 /* user datagram protocol */ return PROTOCOL_STRING_UDP_TXT; default : return PROTOCOL_STRING_UNKNOWN_TXT; } } //--------------------------------------------------------------------------- //*************************************************************************// //* Header File: WMain.h for WMain.cpp class TMainForm //*************************************************************************// //--------------------------------------------------------------------------- #ifndef WMainH #define WMainH //--------------------------------------------------------------------------- #define BUFFER_SIZE 65535 #include #include #include #include <Forms.hpp> #include #include #include #include "netmon.h" //--------------------------------------------------------------------------- class TMainForm : public TForm { __published: // IDE-managed Components TPanel *Panel1; TButton *btnCtrl; TListView *lsvPacket; TLabel *Label1; void __fastcall btnCtrlClick(TObject *Sender); void __fastcall lsvPacketColumnClick(TObject *Sender, TListColumn *Column); void __fastcall lsvPacketCompare(TObject *Sender, TListItem *Item1, TListItem *Item2, int Data, int &Compare); void __fastcall Label1Click(TObject *Sender); private: // User declarations AnsiString __fastcall GetProtocolTxt(int Protocol); public: // User declarations SOCKET sock; SOCKADDR_IN addr_in; IP ip; TCP tcp; PSUHDR psdHeader; char RecvBuf[BUFFER_SIZE]; bool bStop; int iSortDirection; int iColumnToSort; __fastcall TMainForm(TComponent* Owner); __fastcall ~TMainForm(); }; //--------------------------------------------------------------------------- extern PACKAGE TMainForm *MainForm; //--------------------------------------------------------------------------- #endif 偷了個懶, IP, TCP 頭及一些巨集定義用了 netmon.h 的頭, 這個檔在 BCB6 的 include 目錄下可以找得到, 其中與本程式相關內容如下: //*************************************************************************// //* Header File: netmon.h //*************************************************************************// // // IP Packet Structure // typedef struct _IP { union { BYTE Version; BYTE HdrLen; }; BYTE ServiceType; WORD TotalLen; WORD ID; union { WORD Flags; WORD FragOff; }; BYTE TimeToLive; BYTE Protocol; WORD HdrChksum; DWORD SrcAddr; DWORD DstAddr; BYTE Options[0]; } IP; typedef IP * LPIP; typedef IP UNALIGNED * ULPIP; // // TCP Packet Structure // typedef struct _TCP { WORD SrcPort; WORD DstPort; DWORD SeqNum; DWORD AckNum; BYTE DataOff; BYTE Flags; WORD Window; WORD Chksum; WORD UrgPtr; } TCP; typedef TCP *LPTCP; typedef TCP UNALIGNED * ULPTCP; // upper protocols #define PROTOCOL_STRING_ICMP_TXT "ICMP" #define PROTOCOL_STRING_TCP_TXT "TCP" #define PROTOCOL_STRING_UDP_TXT "UDP" #define PROTOCOL_STRING_SPX_TXT "SPX" #define PROTOCOL_STRING_NCP_TXT "NCP" #define PROTOCOL_STRING_UNKNOW_TXT "UNKNOW" 這個檔也有人聲稱沒有. //*************************************************************************// //* Header File: mstcpip.h //*************************************************************************// // Copyright (c) Microsoft Corporation. All rights reserved. #if _MSC_VER > 1000 #pragma once #endif /* Argument structure for SIO_KEEPALIVE_VALS */ struct tcp_keepalive { u_long onoff; u_long keepalivetime; u_long keepaliveinterval; }; // New WSAIoctl Options #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) #define SIO_RCVALL_MCAST _WSAIOW(IOC_VENDOR,2) #define SIO_RCVALL_IGMPMCAST _WSAIOW(IOC_VENDOR,3) #define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) #define SIO_ABSORB_RTRALERT _WSAIOW(IOC_VENDOR,5) #define SIO_UCAST_IF _WSAIOW(IOC_VENDOR,6) #define SIO_LIMIT_BROADCASTS _WSAIOW(IOC_VENDOR,7) #define SIO_INDEX_BIND _WSAIOW(IOC_VENDOR,8) #define SIO_INDEX_MCASTIF _WSAIOW(IOC_VENDOR,9) #define SIO_INDEX_ADD_MCAST _WSAIOW(IOC_VENDOR,10) #define SIO_INDEX_DEL_MCAST _WSAIOW(IOC_VENDOR,11) // Values for use with SIO_RCVALL* options #define RCVALL_OFF 0 #define RCVALL_ON 1 #define RCVALL_SOCKETLEVELONLY 2 現在我們自已的 Sniffer 就做好了, Run, Start......哇, 這麼多資料包, 都是從這一台機器上發出的, 它在幹什麼? 原來 Adminstrator 密碼為空, 中了尼姆達病毒! 六. 小結 優點: 實現簡單, 不需要做驅動程式就可實現抓包. 缺點: 資料包頭不含幀資訊, 不能接收到與 IP 同層的其他資料包, 如 ARP, RARP... 這裏提供的程式僅僅是一個 Sniffer 的例子, 沒有對資料包進行進一步的分析. 寫此文的目的在於熟悉Raw Socket 編程方法, 瞭解 TCP/IP 協定結構原理以及各協定之間的關係 Sniffer實現之用Raw Socket實現Sniffer(2) http://www.chinaitlab.com/www/news/article_show.asp?id=31401 一、引言 上一次介紹了用 Raw Socket 實現 Sniffer 的方法,實現起來比較簡單,但有個缺點就是只能截獲 IP 層以上的包,資料包頭不含幀資訊。對一些特殊的要求就不能滿足了,其中很重要的一條就是不能對 ARP 包進行處理。用 NDIS 驅動程式可以實現對整個乙太網包的截獲,但複雜的驅動程式讓好多人望而卻步。沒關係,有現成的東西幹嘛不好好利用呢?在微軟的 DDK 裏提供了一個 Packet 的例子,Packet.sys 可以對網卡進行任意的操作,Packete32.dll 提供給應用程式一個方便的介面,而與驅動程式通訊相關的複雜的內部操作由 DLL 完成,面向應用層的程式師不需要瞭解這些細節。可惜我按 Packet32.dll 的提供的介面一步一步的做下去,卻總也得不到想要的結果,一抓包就死在那兒不動了。看來它是不想給我幹活了:(還是不想自已寫驅動程式…… 幸運的是有一套 WinPcap 的東東,專門用來在 Win32 平臺下抓包的,可以在 http://winpcap.polito.it 上下載到。而且介面基本上和微軟的 Packet 是一樣的。哈哈,這下好了,原來的代碼還可以用,一試就靈!下面就介紹怎樣利用 WinPcap 直接對網卡進行操作及對接收到的資料進行分析。 二、Windows 系統中的網路通信結構 1.Windows 系統中的網路通信結構 圖1的上層應用程式包括 IE、Outlook 等各種基於網路的軟體,網路驅動協定包括 TCP/IP、NETBEUI 等各種 Windows 支援的網路層、傳輸層協定,NDIS 是 Windows 作業系統網路功能驅動的關鍵部分,下面對 NDIS 進行介紹。 2.NDIS及其特點 NDIS(Network Driver Interface Specification) 是 Microsoft 和 3Com 公司聯合制定的網路驅動規範,並提供了大量的操作函數。它為上層的協定驅動提供服務,遮罩了下層各種網卡的差別。 NDIS 向上支援多種網路協定,比如 TCP/IP、NWLink IPX/SPX、NETBEUI 等,向下支持不同廠家生產的多種網卡。NDIS 還支援多種工作模式,支援多處理器,提供一個完備的 NDIS 庫(Library)。 但庫中所提供的各個函數都是工作在核心模式下的,用戶不宜直接操作,這就需要尋找另外的介面。 三、WinPcap 簡介 1. WinPcap結構圖 2. WinPcap 包括三個部分 第一個模組NPF(Netgroup Packet Filter),是一個虛擬設備驅動程式檔。它的功能是過濾資料包,並把這些資料包原封不動地傳給用戶態模組,這個過程中包括了一些作業系統特有的代碼。 第二個模組packet.dll為win32平臺提供了一個公共的介面。不同版本的Windows系統都有自己的內核模組和用戶層模組。Packet.dll用於解決這些不同。調用Packet.dll的程式可以運行在不同版本的Windows平臺上,而無需重新編譯。 第三個模組 Wpcap.dll是不依賴於作業系統的。它提供了更加高層、抽象的函數。 3. packet.dll和Wpcap.dll packet.dll直接映射了內核的調用。 Wpcap.dll提供了更加友好、功能更加強大的函數調用。 4. WinPcap的優勢 提供了一套標準的抓包介面,與libpcap相容,可使得原來許多UNIX平臺下的網路分析工具快速移植過來 便於開發各種網路分析工具 充分考慮了各種性能和效率的優化,包括對於NPF內核層次上的篩檢程式支援 支援內核態的統計模式 提供了發送資料包的能力 四、Packet.dll 的使用 WinPcap的主頁:http://winpcap.polito.it/你可以到這裏下載它的驅動、DLLs和開發包。這裏只是對WinPcap實現Sniffer做一個簡單的介紹,不做深入研究。你只需要把下載回來的驅動安裝到你的電腦上,用你的程式調用Packet.dll就可以了。Packet.dll在安裝的時候會被拷貝到你的系統目錄下,也可以用WinRAR打開安裝包,可以看到裏面的檔,直接提取你想要的Packet.dll。 Packet.dll提供了一套完整的、功能強大的API,其介面形式與Microsoft DDK提供的Packet32.dll基本一致。開發過Windows應用程式的人,對調用DLL一定不會莫生,如果你還不知道怎麼使用DLL請參考相關書籍,這裏不多講了。新建一個DLL工程命名為sniffer2,保存到硬碟。把開發包裏的include、lib目錄拷貝到工程目錄中。如果你用的是Visual C ,可以直接使用lib裏面的引入庫。shadowstar用的是C Builder,需要用C Builder提供的implib工具為Packet.dll生成一個lib檔,命令行如下: implib -a packet.lib packet.dll 五、簡單實現 shadowstar用C Builder寫了一個簡單的演示程式,這裏只給出主要部分的代碼,完整的代碼可以到http://shadowstar.126.com/下載。 void __fastcall TMainForm::btnCtrlClick(TObject *Sender) { //define a pointer to an ADAPTER structure LPADAPTER lpAdapter = 0; //define a pointer to a PACKET structure LPPACKET lpPacket; int i; DWORD dwErrorCode; DWORD dwVersion; DWORD dwWindowsMajorVersion; //unicode strings (winnt) WCHAR AdapterName[8192]; // string that contains a list of the network adapters WCHAR *temp,*temp1; //ascii strings (win95) char AdapterNamea[8192]; // string that contains a list of the network adapters char *tempa,*temp1a; int AdapterNum=0,Open; ULONG AdapterLength; char buffer[256000]; // buffer to hold the data coming from the driver struct bpf_stat stat; // obtain the name of the adapters installed on this machine AdapterLength=4096; ShowMessage(AnsiString("Packet.dll test application. Library version: ") PacketGetVersion()); ShowMessage("Adapters installed:"); i=0; // the data returned by PacketGetAdapterNames is different in Win95 and in WinNT. // We have to check the os on which we are running dwVersion=GetVersion(); dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); if (!(dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4)) { // Windows NT if(PacketGetAdapterNames((PTSTR)AdapterName,&AdapterLength) == FALSE) { ShowMessage("Unable to retrieve the list of the adapters!\n"); return; } temp=AdapterName; temp1=AdapterName; while ((*temp!='\0')||(*(temp-1)!='\0')) { if (*temp=='\0') { memcpy(AdapterList[i],temp1,(temp-temp1)*2); temp1=temp 1; i ; } temp ; } AdapterNum=i; for (i=0;ihFile == INVALID_HANDLE_VALUE)) { dwErrorCode=GetLastError(); ShowMessage(Format("Unable to open the adapter, Error Code : %lx\n", ARRAYOFCONST(((int)dwErrorCode)))); return; } // set the network adapter in promiscuous mode if(PacketSetHwFilter(lpAdapter,NDIS_PACKET_TYPE_PROMISCUOUS)==FALSE) { ShowMessage("Warning: unable to set promiscuous mode!\n"); } // set a 512K buffer in the driver if(PacketSetBuff(lpAdapter,512000) == FALSE) { ShowMessage("Unable to set the kernel buffer!\n"); return; } // set a 1 second read timeout if(PacketSetReadTimeout(lpAdapter,1000)==FALSE) { ShowMessage("Warning: unable to set the read tiemout!\n"); } //allocate and initialize a packet structure that will be used to //receive the packets. if((lpPacket = PacketAllocatePacket()) == NULL) { ShowMessage("\nError: failed to allocate the LPPACKET structure."); return; } PacketInitPacket(lpPacket,(char*)buffer,256000); if (btnCtrl->Caption == "&Start") { bStop = false; btnCtrl->Caption = "&Stop"; } else { bStop = true; btnCtrl->Caption = "&Start"; } int nIndex = 0; LPIP ip; LPTCP tcp; TListItem *Item; struct bpf_hdr *hdr; int off; BYTE* buf; //main capture loop while(!bStop) { // capture the packets if(PacketReceivePacket(lpAdapter,lpPacket,TRUE)==FALSE) ShowMessage("Error: PacketReceivePacket failed"); off = 0; buf = (BYTE*)lpPacket->Buffer; while(offulBytesReceived & !bStop) { nIndex ; hdr = (struct bpf_hdr *)(buf off); off = hdr->bh_hdrlen; ip = (IP*)(buf off ETHERNET_HEADER_LENGTH); tcp = (TCP*)((BYTE*)ip (ip->HdrLen & IP_HDRLEN_MASK)); off = Packet_WORDALIGN(off hdr->bh_caplen); Item = lsvPacket->Items->Add(); Item->Caption = nIndex; Item->SubItems->Add(GetProtocolTxt(ip->Protocol)); Item->SubItems->Add(inet_ntoa(*(in_addr*)&ip->SrcAddr)); Item->SubItems->Add(inet_ntoa(*(in_addr*)&ip->DstAddr)); Item->SubItems->Add(tcp->SrcPort); Item->SubItems->Add(tcp->DstPort); Item->SubItems->Add(hdr->bh_datalen); Application->ProcessMessages(); } } //print the capture statistics if(PacketGetStats(lpAdapter,&stat)==FALSE) ShowMessage("Warning: unable to get stats from the kernel!\n"); else ShowMessage(Format("\n\n%d packets received.\n%d Packets lost", ARRAYOFCONST(((int)stat.bs_recv,(int)stat.bs_drop)))); PacketFreePacket(lpPacket); // close the adapter and exit PacketCloseAdapter(lpAdapter); return; } 六、結束語 如果在一個繁忙的網路上進行截獲,而且不設置任何過濾,那得到的資料包是非常多的,可能在一秒鐘內得到上千的資料包。如果應用程式不進行必要的性能優化,那麼將會大量的丟失資料包,下面就是我對性能的一個優化方案。 這個方案使用了多線程來處理資料包。在程式中建立一個公共的資料包緩衝池,這個緩衝池是一個LILO的佇列。程式中使用三個線程進行操作:一個線程只進行捕獲操作,它將從驅動程式獲得的資料包添加到資料包佇列的頭部;另一個線程只進行過濾操作,它檢查新到的隊尾的資料包,檢查其是否滿足過濾條件,如果不滿足則將其刪除出佇列;最後一個線程進行資料包處理操作,象根據接收的資料包發送新資料包這樣的工作都由它來進行。上面三個線程中,考慮盡可能少丟失資料包的條件,應該是進行捕獲操作的線程的優先順序最高,當然具體問題具體分析,看應用的側重點是什麼了。 台灣災難都是事後算帳 無人飛行載具(Unmanned Aerial Vehicle,UAV)為什麼沒大量應用於救災行列 絲絲有2種 .net有很多種 一種治眼睛是MS 另一種治腦筋是Borland
系統時間:2024-04-20 22:17:02
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!