国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

php bugs代碼審計基礎詳解

瀏覽:128日期:2022-06-05 17:50:51
目錄
  • 變量覆蓋漏洞
  • 繞過過濾空白字符
  • 多重加密
  • WITH ROLLUP注入
  • erge截斷
  • strcmp比較字符串
  • sha()函數比較繞過

變量覆蓋漏洞

<?php$flag="xxx"; extract($_GET); if(isset($shiyan)) {     $content=trim(file_get_contents($flag));  //將讀取$flag內容并去除左右空白后保存到$content    if($shiyan==$content)    { echo"ctf{xxx}";     }   else   {     echo"Oh.no";   }    }?>

重要點為$shiyan==$content只要滿足這個條件就可以獲取flag。

首先extract()函數的作用為從數組將變量導入到當前符號表,也就是說我們如果構造

xxx.com/index.php?$shiyan=1則會生成一個名字為$shiyan的變量,值為1。

然后通過isset函數來判斷剛生成的$shiyan變量是否為null,如果為null就進入判斷。

$content變量則是通過file_get_contents函數和trim函數來讀取文件,但是此時它所讀取的文件$flag值為xxx,此時這個目錄是不存在的,所以它的值為空。

所以我們此時要做的就是將$shiyan的值變為空即可。

所以構造鏈接xxx.com/index.php?$shiyan=&flag=1即可獲得ctf{xxx}

繞過過濾空白字符

<?php$info = ""; $req = [];$flag="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";ini_set("display_error", false); //為一個配置選項設置值error_reporting(0); //關閉所有PHP錯誤報告if(!isset($_GET["number"])){   header("hint:26966dc52e85af40f59b4fe73d8c323a.txt"); //HTTP頭顯示hint 26966dc52e85af40f59b4fe73d8c323a.txt   die("have a fun!!"); //die — 等同于 exit()}foreach([$_GET, $_POST] as $global_var) {  //foreach 語法結構提供了遍歷數組的簡單方式     foreach($global_var as $key => $value) { $value = trim($value);  //trim — 去除字符串首尾處的空白字符(或者其他字符)is_string($value) && $req[$key] = addslashes($value); // is_string — 檢測變量是否是字符串,addslashes — 使用反斜線引用字符串    } } function is_palindrome_number($number) {     $number = strval($number); //strval — 獲取變量的字符串值    $i = 0;     $j = strlen($number) - 1; //strlen — 獲取字符串長度    while($i < $j) { if($number[$i] !== $number[$j]) {     return false; } $i++; $j--;     }     return true; } if(is_numeric($_REQUEST["number"])) //is_numeric — 檢測變量是否為數字或數字字符串 {   $info="sorry, you cann"t input a number!";}elseif($req["number"]!=strval(intval($req["number"]))) //intval — 獲取變量的整數值{     $info = "number must be equal to it"s integer!! ";  }else{     $value1 = intval($req["number"]);     $value2 = intval(strrev($req["number"]));       if($value1!=$value2){  $info="no, this is not a palindrome number!";     }     else     {  if(is_palindrome_number($req["number"])){      $info = "nice! {$value1} is a palindrome number!";   }  else  {     $info=$flag;  }     }}echo $info;

根據代碼判斷,它需要滿足多個條件才可以執行$info=$flag;之后echo出來的才是flag。

if(is_numeric($_REQUEST["number"])) //is_numeric — 檢測變量是否為數字或數字字符串 {   $info="sorry, you cann"t input a number!";}

先來看看第一個條件,它要求number參數傳入的內容不能為數字,否則返回sorry, you cann't input a number!

但是它的第二個要求為數字必須為整數,否則輸出number must be equal to it's integer!!

elseif($req["number"]!=strval(intval($req["number"]))) //intval — 獲取變量的整數值{     $info = "number must be equal to it"s integer!! ";  } 

導致我們輸入字符串也會報錯

這里我們用到%00來繞過is_numeric函數的判斷。

根據報錯,再來看看$value1,它是$req["number"]的整數值,$value2則為反轉之后的$req["number"]的整數值。

$value1 = intval($req["number"]);$value2 = intval(strrev($req["number"]));  if($value1!=$value2){  $info="no, this is not a palindrome number!";     }

所以第三步要滿足的條件為,它必須為回文數即從左往右和從右往左讀取都要相同的數值,所以我們構造如下

以上三個條件都滿足后,接下來看看最后一個條件

  if(is_palindrome_number($req["number"])){      $info = "nice! {$value1} is a palindrome number!";   }  else  {     $info=$flag;  }

這里調用了is_palindrome_number()函數,我們看看函數內容

function is_palindrome_number($number) {     $number = strval($number); //strval — 獲取變量的字符串值    $i = 0;     $j = strlen($number) - 1; //strlen — 獲取字符串長度    while($i < $j) { if($number[$i] !== $number[$j]) {     return false; } $i++; $j--;     }     return true; } 

可以看到這里函數的作用是判斷數字是否是對稱的,我們的要求是讓它執行return false來執行$info=$flag;所以這里想到的是在數字前加字符串+字符串+is_numeric中是被無視的,也就是說+100與100相等。

所以我們構造%00%2b454即可

多重加密

<?php    include "common.php";    $requset = array_merge($_GET, $_POST, $_SESSION, $_COOKIE);    //把一個或多個數組合并為一個數組    class db    {public $where;function __wakeup(){    if(!empty($this->where))    {$this->select($this->where);    }}function select($where){    $sql = mysql_query("select * from user where ".$where);    //函數執行一條 MySQL 查詢。    return @mysql_fetch_array($sql);    //從結果集中取得一行作為關聯數組,或數字數組,或二者兼有返回根據從結果集取得的行生成的數組,如果沒有更多行則返回 false}    }    if(isset($requset["token"]))    //測試變量是否已經配置。若變量已存在則返回 true 值。其它情形返回 false 值。    {$login = unserialize(gzuncompress(base64_decode($requset["token"])));//gzuncompress:進行字符串壓縮//unserialize: 將已序列化的字符串還原回 PHP 的值$db = new db();$row = $db->select("user=\"".mysql_real_escape_string($login["user"])."\"");//mysql_real_escape_string() 函數轉義 SQL 語句中使用的字符串中的特殊字符。if($login["user"] === "ichunqiu"){    echo $flag;}else if($row["pass"] !== $login["pass"]){    echo "unserialize injection!!";}else{    echo "(╯‵□′)╯︵┴─┴ ";}    }else{header("Location: index.php?error=1");    }?> 

因題目中并沒有給出數據庫配置文件,所以直接看題,在題目中重點部分為

    if(isset($requset["token"]))    //測試變量是否已經配置。若變量已存在則返回 true 值。其它情形返回 false 值。    {$login = unserialize(gzuncompress(base64_decode($requset["token"])));//gzuncompress:進行字符串壓縮//unserialize: 將已序列化的字符串還原回 PHP 的值$db = new db();$row = $db->select("user=\"".mysql_real_escape_string($login["user"])."\"");//mysql_real_escape_string() 函數轉義 SQL 語句中使用的字符串中的特殊字符。if($login["user"] === "ichunqiu"){    echo $flag;}else if($row["pass"] !== $login["pass"]){    echo "unserialize injection!!";}else{    echo "(╯‵□′)╯︵┴─┴ ";}    }else{header("Location: index.php?error=1");    }

條件1為判斷是否存在token參數,如果存在,那么就將token得值進行反序列化和解壓縮后的值進行base64解密。

解密完成后會帶入上面寫得db類中得select方法查詢。

接著就是需要注意得重點,if($login['user'] === 'ichunqiu')即需要傳入的user值為ichunqiu

所以我們逆推出來需要做得就是先將user設定值為ichunqiu,隨后進行base64加密得到值,但是我們剛才說到它在傳值過程中進行了反序列話和解壓縮,所以我們也需要進行壓縮和序列化,分別用

gzcompress來壓縮gzuncompress解壓縮。

serialize來序列化unserialize反序列化。

最終得到如下代碼,并得到token的值為eJxLtDK0qs60MrBOAuJaAB5uBBQ=,提交token即可echo $flag

<?php$arr = array(["user"] === "ichunqiu");$token = base64_encode(gzcompress(serialize($arr)));print_r($token);?>

WITH ROLLUP注入

<?phperror_reporting(0);if (!isset($_POST["uname"]) || !isset($_POST["pwd"])) {    echo "<form action="" method="post">"."<br/>";    echo "<input name="uname" type="text"/>"."<br/>";    echo "<input name="pwd" type="text"/>"."<br/>";    echo "<input type="submit" />"."<br/>";    echo "</form>"."<br/>";    echo "<!--source: source.txt-->"."<br/>";    die;}function AttackFilter($StrKey,$StrValue,$ArrReq){      if (is_array($StrValue)){//檢測變量是否是數組$StrValue=implode($StrValue);//返回由數組元素組合成的字符串    }    if (preg_match("/".$ArrReq."/is",$StrValue)==1){   //匹配成功一次后就會停止匹配print "水可載舟,亦可賽艇!";exit();    }}$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";foreach($_POST as $key=>$value){ //遍歷數組    AttackFilter($key,$value,$filter);}$con = mysql_connect("XXXXXX","XXXXXX","XXXXXX");if (!$con){    die("Could not connect: " . mysql_error());}$db="XXXXXX";mysql_select_db($db, $con);//設置活動的 MySQL 數據庫$sql="SELECT * FROM interest WHERE uname = "{$_POST["uname"]}"";$query = mysql_query($sql); //執行一條 MySQL 查詢if (mysql_num_rows($query) == 1) { //返回結果集中行的數目    $key = mysql_fetch_array($query);//返回根據從結果集取得的行生成的數組,如果沒有更多行則返回 false    if($key["pwd"] == $_POST["pwd"]) {print "CTF{XXXXXX}";    }else{print "亦可賽艇!";    }}else{    print "一顆賽艇!";}mysql_close($con);?>

第四題我們先來看看flag輸出得條件

    if($key["pwd"] == $_POST["pwd"]) {print "CTF{XXXXXX}";    }else{print "亦可賽艇!";    }

要滿足post中提交得pwd與$key = mysql_fetch_array($query);數據庫中讀取到得pwd相等,所以考點在于注入。

但是在AttackFilter函數和$filter中已經限制了sql注入得關鍵字,所以沒辦法直接進行注入。

其實在報錯得過程中已經進行了提示亦可賽艇!,諧音為因缺思汀也就是WITH ROLLUP繞過注入

WITH ROLLUP是對group by分組后得結果進行進一步得匯總,如果按照列名進行分組,因為列得屬性不同,所以會生成一條值null得新數據,如果查詢結果時單一得情況下會生成一條列為null得數據。

我們來看看演示,值直接進行查詢是有結果得

使用group by語句分組查詢也是正常顯示

但是當我們在group by語句后添加WITH ROLLUP,可以看到效果如下

但是我們只需要其中第二列得數據,所以使用limit 1讀取1條數據并使用offset去除一行數據得到我們需要得第二行

pwd得值被設置為了null,所以此題我們可以通過提交admin' GROUP BY pwd WITH ROLLUP LIMIT 1 OFFSET 1-- -來達到$key['pwd'] == $_POST['pwd']得條件并獲取flag。

erge截斷

<?php $flag = "flag";if (isset ($_GET["password"])) {  if (ereg ("^[a-zA-Z0-9]+$", $_GET["password"]) === FALSE)  {    echo "<p>You password must be alphanumeric</p>";  }  else if (strlen($_GET["password"]) < 8 && $_GET["password"] > 9999999)   {     if (strpos ($_GET["password"], "*-*") !== FALSE) //strpos — 查找字符串首次出現的位置      {      die("Flag: " . $flag);      }      else      {echo("<p>*-* have not been found</p>");        }      }     else      {echo "<p>Invalid password</p>";       }   } ?>

先來梳理流程 首先條件一用ereg函數來寫死get參數password得值必須是數字大小寫字母,否則輸出You password must be alphanumeric

第二個條件為strlen($_GET['password']) < 8 && $_GET['password'] > 9999999也就是必須長度小于8但是值又要大于9999999。

所以我們需要用科學計數法來繞過這里得限制1e7為10得7次方10000000。

第三個條件為strpos ($_GET['password'], '*-*') !== FALSE在值中必須存在*-*如果滿足此條件,就沒辦法滿足條件一,所以這里可以采用%00截斷法來進行繞過,因為ereg函數遇到%00后就不會繼續進行判斷

?password=1e7%00*-*即可滿足全部條件,執行die('Flag: ' . $flag);來獲取flag

strcmp比較字符串

<?php$flag = "flag";if (isset($_GET["a"])) {      if (strcmp($_GET["a"], $flag) == 0) //如果 str1 小于 str2 返回 < 0; 如果 str1大于 str2返回 > 0;如果兩者相等,返回 0。     //比較兩個字符串(區分大小寫) die("Flag: ".$flag);      else  print "No";  }?>

這題得考點在于strcmp函數,它的作用在于兩個字符串相比較,如果兩者相等就會==0

此函數是用來處理字符串參數的,如果提交的值是數組的話會返回個null在判斷中使用的是==等值符,如果類型不相同的情況下會轉換為同類型進行比較,所以null==0,執行die('Flag: '.$flag);

所以我們提交一個數組類型的值即可?a[]=1

sha()函數比較繞過

<?php$flag = "flag";if (isset($_GET["name"]) and isset($_GET["password"])) {    if ($_GET["name"] == $_GET["password"])echo "<p>Your password can not be your name!</p>";    else if (sha1($_GET["name"]) === sha1($_GET["password"]))      die("Flag: ".$flag);    elseecho "<p>Invalid password.</p>";}else    echo "<p>Login first!</p>";?>

這題的考點在于sha1($_GET['name']) === sha1($_GET['password'])

他這里使用的是===等同符,他要求兩邊值得類型相同,才會去比較值,否則會直接返回false

首先來看條件一$_GET['name'] == $_GET['password'] name要與password不相等才會執行else if

但是else if又要求===,所以我們可以利用sha1函數不能處理數組得機制來繞過

?name[]=1&password[]=2既滿足了name與password不相等,也滿足了因sha1無法處理數組,導致返回值為false=false所以會執行die('Flag: '.$flag);

到此這篇關于php bugs代碼審計基礎詳解的文章就介紹到這了,更多相關php bugs內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!

標簽: PHP
主站蜘蛛池模板: 亚洲天堂视频在线观看免费 | 欧美成人三级大全 | 精品在线视频免费观看 | 在线观看精品视频 | 亚洲欧美自拍偷拍 | 欧美日韩高清 | 日韩午夜在线观看 | 精品国产日韩亚洲一区二区 | 美女日韩在线观看视频 | 欧美精品在线一区二区三区 | 久久99亚洲精品久久99 | 亚洲精品欧美精品国产精品 | 欧美日韩一区二区综合 | 三级黄色免费网站 | 手机日韩理论片在线播放 | 久久视频精品36线视频在线观看 | 中国三级网站 | 日本阿v视频在线观看高清 日本波多野结衣视频 | 中文字幕一级毛片 | 色综合精品 | 日韩在线手机看片免费看 | 九九99香蕉在线视频免费 | 97国产在线视频公开免费 | 欧美多人三级级视频播放 | 久久国产精品永久免费网站 | 日本一级毛片中文字幕 | 美女视频永久黄网站在线观看 | 老司机精品影院一区二区三区 | 国产精品偷伦费观看 | 欧美色黄毛片 | 国产精品亚洲高清一区二区 | 成人做爰毛片免费视频 | 美女一级片视频 | 在线播放免费一级毛片欧美 | avtt天堂网永久资源手机版 | 国产三级精品91三级在专区 | 一级做a爱过程免费视频麻豆 | 一本色道久久综合亚洲精品 | 久久亚洲一级α片 | 欧美h版成版在线观看 | 亚洲一区二区三区中文字幕 |