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

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

php bugs代碼審計基礎詳解

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

變量覆蓋漏洞

<?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()函數(shù)的作用為從數(shù)組將變量導入到當前符號表,也就是說我們如果構造

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

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

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

所以我們此時要做的就是將$shiyan的值變?yōu)榭占纯伞?/p>

所以構造鏈接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 語法結構提供了遍歷數(shù)組的簡單方式     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 — 檢測變量是否為數(shù)字或數(shù)字字符串 {   $info="sorry, you cann"t input a number!";}elseif($req["number"]!=strval(intval($req["number"]))) //intval — 獲取變量的整數(shù)值{     $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;

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

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

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

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

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

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

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

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

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

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

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

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

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

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; } 

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

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

多重加密

<?php    include "common.php";    $requset = array_merge($_GET, $_POST, $_SESSION, $_COOKIE);    //把一個或多個數(shù)組合并為一個數(shù)組    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);    //函數(shù)執(zhí)行一條 MySQL 查詢。    return @mysql_fetch_array($sql);    //從結果集中取得一行作為關聯(lián)數(shù)組,或數(shù)字數(shù)組,或二者兼有返回根據(jù)從結果集取得的行生成的數(shù)組,如果沒有更多行則返回 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() 函數(shù)轉義 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");    }?> 

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

    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() 函數(shù)轉義 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參數(shù),如果存在,那么就將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)){//檢測變量是否是數(shù)組$StrValue=implode($StrValue);//返回由數(shù)組元素組合成的字符串    }    if (preg_match("/".$ArrReq."/is",$StrValue)==1){   //匹配成功一次后就會停止匹配print "水可載舟,亦可賽艇!";exit();    }}$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";foreach($_POST as $key=>$value){ //遍歷數(shù)組    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 數(shù)據(jù)庫$sql="SELECT * FROM interest WHERE uname = "{$_POST["uname"]}"";$query = mysql_query($sql); //執(zhí)行一條 MySQL 查詢if (mysql_num_rows($query) == 1) { //返回結果集中行的數(shù)目    $key = mysql_fetch_array($query);//返回根據(jù)從結果集取得的行生成的數(shù)組,如果沒有更多行則返回 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);數(shù)據(jù)庫中讀取到得pwd相等,所以考點在于注入。

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

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

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

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

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

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

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

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 — 查找字符串首次出現(xiàn)的位置      {      die("Flag: " . $flag);      }      else      {echo("<p>*-* have not been found</p>");        }      }     else      {echo "<p>Invalid password</p>";       }   } ?>

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

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

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

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

?password=1e7%00*-*即可滿足全部條件,執(zhí)行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。     //比較兩個字符串(區(qū)分大小寫) die("Flag: ".$flag);      else  print "No";  }?>

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

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

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

sha()函數(shù)比較繞過

<?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不相等才會執(zhí)行else if

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

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

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

標簽: PHP
主站蜘蛛池模板: 欧美巨乳在线观看 | 美国人成毛片在线播放 | 看中国一级毛片 | 久久精品亚洲精品一区 | 日本一级毛片视频无遮挡免费 | 男人毛片 | 韩日黄色| 亚洲一区二区三区免费在线观看 | 国产三级国产精品国产国在线观看 | 一区二区三区亚洲视频 | 欧美 日韩 国产 在线 | 久久视精品| 不卡一区在线观看 | 亚洲精品一区二区三区 | 精品视频在线一区 | 国产欧美久久久另类精品 | 成人网在线视频 | 国产精品19禁在线观看2021 | 国产成人精品午夜 | 日日摸人人拍人人澡 | 日本在线观看不卡免费视频 | 久久精品中文字幕首页 | 国产日比视频 | 欧美一级黄视频 | 手机成人看片 | 久久精品国产400部免费看 | 老司机久久影院 | 久久99亚洲精品久久久久网站 | 国产成人十八黄网片 | 欧美亚洲日本视频 | 久久欧美久久欧美精品 | 成人欧美一区二区三区黑人 | 成熟性xxxxx| 欧美成人性做爰 | 男人的天堂视频在线观看 | 久久久久久日本一区99 | 波多野结衣视频在线观看地址免费 | 亚洲成人黄色在线 | 最新国产精品好看的国产精品 | 免费毛片a线观看 | 国产欧美综合精品一区二区 |