原创  AFX Lite TCP Firewall by Aphex 收藏

{
  AFX Lite TCP Firewall by Aphex
  http://www.iamaphex.cjb.net
  unremote@knology.net

  Usage: afxfw.exe <port> <port> <port>...

  Example: afxfw.exe 25 80 1433 6667

  This firewall is the simplest of it's kind. It is a packet
  filtering firewall that monitors SYN packets. When a SYN
  packet is sent to an unauthorized TCP port a RST packet
  is sent to same port, immediately tearing down the
  connection.

  The rules apply to both local and remote connections.
}

program Project1;

{$APPTYPE CONSOLE}

uses
  Windows,
  Winsock2;

type
  TIPHEADER = record
    ip_verlen: byte;
    ip_tos: byte;
    ip_len: word;
    ip_id: word;
    ip_offset: word;
    ip_ttl: byte;
    ip_protocol: byte;
    ip_checksum: word;
    ip_saddr: longword;
    ip_daddr: longword;
  end;

  TTCPHEADER = record
    th_sport: word;
    th_dport: word;
    th_seq: longword;
    th_ack: longword;
    th_len: byte;
    th_flags: byte;
    th_win: word;
    th_checksum: word;
    th_upr: word;
  end;

  TPACKET = record
    d_ip: TIPHEADER;
    d_tcp: TTCPHEADER;
  end;

  TPACKETARRAY = array [0..sizeof(TPACKET)-1] of char;

var
  WSAData: TWSAData;
  ArgLoop: integer;
  Ports: array [0..31] of word;

const
  IOC_RCVALL: cardinal = IOC_IN or $18000000 or 1;

function IntToStr(I: integer):string;
var
  v1: string;
begin
  Str(I, v1);
  Result := v1;
end;

function StrToInt(const S: string): integer;
var
  v1: Integer;
begin
  Val(S, Result, v1);
end;

function CheckSum(var Buffer; Size: integer): word;
type
  TWordArray = array[0..1] of word;
var
  lSumm: LongWord;
  iLoop: integer;
begin
  lSumm := 0;
  iLoop := 0;
  while Size > 1 do
  begin
    lSumm := lSumm + TWordArray(Buffer)[iLoop];
    inc(iLoop);
    Size := Size - SizeOf(word);
  end;
  if Size = 1 then lSumm := lSumm + Byte(TWordArray(Buffer)[iLoop]);
  lSumm := (lSumm shr 16) + (lSumm and $FFFF);
  lSumm := lSumm + (lSumm shr 16);
  Result := word(not lSumm);
end;

procedure RSTHeader(FromIP: dword; FromPort: word; ToIP: dword; ToPort: word; var Buffer: TPACKETARRAY; var Socket: TSockAddr; var Size: dword; Seq: dword);
var
  ipHdr: TIPHEADER;
  tcpHdr: TTCPHEADER;
  TcpHeaderLen: word;
  ChecksumSize: word;
  DataPointer: ^byte;

  procedure IncPtr(Value: integer);
  begin
    DataPointer := pointer(integer(DataPointer) + Value);
  end;

begin
  Size := sizeof(ipHdr) + sizeof(tcpHdr);
  ipHdr.ip_verlen := ((4 shl 4) or sizeof(ipHdr) div sizeof(longword));
  ipHdr.ip_tos := 0;
  ipHdr.ip_len := htons(Size);
  ipHdr.ip_id := 0;
  ipHdr.ip_offset := 0;
  ipHdr.ip_ttl := 128;
  ipHdr.ip_protocol := 6;
  ipHdr.ip_checksum := 0;
  ipHdr.ip_saddr := FromIP;
  ipHdr.ip_daddr := ToIP;
  ChecksumSize := 0;
  tcpHdr.th_sport := FromPort;
  tcpHdr.th_dport := ToPort;
  tcpHdr.th_seq := htonl(Seq);
  tcpHdr.th_ack := 0;
  tcpHdr.th_len := 80;
  tcpHdr.th_flags := 20;
  tcpHdr.th_win := htons(65535);
  tcpHdr.th_checksum := 0;
  tcpHdr.th_upr := 0;
  DataPointer := @Buffer[0];
  FillChar(Buffer, SizeOf(Buffer), 0);
  Move(ipHdr.ip_saddr, DataPointer^, SizeOf(ipHdr.ip_saddr));
  IncPtr(SizeOf(ipHdr.ip_saddr));
  ChecksumSize := ChecksumSize + sizeof(ipHdr.ip_saddr);
  Move(ipHdr.ip_daddr, DataPointer^, sizeof(ipHdr.ip_daddr));
  IncPtr(SizeOf(ipHdr.ip_daddr));
  ChecksumSize := ChecksumSize + sizeof(ipHdr.ip_daddr);
  IncPtr(1);
  Inc(ChecksumSize);
  Move(ipHdr.ip_protocol, DataPointer^, sizeof(ipHdr.ip_protocol));
  IncPtr(sizeof(ipHdr.ip_protocol));
  ChecksumSize := ChecksumSize + sizeof(ipHdr.ip_protocol);
  TcpHeaderLen := htons(sizeof(tcpHdr));
  Move(TcpHeaderLen, DataPointer^, sizeof(TcpHeaderLen));
  IncPtr(sizeof(TcpHeaderLen));
  ChecksumSize := ChecksumSize + sizeof(TcpHeaderLen);
  Move(tcpHdr, DataPointer^, sizeof(tcpHdr));
  IncPtr(sizeof(tcpHdr));
  ChecksumSize := ChecksumSize + sizeof(tcpHdr);
  tcpHdr.th_checksum := CheckSum(Buffer, ChecksumSize);
  FillChar(Buffer, sizeof(Buffer), 0);
  DataPointer := @Buffer[0];
  Move(ipHdr, DataPointer^, sizeof(ipHdr));
  IncPtr(sizeof(ipHdr));
  Move(tcpHdr, DataPointer^, sizeof(tcpHdr));
  Socket.sin_family := AF_INET;
  Socket.sin_port := 0;
  Socket.sin_addr.S_addr := ToIP;
end;

procedure Main;
var
  rSocket, sSocket: TSocket;
  Data, RST: TPACKET;
  BytesReceived, BytesSent: dword;
  Control: dword;
  SockAddrIn: TSockAddrIn;
  ArgLoop, Option: integer;

  function GetInAddr: TInAddr;
  var
    Host: array[0..128] of char;
    HostEnt: PHostEnt;
  begin
    GetHostName(@Host, 128);
    HostEnt := GetHostByName(@Host);
    Result := PInAddr(HostEnt^.h_addr_list^)^
  end;

begin
  if WSAStartup(WINSOCK_VERSION, WSAData) = 0 then
  begin
    rSocket := Socket(PF_INET, SOCK_RAW, 0);
    sSocket := Socket(PF_INET, SOCK_RAW, 0);
    if ((rSocket <> INVALID_SOCKET) and (sSocket <> INVALID_SOCKET)) then
    begin
      SetSockOpt(sSocket, 0, 2, @Option, SizeOf(Option));
      SockAddrIn.sin_family := AF_INET;
      SockAddrIn.sin_addr := GetInAddr;
      SockAddrIn.sin_port := htons(0);
      bind(rSocket, @SockAddrIn, SizeOf(SockAddrIn));
      WSAIoctl(rSocket, IOC_RCVALL, @Control, SizeOf(Control), nil, 0, @BytesReceived, nil, nil);
      while rSocket <> INVALID_SOCKET do
      begin
        BytesReceived := recv(rSocket, Data, SizeOf(Data), 0);
        if BytesReceived > 0 then
        begin
          if Data.d_ip.ip_protocol = 6 then
          begin
            if (Data.d_tcp.th_flags and 2) <> 0 then
            begin
              for ArgLoop := 0 to 31 do
              begin
                if Ports[ArgLoop] = htons(Data.d_tcp.th_dport) then
                begin
                  RSTHeader(Data.d_ip.ip_saddr, Data.d_tcp.th_sport, Data.d_ip.ip_daddr, Data.d_tcp.th_dport, TPACKETARRAY(RST), SockAddrIn, BytesSent, ntohl(Data.d_tcp.th_seq) + 1);
                  SendTo(sSocket, RST, BytesSent, 0, SockAddrIn, sizeof(SockAddrIn));
                  Break;
                end;
              end;
            end;
          end;
        end
        else
        begin
          Break;
        end;
      end;
    end;
  end;
  WSACleanup;
end;

begin
  WriteLn('AFX Lite TCP Firewall by Aphex');
  WriteLn('http://www.iamaphex.cjb.net');
  WriteLn('unremote@knology.net');
  if ParamStr(1) = '' then
  begin
    WriteLn('');
    WriteLn('Usage: afxfw.exe <port> <port> <port>...');
    Halt(0);
  end;
  for ArgLoop := 1 to 32 do
  begin
    if ParamStr(ArgLoop) <> '' then
    begin
      Ports[ArgLoop - 1] := StrToInt(ParamStr(ArgLoop));
    end;
  end;
  Main;
end.

发表于 @ 2005年11月25日 11:42:00 | 评论( loading... ) | 编辑| 举报| 收藏

旧一篇:SynScan --www.iamaphex.net | 新一篇:一个简单的花指令伪装器--Delphi版木马彩衣

  • 发表评论
  • 评论内容:
  •  
Copyright © hnxyy
Powered by CSDN Blog