广发英雄帖-招聘广告(DBA、PHP开发、运维工程师、BI专员) 首先,我已经改行了,因此这个招聘和安全无关,不是招安全工程师的。 其次,我现在所在的团队,是一个比较年轻的团队,无论是同事的平均年龄,还是公司的成立时间,或者是公司的收入状况。 所以,如果你现在觉得自己充满激情,渴望学习和成长,耐得住性子,能做好在小公司待2年以上的准备,不太在乎加班多(不一定有加班费),不太计较眼前得失,希望和公司一起成长,渴望自己的努力在公司的成功道路上占据重要的比重(相对于大公司比较细分化的工作岗位),并且有志于往下列岗位发展,欢迎投递简历至 cfc4n # cnxct {dot} com ,最好来信注明薪资期望 公司性质:网游 规模: 100人左右 工作地点:上海 待遇:根据个人能力而定,本次招聘主要面向中、基层岗位 除BI专员外,其余岗位无学历限制 职位:运维工程师 招聘人数:3-4人 职位描述: 1. 负责生产网络、服务器、数据库与支撑系统的建设、运维和监控,保证各业务系统正常运营; 2. 负责突发性事件的快速响应和处理,解决服务器和网络故障; 3. 研究运维相关技术,制定运维技术方案、部署统一化、集中化的运维系统和工具; 4. 负责对现有运维系统的性能改善。 职位要求: 1. 计算机或相关理工科专业专科或以上学历,为人真诚正直; 2. 熟悉Linux操作系统,熟悉Linux脚本编程; 3. 熟悉Apache、nginx、Mysql等应用的配置与维护; 4. 熟悉防火墙,交换机等网络设备的安装、配置; 5. 2年以上相关工作经验,深入理解Linux系统的和部署,有系统调优经验者优先; 6. 具备良好的沟通能力和强烈的责任心,热爱运维技术,有良好的文字表达能力和自学能力,有良好的团队合作意识。 职位:PHP开发工程师 招聘人数:3人 职位描述: 负责如下系统的设计,编码,测试,文档记录,开发优化维护等: 1. passport中心 2. 支付平台 3. 论坛整合插件(discuz!) 4. 在线活动项目 5. 资产管理系统 6. 广告统计系统 7. 服务器监控系统 8. 周边产品的 职位要求: 1. 精通PHP5开发(2年以上工作经验,有WebGame或者社区开发经验优先) 2. 扎实的编程基础。代码构造清晰,易读。擅长代码和算法优化。 3. 熟悉MySql数据库设计,了解Memcached优化。 4. 了解PHP与FLASH(或者其它非浏览器客户端)的常用通信方式。(如AMFPHP)了解HTTP协议。 5. 熟悉javascript,善用ajax等技术,熟悉Jason数据格式。 6. 熟悉各浏览器的安全机制上的差异,能够解决兼容性问题,如:iframe,cookies,ajax。 7. 熟悉PHP(APC之类)缓存技术,对异步机制下的状态维持、更新有一定的了解 8. 熟悉SVN等版本控制开发环境。 职位:数据库管理员/DBA 招聘人数:1-2人 职位描述: 1. 负责公司游戏产品、支撑平台的数据库日常维护和监控; 2. 负责数据库的更新和运营相关数据的统计分析。 职位要求: 1. 熟悉MySQL,Oracle的体系结构,复制,高可用,监控和备份机制; 2. 具备较强的数据库故障解决能力; 3. 至少熟悉Shell或Python脚本语言之一; 4. 熟练使用PL/SQL,对大数据量下的数据处理有一定经验,有PL/SQL, SQL调优经验者优先; 5. 熟悉数据仓库的ETL开发和数据建模优先; 6. 能阅读各类英语文档。 职位:BI&UCD专员 招聘人数:1 职位描述: 1. 辅助运营流程建设; 2. 辅助运营数据统计、分析、挖掘; 3. 参与实施BE/UCD管理及团队建设; 4. 数据化衡量运营质量、提供决策参考依据; 职位要求: 1. 本科学历是必须条件,计算机及相关专业优先; 2. 学习能力强,具有较强的沟通与领悟能力; 3. 具备自我驱动能力,抗压能力强,服务意识及团队合作精神佳; 说明:招聘详情是我直接从我同事BLOG上复制过来的,只改了邮箱地址,别的都照搬。文中头部描述也是我的现状,我也不做安全了,回归到开发上来了。 2010-11-12 +3 7 0
apache RewriteMap MapSource自定义规则使用手记 10.1期间,一位朋友问我一个apache的 Rewrite规则中一个高级语法RewriteMap的用法问题。其想要实现的是这个功能,有个多用户的blog,用户访问的时候,是用三级域名访问的。比如http://cfc4n1.blog.cnxct.com,http://cfc4n2.blog.cnxct.com这种三级域名。在服务器上,是对三级域名做泛解析。每个三级域名都生成了一个静态的html主页文件。由于用户数量较多,linux ext硬盘格式上同一目录文件太多,检索文件的速度会有折扣,遂将文件打散到不同的目录下。打散方式是以用户名【三级域名中的cfc4n1,cfc4n2等】的MD5值的每隔两位作为一个目录。MD5的默认长度是32位,每隔两位分一次目录的话,那就有16级目录。每级目录的目录名是2个字符,每个字符的有16种可能【0-9a-f】,那么每级目录的目录数为256个目录,16级的话就有4096个目录。每个目录存1000个文件的话,可以存放4096000个文件,这样做,即可以把文件均匀打散到各个小目录中,同时,每个目录下的文件数又不是很多。当用户访问的时候,取目录里的用户名,计算MD5hash,做字符分割,重写到对应的目录下的文件中,如果文件不存在,则重写到生成这个文件的动态页面中。 到apache手册里找了下RewriteMap的用法 RewriteMap MapName MapType:MapSource 遂顺手在.htaccess里这么写了 然后访问一个三级域名试试。结果提示500 http 错误。到apache日志里看到如下 /var/www/.htaccess: RewriteMap not allowed here 搜了半天,不知道是什么错误,只好再次看手册,这时候,才发现rewritemap的作用域却是server config, virtual host,真汗了一下。自己没认真看手册。 改到virtual host里之后,重启apache,结果,还是http 500。再到错误日志里查个究竟。里面记录的确实(13)Permission denied: mod_rewrite: could not start RewriteMap program /var/www/1.php。呃,权限,权限。。赶紧chmod了一下。再次启动,却提示404。。。 /0a/c1/..../...html那种MD5字符串切割之后的文件找不到。但目录里确实是存在的啊。又到日志里查看,原来却是/0a/c1/...../...html\r 文件无法找到了。为什么地址后面多个\r呢?打开MapSource的脚本文件,才看到里面PHP操作流的结束字符里是“\r\n”了,去掉\r 才可以。 总结一下使用APACHE URL REwrite的RewriteMap方法要注意以下几点: 作用域-server config, virtual host,其他配置里无效。 自定义规则MapSource中流的结束符要跟操作系统符合,linux的要用“\n”,同时,切记在win平台编辑脚本传到linux上的时候,文件换行符要用linux格式的,不然,同样会出现问题。 要给apache赋予对脚本的读权限。 apache会在启动的时候,将自定义规则的脚本读取到内存中,之后,再次修改脚本时,不会立刻生效,需要重启 apache apache 的error.log中会记录[warn] mod_rewrite: Running external rewrite maps without defining a RewriteLock is DANGEROUS!这样的错误日志,在apache2.conf【我的系统是ubuntu,其他linux在httpd.conf中】中添加RewriteLock /etc/apache2/script/cfc.lock来指定RewriteLock的文件位置。记得给apache对script目录下有读写权限。 自定义脚本的代码格式如下: 2010-10-14 0 0
wordpress博客永久地址的二次重写 在很久很久以前,从前有座山,山上有个庙,庙里有个和尚在讲故事,讲什么呢? 从前有座山,山上有个庙,庙里有个和尚在讲故事,讲什么呢…… ...... 言归正传,很久以前,博客的URL是这种形式http://www.cnxct.com/cnxct/612/ 这种形式,后来呢,听网上SEOer说,为了更好的SEO,URL中包含关键词,可提高权重等等等等。遂打算把老的URL形式重写成hhttp://www.cnxct.com/%e6%88%91%e6%9c%80%e8%bf%91%e5%be%88%e6%b5%ae%e8%ba%81/这种形式。 服务器web services是nginx,需要更改如下规则 把/cnxct/数字/这种形式的老URL重写到/?p=数字这种形式,然后,Wordpress里在启用新的URL形式,让wordpress再把/?p=数字形式的URL再重写到目标URL。 效果如下图 一网友问到,遂共享出来 2010-09-25 +2 6 0
密码保护:四年前的今天 四年前的今天,CFC4N写过一篇文章,“特殊的一天”,所谓“特殊”也就是在下的生日。当年,技术还没入门,PHP还刚刚停留在Hello World的阶段。主要还是因为学入侵,比较羡慕4ngle同学的PHP+MYSQL注入的技术能力,才走上学PHP的道路,在此,再次感谢一下。 那篇日志中,提到“熟悉UBUNTU”,主要是在捣鼓Kylin麒麟操作系统的时候,认识了DanceFire,是他的推荐,使我认识了UBUNTU。同样,表示感谢。那时候,第一份UBUNTU6.04的光盘是从网上申请的,免费快递到学校。从UBUNTU6.04,到现在的UBUNTU10.04,整整4年了,8个版本(UBUNTU每年的4月,10月都出一个版本,版本号就是年份+月份,比如ubuntu10.04和即将发布的ubuntu10.10)而我只仅仅停留在使用阶段,还是作为桌面系统的使用阶段。。。这是我该反省的一点。 提到的另外一个“PHP、MYSQL、APACHE”这个只能算是实现了PHP的熟悉吧(不敢称精通),MYSQL跟APACHE,只谈得上了解。已经打算翻阅PHP源码了,自我感觉,良好,勉强算实现了。另外一个“C++”,啊哈,看到之后,我就想笑,压根没碰。哎,更该反思了。。。 日志中还提到了很中要的一点“身体健康”,想必,我当初提到“身体健康”是因为我那时候已经知道自己是“腰肌劳损”了。病因是我天天做在电脑面前导致,现在这破玩意病还在,而且,很多程序员都有的职业病。确实该注意保养身体了。。。 在此,再立下三个目标,勉励自己。 其一,做一个属于自己的项目产品。(这里说的是产品,产品要有用户,一定要经营起来) 其二,把PHP源码看完,熟悉HTTP协议,了解TCP/IP。以前我所学的入侵手段,都停留在使用上,不懂原理,而现在,我可以很容易的理清当年所用的攻击入侵手段的原理。现在的职业是web安全,代码审计等。更需要有经验,懂原理。现在我做工作,觉得没什么难度,但仍需努力。 其三,身体呀身体,身体是一切的本钱,一定要身体好,我的老毛病“腰肌劳损”已经习惯了,每天都痛。一次,做出租车,听司机说,做做拔火罐,祛除一下腰部寒气,或许会舒服很多,一直想尝试,一直拖着。 Wordpress3.0的中文版本终于出了,更新一下。也顺便更新一下BLOG。好久没写了,最近事情不叫多,尤其是8月份,回家了一趟,处理了一些事情,在家里,被蚊子咬了几口,我居然不能抵抗的了家里的蚊子,鼓了很大的包,我禁受不住瘙痒,抓了几下,结果,发炎流脓了。回到上海,周末还特意的去了下医院。现在终于好了。 2010-08-08 0 0
如何精确查找PHP WEBSHELL木马? 上篇提到了关于网上流传查找PHP webshell的python脚本中,不严谨的代码,并且给出了一个python的检测代码,同时,下文里也提到不能检测到反引号的命令执行的地方。今天,我想了下,现在把思路发出来。 先来看下反引号可以成功执行命名的代码片段。代码如下: 正则表达式该如何写? 分析: 对于可移植性的部分共同点是什么?与其他正常的包含反引号的部分,区别是什么? 他们前面可以有空格,tab键等空白字符。也可以有程序代码,前提是如果有引号(单双)必须是闭合的。才是危险有隐患的。遂CFC4N给出的正则如下:【(?:(?:^(?:\s+)?)|(?:(?P<quote>["'])[^(?P=quote)]+?(?P=quote)[^`]*?))`(?P<shell>[^`]+)`】。 解释一下: 【(?:(?:^(?:\s+)?)|(?:(?P<quote>["'])[^(?P=quote)]+?(?P=quote)[^`]*?))】匹配开始位置或者开始位置之后有空白字符或者前面有代码,且代码有闭合的单双引号。(这段PYTHON的正则中用了捕获命名以及反向引用) 【`(?P<shell>[^`]+)`】这个就比较简单了,匹配反引号中间的字符串。 然后我将这段代码写入程序中,测试跑了一下discuz的程序。结果有一个误报。误报的位置为“config.inc.php”中的“define('UC_DBTABLEPRE', '`ucenter`.uc_');”,什么原因造成的?这行代码符合了前面有闭合的引号,也有反引号的使用,所以,符合要求,被检测到了。如何再排除这种情况呢?这个有什么特殊的?前面有逗号“,”?如果是字符串连接的点号“.”呢?再排除逗号? 好吧,我错了,我不该用我的思维来误导你。换个思路。找下反引号可执行的代码的前面字符串的情况,他们只能是行的开始,或者有空白字符(包括空格,tab键等),再前面也可以有代码的结束标识分号“;”,其他的情况,都是不可以执行的吧?嗯,应该是这样。(如有错误,欢迎斧正)既然思路有了,那正则代码更好写了。如下【(^|(?<=;))\s*`[^`]+`】,解释一下,【(^|(?<=;))】匹配位置,是行的开始,或者前面有分号“;”。【\s*`[^`]+`】空白字符任一个,然后是....(你懂的)。OK,写好之后,检测,又发现一个问题。 匹配引入文件的正则也匹配了“require_once './include/db_'.$database.'.class.php';”这种代码,什么原因造成的,您自己分析吧。 给出修复之后的python代码,如下: 稍微检测了一下Discuz7.2的代码,还是有误报的,误报的为这种包含sql的代码: 由于这个脚本是按照一行一行的代码来处理的,所以,有这种误报。您自己去修复吧。相对网上流传的脚本来说,还是比较准确的。 欢迎转载。转载请注明来源,以及留下博客链接,同时,不能用于商业用途。(已经修复,增加了反引号后面【\s*;】的判断。2010-07-27 17:06) PS:如果说上传文件也算是危险的、值得注意的操作的话,建议加上move_uploaded_file函数的检测。你知道在哪里加的。^_^ 2010-12-17 关于这些代码,已经放到google 的代码托管上了。SVN地址为 https://code.google.com/p/cnxct/ 大家个获得最新版。 我是一个PHPer,写的python有点憋,有点懒,还请各位安全界的大牛,程序界的前辈不要鄙视,要给建议,谢谢。php版的以后在写吧。同时,也欢迎各位安全爱好者反馈最新的web shell特征代码,我尽力增加到程序中区。 2013-09-13更新: PHP版基于语法扫描,语义分析的扫描器,已经实现,详情见: Pecker Scanner php编写的webshell扫描器 2010-07-27 +16 20 0
关于网上流传查找PHP webshell的python脚本中,不严谨的代码 不是闲着蛋疼,也不是批评谁,只是不忍心看到不严谨的代码在网上被疯传,误导初学者。以下引用的代码以及思路来自网络,只针对代码,不针对人。如有雷同,纯属巧合。 来自某大牛python版本的检测服务器上PHP代码中webshell的脚本代码片段如下: 然后,接着是python处理上面列表(数组),把每个列表的第一个元素作为正则表达式内容,然后进行匹配处理的。先看第一个检测“PHP一句话木马”的这个正则。【eval\(\$\_POST】这里转义了字符【_】,字符“_”不是元字符,不需要转义的,其实,转义也无妨,聪明的正则表达式引擎会识别修正的。来说下这个思路的遗漏之处。这里仅仅匹配字符串“eval(”后面的变量“$_POST”,如果是“$_GET”呢?如果是“$_REQUEST”呢?如果程序先把$_POST/$_GET/$REQUEST的key的变量先赋值给一个自定义的变量名,然后在用PHP的“eval”函数执行这个变量呢?是不是就查找不到了?其实,并不需要知道“eval”函数执行的变量名是什么,只要查找“eval(”即可,当然,还要注意“eval”函数后面可以有空格,tab键之类空白字符。上面的代码片段中,也没考虑到这一点。 再看看下一个列表的第一个元素。【(system|shell_exec|exec|popen)】,这个正则的意思是只要字符串里包含“system”、“shell_exec”、“exec”、“popen”这四组字符串即判定为危险字符。很明显,这个方法太不严谨。如果程序员写的代码中,包含了这四组字符,即可被判定为危险函数。很不准确,误报率极高。见下图 到底什么样的代码是可疑的代码?关键词是什么? 可疑的代码肯定是由可以执行危险操作的函数构成,可以执行危险操作的PHP函数最重要的就是“eval”函数了,对于加密的PHP代码(仅变形字符串,非zend等方式加密),肯定要用到“eval”函数,所以,对于不管是用哪种加密方法的代码,肯定要用到“eval”函数。其次就是可以执行系统命令的函数了,比如上面某牛的代码中提到的四个“system”、“shell_exec”、“exec”、“popen”。当然还有其他的,比如passthru等。PHP还支持“·”字符(ESC键下面那个)直接执行系统命令。我们可以把正则写成这样【\b(?P<function>eval|proc_open|popen|shell_exec|exec|passthru|system)\b\s*\(】。 解释一下: 大家都知道【\b\b】用来匹配单词两边的位置的。要保证【\b\b】中间的是单词,即使函数名前面加特殊字符,也一样通过匹配,比如加@来屏蔽错误。后面的【\s*】用来匹配空白字符的,包括空格,tab键,次数为0到无数次。前面的【(?P)】是捕获命名组。用来当作python代码直接引用匹配结果的key。 还有的网友提到了,如果我把代码放到图片拓展名的文件里呢?那你只检测.php,.inc的文件,还是找不到我的呀。嗯,是的,如果恶意代码在gif、jpg、png、aaa等乱七八糟的拓展名文件里,是不能被apache、IIS等web Services解析的,必须通过include/require(_once)来引入。那么,我们只要匹配include/require(_once)后面的文件名是不是常规的“.php”、“.inc”文件。如果不是,则为可疑文件。正则如下【(?P<function>\b(?:include|require)(?:_once)?\b)\s*\(?\s*["'](?P<filename>.*?(?<!\.(?:php|inc)))["']】。 解释一下: 先看【(?P<function>\b(?:include|require)(?:_once)?\b)】,【(?P<name>)】为正则表达式的“命名捕获”,PHP中有同样的用法。也就是说,在这括号内的捕获的数据,会分配到结果数组的key为“name”的value中。再看里面的【\b(?:include|require)(?:_once)?\b】,【\b\b】不解释了,为单词边界位置。里面的【(?:include|require)】匹配字符串“include”、“require”两个单词,其中前面的【(?:)】未不分配组,用于提高效率,可以去掉【?:】变成【(include|require)】。在后面一个【(?:_once)】也是做不分配组的操作,便于提高正则表达式效率。同样,后面的量词是“?”代表这个组可有可无。就满足了“include”、“include_once”、“require”、“require_once”四种情况。有的朋友可能这样写【(include|include_once|require|require_once)】也能实现目的。但是,为了更搞的效率,我们对这个正则做优化,针对部分字符串做分支更改,改成上面那个【\b(?:include|require)(?:_once)?\b】。 再看下面的【\s*\(?\s*["'](?P<filename>.+?(?<!\.(?:php|inc)))["']】中,【\s*】匹配空白字符,包括空格,tab键等。后面的【\(?】,匹配字符“(”,后面的量词“?”表示这半个小酷括号可有可无。防止“incude "123.php"”这种没有括号的情况。再后面【["']】匹配双引号,单引号的。最后的也是。再看看这个【(?P<filename>.+?(?<!\.(?:php|inc)))】,其中【(?P<filename>)】上面介绍了,为命名捕获,把结果放到match.group("filename")里。【.*?】为任意字符,后面的量词是“忽略优先量词”,也就是平常说的“非贪婪”。这里最少匹配零个,(防止.aa、.htaccess这种没有文件名,只有文件拓展名的文件被引入)。后面的【(?<!\.(?:php|inc))】,这里用到了反向零宽断言(环视)的非操作(只匹配位置,不匹配字符串,跟【^$\b】等一样)。这个表达式是针对这个位置的后面字符起作用的,也就是说后面的【["']】的前面不能是“.php”、“.inc”,这里也就是取了文件名的最后的拓展名。(正则里,可以用【^】对字符取非,但是不能对“字符串组”取非,这里用了零宽断言来实现。) 综上所述,最后,鄙人给出的python代码如下: 仅供参考,欢迎斧正。 下面截图为扫描Discuz7.2的效果图,当然,也有误报。相对网上流传的python脚本,误报更少,更精确了。 问:这个方法完美了吗?可以查找目前已知的所有危险函数文件了吗? 答:不能,如果include等引入的文件没有拓展名,这里就匹配不到了。 问:如何解决? 答:留给你解决,聪明的你,肯定可以搞定。 PS:“`”反引号 执行命令的还没写,暂时没好的办法。容易跟SQL语句中的反引号混淆。不太好匹配。如果光匹配反引号就提示的话,那误报太大了。待定吧。(术业有专攻,请勿因为一处不好的代码,否定一个人的能力。你懂的。再次重申,此文只针对代码,不针对人。其次,鄙人给出的python代码随便复制,随便传播,爱留版权就留版权,不爱留就删了相关字符,也就是您爱干吗干吗。) 我先休息一会,明天再说。(前半句为三国杀曹仁的台词,哈。) =============================我是万恶的分割线====================================== 最新代码在这里给出了。 2010-07-26 3 0
snoopy.class.php中_striplink方法的正则分析 上周提到老爷机坏了,昨天早上早早的抱去修理,维修工程师更换硬件排除法最后得知,故障出现在显卡,插入显卡,主板灯亮,按开关,没反映,或者CPU风扇抖动一下即停止。卸下显卡,开机正常。这位维修人员的结论是显卡坏了,建议更换显卡。我们有N卡9200,只要320元。我提出把显卡放到别的主机上试试,被拒绝了,好吧,那我也拒绝。最后,对方收我20元检测费。虽然我心里有点不情愿,他只是换了几个零件的简单排除法得出很有可能的结论而已,并没有告诉我准确的病因,是显卡的哪里出问题了?能否维修?他都没有告诉我。尽管这样,我还是给了,也没争论。 主机抱回来之后,自己卸下了显卡。开机,上网,打算到网上买块新的。老的显卡是我07年在学校买的。ATI RADEON X550,在当初,还算比较前卫的硬件。周五还赞扬其能勤奋工作到现在,而结果得知出问题的就是它。工作了3年多,不到四年,还能接收吧。主板换了华硕P5GC-MX/1333 ,作为硬件小白的我,也不知道换什么显卡较好。熟悉硬件的朋友,麻烦留言告诉一下,感谢了。现在打开网页,拉动浏览器滑动条的时候,卡的比较厉害,播放电影更是,像放映幻灯片一样。实在不能接受。遂网上搜了相关信息。价格在500左右。是有点贵了。遂暂时作罢。一整天心情都很低落,或者说,自从老爷机出问题了,心情一直很差。中午窝在家里,洗了洗衣服,趁太阳好,把冬天穿的衣服拿出来晒了晒。又挪动电脑附近的两个大桌子,打扫卫生,清理一番。一直忙到下午3点,头饿的晕忽忽的。匆忙到沙县小吃随便吃了点,下午,看会书,睡了会觉,早上送GF回家,起得太早了,困的厉害。睡醒之后,都7点多了,照照镜子,看看自己蓬松的发型,猥琐的样子,不禁笑了一笑。洗了把脸,到小区的理发店里剪了头发,由于是小区内,专门给老头老太太理发的,所以费用仅5元,在上海,应该没有比这还低了吧。晚上,把显示器接到电视盒上,看了会电视,差不多都是娱乐类的弱智脑残节目,我极为反感觉,又将显示器接回主机箱,开机到当当网上看了一番。因工作需要,要做个代码自动审计化的程序,我的想法是,不仅仅停留在对关键危险函数的正则匹配,而是做到语法分析,识别未初始化的变量、未过滤的富文本字段、SQL注入的方法等。想必,肯定的熟悉《编译原理》以及LEX、YACC之类相关知识,后悔大学没认真听,造成自己基础薄太弱了。当然,我也觉得大学的时候,直接教学生这么底层的知识没有循序渐进的引导学生去深入更好。可以从最简单的网页制作开始,然后,让学生对其感兴趣,再引导到动态,然后,联合数据库,然后效率优化,然后代码执行原理,然后编译原理类似这种步骤引导学生更好。比起现在的方式,可能更让学生感兴趣。(扯远了)东看西看,忙到了12点多才睡。 对于已经习惯8点左右起床上班的我来说,生物钟在早上8点左右,准时醒,有时候想赖床,但也无法再次入睡。起床洗漱,打开电脑,玩了两局web的三国杀,逛逛论坛,觉得饿了,才去煮点面条吃。回来继续,无意中打开PPC,看到一位网友“落叶人生”同学的帖子问一个正则问题,纠结了一下是否解释一下,以便给对方释疑解惑,也加固自己的知识。犹豫半天,觉得还是写下吧。下面正题: PPC链接http://bbs.phpchina.com/thread-189797-1-1.html preg_match_all("'<\s*a\s.*?href\s*=\s*([\"\'])?(?(1)(.*?)\\1|([^\s\>]+))[^>]*>?(.*?)</a>'isx",$document,$links); 对于一般的规范链 接能很好的使用,但不知道为什么对href=后面的网址不含引号的情况无法提取成功,哪个朋友帮分析下?谢谢! 其实,我没明白他的意思是想提取链接地址href后面的内容的,还是提取整个标签a中间的所有。 在下面的回帖中,他提到了这个正则来自snoopy.class.php的_striplink方法中的正则,遂到sf.net上下载一份原版到本地。 代码如下 先看下修饰符部分。【isx】,大家都知道【i】是不区分大小写;【s】是点号通配模式,也就是元字符【.】可以匹配换行符。在这里的作用是为了防止链接中出现换行的情况; 【x】宽松排列和注释模式,也就是空白字符不会被当成正则表达式的一部分,#后面的为注释,方便阅读的作用了。顺便说下括号后面的双引号后面的单引号,跟修饰符i前面的单引号,他们只是正则的起始标识,不是正则的一部分。其实,表达式里有单引号了,这里最好使用别的,比如斜杠,或者闭合的大括号等。 再看表达式【<\s*a\s.*?href\s*=\s*】,其后面也注释了,是匹配“<a href=”的,第一个【\s】匹配"<"到"a"之间的空白字符,不过一般都没的吧。都直接写"<a......"。后面的【\s】也是空白字符,不详细解释了。在后面的【.*?】是匹配“<a "到“href=”之间的内容,比如"title="....."、target="...."等。【href=】中没有元字符,就是匹配【href=】. 再后面【([\"\'])?】这里的单引号,双引号是被PHP语法转义的,真正的表达式是【(["'])?】,匹配单引号和双音号,并且,用小括号分配了组(整个表达式的第一组),后面有【?】量词,意味这可有可无。 再后面很重要了。去掉PHP的转义字符之后【(?(1) (.*?)\1 | ([^\s>]+)】,这是一个正则表达式的高级用法,叫“条件判断”表达式。语法为【(? if then| else)】。这里的if部分为【(1)】也就是前面说的“整个表达式的第一组”的内容,如果为真,则使用表达式【(.*?)\1】来匹配(\1是引用捕获的第一个组的内容),如果【(1)】没匹配到,则使用【([^\s>]+)】来匹配。这样,就可以实现没有引号的情况下,也是可以匹配到了。(正则表达式的条件判断语法,【|else】可以不写,表示不用else部分的表达式) 对于楼主的问题。应该怎么改?我刚刚刷新了帖子,看到楼主的正则是可以匹配的呀。 汗,贴下PHP的代码吧。 文章标题跟内容有很大出入,见谅哈。 2010-07-25 +4 8 0
PHP中正则表达式对UNICODE字符码的匹配 酷暑难耐,又在家宅一整天。天气热或许是借口,尽管不热,我也喜欢宅在家。晚上看新三国83集(插一句,最近世界杯很火,可是我不看世界杯。来鄙视我吧),一直看到10点半,突然觉得肚子痛,赶紧直奔厕所。如厕之后,觉得精神抖擞,容光焕发,年轻了二十多岁,打开QQ,看到N多条消息,其中有条是生命如蓝同学留的。打开一看,是PPC的链接,突然觉得我好久没登陆PPC了,想当年........算了,看链接吧。 打开链接,看到标题是“请教PHP 一个正则匹配的问题”,又是正则表达式,好吧,看下,谁让俺比较喜欢鼓捣正则呢。下面开始正题。 网友ainiaa的问题是 PHP代码如下 为什么打印的结果会是: otherStr: ! #$% & {}| '"你好啊我们 麻烦问下其中正则表达式 /[chr(128)-chr(256)]+/is 代表什么意思? 如果/[chr(128)-chr(256)]+/is 指的是ascii码在128到256的字符,为什么a-zA-Z这样的字符也被替换掉了,他们的ascii码是小于127的。 最令人郁闷的是为什么ascii码同在0-127区间"#","$","%","&", "!"," {","}","|"," '","确没有被替换掉???? 更令人感觉神奇的是 如果把正则表达式修改为"/[chr(128)-chr(256)]+/s"的话,输出的结果就变成了: otherStr: defg ijklmnopq stuvwxyz ! #$% & {}| '"你好啊我们 只是把正则表达式中的符号‘i’给去掉,结果缺失这样的。 完全的令我理解不了。 不知各位 有何见解???? 另附ascii 码 对照表 (这个ASCII码表的图我就不贴了) 回帖中,有个网友说没解析chr(128)这些,并给出了新的解决方法。首先说下此网友回答的是正确的,先不评论他是否“知其然,且知其所以然”,这位网友没有给出错误的原因。 CFC4N来回答一下这位网友: PHP的正则的preg_match函数用的是PCRE正则引擎,这位网友的代码中,PCRE引擎处理的正则表达式为【/[chr(128)-chr(256)]+/is】,后面的is是什么呢? 在PHP的正则里,边界字符后面的叫模式修饰符。它会告诉引擎如何解析,处理正则。其中i修饰符表示不区分大小写。s表示“点号通配模式”,用来让正则里的元字符点号【.】可以匹配换行符,这个修饰符仅对点号【.】起作用。在这位网友的问题中,修饰符s并不起作用的。 查找原因: 我们在来分析一下这个网友写的正则表达式【[chr(128)-chr(256)]+】,正则表达式的PCRE引擎是如何解释这个正则的呢?首先,我们要知道,在正则表达式中,中括号【[]】表示字符组,字符组中除了连接符【-】只外,都不是元字符,也就是说,都是普通字符,当然,如果连字符出现在第一个,或者不是标识两个字符之间范围的,都是普通的字符横杠“-”罢了。这里的chr(128)只是标识ASCII码为128(确切的说,ASCII码只是0-127个,128到其他的,应该不叫ASCII码了。),但是在正则里,他仍然代表【c、h、r、(、1、2、8、)】(顿号不是,只是区分易读的)这八个字符罢了。这个正则里的连接字符,是哪些范围呢?很明显,这里的连接字符的范围是【)-c】,“)”ASCII码为0x29,也就是十进制的41;“c”的ASCII码为0x63,也就是十进制的99,那么,他这个连接字符的范围就是ASCII 41(chr(41))到ASCII 99(chr(99))之间的字符。也就是说,这位网友的正则的范围是【[hr)-c(]】,就是chr(41)到chr(99)外加hr这两个字母和前面的“(”。 网友第一次测试的时候,有修饰符i,意思就是说,不区分大小写,那么在chr(41)到chr(99)之间的字符,以及这些字符如果有大小写,则包括他们的大小写都符合匹配。都会被替换成空。其第二次测试的时候,去掉了修饰符i,进行了不区分大小写的匹配,由于其范围只到c,但突然,再除了小写字母的“h”、“r”,所以,测试结果会多出“defgijklmnopqstuvwxyz”。所以,他的结果出现了这些差别。 网友的表达式等同于如下图所示 解决办法: 错误的原因找出来了,那么,解决的办法呢? 我们先来看看这位网友的需求,他的需求是将unicode(ASCII只是0-127位的,128之后的,应该叫UNICODE码)的chr(128)到chr(255)之间的字符匹配,替换为空罢了。正则表达式里,对十六进制的字符匹配的表示方式有两种,【\u】和【\x{}】,前者只能表示【\u】后面4位的十六进制数值,而后者【\x{}】则可以表示任意多的十六进制位数(写在大括号中)。 那么,这个正则表达式该如何写???? 网友的目的是chr(128)到chr(255),那么就是【[\u0080-\u00FF]】或者【[\x{0080}-\x{00FF}]】。 其目的是匹配下图中的红框内字符 提醒一下,PHP里正则匹配unicode字符时,需要使用u修饰符。 根据网友需求,更改正则之后的PHP代码如下: 其运行结果是仍然输出那段字符串,为什么呢?因为哪些字符串都不在chr(128)到chr(255)的范围之内。 (测试时,注意文件编码为UTF-8) 以上为鄙人愚见,欢迎批评指正。 2010-07-04 +2 6 0
eval、gzinflate、 base64_decode三函数加密的代码在线解密 其实,这边日志的主题不是想写被eval、gzinflate、 base64_decode三函数加密的代码的在线解密的。主要写生活中的两三件事。 其一,刘威同学生了个儿子,在这里恭喜一下。俺又多了个侄子,年底回家,连他结婚的喜酒,跟小侄子的见面礼一并给了。(此人已经生子,还未结婚,大家一起来鄙视一下,当然,你也可以羡慕一下。)团队的SCY已经有两个孩子了,一个女儿一个儿子,岁月不饶人啊,哥老了。 其二,前天下午听姐姐说晚上跟今天早上,还有中午打电话回家,都没人接听。我听了之后,有点心慌,也假装镇定到下班回家,先是打了电话到大姐家,接电话的是外甥,其也说也曾经尝试了几次,也是没接通,然后,决定明天去我父母家看望一下(中考完毕),顺便带点农副产品。我听了之后,却愈加担心,也有点欣慰。担心的是家里的电话为什么没人接,欣慰的是外甥很懂事了,也很孝顺他的姥姥,也就是我的父母。接着,我又尝试几遍,仍未有响应。又打了一通电话,后得知家里电话坏了,才放下心来。继续坚持每周一个电话回家。 其三,天气渐热,把去年买的风扇拿出来。安装了一下,发现扇叶以及其他部件都是崭新、一尘不染的,遂不住赞叹自己当初认真清理打扫,收藏放置的态度。 其四,放BLOG的服务器,被入侵了。入口是ECSHOP的BUG引起的。俺也没啥说的,只想对这位“大侠”说:“你爱干吗就干吗,只要别删数据,要是挂黑页,证明你的能力的话,那记得帮俺备份一下,拜谢了”。接着说,顺便发现了其使用的PHP木马,打开看了下源码,加密了。其加密方式为 eval(gzinflate(base64_decode(这种的,见下面代码: 大体代码就这样,没贴完,费了1个多小时,写了解密代码程序,见http://www.cnxct.com/cfc4n/eval-gzinflate-base64_decode.php,方便大家用得到的时候用下。 顺便说下,此PHP木马程序加密了9次左右吧,解密之后的代码为 哦.....这哥们的密码居然就两位字母,就是wx ,这一不小心还能按对。。PS:这木马不错,留着自己用了。打包在下面,想用的可以拿去。 无图无真相,上图。 艹,Wordpress不能上传了,提示"临时文件夹丢失。"好吧,好吧,我先写周报,等会再调试。 搞定了,gleon调试,把php.ini中的upload_tmp_dir配置项去掉了,开启之后,给相应目录足够权限即可,比如755. 附件:php木马加密前与加密后的两个文件打包 下面上图 2010-06-25 +7 11 0
升级ubuntu内核,virtualbox提示Kernel driver not installed (rc=-1908)出错 今天,我闲的蛋疼,更新来ubuntu内核,重启之后,也没在意,为了PS一张图,GIMP用起来不方便,遂开虚拟机virtualBox,进XP,用PhotoShop来操作,结果,VirtualBox却提示“ernel driver not installed (rc=-1908)”,我还没来得及点确定,又提示 The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Re-setup the kernel module by executing '/etc/init.d/vboxdrv setup' as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary. 好吧,我照办,开中端,敲入sudo /etc/init.d/vboxdrv setup,回车,立马提示 屏幕停止在“Recompiling VirtualBox kernel module ”半天没反映,我有点心慌来,赶紧搜下。等到我切换到终端看结果的时候,却发现提示“* Starting VirtualBox kernel module * done.”,我 草,好了。那好吧,打开虚拟机看看,进XP。。。OK,正常了。。 附截图一张。 至于这个错误是什么原因导致的,等我下次蛋疼的时候,再去查明真相吧。 2010-06-21 +1 5 0