|
分類:[C#]
Microsoft Windows XP SP2 Microsoft .NET Framework 3.0 Microsoft Visual Studio 2005 Standard Edition(C#)
こんにちは。 C#で、以下の目的を達成するツールを書こうと思っています。
・特定のURL(複数)へのアクセスをブロックしたい ・禁止URLリストに該当するURLへの接続を発見次第、警告を出したい ・(可能であれば)警告のみならず、そのアクセスを無効にしたい
このために、rawソケットを使ってパケットをキャプチャし、禁止URLを発見するところまでは動きました。このあと、可能であれば禁止URLへのパケット(HTTPリクエスト)自体を破棄したいのですが、どなたか良い方法をご存知の方がいらっしゃいましたらご教授いただけないでしょうか。
参考までに、ソースコードの抜粋を記載します。
----- ソースコード(抜粋)ここから -------------------------------------
/// <summary> /// 危険なURLのリスト /// </summary> string[] targetUrlList = { @"xxx.yyy.com", @"xxx.yyy.co.jp", @"xxx.yyy.net" };
// ソケットの生成 socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); socket.Bind(new IPEndPoint(IPAddress.Parse(this.IP), 0));
// ソケットの初期設定 socket.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true ); socket.IOControl( IOControlCode.ReceiveAll, byTrue, byOut );
// キャプチャ開始 IAsyncResult result = socket.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state );
/// <summary> /// 受信用メソッド /// </summary> /// <param name="ar"></param> private static void ReceiveCallback(IAsyncResult ar) { // データの取得 int bytesRead = currentsocket.EndReceive(ar);
// 解析 if (bytesRead > 0) { // IPヘッダ部分 StringBuilder ipHeader = new StringBuilder(); foreach (byte b in currentstate.buffer) { string s = b.ToString("X"); string str2 = Convert.ToString(b, 2); string str3 = String.Format("{0:D8}", Convert.ToInt32(str2)); ipHeader.Append(str3); } int version = Convert.ToInt32(ipHeader.ToString().Substring(0, 4), 2); int headerLength = Convert.ToInt32(ipHeader.ToString().Substring(3, 4), 2); int serviceType = Convert.ToInt32(ipHeader.ToString().Substring(8, 8), 2); int dataGramLength = Convert.ToInt32(ipHeader.ToString().Substring(16, 16), 2); int id = Convert.ToInt32(ipHeader.ToString().Substring(32, 16), 2); int flag = Convert.ToInt32(ipHeader.ToString().Substring(48, 3), 2); int flagmentOffset = Convert.ToInt32(ipHeader.ToString().Substring(51, 13), 2); int ttl = Convert.ToInt32(ipHeader.ToString().Substring(64, 8), 2); int protocolNo = Convert.ToInt32(ipHeader.ToString().Substring(72, 8), 2); int checkSum = Convert.ToInt32(ipHeader.ToString().Substring(80, 16), 2); int offset = 0; int ipFrom1 = Convert.ToInt32(ipHeader.ToString().Substring(96 + offset, 8), 2); int ipFrom2 = Convert.ToInt32(ipHeader.ToString().Substring(104 + offset, 8), 2); int ipFrom3 = Convert.ToInt32(ipHeader.ToString().Substring(112 + offset, 8), 2); int ipFrom4 = Convert.ToInt32(ipHeader.ToString().Substring(120 + offset, 8), 2); int ipTo1 = Convert.ToInt32(ipHeader.ToString().Substring(128 + offset, 8), 2); int ipTo2 = Convert.ToInt32(ipHeader.ToString().Substring(136 + offset, 8), 2); int ipTo3 = Convert.ToInt32(ipHeader.ToString().Substring(144 + offset, 8), 2); int ipTo4 = Convert.ToInt32(ipHeader.ToString().Substring(152 + offset, 8), 2); StringBuilder ipFrom = new StringBuilder(); ipFrom.Append(ipFrom1); ipFrom.Append(@"."); ipFrom.Append(ipFrom2); ipFrom.Append(@"."); ipFrom.Append(ipFrom3); ipFrom.Append(@"."); ipFrom.Append(ipFrom4); StringBuilder ipTo = new StringBuilder(); ipTo.Append(ipTo1); ipTo.Append(@"."); ipTo.Append(ipTo2); ipTo.Append(@"."); ipTo.Append(ipTo3); ipTo.Append(@"."); ipTo.Append(ipTo4);
// データ部分 StringBuilder receivedString = new StringBuilder(); string strMS932 = Encoding.UTF8.GetString(currentstate.buffer); byte[] bytesUicode = Encoding.UTF8.GetBytes(strMS932); foreach (byte b in bytesUicode) { string s = b.ToString("X"); receivedString.Append(StringUtility.FromAsciiCodeEx(s)); } string data = receivedString.ToString(); // 再取得 if (!currentstate.closed) { currentsocket.BeginReceive( currentstate.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), currentstate ); }
// HTTP/HTTPSプロトコル以外は無視 if (IpPacket.GetProtocol(data) == IpPacket.Protocol.Other) return;
// データをセット IpPacket packet = IpPacket.FromRealPacket( ipFrom.ToString(), ipTo.ToString(), data );
// 危険なら警告 for (int i = 0; i < targetUrlList.Length; i++) { if (packet.URL.Contains(targetUrlList[i])) { // TODO: 本当はこのあたりでこのHTTPリクエストを無効にしたい // TODO: 本当はこのあたりでこのHTTPリクエストを無効にしたい // TODO: 本当はこのあたりでこのHTTPリクエストを無効にしたい // TODO: 本当はこのあたりでこのHTTPリクエストを無効にしたい // TODO: 本当はこのあたりでこのHTTPリクエストを無効にしたい } }
// 表示 Debug.WriteLine(packet.ToString()); } }
|