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

ctfshow web 入门 php特性

web 89

<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 15:38:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/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;}
}

preg_match当检测的变量是数组的时候会报错并返回0。而intval函数当传入的变量也是数组的时候,会返回1

// intval 转换数组类型时 不关心数组中的内容 只判断数组中有没有元素

// 空数组 返回 0

// 非空数组 返回 1

?num[]=1

web90

<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:06:11
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/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($var,$base),其中var必填,base可选,这里base=0,则表示根据var开始的数字决定使用的进制: 0x或0X开头使用十六进制,0开头使用八进制,否则使用十进制。 这里===表示类型和数值必须相等,我们可以使用4476的八进制或十六进制绕过检测。 paylod:num=010574或num=0x117c

可以使用科学计数法进行绕过 ?num=4476.0 /** intval('4476.0')=4476 小数点
intval('+4476.0')=4476 正负号 intval('4476e0')=4476 科学计数法 intval('0x117c')=4476 16进制 intval('010574')=4476 8进制 intval(' 010574')=4476 8进制+空格 **/

有关这个函数intval(str,int)的讲解: 关于他的使用,当你使用 intval($_GET['num'], 0) 时,PHP 将对字符串 4476# 进行整数转换,PHP 的 intval 函数会从字符串的开始部分提取有效数值,直到遇到非数字字符就停止了,所以当你传入4476的时候,只要在其后面加入特殊符号的url编码值即可绕过 示例:?num=4476%23 ?num=4476%09 等等

web94

<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:46:19
# @link: https://ctfer.com*/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不能等于4476

会正则匹配a-z,不能出现字母,基本十六进制绕过就行不通了

strpos函数会检测匹配的字符在检测的字符串中出现的位置,第零个字符出现就返回0,题目要求为0的话就会返回no,no,no显然开头不能有零,但是字符串里其他地方必须有个零

综上,可以用八进制绕过/?num=+010754(前面的0和十六进制的0x是一个意思)

解释一下为什么呢=可以绕过,strpos匹配的时候+会占一位,所以实际0被匹配的时候是第二位了

image

也可以用小数/?num=4476.0

也可以用换行?num=4476%0a0

也可以在最前面加空格?num=%204476

web95

<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:53:59
# @link: https://ctfer.com*/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;}
}

跟上题相比多了个.的绕过,小数绕过行不通了,还多了个弱比较相等,

用+010574可以绕过(因为弱比较不会识别八进制),还可以用%2010574(strpos函数会将%20自动算作一位)

web96

<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 19:21:24
# @link: https://ctfer.com*/highlight_file(__FILE__);if(isset($_GET['u'])){if($_GET['u']=='flag.php'){die("no no no");}else{highlight_file($_GET['u']);}}

拼接不行fl''ag.php

image

通配不行f?ag.php

image

转义也不行flag.php%00

image

看来只能老老实实的用目录遍历写了

./flag.php

/var/www/html/flag.php

当然php伪协议也是可以的,file协议也可以

php://filter/read=covert.base64-encode/resource=flag.php

file:///var/www/html/flag.php

web98

<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 21:39:27
# @link: https://ctfer.com*/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__);?>

这里涉及到php的三元运算符XXXX?XX:xx,如果XXXX成立,冒号前的为真,反之冒号后的为假

$_GET?$_GET=&$_POST:'flag';首先判断是否存在get参数,存在的话就将 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">$_GET</font>** 赋值为 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">$_POST</font>**引用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">&</font>** 表示引用,即两者指向同一内存地址,修改其中一个会影响另一个),不存在的话

就是flag,但是貌似没啥意义

<font style="color:rgb(64, 64, 64);">$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';</font>首先判断GET传参的flag参数的值是否为'flag',如果是的话就把将 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">$_GET</font>** 赋值为 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">$_COOKIE</font>**引用,不存在的话就是flag,但是貌似没啥意义

<font style="color:rgb(64, 64, 64);">$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';</font>首先判断GET传参的flag参数的值是否为'flag',如果是的话就把将 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">$_GET</font>** 赋值为 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">$_SERVER</font>**引用,不存在的话就是flag,但是貌似没啥意义

<font style="color:rgb(64, 64, 64);">highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);</font>首先判断GET传参的HTTP_FLAG参数的值是否为'flag',是的话就输出flag,不是的话就输出当前php文件源码

解题思路

分析上面的代码可以看出来,只要有输入的get参数就将get方法改变为post方法(修改了get方法的地址),而第二三行代码没啥用,我们用不到,直接看第四行,如果get参数HTTP_FLAG的值为flag,就读取文件,也就是输出flag。所以思路就有了,我们通过get随便传一个参数并赋值,然后我们通过post请求传HTTP_FLAG参数并赋值为flag即可获得flag。

image

web99

<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 22:36:12
# @link: https://ctfer.com*/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']);
}?>

代码审计可以得到,创建一个对象赋值为空数组,然后从i=36开始一直到0x36d(877)

在每次循环中,使用 rand(1, $i) 函数生成一个 1 到 $i 之间的随机数(也就是 1~877),并将其添加到 $allow 数组的最后一个元素

检查是否设置了名为 n 的 GET 参数,并且确保它的值在 $allow 数组中。如果 $_GET['n'] 的值在 $allow 数组中,将 $_POST['content'] 的内容写入文件 $_GET['n'] 中。

接下来我们先看一个关于 in_array 函数的小测试:

<?php
$allow = [1,2,3];
$a = '2.php'
echo in_array($a,$allow)
?>

**结论:in_array() 函数存在弱比较的漏洞,如果没有设置第三个参数,in_array() 函数在比较时默认是弱类型比较,这意味着它会进行自动类型转换。例如数组中的元素是整数,而搜索的值是字符串,PHP 会尝试将字符串转换为整数来进行比较。比如上面字符串类型的 1.php 就自动转换为了整数 1,也就符合在数组中的条件。**

关于 in_array() 函数的参数和用法:

image
因此我们的文件名的数字只要符合在 1~877 之间,理论上来说就都可以写入一句话木马。

保险起见我们使用大概率会出现的,比如 1 ,多试几次。

写入一句话木马

get:

:::info
?n=1.php

:::

image

post:

:::info
?content=

:::

image

页面为空白说明成功写入

image

image

http://www.zskr.cn/news/8229.html

相关文章:

  • 详细介绍:Git如何无痕上传当前项目最新状态从当前远程到另一个远程
  • 【qt】全局事件总线
  • 深入解析:React Device Detect 完全指南:构建响应式跨设备应用的最佳实践
  • ctfshow web89
  • ctfshow web90
  • web360
  • hbase的安装应用
  • ctfshow web357
  • 深入解析:Java全栈开发面试实录:从基础到微服务的实战解析
  • 谁会不爱低温静音 性能还更强的!酷睿Ultra 5 230F vs 锐龙5 9600X生产力、功耗、温度全方位对比
  • WPF viewmodel retrieve matched view /window
  • ctfshow web353
  • fxztgxj5.dll fxzrs4qj.dll fxztgxa5.dll fxzrs3qj.dll fxzpmc1.dll fxzrs2qj.dll fxzmpxa5.dll - 实践
  • 测试新手必学:10个让Bug无处遁形的黑盒测试技巧
  • 数据分类分级如何高效低成本落地?|高效智能的数据分类分级产品推荐(2025)
  • 文化课暂时计划
  • private void Form1_Load和 private void Form1_Activated 方法区别
  • BGP反射路由器
  • 完整教程:苹果WWDC25开发秘技揭秘:SwiftData3如何重新定义数据持久化
  • H5 页面与 Web 页面的制作方法 - 实践
  • Spring Cloud Gateway吞吐量优化
  • 完整教程:WinForms 项目里生成时选择“首选目标平台 32 位导致有些电脑在获取office word对象时获取不到
  • nginx学习笔记一:基础概念
  • AUTOSAR进阶图解==>AUTOSAR_SWS_PDURouter - 实践
  • getDefaultMidwayLoggerConfig报错;解决方法。
  • Python实现Elman RNN与混合RNN神经网络对航空客运量、啤酒产量、电力产量时间序列数据预测可视化对比
  • 解题报告-老逗找基友 (friends)
  • Python_occ 学习记录 | 细观建模(1) - 教程
  • 【小白也能懂】PyTorch 里的 0.5 到底是干啥的?——一次把 Normalize 讲透! - 教程
  • 051-Web攻防-文件安全目录安全测试源码等