攻防世界题目练习——Web难度1(二)_< php highlight_file(__file__); include("

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上网络安全知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注网络安全)
img

正文

要求$c[“m”]不是数字字符串并且 $c[“m”] > 2022,根据我们前面
攻防世界题目练习——Web难度1(一)中的12.simple_php中学到的is_numeri绕过,

可以构造"m":"2023a"

再看对$c的"n"的要求:

if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){
        $d = array_search("DGGJ", $c["n"]);
        $d === false?die("no..."):NULL;
        foreach($c["n"] as $key=>$val){
            $val==="DGGJ"?die("no......"):NULL;
        }
        $key2 = 1;
    }

is_array()判断是否是数组变量:PHP is_array()函数详解,PHP判断是否为数组
count()返回数组中元素的数目:PHP count() 函数
array_search("DGGJ", $c["n"])在数组 $c[“n”]中搜索键值 “DGGJ”,并返回它的键名:PHP array_search() 函数

foreach($c["n"] as $key=>$val)
foreach仅能用于遍历数组,每次循环中,当前单元的键值被赋给 $val,当前单元的键名也会在每次循环中被赋给变量 $key。参考博客:PHP: foreach - Manual

因此我们可以读懂对"n"的要求:
是数组、数组有2个元素、且第一个元素是数组。
if里面的内容:
$d = array_search("DGGJ", $c["n"]);要求存在键值"DGGJ";
后面foreach循环又说明遇到值为"DGGJ"的就退出;
这里看起来很矛盾,因此需要绕过其中一个条件。
参考博客的题解:
CTF之旅WEB篇(8)–[xctf] 江苏工匠杯easyphp
指出array_search()函数可以绕过,我们学习一下这个函数:
PHP: array_search - Manual
江苏工匠杯easyphp(array_search绕过)
array_search(mixed $needle, array $haystack, bool $strict = false): int|string|false
我们可以知道这个函数有3个参数,第3个参数通常默认为false,如果可选的第三个参数 strict 为 true,则 array_search() 将在 数组 中检查完全相同的元素。 这意味着同样严格比较前两个参数的类型。
因此当第3个参数为false时,就导致了弱类型比较漏洞,也就是这个函数的比较相当于在用"=="进行比较。
举例:
“admin”==0 //admin被转换成数字,由于admin是字符串,转换失败,int(admin)=0,所以比较结果是true。参考文章:【从零开始学CTF】4、PHP中的弱类型比较
因为本题中字符串"DGGJ"是没有数字的字符串,因此,当我们的$c[“n”]=0的时候(或者null),会将前面要查找的字符串自动转化为0然后进行比较。只需要保证在c[“n”]中非0下标的元素中存在值0即可,在php中"字符串"==0是成立的。

所以构造"n":[[],0]

其中[]是短数组语法,参考博客:PHP: Array 数组 - Manual

综上,构造url的GET参数为:
?a=7e6&b=53724&c={"m":"2023a","n":[[],0]}
成功获取flag

4. file_include

题目源码如下:

<?php
highlight\_file(\_\_FILE\_\_);
    include("./check.php");
    if(isset($\_GET['filename'])){
        $filename  = $\_GET['filename'];
        include($filename);
    }
?>

用御剑扫描目录后知道同一目录下存在flag.php文件。
尝试用php://filter/read=convert.base64-encode/resource=flag.php获取flag,出现报错提示:“do not hack”。
后又尝试了data://text/plain、php://input,想上传可执行命令或者木马来查看flag都失败了,页面没有任何反应。
查看WriteUp,他们说有存在一些字符过滤,可能对base64、read都进行了过滤。
看了他们的解答知道了有另一种转换过滤器iconv.* 可以用,具体参考博客:
详解php://filter以及死亡绕过

还是不懂加不加"read="有什么区别。

从博客知道convert.iconv.<input-encoding>.<output.encoding>支持多种编码方式,并且存在后面两个位置都要进行编码方式的设置。
需要构造url如下:
?filename=php://filter/convert.iconv.xx.xx/resource=flag.php

于是用BurpSuite对这两个位置用convert.iconv*支持的几种编码方式进行爆破。
支持的编码方式参考官方文档:PHP: Supported Character Encodings - Manual
筛选了一些常用的编码方式作为字典进行爆破:

UCS-4\*
UCS-4BE
UCS-4LE\*
UCS-2
UCS-2BE
UCS-2LE
UTF-32\*
UTF-32BE\*
UTF-32LE\*
UTF-16\*
UTF-16BE\*
UTF-16LE\*
UTF-7
UTF7-IMAP
UTF-8\*
ASCII\*

在一堆爆破结果返回长度较长的结果中查看他们的响应报文,找到flag显示比较正常的那些,如下图:
在这里插入图片描述

5. unseping

先放两篇参考文献,等我看懂再写
unseping
PHP反序列化漏洞详解(万字分析、由浅入深)

要看懂WriteUp,首先要理解php反序列化漏洞的原理,参考文献如上。

网页源码如下:

<?php
highlight\_file(\_\_FILE\_\_);

class ease{
    
    private $method;
    private $args;
    function \_\_construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
 
    function \_\_destruct(){
        if (in\_array($this->method, array("ping"))) {
            call\_user\_func\_array(array($this, $this->method), $this->args);
        }
    } 
 
    function ping($ip){
        exec($ip, $result);
        var\_dump($result);
    }

    function waf($str){
        if (!preg\_match\_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat\_array)) {
            return $str;
        } else {
            echo "don't hack";
        }
    }
 
    function \_\_wakeup(){
        foreach($this->args as $k => $v) {
            $this->args[$k] = $this->waf($v);
        }
    }   
}

$ctf=@$\_POST['ctf'];
@unserialize(base64\_decode($ctf));
?>

根据php的参考博客中的讲解我们知道,php中存在一些以两个下划线__开头的函数,称为魔术方法(Magic methods),后面我们简称为魔法函数 : )

这些函数在这段源码中具体有:
__construct(类的构造函数,创建对象时触发)
__destruct(类的析构函数,对象被销毁时触发)
__wakeup(执行unserialize()时,先会调用这个方法)

php反序列化漏洞的原理就是:
php为了方便传输一个对象而将这个对象序列化为一个字符串,反序列化就是将这个字符串重新恢复为一个对象。
php只序列化属性而不序列化其中的方法,正常使用这个对象的话我们必须要依托这个类要在当前作用域存在的条件,漏洞利用攻击就是寻找合适能被控制的属性,利用作用域本身存在的方法,基于属性发动攻击。
也就是说,将我们反序列化后的对象中的属性带入到作用域中存在的方法进行利用。
当传给unserialize()的参数可控时,可以通过传入一个精心构造的序列化字符串,使其被反序列化后的内容包含我们想要传递的对象的属性参数,使这个参数带入到某一个方法中。

具体到这个题目里,有methodargs两个属性,call_user_func_array回调函数将args作为method表示的函数的参数来调用method,前面的if条件要求method中含有数组"ping",简单点也就是要求$method=“ping”,从而调用function ping

仔细看function ping中其实并没有执行ping命令,而是直接用exec()函数将function ping的参数作为命令来执行。再结合前面的回调函数将args作为method的参数,也就是说,可以将我们想要执行的命令作为args参数传进exec()函数中执行。

再看源码中的function __wakeup()函数,调用function waf($str)函数对args参数的值进行匹配。
匹配规则
waf函数中用preg_match_all()函数进行了匹配,第一个参数是给定的用来模式匹配的正则表达式,第二个参数是输入的要匹配的字符串。
第一个参数"/(\||&|;| |\/|cat|flag|tac|php|ls)/"中正则表达式各个字符含义如下:
最外面一对//是一对定界符,每段正则表达式都要有;
里面一对()被用来合并小节,并定义字符串中必须存在的字符。例如(a|b|c) 能够匹配 a 或 b 或 c;
要使用一些符号本身,必须在前增加一个\\ 将下一个字符标记为一个特殊字符、或一个原义字符;
|是选择符 匹配它的左边或者右边;
有一些修正符例如i,在//的后面加上i则表示不区分大小写来匹配
因此,源码中匹配规则的各个字符拆分组合如下:
\|(特殊字符|) | & | ; | (空格) | \/(特殊字符/) | cat | flag | tac | php | ls
参考博客:
preg_match函数的用法和匹配字符的的含义
PHP正则表达式

字符绕过
现在我们知道了waf函数过滤的有哪些字符或字符串,我们要避免直接输入这些关键词,但是有些字符在我们查找flag的过程中不可避免地会用到,因此我们对它们进行绕过,绕过的方式有如下几种。

(1)引号绕过:
根据php单双引号的性质,被单引号括起来的字符都是普通字符,就算特殊字符也不再有特殊含义,如 ‘$’ 就只表示字符 $ ;而被双引号括起来的字符中," $ “、” \ " 和反引号是拥有特殊含义的," $ " 代表引用变量的值,而反引号代表引用命令。
并且在linux 下,只要引号是出于闭合状态都不影响命令执行。
使用示例:

$name=123;

echo '$name','\n';
输出结果:
$name\n

echo "$name";
输出结果:
123


ls''
l""s
''ls
都可以正常输出ls命令执行的结果

cat ''12""3.txt""
可以正常输出命令cat 123.txt的执行结果

(2)空格绕过:
空格可以用以下字符代替:
<<>%20(space)%09(tab)$IFS$9${IFS}$IFS
${IFS}是Linux中的一个特殊变量,它代表了当前的字段分隔符,它的默认值是空格、制表符和换行符,当输入命令时,会以空格、制表符或换行符作为分隔符,将输入的内容分割成不同的字段,每个字段将作为命令的一个参数进行解析和执行。${IFS}是在命令执行之前被解析和替换的,在命令执行时不会再被解析为字段分隔符,想作为普通字符使用就要转义或者用单引号。

$IFS在Linux下表示为空格,$9 是当前系统shell进程第九个参数持有者,始终为空字符串,$IFS在linux下表示分隔符,但是如果单纯的cat$IFS2,bash解释器会把整个IFS2当做变量名,所以导致输不出来结果,然而如果加一个{}就固定了变量名,同理在后面加个 $ 可以起到截断的作用 $ 后可以接任意数字,例如 $IFS$1$IFS$2
使用示例:

echo 12${IFS}34
输出结果:
12
34

cat<>123.txt

cat$IFS$1flag.php

(3)printf编码绕过:
printf的格式化输出,可以将十六进制或者八进制的字符数字转化成其对应的ASCII字符内容输出。
使用示例:

$(printf "\154\163")
==>ls

$(printf "\x63\x61\x74\x20\x2f\x66\x6c\x61\x67")
==>cat /flag

(4)利用Shell 特殊变量绕过

linux shell中 

$0 是当前脚本的文件名

$n 表示传递给脚本或函数的参数。
n 是一个数字,表示第几个参数。
例如,第一个参数是1,第二个参数是2。而参数不存在时其值为空。
示例:ca$1t fla$2g

$\*	传递给脚本或函数的所有参数,而参数不存在时其值为空。

$@ 是传递给脚本或函数的所有参数,参数不存在时其值为空。被双引号包函时与$\*稍有不同
示例:ca$@t fla$@g

(5)反斜杠绕过
使用示例:

c\at fl\ag

(6)变量拼接绕过:
示例:

a=c;b=at;c=fl;d=ag;$a$b $c$d

(7)内联执行绕过:
意思是以某一个指令的输出结果作为另一个指令的输入项。
使用示例:

cat$IFS$9`ls`

m0re $(pwd)

echo “a`pwd`”//以在根用户目录下胃里
输出结果:
a/root

echo “abcd $(pwd)”
输出结果:
abcd /root

参考博客:
命令执行漏洞各种绕过方式
关于命令执行/注入 以及常见的一些绕过过滤的方法
CTFWeb-命令执行漏洞过滤的绕过姿势

在本题目中,我们直接使用${IFS}绕过空格,反斜杠\将命令分隔开来绕过即可。

接下来我们构造第一步的payload:

<?php


## 学习路线:

这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/7a04c5d629f1415a9e35662316578e07.png#pic_center)





**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)**
![img](https://img-blog.csdnimg.cn/img_convert/49bcebab5db0c774c06103f30281e98a.png)

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/7a04c5d629f1415a9e35662316578e07.png#pic_center)





**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)**
[外链图片转存中...(img-ulPDxROH-1713249046375)]

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值