当前位置:   article > 正文

ctfshow-web入门-php特性(web104-web108)

ctfshow-web入门-php特性(web104-web108)

目录

1、web104

2、web105

3、web106

4、web107

5、web108


1、web104

需要传入的 v1 和 v2 进行 sha1 加密后相等。

解法1:

这里都没有判断 v1 和 v2 是否相等,我们直接传入同样的内容加密后肯定也一样。

?v2=1

post: 

v1=1

拿到 flag:ctfshow{bd4eea6b-872d-462c-b8f2-20f48d3ee652} 

解法2:

对于 php 强比较和弱比较:md5(),sha1() 函数无法处理数组,如果传入的为数组,会返回 NULL ,两个数组经过加密后得到的都是 NULL ,也就是相等的。

?v2[]=1

post:

v1[]=2

解法3:

对于某些特殊的字符串加密后得到的密文以 0e 开头,PHP 会当作科学计数法来处理,也就是 0 的 n 次方,得到的值比较的时候都相同。

下面是常见的加密后密文以 0e 开头的字符串:

  1. md5
  2. 240610708:0e462097431906509019562988736854
  3. QLTHNDT:0e405967825401955372549139051580
  4. QNKCDZO:0e830400451993494058024219903391
  5. PJNPDWY:0e291529052894702774557631701704
  6. NWWKITQ:0e763082070976038347657360817689
  7. NOOPCJF:0e818888003657176127862245791911
  8. MMHUWUV:0e701732711630150438129209816536
  9. MAUXXQC:0e478478466848439040434801845361
  10. sha1
  11. 10932435112: 0e07766915004133176347055865026311692244
  12. aaroZmOk: 0e66507019969427134894567494305185566735
  13. aaK1STfY: 0e76658526655756207688271159624026011393
  14. aaO8zKZF: 0e89257456677279068558073954252716165668
  15. aa3OFF9m: 0e36977786278517984959260394024281014729
  16. 0e1290633704: 0e19985187802402577070739524195726831799
?v2=aaroZmOk

 post:

v1=aa3OFF9m

2、web105

foreach 在 PHP 中用于遍历数组或对象:

key 和 value 分别表示数组中的键和对应的值。

  1. foreach ($array as $value) {
  2. // 对 $value 进行操作
  3. }
  4. foreach ($array as $key => $value) {
  5. // 对 $key 和 $value 进行操作
  6. }

一眼看到使用了两个 $,直接将用户输入用作变量名,可能导致变量覆盖问题。

$$key=$$value;

代码中共有三个变量:$error,$flag,$suces

  1. foreach($_GET as $key => $value){
  2. if($key==='error'){
  3. die("what are you doing?!");
  4. }

get 请求的 key(参数)不能是 error

  1. foreach($_POST as $key => $value){
  2. if($value==='flag'){
  3. die("what are you doing?!");
  4. }

post 请求的 value(值)不能是 flag

(1)通过 die($error);  输出 flag,可以将 $error 覆盖为 $flag,payload:

  1. ?suces=flag
  2. ​ post: error=suces

get 传入 suces=flag,请求参数不是 error,因此不会触发第一个 die 函数;

接下来执行

key=
value; 即 $suces=$flag,也就是将 $flag 的内容赋值给 $suces;

post 传入 error=suces,value 是 suces,不是 flag,因此也不会触发第二个 die 函数;

之后执行 

key=
value; 即 $error=$suces,也就是将 $suces 的内容赋值给 $error;

  1. if(!($_POST['flag']==$flag)){
  2. die($error);
  3. }

最后检查是否 post 提交了 flag 并且内容就是 $flag,显然是没有的,前面还有一个 ! ,因此 if 语句成立,执行第三个 die 函数,输出变量 $error 的内容,即我们 flag 的内容。

验证:

拿到 flag:ctfshow{d346b9f7-d63f-492c-b573-c7ed4c7394e4}

其实这里的这个 $suces 只是一个中间者,我们只要不使用 error,其他任何的参数名都是可以的。

比如:

  1. ?1=flag
  2. error=1

(2)通过 die($suces); 输出 flag,将 $suces 覆盖为 $flag,payload:

?suces=flag&flag=

或者 

  1. ?suces=flag
  2. post:flag=

一来就先将 $flag 的内容赋给 $suces,之后将 $flag 赋为空(null),使得 $_POST['flag']==$flag 成立,执行 echo "your are good".$flag."\n"; 和 die($suces); 进而输出 $suces,即 flag 的内容。

3、web106

新增:

$v1!=$v2

采用数组绕过:

  1. ?v2[]=1
  2. post:v1[]=2

拿到 flag:ctfshow{a0d7580e-60f6-4a19-bef2-af27d8c2d017}

4、web107

parse_str() 函数:把查询字符串解析到变量中。

用法:parse_str(string,array)

参数描述
string必需。规定要解析的字符串。
array可选。规定存储变量的数组名称。该参数指示变量存储到数组中。

关于题目代码的详细解释:

parse_str($v1,$v2);

parse_str 函数将字符串 $v1 解析为变量并存储到数组 $v2 中。
$v1 是一个包含查询字符串的变量,例如:"flag=123&name=myon"。
解析后的结果将存储在数组 $v2 中,例如:$v2 将包含 ['flag' => '123', 'name' => 'myon']。 

  1. if($v2['flag']==md5($v3)){
  2. echo $flag;
  3. }

$v2['flag'] 是从解析后的数组 $v2 中获取的 flag 参数值,检查 $v2['flag'] 是否等于 md5($v3) 即 v3 经过 md5 加密后的值,等于则输出 flag。

理解题目意思后,这里的 payload 就有很多,只要符合要求都可以:

?v3=123

post 传入:

v1=flag=202cb962ac59075b964b07152d234b70

其中 202cb962ac59075b964b07152d234b70 是 123 的 md5 加密值:

拿到 flag:ctfshow{b91751db-f7b7-40ae-b920-fd2e3edc8964}

5、web108

代码审计: 

ereg ("^[a-zA-Z]+$", $_GET['c'])

使用 ereg 函数检查 $_GET['c'] 是否只包含大小写字母,不满足直接 die。

  1. if(intval(strrev($_GET['c']))==0x36d){
  2. echo $flag;
  3. }

通过 strrev 函数将 $_GET['c'] 反转,使用 intval 将反转后的字符串转换为整数,检查该整数是否等于十六进制的 0x36d(十进制的 877),如果相等,则输出 $flag 的内容。

其中 ereg 函数存在 NULL 截断漏洞,我们可以使用 %00 进行截断,payload:

?c=a%00778

这样正则就只会匹配 %00 之前的内容,即匹配到 a,符合要求,函数返回 true,if 语句不成立,跳过 die 函数,payload 经 strrev 函数反转后变为 877%00a,因为是弱比较,会存在自动类型转换,经过 intval 转为整数 877,比较成立,输出 flag。

拿到 flag:ctfshow{9fb901bb-8855-4a17-b4bc-a587d28a3f15}

为什么 %00 前面还要有一个 a,而不能是空的呢?

由于截断前的内容为空,ereg 函数还是会返回 false,就像我们什么都没有传入一样。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/829035
推荐阅读
相关标签
  

闽ICP备14008679号