phpdisk用的文件类型检查脚本

phpdisk虽说也能够限制用户上传文件的类型。但总有那么些自作聪明的主,把文件扩展名改了,然后上传。是故,魔高一尺,道高一丈。我写了这个脚本。目的就是赶尽杀绝!使用者注意杀伤力,以免波及无辜。

另外,脚本使用了最新版本的file-5.13命令,centos系统自带的file命令无法识别office 2007+的文档格式。所以,自己编译好文件再用我的脚本哦

#!/bin/bash
#
#
# check-forbidden-files.sh - 一个检查用户上传文件格式的小脚本。每天5分钟
#执行一次。用于防止用户通过修改后缀名的形式上传非法文件。
#
# 作者: 刘西洋 66954
#              <locke@honliv.com> <xiyangliu1987@gmail.com>
#              http://www.xiyang-liu.com
#
# 软件自由,版权没有
# 创建时间:2013年2月26日一个阳光明媚的上午
#
#¥¥¥¥¥¥¥¥¥¥程序设计思路¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥#
#    phpdisk通过限制文件选择框的形式限制用户上传文件爱你的格式。然而,比较
#聪明的用户会想到通过修改文件后缀名上传被禁止的文件。
#linux的file命令通过分析文件内容,而不是只看后缀名来判断文件类型。通过
#file命令依次检查当日用户上传的文件。凡是不合规范的都会被移动到特定的文件夹
#并以日志的形式记录用户ID和Email地址。并且在数据库中删除相应文件记录。
#$$$$$$$$$$$$$$$$$$$$$结束$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$#

##设置全局变量
DB_HOSTNAME="localhost"
DB_PORT="3306"
DB_USERNAME="phpdisk"
DB_PASSWORD="PASS0D"
DB_NAME="phpdisk"
FILE_POOL_PATH=/srv/www/filestores/`date +%Y/%m/%d`
FILE_CMD_PATH=/srv/file/bin/
TMP_DIR=/srv/tmp/
LOG_FILE=/srv/forbidden.log


##允许的文件类型列表:Office 1997-2003文件 Office 2007以上文档,PDF文档,jpeg,png,bmp格式照片,纯文本文件
declare permit_file_type=("Composite Document File V2 Document" "Microsoft Word 2007+" "Microsoft PowerPoint 2007+" "Microsoft Excel 2007+" "PDF document" "JPEG image data" "PC bitmap" "PNG image data" "text")


##输出所有文件的检测结果到临时文件中

cd $FILE_POOL_PATH
$FILE_CMD_PATH/file `ls $FILE_POOL_PATH` > $TMP_DIR/file_cmd_output.txt

##循环检测,删除在允许文件列表中的条目。
type_i=0
type_len=${#permit_file_type[@]}
while [ $type_i -lt $type_len ]
do  
   /bin/sed -i -e "/${permit_file_type[$type_i]}/d" $TMP_DIR/file_cmd_output.txt

let type_i++
done

##输出过滤后剩余的文件条目,也就是非法文件类型的条目到 forbidden_file_name.txt

cat $TMP_DIR/file_cmd_output.txt | /bin/cut -d ":" -f 1  >> $TMP_DIR/forbidden_file_name.txt

##根据不合法文件内容,从mysql中查询文件属主。记录到文件中。并把文件移动到特定目录

declare forbidden_file_name=(`cat $TMP_DIR/forbidden_file_name.txt | cut -d "." -f 1 | xargs` )

name_i=0
name_len=${#forbidden_file_name[@]}
while [ $name_i -lt $name_len ]
do 
    SQL_GET_UID="select userid from pd_files where file_real_name='${forbidden_file_name[$name_i]}';"
    SQL_GET_USER_EMAIL="select email from pd_users where userid='$OWNER_ID';"
    SQL_DEL_FILE="delete from pd_files where file_real_name='${forbidden_file_name[$name_i]}';"

    OWNER_ID=`/usr/bin/mysql -sN -h $DB_HOSTNAME -P $DB_PORT -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME -e "$SQL_GET_UID"`
    OWNER_EMAIL=`/usr/bin/mysql -sN -h $DB_HOSTNAME -P $DB_PORT -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME -e "$SQL_GET_USER_EMAIL"`

    FULLNAME_FILE_NAME=`/bin/grep ${forbidden_file_name[$name_i]} $TMP_DIR/forbidden_file_name.txt`
    FULLNAME_FILE_TYPE=`$FILE_CMD_PATH/file -b $FULLNAME_FILE_NAME`

    mv `grep ${forbidden_file_name[$name_i]} $TMP_DIR/forbidden_file_name.txt ` /srv/forbidden_files/

    echo "`date +%Y-%m-%d %H:%M` `grep ${forbidden_file_name[$name_i]} $TMP_DIR/forbidden_file_name.txt` $OWNER_ID $OWNER_EMAIL $FULLNAME_FILE_TYPE " >> /srv/forbidden.log
   mysqldump -h $DB_HOSTNAME -P $DB_PORT -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME pd_files | sed -e 's#),(#)n(#g'  | grep ${forbidden_file_name[$name_i]} >> $TMP_DIR/restore_deleted_file.sql
   /usr/bin/mysql -sN -h $DB_HOSTNAME -P $DB_PORT -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME -e "$SQL_DEL_FILE"

let name_i++
done
##移动记录文件列表,以备后查。
> $TMP_DIR/forbidden_file_name.txt
mv $TMP_DIR/file_cmd_output.txt $TMP_DIR/`date +%Y%m%d%H%M`-file_cmd_output.txt
echo ok

检查后,如果有误杀。或者领导介入了。你还可以通过移动文件回原位置,插入导出的条目到数据库来还原操作。具体我就不说了。相信你懂的。

相关的文章:
  • 抱歉,暂无相关文章。

1条评论

写评论
  • 大西洋 回复

    转载好歹著名出处。我表示深深的鄙视!