更新時間:2018-04-27 來源:黑馬程序員 瀏覽量:
1、 概述
網絡攻擊的主要內容包括系統(tǒng)安全攻防、網絡安全攻防、物理攻擊與社會工程學三部分: 系統(tǒng)安全攻防主要是利用軟件安全漏洞進行攻擊,網絡安全攻防利用協(xié)議棧的安全漏洞(不局限于此), 物理攻擊與社會工程學攻擊主要是利用人的心里弱點、物理設計缺陷。
TCP(Transmission Control Protocol) 傳輸控制協(xié)議是TCP/IP協(xié)議棧的核心協(xié)議,它位于IP協(xié)議層之上,在網絡上的兩臺計算機之間提供可靠的、有序的通信通道。許多應用比如瀏覽器、SSH、Telnet、Email等使用TCP進行通信。TCP協(xié)議處于為應用提供主機到主機通信服務的傳輸層。
一般我們講TCP提供可靠的有連接服務,這個可靠包括三層含義
2、TCP協(xié)議的工作原理
我們通過一個簡單的TCP client程序和TCP Server程序來展示TCP建立連接、數據傳輸、斷開連接的過程。以下這兩個程序中,為了能清晰說明程序的通信過程,不做容錯處理,力求簡單。工作當中這樣的程序是不能正常工作的。
2.1 TCP Client 程序
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SER_ADDR "127.0.0.1"
#define SER_PORT 9999
//#define SER_ADDR "172.16.28.98"
/* main function */
int main(int argc, char *argv[])
{
/**
* Step 1: 創(chuàng)建一個socket, 指定SOCK_STREAM參數代表基于TCP協(xié)議
* 如果是UDP協(xié)議,則需要用SOCK_DGRAM
*/
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
/**
* Step 2: 設置目標主機IP地址和端口號
* IP+Port, 標識網絡上某個主機的通信進程
*/
struct sockaddr_in dest;
memset(&dest, 0, sizeof(struct sockaddr_in));
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = inet_addr(SER_ADDR);
dest.sin_port = htons(SER_PORT);
/**
* Step 3: 連接服務器
*/
if (connect(sockfd, (struct sockaddr *)&dest,
sizeof(struct sockaddr_in)) != 0){
/* 此處SYN Flood攻擊會用到 */
fprintf(stdout, "Error for connect: %s\n", strerror(errno));
return 1;
}
/**
* Step 4: 向Server發(fā)送數據
*/
char *buffer1 = "Hello Server!\n";
char *buffer2 = "Hello Again!\n";
write(sockfd, buffer1, strlen(buffer1));
write(sockfd, buffer2, strlen(buffer2));
/**
* Step 5: 關閉連接
*/
close(sockfd);
return 0;
}
一個客戶端程序大概如下幾個步驟: 1. 創(chuàng)建一個socket,通過過指定參數SOCK_STREAM,來標識基于TCP傳輸, 如果需要用UDP協(xié)議的話,則需要指定SOCK_DGRAM. 特別指出,如果需要通過原始套接字進行通訊,需要指定SOCK_RAW。 2. 指定地址信息, 在網絡上,我們通過IP地址和Port來標識一個特定主機上的進程,此處填寫Server端的IP地址和端號。 3. 與Server建立連接, TCP是基于連接下協(xié)議,因此在數據傳輸之前,需要通過三次握手建立連接。 4. 收發(fā)數據, 一旦連接建立成功,C/S兩端就可以通過write/send/sendto/sendmsg發(fā)送數據,可以通過read/recv/recvfrom/recvmsg/接收數據 5. 關閉連接, 當數據收發(fā)完畢后,連接不在需要時,可以通過close斷開連接。
2.2 TCP Server程序
下面我們編寫一個TCP Server程序,還是老規(guī)矩,力求簡單,不做容錯處理
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#define SER_ADDR 9999
int main(int argc, char *argv[])
{
int sockfd, newsockfd;
struct sockaddr_in my_addr, client_addr;
char buffer[100];
/**
* Step 1: 創(chuàng)建一個socket, 指定SOCK_STREAM代表TCP
*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
/**
* Step 2: 綁定一個端口號
*/
memset(&my_addr, 0, sizeof(struct sockaddr_in));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(SER_ADDR);
bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in));
/**
* Step 3: 監(jiān)聽連接
*/
listen(sockfd, 5);
fprintf(stdout, "Serve listenning....\n");
while(1){
/**
* Step 4: Accept 一個連接請求
*/
socklen_t client_len = sizeof(client_addr);
newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_len);
/**
* Step 5: 從當前連接讀取數據 */
memset(buffer, 0, sizeof(buffer));
int len = read(newsockfd, buffer, 100);
printf("Received %d bytes: %s", len, buffer);
/**
* Step 6: 關閉當前鏈接*/
close(newsockfd);
}
/**
* Step 7: 關閉套接字
*/
close(sockfd);
return 0;
}
一個Server程序的大致步驟為:
1. 創(chuàng)建一個socket
2. 綁定一個端口號
3. 開始監(jiān)聽
4. 接受一個連接請求。
5. 收發(fā)數據
6. 關閉連接請求
7. 關閉socket
其中 4、5、6可作為一個循環(huán),多次響應連接請求。
2. 3 掀開數據傳輸的面紗
一旦連接建立, OS分別為Client端和Server端申請兩個Buffer, 一個是SendBuffer,用于發(fā)送數據,一個是ReceiveBuffer,用于接收數據。 TCP協(xié)議是全雙工的,兩端都可以發(fā)送和接收數據。詳細流程見下圖:
這里面有幾個問題,我們此處并不會對TCP協(xié)議完整展開解釋,選取和我們后續(xù)課程相關重點的描述一下:
1.TCP提供面向連接的服務, 連接的建立過程在下一章節(jié)中,重點描述。
2.數據有序傳輸? 每個數據包編個序號,數據包到達主機可能錯序,在傳輸層調整順序后上傳。
3.丟包重傳機制:引入滑動窗口機制, 窗口內的數據如果沒有接到應答ack, “超時”進行重傳
4.流量控制機制:引入滑動窗口機制后,接收端實時通知發(fā)送端當前自己接受窗口大小,從而約束發(fā)送端的發(fā)送,進行流量控制
TCP 部分一般稱之為Segment, 數據段, (補充: 在應用層--消息、傳輸層--數據段Segment、網絡層--包/分組 packet、 鏈路層--幀frame、 物理層bits),對于TCP header的格式如上圖所述, 詳細解讀如下:
l 源端口號和目的端口號, 各占16bits
l 32位序號 (seq)
l 32位應答序號(ack)
l TCP header長度: 4位, 以4字節(jié)度量, 故Header最長為64字節(jié)
l 保留: 6位
l 標志位: 6位, 包括 SYN、FIN、ACK、RST、PSH、URG
l 滑動窗口: 16位, 可用于流量控制
l 校驗: 16位
l 緊急指針:16位, 當URG標志置位時, 此指針有效,用于帶外數據
l 選項:0~320bits, 以32bits為單位,TCP可以通過options攜帶一些補充數據
我們講,TCP是面向連接的服務, 因此就存在建立連接, 斷開連接等操作。后續(xù)我們選取針對連接建立過程和連接斷開過程進行攻擊方面的展示。
3. TCP SYN Flood 攻擊
3.1 TCP 建立連接(三次握手)
我們說TCP提供面向連接的服務, 因此數據發(fā)送前需要先通過三次握手建立連接:
1.第一次握手: 首先客戶端C(?)主動發(fā)起連接,發(fā)送SYN(連接請求標志), 以及序號SEQ=x(序號x隨機生成)到服務器端S。
2.第二次握手: 服務器端S接受到SYN后, 向客戶端C也發(fā)送SYN及ACK, 且ack=x+1, 以及序號Seq=y(序號y隨機生成)。
3.第三次握手: 客戶端接到SYN及ACK后, 核查ack是否為x+1, 若正確, 則客戶端C發(fā)送ACK 且ack=y+1,至服務器端S。
4.服務器端S接收到ACK,核查ack是否為y+1. 若正確,則連接正常建立。
三方握手建立連接的過程詳細見下圖
3.2 SYN Flooding 攻擊
在探討SYN攻擊之前,我們先看看linux內核對SYN是怎么處理的: 1. Server接收到SYN連接請求。 內部維護一個隊列(我們暫稱之半連接隊列,半連接并不準確), 發(fā)送ack及syn給Client端,等待Client端的ack應答,接收到則完成三次握手建立連接。 如果接收不到ack應答,則根據延時重傳規(guī)則繼續(xù)發(fā)送ack及syn給客戶段。
利用上述特點。我們構造網絡包,源地址隨機構建,意味著當Server接到SYN包時,應答ack和syn時不會得到回應。在這種情況下, Server端,內核就會維持一個很大的隊列來管理這些半連接。 當半連接足夠多的時候,就會導致新來的正常連接請求得不到響應。 也就是所謂的DOS攻擊。
詳細見下圖所示:
3.3 SYN Flood 攻擊防護手段
l tcp_max_syn_backlog: 半連接隊列長度
l tcp_synack_retries: syn+ack 的重傳次數
l tcp_syncookies : syn dookie
一般的防御措施就是就是減小SYN+ACK重傳次數,增加半連接隊列長度,啟用syn cookie。不過在高強度攻擊面前,調優(yōu) tcp_syn_retries 和 tcp_max_syn_backlog 并不能解決根本問題,更有效的防御手段是激活 tcp_syncookies,在連接真正創(chuàng)建起來之前,它并不會立刻給請求分配數據區(qū)存儲連接狀態(tài),而是通過構建一個帶簽名的序號來屏蔽偽造請求。
傳智播客黑馬程序員C/C++與網絡攻防學科培養(yǎng)專項白帽子安全人才,課程包含 C語言開發(fā)實戰(zhàn)、C高級編程、C++核心編程與桌面應用開發(fā)、Linux高并發(fā)服務器開發(fā)、信息安全與企業(yè)應用開發(fā)、分布式云平臺開發(fā)、入侵檢測與網絡攻防等階段。
黑馬程序員C/C++與網絡攻防課程關鍵技術點
涉及到的熱門技術有:·
Nginx(高并發(fā)反向代理服務器)
·GIT(分布式版本控制系統(tǒng))
·Redis(NoSQL緩存數據庫)
·Memcache(key-value分布式緩存數據庫)
·Libevent(高并發(fā)反應堆模式API)
·Epoll(Linux內核高級多路IO技術)
·GDB(逆向工具)
·SHM(共享內存映射機制)
·VIM(文本編輯器)
·QT(跨平臺應用界面框架)
涉及到的新興技術有:
·fastDFS(分布式文件系統(tǒng))
·Golang(Google推出的開發(fā)編程語言)
·Docker(虛擬化容器技術)
·Go-micro(Go語言微服務框架)
·Beego(Go語言高性能web服務器框架)
·GEO(地理位置核心算法)
·ASN.1(跨平臺安全傳輸協(xié)議)
·RPC(遠程調用過程)
·Oracle(高級事務關系型數據庫)
涉及到的網絡攻防技術有:
·Kali Linux(Hacker操作系統(tǒng))
·Wireshark(網絡抓包分析工具)
·Aircrack-ng(可破解WEP/WPA/WPA2加密)
·AppScan(漏洞掃描工具)
·DDos(分布式拒絕服務攻擊)
·Web滲透(Web頁面代碼的攻擊形式)
·iptables(Linux內核防火墻技術)
·NetCat(網絡攻擊瑞士軍刀)
·TCPDump(Linux內核網絡協(xié)議捕捉器)
·SQLMAP(SQL注入漏洞攻防技能)
本文版權歸黑馬程序員C/C++與網絡攻防學院所有,歡迎轉載,轉載請注明作者出處。謝謝!
作者:黑馬程序員C/C++與網絡攻防學院
首發(fā):http://c.itheima.com/