1. 程式人生 > 實用技巧 >程式碼審計

程式碼審計

開啟題目,又是MD5函式

以為又是一個套路直接md5('240610708') == md5('QNKCDZO')去嘗試

結果構造http://123.206.87.240:9009/18.php?username=240610708&&password=QNKCDZO一直失敗

後來再審計程式碼,發現判斷的時候用了===,

所以而剛才我用那個的方法MD5只能==弱型別繞過

後來上網搜尋發現,MD5無法處理陣列

後來構造如下連結,拿到flag

題目

0x01 start

1.分析

這是一道程式碼審計的題目。
所以先來看看程式碼。

<?php
if(eregi("hackerDJ",$_GET[id])) {
echo("

not allowed!

");
exit();
}
$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "hackerDJ")
{
echo "
Access granted!

";
echo "
flag

";
}
?>

來整理一下說明緣由。

種類的eregi就是在字串中進行匹配
然後urldecode這個,因為最近就在看程式碼審計,所以這個還是很熟悉的,如果有需要,請看。

目標

所以我們現在就要對這個進行繞過了。

2. 繞過

首先我們想到的是二次轉碼,瀏覽器轉碼一次,然後urldecode轉碼一次,那麼我們就可以利用%25,轉碼之後就是%,那麼我們只要找到字母的url編碼就可以成功繞過了。

構造payload:

?id=%25%61ackerDJ
  • 1


首先分析程式碼,函式要求變數$temp不能存在1~9之間的數字,

最後,又要求$temp=3735929054;

這本來是自相矛盾的,但php在轉碼時會把16進位制轉化為十進位制.於是把

3735929054轉換成16進製為0xdeadc0de,記得帶上0x;

構造payload

?password=0xdeadc0de

拿到flag

ereg正則%00截斷的一道程式碼審計:

  1. if (isset ($_GET['password'])) {
  2. if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
  3. {
  4. echo '<p>You password must be alphanumeric</p>';
  5. }
  6. else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)
  7. {
  8. if (strpos ($_GET['password'], '*-*') !== FALSE)
  9. {
  10. die('Flag: ' . $flag);
  11. }
  12. else
  13. {
  14. echo('<p>*-* have not been found</p>');
  15. }
  16. }
  17. else
  18. {
  19. echo '<p>Invalid password</p>';
  20. }
  21. }

分析程式碼,有兩個函式需要注意:

  1. ereg() 正則限制了password格式,只能是一個或者多個數字、大小寫字母
  2. strpos() 查詢某字串在另一字串中第一次出現的位置(區分大小寫),本題中需要匹配到"*-*"才能輸出flag

解題方法1:利用陣列繞過這兩個函式

ereg() 只能處理字串,而password是陣列,所以返回的是null,三個等號的時候不會進行型別轉換。所以null!==false。

strpos() 的引數同樣不能夠是陣列,所以返回的依舊是null,null!==false也正確。

Payload:http://123.206.87.240:9009/5.php?password[]=1

解題方法2:%00截斷繞過正則匹配

判斷是不是長度<8且>9999999

判斷是不是有“*-*”

Payload:http://123.206.87.240:9009/5.php?password=1e9%00*-*