PHP代碼審計四

2021-03-02 阿傑談技術

變量覆蓋漏洞

變量覆蓋(Dynamic Variable Evaluation)是指變量未被初始化,我

們自定義的參數值可以替換程序原有的變量值

通常結合程序的其它漏洞實現完整的攻擊,比如文件上傳頁面,覆蓋

掉原來白名單的列表,導致任意文件上傳;用戶註冊頁面控制沒覆蓋的未

初始化變量導致SQL

思路

$$extract()函數parse_str()函數執行import_request_variables()函數

如下代碼:

<?php$a = 1;foreach (array('_COOKIE','_POST','_GET') as $_request){    foreach ($$_request as $_key => $_value){        $$_key = addslashes($_value);    }}echo $a;?>

a 賦值後為1  

重新賦值變量a 

extract()函數

int extract ( $array , extract_rules,prefix ) $array 關聯的數組,受第二個和第三個參數的影響。 extract_rules 對待非法/數字和衝突的鍵名的方法將根據取出標記prefix 僅在第二個參數特殊時需要,添加前綴
EXTR_OVERWRITE - 默認。如果有衝突,則覆蓋已有的變量。EXTR_SKIP - 如果有衝突,不覆蓋已有的變量。(忽略數組中同名的元素)EXTR_PREFIX_SAME - 如果有衝突,在變量名前加上前綴 prefix。自 PHP 4.0.5 起,這也包括了對數字索引的處理EXTR_PREFIX_ALL - 給所有變量名加上前綴 prefix(第三個參數)EXTR_PREFIX_INVALID - 僅在非法或數字變量名前加上前綴 prefix。本標記是 PHP 4.0.5 新加的。EXTR_IF_EXISTS - 僅在當前符號表中已有同名變量時,覆蓋它們的值。其它的都不處理。可以用在已經定義了一組合法的變量,然後要從一個數組例如 $_REQUEST 中提取值覆蓋這些變量的場合。本標記是 PHP 4.2.0 新加的。EXTR_PREFIX_IF_EXISTS - 僅在當前符號表中已有同名變量時,建立附加了前綴的變量名,其它的都不處理。本標記是 PHP 4.2.0 新加的。EXTR_REFS - 將變量作為引用提取。這有力地表明了導入的變量仍然引用了 var_array 參數的值。可以單獨使用這個標誌或者在 extract_type 中用 OR 與其它任何標誌結合使用。本標記是 PHP 4.3.0 新加的。

<?php
$password = 'pwd';$arr =array( 'username' => 'username', 'password' => 'password');extract($arr,EXTR_PREFIX_SAME,"pwd");echo "$password" . "<br>";echo $pwd_password;?>

<?php
$password = 'pwd';$arr =array( 'username' => 'username', 'password' => 'password');extract($arr,EXTR_OVERWRITE);echo "$password";?>

<?php
$password = 'pwd';$arr =array( 'username' => 'username', 'password' => 'password');extract($arr,EXTR_IF_EXISTS);echo "$password";?>

parse_str()函數

void parse_str ( string $encoded_string [, array &$result ] )$encoded_string 輸入的字符串$result 變量將會以數組元素的形式存入到這個數組,作為替代

<?php$a = 'a';parse_str($a = 'b');echo $a;?>

import_request_variables()函數

(PHP 4 >= 4.1.0, PHP 5 < 5.4.0)import_request_variables — 將 GET/POST/Cookie 變量導入到全局作用域中
bool import_request_variables ( string $types [, string $prefix ] )$type 指定需要導入的變量。可以用字母『G』、『P』和『C』分別表示 GET、POST 和 Cookie$prefix 變量名前綴

<?php$a = 0;import_request_variables('G');if ($a == 1){    echo 'sucess';} else{    echo 'fail';}?>

序列化漏洞

序列化:把對象轉換為字節序列的過程稱為對象的序列化反序列化:把字節序列恢復為對象的過程稱為對象的反序列化

反序列化對象中存在魔術方法,而且魔術方法中的代碼可以被控制,漏洞根據不同的代碼可以導致各種攻擊,如代碼注入、SQL注入、目錄遍歷等等

<?php$name = 'ajie';echo serialize($name);
?>

<?php
class A { private $test1 = "ajie"; public $test = "ajie"; protected $test2 = "ajie";}$test = new A();echo serialize($test);?>
O:1:"A":3:{s:8:" A test1";s:4:"ajie";s:4:"test";s:4:"ajie";s:8:" * test2";s:4:"ajie";}

魔術方法

__construct(), __destruct()__call(), __callStatic()__get(), __set()__isset(), __unset()__sleep(), __wakeup()__toString()__invoke()__set_state()__clone()__debugInfo()

參考文檔:https://www.cnblogs.com/20175211lyz/p/11403397.html

弱類型

標準類型:布爾boolen、整型integer、浮點float、字符string複雜類型:數組array、對象object特殊類型:資源resource

操作之間比較

(1) 字符串和數字比較(2) 數字和數組比較(3) 字符串和數組比較(4) "合法數字+e+合法數字"類型的字符串(5) == 和 ===

<?phpvar_dump(0=="admin");   var_dump(1=="1admin");  var_dump(1=="admin1");  var_dump(0=="admin1");  
$arr = array();var_dump(0==$arr);
$arr = array();var_dump("0"==$arr);
var_dump("0e123"=="0e456"); var_dump("1e1"=="10"); ?>

empty 和 isset 

變量為:0,"0",null,'',false,array()時,使用empty函數,返回的都為true變量未定義或者為null時,isset函數返回的為false,其他都為true

$a = null;$b = 0;$c = '';
var_dump(isset($a)); var_dump(isset($b)); var_dump(isset($c));

函數md5

string md5 ( string $str [, bool $raw_output = false ] )參數 描述string 必需。規定要計算的字符串。raw可選。規定十六進位或二進位輸出格式:TRUE - 原始 16 字符二進位格式FALSE - 默認。32 字符十六進位數

$a = array("1","2","3");$b = array("1","2","4");var_dump(md5($a) == md5($b));  

strcmp函數

int strcmp ( string $str1 , string $str2 )
string1 必需。規定要比較的第一個字符串。string2 必需。規定要比較的第二個字符串。
返回值:本函數返回:0 - 如果兩個字符串相等<0 - 如果 string1 小於 string2

<?php
$password = "123456";if (isset($_GET['pwd'])){ if(strcmp($_GET['pwd'],$password) == 0){ echo "success"; } else { echo "fail"; }}?>

in_array() 和 array_search()

bool in_array ( mixed $search , array $array [, bool $type = FALSE ] )

search必需。規定要在數組搜索的值。array 必需。規定要搜索的數組。

type

可選。如果設置該參數為 true,則檢查搜索的數據與數組的值的類型是否相同。

mixed array_search ( mixed $value , array $array [, bool $type = false ] )

value 必需。規定需要搜素的鍵值。array 必需。規定被搜索的數組。strict可選。如果該參數被設置為 TRUE,則函數在數組中搜索數據類型和值都一致的元素。可能的值:true false - 默認

swith語句

如果switch是數字類型的case的判斷時,switch會將參數轉換為int類型

$a = "1asd";switch ($a){    case 1:        echo "success";        break;    case 2:        echo "fail";        break;}

偽協議

file:// 協議

條件

allow_url_fopen:off/onallow_url_include :off/on

作用

用於訪問本地文件系統如導入為非.php文件,則仍按照php語法進行解析,這是include()函數所決定的。

用法

php:// 協議

條件

allow_url_fopen:off/onallow_url_include :off/on僅php://input php://stdin php://memory php://temp 需要on

作用

php:// 訪問各個輸入/輸出流(I/O streams),php://filter用於讀取源碼,php://input用於執行php代碼。

php://input可以訪問請求的原始數據的只讀流,在POST請求中訪問POST的data部分,在enctype="multipart/form-data" 的時候php://input 是無效的。php://output只寫的數據流,允許以 print 和 echo 一樣的方式寫入到輸出緩衝區。php://fd(>=5.3.6)允許直接訪問指定的文件描述符。例如 php://fd/3 引用了文件描述符 3。php://memory php://temp(>=5.1.0)一個類似文件包裝器的數據流,允許讀寫臨時數據。兩者的唯一區別是 php://memory 總是把數據儲存在內存中,而 php://temp 會在內存量達到預定義的限制後(默認是 2MB)存入臨時文件中。臨時文件位置的決定和 sys_get_temp_dir() 的方式一致。php://filter(>=5.0.0)一種元封裝器,設計用於數據流打開時的篩選過濾應用。對於一體式(all-in-one)的文件函數非常有用,類似 readfile()、file() 和 file_get_contents(),在數據流內容讀取之前沒有機會應用其他過濾器。php://filter 參數描述
resource=<要過濾的數據流>必須項。它指定了你要篩選過濾的數據流。
read=<讀鏈的過濾器>可選項。可以設定一個或多個過濾器名稱,以管道符(*\*)分隔。write=<寫鏈的過濾器>可選項。可以設定一個或多個過濾器名稱,以管道符(\)分隔。<; 兩個鏈的過濾器>任何沒有以 read= 或 write= 作前綴的篩選器列表會視情況應用於讀或寫鏈。

用法:

php://filter/read=convert.base64-encode/resource=[文件名]讀取文件源碼(針對php文件需要base64編碼)

http://127.0.0.1/include.php?file=php://filter/read=convert.base64-encode/resource=phpinfo.php

php://input + [POST DATA]執行php代碼

http:[POST DATA部分]<?php phpinfo(); ?>

‍data:// 協議

allow_url_fopen:onallow_url_include :on

作用

data://text/plain

data://text/plain;base64,

http://127.0.0.1/include.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b

http:// & https:// 協議

allow_url_fopen:onallow_url_include :on

作用

常規 URL 形式,允許通過 HTTP 1.0 的 GET方法,以只讀訪問文件或資源

http://127.0.0.1/include.php?file=http://127.0.0.1/phpinfo.txthttps://test.com/1.txt

會話劫持

遇到的比較多的就是出現在cookie驗證上面,通常是沒有使用session來認證,直接將用戶信息保存在cookie中

Session劫持攻擊是指黑客劫持目標用戶的session id來獲取網站伺服器上未經許可的存取信息,特別是竊取目標用戶等的cookie數據,來取得網站的認可

session.php

<?phpheader("Content-type:text/html;charset=utf-8");session_start();if (isset($_POST['login'])){    $username = $_POST['username'];    $password = $_POST['password'];    $conn = mysql_connect("127.0.0.1","root","123456");    mysql_select_db("admin",$conn);    $sql = "SELECT * FROM user WHERE name ='".$username ."'";    $result = mysql_query($sql) or die("執行語句失敗". mysql_error());    if($row = mysql_num_rows($result)){        $_SESSION['username'] = $username;        $_SESSION['password'] = $password;        header("Location:http://127.0.0.1/member.php?user=".$username);    }}?>
<html><body><form method="post" name="form"> 帳號:<input type="text" name="username" /> 密碼:<input type="password" name="password" /> <input type="submit" name="login" /></form></body></html

member.php

<?phperror_reporting(E_ALL & ~E_NOTICE);session_start();echo "The session id is " . session_id() ."<br>";echo "The user is " . $_GET['user']  ."<br />";echo "The book num is 1";?>

attack.php

<?phpheader("Content-type:text/html;charset=utf-8");session_start();echo "The session id is " . session_id() ."<br>";echo "The user is " . $_SESSION['username']  ."<br />";echo "The book num is 2000";?>

基礎講完了,下一篇 正式進行實戰!

相關焦點

  • 搜索 PHP代碼審計之旅
    但如果這些代碼是分布在一套源碼中(如CMS),需要我們去發現,去找到並會利用,就需要有一定的查找以及利用思路,這次測試的是BlueCMS1.6,重要不在於去復現這個CMS的漏洞,而在先了解一下整個審計思路還有過程是怎麼樣的,去鍛鍊自己的審計能力。由於我比較菜,所以有錯誤的地方也請師傅們指正。何為白盒、黑盒、灰盒測試審計代碼會經常遇到這三個名詞,這又代表是什麼意思那?
  • 二.PHP代碼審計涉及到的超全局變量
    · 出品|安全幫(www.secbang.com)概述:安全幫專注安全教育大牛繞過 針對零基礎小白【本章目的】掌握代碼審計中常用的代碼調試函數修改tets.php代碼,定義了一個名為test()的函數,賦值局部變量$xipu的值為simple,「echo $GLOBALS[『secbang』]」語句由於使用了$GLOBALS($GLOBALS['var']是外部的全局變量本身),故輸出的是test()函數之外定義的全局變量,即$secbang = "secbanger";,所以輸出secbanger。
  • 【代碼審計】PHP代碼審計之CTF系列(3)
    phpif(isset($_GET) && !empty($_GET)){ $url = $_GET['file']; $path = 'upload/'.payload:http://127.0.0.1/ctf/1.php?file=http://127.0.0.1//ctf/1.php?
  • 代碼審計入門實戰
    雖然有PHP是世界上最好的語言這種說法,但是也有一些因為弱類型語言的安全性問題出現,這就需要安全人員通過代碼審計來檢查PHP程序的安全性。0x02 代碼審計又是什麼代碼審計,顧名思義就是檢查原始碼中的安全缺陷。
  • ZZZPHP1.61 代碼審計-從SQL注入到Getshell
    近期有很多小夥伴在後臺留言想看關於代碼審計的文章,其實有關審計的文章網上資源是比較多的,但是從代碼審計開始到結束的這類文章卻少之甚少。
  • XDCMS V1 代碼審計之旅
    3:訪問特定功能點,進行特定代碼審計,也就是說一個功能點看一段代碼(這裡如果出現了過濾函數,基本上可以在2中找到)審計之旅先打開首頁看看,看到有登陸框和註冊框,那就先從註冊框開始審計,查看代碼,蕪湖,沒有進行過濾,直接調用,舒服了(這裡默認後綴為.php)
  • 【作者投稿】PHP代碼審計-sprintf函數中的安全問題
    測試代碼:<?php  $str = '788 1and 1=1';  echo sprintf('output is %d',$str);  ?對每個元素進行分隔) 必須,百分號%可選,美元符號$和單引號'可選,長度百分號為識別符,被認為是特定匹配模式的開始;後面的數字是從模式參數後面的第n個參數輸入數據;美元符號和後面的單引號是開啟padding模式(字符填充)的標識,緊跟在$'後面的是用來填充的字符;長度則為規定的輸入數據長度,如果數據足夠的話無效,如果數據不夠的話就使用$'後面的填充字符進行填充;最後的為數據類型 s表示字符串,d表示整數測試代碼
  • php代碼審計學習之函數缺陷
    $this->file['name'] ); } }}$challenge = new Challenge($_FILES['solution']);代碼為一個文件上傳的代碼,如果文件名存在於1-24中,則上傳文件in_array
  • 代碼審計Day9 - str_replace函數過濾不當
    前言大家好,我們是紅日安全-代碼審計小組。最近我們小組正在做一個PHP代碼審計的項目,供大家學習交流,我們給這個項目起了一個名字叫 PHP-Audit-Labs 。具體代碼如下:/load.class.php 文件):
  • 代碼審計之PHPWIND
    圖1跟蹤代碼執行當本地上傳時會進入uploadAction函數,先進行了用戶驗證然後新建一個文件上傳的PwApplicationUpload類開始執行上傳具體代碼如下根據分析安裝成功後的目錄名為alias名稱,最後訪問a.php getshellhttp://192.168.86.232/phpwind/src/extensions/test211/a.php
  • PHP代碼安全
    }以上代碼如果沒有限制 pagesize 的範圍,惡意請求者請求把 pagesize 輸入 5000,10000 等甚至更大的數,會給資料庫帶來一定的壓力,localhost/api/articles?
  • PHP Document 代碼注釋規範
    首頁 > 語言 > 關鍵詞 > php最新資訊 > 正文 PHP Document 代碼注釋規範
  • PHP 代碼規範簡潔之道
    之前整理過 PSR 的標準,也找過 php-cs-fixer 這樣的工具。這些都是規範代碼的重要手段。有統一的標準,配合上工具的檢查,形成統一的編碼約束不是什麼難題。沒有規範,不同的人甚至同一個人在空格、換行和命名上都有可能是十分隨意的。代碼一長,回使整個文件看起來無比雜亂。
  • 代碼執行、命令執行漏洞-PHP
    php echo(escapeshellcmd($_GET['cmd']));?php preg_replace("/\[(.*)\]/e",'\\1',$_GET['str']); //從$_GET['str']變量裡搜索括號[]中間的內容作為第一組的結果,preg_replace()函數的第二個參數為'\\1'代表這裡用第一組結果填充,這裡可以直接執行代碼?
  • PHP代碼20個實用技巧
    還可做得更多:為同樣文件查找多個目錄。能很容易的改變放置類文件的目錄,無須在代碼各處一一修改。可使用類似的函數加載文件,如html內容。為應用保留調試代碼  在開發環境中,我們列印資料庫查詢語句,轉存有問題的變量值,而一旦問題解決,我們注釋或刪除它們。然而,更好的做法是保留調試代碼。在開發環境中,你可以:
  • PHP的語言層面的優化以及代碼優化技巧
    首頁 > 語言 > 關鍵詞 > php最新資訊 > 正文 PHP的語言層面的優化以及代碼優化技巧
  • 通過PHP與Python代碼對比淺析語法差異
    這裡也有換行的字符串"""來定義一大段字符串;字符串可以使用字符串 + 字符串的方式進行拼接,也可以使用 字符串 * 數字,將字符串重複憑藉,比如 'abc' * 2,name得出的字符串便是abcabc3.2.3 數據類型在整型和浮點數據類型中加減乘除沒有什麼太特別,同樣是使用+、-、*、/這四個符號
  • 0060 PHP代碼嵌入到HTML網頁當中
    PHP嵌入HTML的方式前面幾節課都是純粹的PHP代碼,然後通過php命令執行php文件代碼的方式來運行PHP代碼。PHP代碼的作用,僅僅是通過動態程式語言生成需要的數據或者是顯示格式。可以這樣理解,PHP代碼在伺服器端運行,運行結束後的文件內容是HTML內容。這樣的好處不言而喻,可以根據需求對每一個客戶端瀏覽器生成完全不同的網站內容。
  • php語法檢查的方法有哪些?(代碼示例)
    php中語法檢查是非常有必要的,如果不檢查語法,則在發生錯誤時無法正常工作,如果同時執行語法檢查,則可能不會發生該錯誤,本篇文章我們就來看一看php語法檢查的方法。※php_check_syntax這個語法檢查函數已經被廢止,所以不能使用。然後準備實際出現錯誤的php文件。lint_test.php<?
  • 如何使用PHP處理CSV文件?(代碼示例)
    源 / php中文網      源 / www.php.cn在PHP中我們可以使用fgetcsv()函數來解析CSV文件,它可以自動解析給定資源中的CSV欄位。為了使用fgetcsv()函數,我們需要先用fopen()函數打開文件進行讀取,然後用fclose()函數關閉文件來結束代碼。在兩者之間,我們使用一個循環,分別解析CSV每一行。