linux下tcp connect掃描器的製作

兩年前的文章,貼過來充門面。

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

linux下tcp connect掃描器的製作

( 作者:mikespook | 發佈日期:2002-12-8 | 瀏覽次數:111 )

關鍵字:linux,網絡,掃描,connect()
前言:
     本文章只是爲了給廣大和我一樣的菜鳥一個指引。如果你是高手,或對編程毫無興趣。建議請不要在此浪費時間。

     tcp connect掃描是一種最基本的掃描方式。通過connect()函數,與要掃描的目標主機建立可靠連接。訪問指定端口。如果端口被監聽就記錄下來。否則轉到下一個端口進行連接測試。它的優點是不需要任何特權。只要你是linux上的用戶就可以運行。而且速度非常快。除了象本文這樣逐一掃描外,還可以用非阻塞方式打開多個socket進行掃描。但是 tcp connect 有一個最大的缺點。它很容易被檢測到,而且防備較好的主機還有可能對其進行過濾。系統日誌會對其進行記錄。
     掃描器的編制原理非常簡單。下面我們就從原代碼直接學習它的製作方法。

/*------------------------------scan.c-----------------------------------*/
/*gcc -O -o tcpscan scan.c*/
/*Unsafe Scan*/
/*For studing*/
/*mikespook*/
/*2002.5.18*/

#include
#include
#include
#include
#include
#include
/* 這個函數是用來檢查輸入的參數是IP地址還是主機名 */
int correcthost(const char *host, struct sockaddr_in *sock);

int main(int argc, int *argv[])
{
  /* 端口變量 */
  int n_port, n_begin_port, n_end_port;
  /* socket套接字 */
  int sock_id;
  int rtn_err;
  /* socket結構 */
  struct sockaddr_in remote_sock;

  if(argc != 4){
    printf("Usage: scan /n");
    printf("Writen by mikespook/n");
    printf("[email protected]/tWith subject:report for scan/n");
    exit(0);
  }

  n_begin_port = atoi(argv[2]);
  n_end_port = atoi(argv[3]);
  remote_sock.sin_family = AF_INET;
  rtn_err = correcthost((char *)argv[1], (struct sockaddr_in *)&remote_sock);

  if(rtn_err != 0)
    exit(1);
  /* 使用for循環逐一掃描端口 */
  for(n_port = n_begin_port; n_port <= n_end_port; n_port++){
    /* 爲了保證在不同處理器上能夠很好的運行,必須使用htons()函數處理傳入的端口號 */
    remote_sock.sin_port = htons(n_port);

    sock_id = socket(AF_INET, SOCK_STREAM, 0);/* 初始化一個socket */
    /* 如果初始化失敗就輸出錯誤,並退出程序 */
    if(sock_id < 0){
      perror("/nsocket");
      exit(2);
    }
    /* 連接到主機上 */
    rtn_err = connect(sock_id, (struct sockaddr *)&remote_sock, sizeof(remote_sock));
    /* 如果連接成功就輸出端口 */
    if(rtn_err < 0){
      fflush(stdout);
    }
    else{
      printf("%s:%d accepted./n", argv[1], n_port);
      /* 關閉輸出、輸入連接 */
      if(shutdown(sock_id, 2) < 0){
        perror("/nshutdown");
        exit(2);
      }
    }
    /* 關閉套接字。如果不關閉套接字或將這句放到循環外的話,會因爲打開太多的套接字而操作失敗。*/
    close(sock_id);
  }
  printf("Scan over!/n");
  exit(0);
}

/* 檢查參數是IP還是主機名 */
int correcthost(const char *host, struct sockaddr_in *sock)
{
  struct hostent *struct_host;
  /* 如果輸入的參數*host是數字則認爲輸入的是IP地址,否則認爲輸入的是主機名 */
  if(isdigit(*host))
    sock->sin_addr.s_addr = inet_addr(host);
  else{
    struct_host = gethostbyname(host);
    /* 如果成功取得主機名就將其傳入 sockaddr_in 的結構中去,否則輸出錯誤退出。*/
    if(struct_host != NULL){
      bcopy(struct_host->h_addr, (char *)&sock->sin_addr, struct_host->h_length);
    }
    else{
      printf("Get error with host name./n");
      return(-1);
    }
  }
  return(0);
}
-------------------------------------------------------------------------------
最後我還想說明一下,你還可以使用fork()進行多進程掃描。或開起多個socket然後分段用多個socket的非阻塞方式掃描。而且得到可用的PORT列表後還可以通過read()和write()函數進行進一步的測試。一切都由你自由發揮了。
由於我是菜鳥,或許有什麼不對的地方。也可能一些細節我沒有考慮到。如果你知道的話希望不惜指教。
發佈了34 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章