二十一背苦、數(shù)字驗證正則繞過 *
<?php
error_reporting(0);
$flag = 'flag{test}';
if ("POST" == $_SERVER['REQUEST_METHOD'])
{
$password = $_POST['password'];
if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password)) //preg_match — 執(zhí)行一個正則表達式匹配
{
echo 'Wrong Format';
exit;
}
while (TRUE)
{
$reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
if (6 > preg_match_all($reg, $password, $arr))
break;
$c = 0;
$ps = array('punct', 'digit', 'upper', 'lower'); //[[:punct:]] 任何標點符號 [[:digit:]] 任何數(shù)字 [[:upper:]] 任何大寫字母 [[:lower:]] 任何小寫字母
foreach ($ps as $pt)
{
if (preg_match("/[[:$pt:]]+/", $password))
$c += 1;
}
if ($c < 3) break;
//>=3互捌,必須包含四種類型三種與三種以上
if ("42" == $password) echo $flag;
else echo 'Wrong password';
exit;
}
}
?>
$reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
if (6 > preg_match_all($reg, $password, $arr))
意為匹配到的次數(shù)要大于6次
$ps = array('punct', 'digit', 'upper', 'lower'); //[[:punct:]] 任何標點符號 [[:digit:]] 任何數(shù)字 [[:upper:]] 任何大寫字母 [[:lower:]] 任何小寫字母
foreach ($ps as $pt)
{
if (preg_match("/[[:$pt:]]+/", $password))
$c += 1;
}
if ($c < 3) break;
意為必須要有大小寫字母,數(shù)字行剂,字符內容三種與三種以上
if ("42" == $password) echo $flag;
意為必須等于42
答案:
42.00e+00000000000
或
420.000000000e-1
正則還不是很熟秕噪,先引用別人的解題思路。
二十二厚宰、弱類型整數(shù)大小比較繞過
<?php
error_reporting(0);
$flag = "flag{test}";
$temp = $_GET['password'];
is_numeric($temp)?die("no numeric"):NULL;
if($temp>1336){
echo $flag;
}
?>
要求很簡單腌巾,不能是數(shù)字且大于1336,只要使用PHP弱類型即可铲觉,php當一個其它類型的數(shù)據(jù)和數(shù)值類型的數(shù)據(jù)比較大小時澈蝙,會先將其他類型的數(shù)據(jù)轉換成數(shù)值類型,這里我們只要輸入類似9999a
的數(shù)據(jù)即可滿足條件撵幽。
二十三灯荧、md5函數(shù)驗證繞過
<?php
error_reporting(0);
$flag = 'flag{test}';
$temp = $_GET['password'];
if(md5($temp)==0){
echo $flag;
}
?>
要求md5值加密后為0,據(jù)我所知有一下方法:
- 弱類型法 弱類型比較NULL == 0,可以輸入空的password盐杂,加密后結果為null逗载。也可以輸入一個數(shù)組,php對數(shù)組進行hash運算后得到的結果為null
- 科學記數(shù)法法 前面的題目提到過 0exxx==0链烈,只要找到一個md5加密后0e開頭的數(shù)據(jù)就可以滿足數(shù)值為0
二十四厉斟、md5函數(shù)true繞過注入
error_reporting(0);
$link = mysql_connect('localhost', 'root', 'root');
if (!$link) {
die('Could not connect to MySQL: ' . mysql_error());
}
// 選擇數(shù)據(jù)庫
$db = mysql_select_db("security", $link);
if(!$db)
{
echo 'select db error';
exit();
}
// 執(zhí)行sql
$password = $_GET['password'];
$sql = "SELECT * FROM users WHERE password = '".md5($password,true)."'";
var_dump($sql);
$result=mysql_query($sql) or die('<pre>' . mysql_error() . '</pre>' );
$row1 = mysql_fetch_row($result);
var_dump($row1);
mysql_close($link);
?>
這個是思路是真沒見過,md5($password,true) 將md5后的hex轉換成字符串测垛,想要完成注入捏膨,不難看出我們需要一個可以轉換成'or'xxx
的md5值,難就難在找到符合條件的字符串食侮,我這里就不寫代碼自己找了号涯,直接順手牽羊一個。
字符串:ffifdyop
md5后锯七,276f722736c95d99e921722cf9ed621c
二十五链快、switch沒有break 字符與0比較繞過
<?php
error_reporting(0);
if (isset($_GET['which']))
{
$which = $_GET['which'];
switch ($which)
{
case 0:
case 1:
case 2:
require_once $which.'.php';
echo $flag;
break;
default:
echo GWF_HTML::error('PHP-0817', 'Hacker NoNoNo!', false);
break;
}
}
?>
這題要求包含flag.php
直接使用?which=flag
就成功了,為什么呢眉尸?
問題就在于 'flag' == 0 結果為true和沒有使用break域蜗,'flag' == 0是因為弱類型比較巨双,此處不再做過多解釋。因為'flag' == 0成立所以case 0 被執(zhí)行霉祸,又因為沒有使用break語句筑累,所以case1和case2也被執(zhí)行,所以直接輸入?which=flag
就可以執(zhí)行成功丝蹭。