兩年前的文章,貼過來充門面。
---------------------------------------------
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()函數進行進一步的測試。一切都由你自由發揮了。 由於我是菜鳥,或許有什麼不對的地方。也可能一些細節我沒有考慮到。如果你知道的話希望不惜指教。 |