埠詳解+埠掃描原理+簡單埠掃描實現
阿新 • • 發佈:2019-02-15
一 摘要
埠是個網路應用中很重要的東西,相當於“門”。
二 什麼是埠
埠在計算機網路中是個非常重要的概念,他不是硬體,不同於計算機中的插槽,可以說是個軟插槽。如果有需要,一臺計算機中可以由上萬個埠。
埠是由計算通訊協議TCP/IP協議定義的。其中規定,用IP地址和埠作為套接字,它代表TCP連結的一個連線端,一般稱為socket,具體來說,就是用[ip:埠]來定位一臺主機中的程序。可以做這樣的比喻,埠相當於兩臺計算機程序間的大門,可隨便定義,其目的只是為了讓兩臺計算機能找到對方的程序。計算機就想一座大樓,這個大樓有好多入口(埠),進到不同的入口中就可以找到不同的公司(程序)。如果要和遠端主機A的程式通訊,那麼只要把資料發向[A;埠]就可以實現通訊了。
三 埠的分類
在Internet上,按照協議型別分類,埠被分為TCP埠和UDP埠兩類,雖然他們都用正整數標識,但這並不會引起歧義,比如TCP的80埠和UDP的80埠,因為資料報在標明埠的同時,還將標明埠的型別。
從埠的分配來看,埠被分為固定埠和動態埠兩大類(一些教程還將極少被用到的高階口劃分為第三類:私有埠):
固定埠(0-1023):
使用集中式管理機制,即服從一個管理機構對埠的指派,這個機構負責釋出這些指派。由於這些埠緊綁於一些服務,所以我們會經常掃描這些埠來判斷對方 是否開啟了這些服務,如TCP的21(ftp),80(http),139(netbios),UDP的7(echo),69(tftp)等等一些大家熟 知的埠;
動態埠(1024-49151):
這些埠並不被固定的捆綁於某一服務,作業系統將這些埠動態的分配給各個程序, 同一程序兩次分配有可能分配到不同的埠。不過一些應用程式並不願意使用作業系統分配的動態埠,他們有其自己的‘商標性’埠,如oicq客戶端的 4000埠,木馬冰河的7626埠等都是固定而出名的。
四 埠在入侵中的作用
有人曾經把伺服器比作房子,而把埠比作通向不同房間(服務)的門,如果不考慮細節的話,這是一個不錯的比喻。入侵者要佔領這間房子,勢必要破門而入(物理入侵另說),那麼對於入侵者來說,瞭解房子開了幾扇門,都是什麼樣的門,門後面有什麼東西就顯得至關重要。
入侵者通常會用掃描器對目標主機的埠進行掃描,以確定哪些埠是開放的,從開放的埠,入侵者可以知道目標主機大致提供了哪些服務,進而猜測可能存在 的漏洞,因此對埠的掃描可以幫助我們更好的瞭解目標主機,而對於管理員,掃描本機的開放埠也是做好安全防範的第一步。
五、埠掃描原理:嘗試與目標主機建立連線,如果目標主機有回覆則說明埠開放。
掃描分類:
1. 全TCP連線,這種方法使用三次握手與目標主機建立標準的tcp連線。但是這種方法跟容易被發現,被目標主機記錄。
2. SYN掃描,掃描主機自動向目標主機的指定埠傳送SYN資料段,表示傳送建立連線請求。
!!如果目標主機的迴應報文SYN=1,ACK=1.則說明該埠是活動的,接著掃描主機發送回一個RST給目標主機拒絕連線。導致三次握手失敗。
!!如果目標主機迴應是RST則埠是“死的”。
3 FIN掃描,傳送一個FIN=1的報文到一個關閉的視窗該報文將丟失並返回一個RST,如果該FIN報文傳送到活動視窗則報文丟失,不會有任何反應。
4.代理掃描。就是抓雞啦。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <pthread.h>
#define MAX_THREAD_NUM 100
#define SEG_LEN 655
#define MAX_PORT 65535
typedef struct PortNode
{
char ip[30];
int minPort;
int maxPort;
}PortNode;
pthread_t tid;
void* doit(void* arg)
{
int i, sockfd, connfd;
struct sockaddr_in servaddr;
PortNode* port = (PortNode*)arg;
pthread_detach(pthread_self());//為避免儲存器洩漏,每個可結合線程都應該被其他執行緒顯式地收回,要麼通過呼叫pthread_detach函式被分離
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
//inet_pton(AF_INET, port->ip, &servaddr.sin_addr);
servaddr.sin_addr.s_addr = inet_addr(port->ip);
for(i = port->minPort; i <= port->maxPort; i++){
servaddr.sin_port = htons(i);
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
perror("socket error");
pthread_exit(NULL);
}
if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)) == 0){
printf("%s:%d\n", port->ip, i);
}
close(sockfd);//注意關閉!!
}
pthread_exit(NULL);
}
int main(int argc, char** argv)
{
int i,j;
for(i = 1; i < argc; i++){
PortNode* port = (PortNode*)malloc(sizeof(PortNode));
for(j = 0; j < MAX_THREAD_NUM; j++){
strcpy(port->ip, argv[i]);
port->minPort = j*SEG_LEN + 1;
if(j == (MAX_THREAD_NUM - 1))port->maxPort = MAX_PORT;
else port->maxPort = port->minPort + SEG_LEN - 1;
if(pthread_create(&tid, NULL, doit, (void*) port) != 0 ){
perror("pthread create error.\n");
free(port);
port=NULL;
exit(1);
}
}
}
sleep(3);
}