1. 程式人生 > 其它 >基於pikachu的漏洞學習(三)完結

基於pikachu的漏洞學習(三)完結

命令執行&&程式碼執行

原理也是之前說過n次的,觀察下面的輸入

這是一個ping IP的介面,我們結束一個命令,新增一個命令,&&作為分隔符

就會返回相應的結果

下一個是個eval函式,php的執行命令的函式,輸入phpinfo()

沒什麼多說的,就是提供的介面就是執行命令&程式碼的,但是沒有限制能執行哪些命令

檔案包含

檔案包含主要是程式碼複用用的到的,像是網站的導航欄,每個頁面都有,但是程式碼又不能每頁都寫一遍,所以會把導航欄拆分出來成為一個單獨的檔案,然後用require引用一下就ok了

漏洞的原理就是對引用的檔案沒有限制,隨便引用

$html='';
if(isset($_GET['submit']) && $_GET['filename']!=null){
    $filename=$_GET['filename'];
    include "include/$filename";//變數傳進來直接包含,沒做任何的安全限制
}

應該做過濾,比如只能引用這幾個檔案

if($filename=='file1.php' || $filename=='file2.php' || $filename=='file3.php' || $filename=='file4.php' || $filename=='file5.php'){
    include "include/$filename";
}

暫時想象不出來什麼情景會需要這個函式

關於需要使用幾個../的問題,多幾個保證穿到根目錄,讀取一些配置檔案,要看看是什麼系統,有沒有那些檔案

./是當前目錄
../是上一級目錄

包含遠端檔案更簡單了,只看網站讓不讓引用了,兩個配置allow_url_fopen,allow_url_include都為on就可以

修改完配置,直接通過url引用外部檔案

本地包含檔案只能讀取一些配置檔案,那麼更進一步就是自己上傳程式檔案再進行包含

檔案上傳

先介紹一個函式

$_FILES()

這是一個預定義的陣列,通過POST方法接收上傳的檔案的資訊,和session陣列類似,session是儲存會話的一些資訊

$_FILES()["file"]["name"]        //上傳檔案的名稱
$_FILES()["file"]["type"]        //上傳檔案的型別
$_FILES()["file"]["tmp_name"]    //儲存在伺服器的檔案的臨時副本的名稱
$_FILES()["file"]["size"]        //上傳檔案的大小
$_FILES()["file"]["error"]       //報錯

普通使用者上傳都是傳一些圖片啊,文件什麼的,那麼沒有對檔案做驗證,攻擊者上傳個一句話木馬,就會產生危害

檔案驗證也是分為前端和後端驗證

我們說過,前端驗證都是紙老虎,沒有不能繞過的,這個只是最初級的檔案頭檢驗就更別提了

使用js函式

檢驗content-type,此引數是通過http頭獲取的

可以看到此處有兩個content-type,我們需要修改的是下面的,第一個content-type是傳輸例如視訊、圖片、音訊等的特殊編碼格式的說明,傳輸的是二進位制資料,分段傳輸,第二個才是伺服器獲取的檔案型別

這些都是小case,還有檢查檔案頭的,檔案頭就是系統識別如何解釋(?)檔案的特殊編碼,比如

jpg圖片的檔案頭

用010editor開啟jpg格式的圖片

都是以FF D8開頭的,將其刪除,圖片就無法開啟,或者將JFIF對應的編碼4A 46 49 46這一段刪除,檔案也是無法識別的,其它的大家自己測試學習,在系統中,資料都是以二進位制的形式儲存的,並不存在什麼所謂的型別,所以設定了一些檔案頭來選擇以什麼形式來執行,檔案字尾這種就不說了

在傳輸時,只能看到JFIF的文字

直接在圖片編碼縫隙中插入程式碼,失敗,原來,檢查檔案頭這個函式不僅僅檢查檔案頭,還有檔案大小是否匹配

正常上傳圖片,修改content-length大小,原值是10306,上傳失敗

那麼解決方法就是先將程式碼插入圖片再上傳

copy /b images.jpg+p0.php 1.jpg         # 生成1.jpg

我們可以看到程式碼被拼接到最後,content-length變為10319,上傳成功

值得注意的是,檔案上傳後被儲存為jpg字尾的檔案,那麼能否按php檔案執行?

不行,所以說只有把圖片按php檔案執行能利用(因為我們插入的是php程式碼)

剛才講到的檔案包含漏洞,include和require兩個函式,include函式在包含時遇到錯誤會繼續執行,也就是說我們可以直接引用圖片,圖片中的程式碼會正常執行,而require在遇到錯誤時不再執行

順便說一下任意檔案下載,原理就是下載的時候傳檔名,這個檔名可以被控制且沒做許可權控制,導致我們可以隨便下載伺服器的檔案,要求知道檔名和路徑,聽起來很簡單,實驗起來也很簡單,但是遇到有價值的利用場景並不容易

越權

我們在執行一些敏感操作時,比如查詢xx使用者的個人隱私資訊,應該判斷請求的使用者是否是請求檢視自己的資訊,當身份和請求不匹配時,就會產生各種許可權控制問題

案例1:

通過提交使用者名稱檢視個人資訊

程式碼中未對當前會話的使用者和請求檢視哪個使用者進行比對,是否是一個人或者許可權是否允許,我們可以通過註冊一些session變數儲存當前使用者資訊

案例2:

兩個使用者,管理員admin具有新增使用者的操作許可權,同理,普通使用者pikachu是否能執行該操作?

首先嚐試訪問新增使用者的頁面,並未對身份進行校驗

在我未登入任何賬號的情況下,訪問該頁面,跳轉登入,說明只對登入態做了校驗,沒有校驗是否是管理員

修改使用者資訊,提交,發現其又跳轉到登入頁面,但是使用者已經成功添加了

反序列化

所謂序列化就是一個函式,通過serialize這個函式把物件轉換為字串,方便傳輸

o代表物件型別,1代表1個變數,多個變數就在後面繼續排,新增一個testt2變數

O:4:"PIKA":2:{s:5:"test1";s:7:"pikachu";s:5:"test2";s:4:"tien";}
物件型別:長度:"類名":類中變數的個數:{型別:長度:"值";型別:長度:"值";......}

class類物件包括函式和變數,序列化後的這一串字元包括變數型別,長度,值,但是物件中的方法並不會被序列化

object(PIKA)#2 (1) { ["test1"]=> string(7) "pikachu" }

我覺得倒是更像一個數組,還是類似session那種,儲存某個物件的一些值

翻了一些講解,什麼魔術方法,不知所云,看的雲裡霧裡

我們在反序列化後的資料就是一串變數,如果程式不進行處理就沒什麼危害了

看下面這個例子

class User
{
  public $age = 0;
  public $name = '';
 
  public function PrintData()
  {
    echo 'User '.$this->name.'is'.$this->age.'years old. <br />';
  }
}

同樣是一個物件,包含兩個變數和一個函式,賦值

$user = new User();
$user->age = 20;
$user->name = 'day';

序列化

$ser=serialize($user);
O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:3:"day";}

反序列化

var_dump(unserialize($ser));
object(User)#2 (2) { ["age"]=> int(20) ["name"]=> string(3) "day" }

關鍵步驟來了,用反序列化的資料重建物件,然後呼叫(函式可重用,屬性值不同)

程式的後臺程式碼反序列化後呼叫了PrintData方法

$user2 = unserialize($ser);
$user2->PrintData();

這個函式是直接echo了變數到頁面,漏洞就出現在這裡,很容易聯想到我們剛學的xss漏洞,只是傳輸的流程不一樣,並不是因為反序列化,也不是因為魔術方法所以存在漏洞,而是通過這種資料傳輸格式,將惡意payload交給某個函式執行,而這個函式將值輸出到前端頁面導致了xss

直接把day這個變數值替換為xss payload,注意字元長度匹配,27個字元

$user2 = unserialize('O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:27:"<script>alert(233)</script>";}');

預期彈框

魔術方法就是會在某些時刻自動呼叫,比如銷燬某些變數會呼叫__destruct()函式,那麼會存在漏洞嗎?也是要看具體執行了什麼程式碼,和普通方法其實沒什麼差別,但是這可能是反序列化漏洞特有的地方

XXE

定義:輸入的惡意xml文件被解析,造成這個什麼xxe漏洞,要求libxml<2.9.0,因為高版本預設是禁止解析外部實體的

xml文件是傳輸和儲存資料的,libxml是解析xml文件的庫

一個基礎的xml文件,看起來和html差不多,還是有本質區別的

<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

一個基礎的xxe payload

<!--宣告xml-->
<?xml version = "1.0"?>         
<!DOCTYPE ANY [
    <!--SYSTEM識別符號說明後面的文件是外部實體 f命名該檔案-->
    <!ENTITY f SYSTEM "file:///etc/passwd">
]>
<!--引用該檔案-->
<x>&f;</x>

產生漏洞的程式碼

$html='';
//考慮到目前很多版本里面libxml的版本都>=2.9.0了,所以這裡添加了LIBXML_NOENT引數開啟了外部實體解析
if(isset($_POST['submit']) and $_POST['xml'] != null){
    $xml =$_POST['xml'];
    //simplexml_load_string將xml字串轉換為物件,就是方便操作文件內容
    $data = @simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOENT);
    if($data){
        $html.="<pre>{$data}</pre>";
    }else{}
}

後端接收了我們的xml字串,解析了我們的輸入,然後發現要引用/etc/passwd這個檔案,就引用並將資料輸出到前端頁面,我們在html文件中引用,比如php檔案,字型檔案,css檔案的介面,只要可控,是不是也可能存在漏洞呢?

SSRF

定義:後端在向不同伺服器請求資源時,如果這個url引數可控,我們就可以請求其內網的資源

這為什麼是一個漏洞呢?因為內網的很多資源都是比較敏感的,對於外網使用者不可見的,一些人經常用它來探測內網資訊收集

獲取檔案

if(isset($_GET['file']) && $_GET['file'] !=null){
    $filename = $_GET['file'];
    $str = file_get_contents($filename);
    echo $str;
}

這個漏洞更像是偏?代理的那麼一個東西??

不安全的url跳轉

我覺得這個漏洞看到名字就知道是什麼意思了,也不用說,只是提醒一下,這個東西也是個漏洞,釣魚用都可以

其它

本次學習的漏洞基本都是由於不安全的輸入導致的,具體的利用方式是後端決定的,如何處理我們的輸入,我們根據其邏輯構造不同的惡意程式碼

講的都很淺,主要是理解原理 ,後面會繼續進階學習

在自學的過程中,動輒幾十甚至上百小時的教程,確實很勸退,短教程又無法讓我們在最開始建立相對完整的體系,對此,只能說,一定要記錄自己的學習進度甚至做學習筆記,在你放棄後再次學習的時候,不需要重頭再來,總是處於反覆入門的狀態