(限时投稿)CTF中的一些常见骚姿势(实战可以没有这个情景,但是不能不会)

g1870412862   ·   发表于 2021-04-15 16:34:25   ·   技术文章

0X01:前言

近期被学校的小伙伴拉去打ctf,上次线下赛被虐成?的情景还记忆犹新,这次务必要拿出成绩证明一下自己,希望自己可以变得像M1ng师傅、绮丽丽、爆栈倒斗师傅他们那样强,这段时间刷了挺多的ctf题,总结了一些ctf中常见的骚姿势。

0X02:来啦来啦,骚姿势总结来

一. 弱类型比较

ctf中见怪不怪了,经常已经知道题目要考察的是什么知识了,传参都要用个弱类型比较来为难一下我们。

  1. ‘=’,‘==’,‘===’
    一个等于是赋值,两个等于是将两个变量转相同的类型再比较,三个等于先比较变量类型是否相同再比较值。

  2. 非相同类型比较
    如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照数值来进行

先看几组比较结果:

当我们用字符串与数值类型比较时会将字符转变为数值,与C语言不同的是,他这里并不会转变为ascii码,而是将开头的数字转为对应的数值,开头没有数字则转为0,”0e123456”==”0e456789”相互比较的时候,会将0e这类字符串识别为科学技术法的数字,0的无论多少次方都是零,所以相等。

PHP手册是这么说明的:当一个字符串欸当作一个数值来取值,其结果和类型如下:如果该字符串没有包含'.','e','E'并且其数值值在整形的范围之内 该字符串被当作int来取值,其他所有情况下都被作为float来取值,该字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,否则其值为0。

0X03弱类型比较的利用

1.md5绕过,当传入的参数哈希值为0e开头时有可能触发。
2.json绕过,当我们不知道键的名字时可以尝试传入0,尝试能否满足形似0==“admin”
3.array_search is_array绕过。
4.strcmp漏洞绕过,要求PHP版本<5.3

0X04总结

正如风哥所说,我们和开发最大的不同就是学习这些冷门的奇技淫巧。还有就是,代码功底正是很重要,后悔浪费了前两年,走马观花式学习,现在开始恶补java和PHP,想捞个哥哥带带弟弟。
最后附上一句正在某互联网大厂做PM的前辈对我说过得的话:互联网是现在为数不多的可以靠努力改变现状的机会,年轻的时候不拼一把,简直是浪费。

后续还会写rce,奇怪的sql注入,模版注入等一些文章。最近在备战蓝帽杯,实在有点忙。

耳听为虚,眼见为实,用代码说话

1.MD5绕过

  1. <?php
  2. use phpDocumentor\Reflection\Types\Null_;
  3. header('Content-type:text/html;charset=utf-8');
  4. show_source(__FILE__);
  5. ?>
  6. <html>
  7. <body>
  8. <title>md5绕过</title>
  9. <meta charset="utf-8">
  10. </body>
  11. <body>
  12. <form method="POST">
  13. Str1:<input type="text" name="str1"><br>
  14. Str2:<input type="text" name="str2"><br>
  15. <input type="submit" value="提交">
  16. </form>
  17. </body>
  18. </html>
  19. <?php
  20. $var1 = $_POST["str1"];
  21. $var2 = $_POST["str2"];
  22. if (isset($var1) && isset($var2) && $var1 !== Null && $var2 !== Null) {
  23. if (md5($var1) == md5($var2)) {
  24. echo ("bypass success!!!<br>");
  25. echo ("md5_1 = " . md5($var1) . "<br>");
  26. echo ("md5_2 = " . md5($var2));
  27. } else {
  28. echo ("sorry,please hack me again!");
  29. }
  30. }


这边传入的值不一样,md5值也不同但是都是0exxxxxx格式的,在比较前做类型转换时会被当作科学计数法值为0所以bypass成功

2.json绕过

  1. <html>
  2. <head>
  3. <title>json绕过</title>
  4. <meta charset="uft-8">
  5. </head>
  6. <body>
  7. <form method="POST">
  8. message:<input type="test" name="message">
  9. <input type="submit" name="提交">
  10. </form>
  11. </body>
  12. </html>
  13. <?php
  14. show_source(__FILE__);
  15. header('Content-type:text/html;charset="utf-8"');
  16. if (isset($_POST['message'])) {
  17. $message = json_decode($_POST['message']);
  18. $key = "admin";
  19. if ($message->key == $key) {
  20. echo "success";
  21. } else {
  22. echo "fail";
  23. }
  24. }

输入一个数组进行json解码,如果解码后的message与key值相同,会得到flag,主要思想还是弱类型进行绕过,我们不知道key值是什莫,但是我们知道一件事就是它肯定是字符串,这样就可以了,上文讲过,两个等号时会转化成同一类型再进行比较,直接构造一个0就可以相等了。最终payload message={“key”:0}

3.array_search is_array绕过

  1. <?php
  2. if(!is_array($_GET['test'])){exit();}
  3. $test=$_GET['test'];
  4. for($i=0;$i<count($test);$i++){
  5. if($test[$i]==="admin"){
  6. echo "error";
  7. exit();
  8. }
  9. $test[$i]=intval($test[$i]);
  10. }
  11. if(array_search("admin",$test)===0){
  12. echo "flag";
  13. }
  14. else{
  15. echo "false";
  16. }
  17. ?>

这段代码的意思就是先判断是不是数组,然后在把数组中的内容一个个进行遍历,所有内容都不能等于admin,类型也必须相同,然后转化成int型,然后再进行比较如果填入值与admin相同,则返回flag,如何绕过呢?

基本思路还是不变,因为用的是三个等于号,所以说“= =”号这个方法基本不能用,那就用第二条思路,利用函数接入到了不符合的类型返回“0”这个特性,直接绕过检测。所以payload:test[]=0。

在PHP手册中,in_array()函数的解释是bool in_array ( mixed needle,arrayhaystack [, bool strict=FALSE]),如果strict参数没有提供或者是false(true会进行严格的过滤),那么inarray就会使用松散比较来判断needle是否在$haystack中。当strince的值为true时,in_array()会比较needls的类型和haystack中的类型是否相同。

  1. $array=[0,1,2,'3'];
  2. var_dump(in_array('abc', $array)); //true
  3. var_dump(in_array('1bc', $array)); //true

4.strcmp漏洞绕过(PHP版本<5.3)

  1. <?php
  2. show_source(__FILE__);
  3. error_reporting(0);
  4. $var1 = $_REQUEST['string1'];
  5. $var2 = $_REQUEST['string2'];
  6. echo ("String1:" . $var1 . " " . "type:" . gettype($var1));
  7. ?>
  8. <br>
  9. <?php
  10. echo ("String2:" . $var2 . " " . "type:" . gettype($var2));
  11. ?>
  12. <br>
  13. <?php
  14. $bool = strcmp($var1, $var2);
  15. if ($bool < 0) {
  16. echo $bool . '<br>';
  17. echo ("str1<str2");
  18. } elseif ($bool == 0) {
  19. echo $bool . '<br>';
  20. echo ("str1=str2");
  21. } else {
  22. echo $bool . '<br>';
  23. echo ("str1>str2");
  24. }


语法:strcmp(string1,string2)
返回值:
0 - 如果两个字符串相等

<0 - 如果 string1 小于 string2

0 - 如果 string1 大于 string2
漏洞:在PHP5.3之前,传入非String类型的会返回0,即相等。

用户名金币积分时间理由
Track-聂风 40.00 0 2021-06-16 21:09:57 一个受益终生的帖子~~

打赏我,让我更有动力~

0 Reply   |  Until 2021-5-14 | 811 View
LoginCan Publish Content
返回顶部 投诉反馈

© 2016 - 2022 掌控者 All Rights Reserved.