[转]古诗中的”斜“究竟怎么读

《小学语文教师》2000年第5期上刊有胡孟铭老师的文章《“斜”在〈山行〉中还是读xia好》,主张将“斜”字还其旧读、读古音xia,理由是:“既然课题为古诗,就应读古韵,取古义,才能字义准确,和谐动听”。本刊2000年第10期上又刊有史南先生的文章《“斜”不可读xia》,予以反对,理由是:1985年国家公布的《普通话异读词审音表》“不管那些当时不存在异读的词;如‘斜’字在普通话字(词)典上早已取消了古读音,因此在《审音表》中没有收列它,表明它除了读xie之外,普通话中不存在别的读音”“小学语文教学大纲要求小学生能用普通话朗读课文……再坚持读古音,就违背了国家有关语言文字的政策法规”。 问题至此似乎已有了答案。但笔者的看法却与以上两位老师皆有所不同。语言文字的使用,的确如史老师所说,应当以国家的政策法规为依据。而最高的依据则是2000年10月31日九届人大常委会通过并颁布的《中华人民共和国国家通用语言文字法》(以下简称《语言文字法》)。两位老师讨论时,本法尚未公布。但本法自2001年1月1日实施以后,“斜”的读音问题理当有新的答案。 “斜”字确实存在着旧读音xia,后来演变出xie音,但意义没变(胡老师所谓“‘斜’的读音发生了变化,词义的范围也大大缩小了。倘若将‘斜’还其旧韵xia,(则有)古义‘倾侧或曲折向前延伸’”是无根据的,《康熙字典》《辞源》等古今字书辞书足以为训)。但在古诗教学中究竟应读古音xia,还是今音xie?则应视情形而论。 《语言文字法》规定:“本法所称的国家通用语言文字是普通话和规范汉字”,我们在教学中就应当以国家通用语言文字为准,这是毫无疑义的。所以,教材在古诗《山行》中将“斜”注音为xie是正确的,不但如此,“斜”在本篇课文中还是个生字,教师在教学“斜”这个单字时,也应当训为xie。胡老师对这一点提出异议,笔者不能苟同。但在读本诗的时候也读为xie,又确实拗口。本诗的“斜”字出现在首句,似乎还可将就一二,很多唐诗中“斜”字都出现在偶句末尾。我们知道,古诗的平仄、对仗、押韵,以押韵为第一,当时这些诗都是严格押韵的。若诵读这些诗时也读该字为xie,古诗固有的韵律美被破坏,更让人难于接受。如: 刘禹锡《乌衣巷》 朱雀桥边野草花,乌衣巷口夕阳斜。旧时王谢堂前燕,飞入寻常百姓家。 刘方平《夜月》 更深月色半人家,北斗阑干南斗斜。今夜偏知春气暖,虫声新透绿窗纱。 张泌《寄人》 别梦依依到谢家,小廊回合曲阑斜。多情只有春庭月,犹为离人照落花。 韩君平《寒食》 春城无处不飞花,寒食东风御柳斜。日暮汉宫传蜡烛,轻烟散入五侯家。 元稹《菊花》 秋丛绕舍似陶家,遍绕篱边日渐斜。不是花中偏爱菊,此花开尽更无花。 皎然《寻陆鸿渐不遇》 移家虽带郭,野径入桑麻。近种篱边菊,秋来未着花。扣门无犬吠,,欲去问西家。报道山中去,归来每日斜。 张若虚《春江花月夜》(节录) 昨夜闲潭梦落花,可怜春半不还家。江水流春去欲尽,江潭落月复西斜。 张祜《吴兴新堤》(节录) 春堤一望思无涯,树势还同水势斜。深映菰蒲三十里,晴分功利几千家。 史老师在文章最后说:“但为了让学生知道原来是押韵的,在教学时不妨告诉学生‘斜’在古代的韵母就读ia,直到今天,吴方言中还保留它的古读音,读zia”。笔者认为这样还不够,在诵读这些古诗时就应当读‘斜’为xia。因为教学语言文字与欣赏文学艺术是两回事。我们教学古诗时,这两种活动是同时存在的,但也是完全能够而且应该把二者区分开来的。有的老师就是这样教的:领着学生读“远上寒山石径斜xia……”,然后跟学生讲:“‘斜’字课本上注音为xie,就是‘歪斜’的意思,平时就应当读xie,为什么在诗里读xia呢?这是因为这个字在以前的韵母就是ia,这首诗当时是很押韵的。我们读诗时,为了体会诗的韵律美,也为了更上口,就暂时读xia”。可以确信,只要老师教得明白,学生是不会在其他场合、在说话和写作应用中也读为xia的。这样,不但不会影响到语言文字规范化纯洁化的问题,相反学生还会多学到一点知识,知道“斜”字在古音韵母读ia,知道古人作诗是很重押韵的,更能体会到古诗的韵律美,更容易体会到前人的诗歌艺术才华和成就。岂不更好?重要的是,这样做也有法律的依据。《语言文字法》明确规定:“有下列情形的,可以使用方言:……三戏曲影视等艺术形式中需要使用的;四出版、教学、研究中确需使用的”。这里所谓的“方言”,当然也包括像“斜xia”这样的以方言形式存在的古音韵母。 当然,这种“暂时地读为古音”也是有条件的:必须是“斜”字作韵脚,在韵律的“胁迫”下自然而然地读为xia;如果“斜”虽在古诗中,但不作韵脚,则须还其正读xie音。 对于这种处理,我们还可从对古字形的处理当中找到类似的旁证。比如胡、史二位老师讨论的“鹿柴”。“鹿柴”中“柴”之所以读zhai,是因为“柴”是“寨”的通假字。但是在现代汉语用字标准中,“寨”是不能再写作“柴”了。课本之所以仍保留原来的字形“柴”,无非也是让学生多一点知识,知道“寨”在古代可通写作“柴”,为以后直接阅读古书提供方便而已。《语言文字法》也有相应的规定:“有下列情形的,可以保留或使用繁体字、异体字:……三书法、篆刻等艺术作品;……五出版、教学、研究中需要使用的”。 至于汉匈奴单于“伊稚斜”仍读cha,不读xie,则是因为《审音表》“对大量的人名、地名中的异读字未加审订,这些人名、地名中的异读字照样异读”。 在欣赏性的唐诗吟诵中,为求合于韵律、为求顺口而需要暂时恢复原来读音的字,还有很多。除“斜”字外,另一个比较常见的是“回”字。古诗中“回”作韵脚时,应读古音huai,而不读hui。如: 李白《望天门山》 天门中断楚江开,碧水东流至此回。两岸青山相对出,孤帆一片日边来。 杜甫《登高》(节录) 风急天高猿啸哀,渚清沙白鸟飞回。无边落木潇潇下,不尽长江滚滚来。 刘禹锡《戏赠看花诸君子》 紫陌红尘拂面来,无人不道看花回。玄都观里桃千树,尽是刘郎去后栽。 刘禹锡《石头城》 山围故国周遭在,潮打空城寂寞回。淮水东边旧时月,夜深还过女墙来。 杜牧《早雁》 金河秋半虏弦开,云外惊飞四散哀。仙掌月明孤影过,长门灯暗数声来。须知胡骑纷纷在,岂逐春风一一回。莫厌潇湘少人处,水多菰米岸莓苔。 “回”在唐诗韵脚中读huai,当无疑义。不过这又牵涉到另一个“衰”的读音。《长歌行》有“阳春布德泽,万物生光辉。长恐秋节至,焜黄华叶衰。百川东到海,何时复西归。”;贺知章《回乡偶书》有“少小离家老大回,乡音无改鬓毛衰。儿童相见不相识,笑问客从何处来。”--“衰”当读何音?历来说法不一:或有前首训为shuai的,或有后首训为cui的。笔者的意见则是:“衰”在前诗中训为cui,或有后诗中训为shuai。因为:“衰”字,作“形容萎缩、体量递减”时读cui,如“等衰”;作“气色衰老”时读shuai,如“衰草”。因此,“焜黄华叶衰”中读cui,是指鲜亮的花和叶子萎缩脱落、是形体之变;而“鬓毛衰”中读shuai,是两鬓斑白之意,是气色之变,不是形体之变,不是鬓毛萎缩脱落之意(因为人的鬓毛是头发中最不易脱落的)。诗中的韵脚“辉、归”“回、来”等字可作旁证。

防范 CSRF 跨站请求伪造

CSRF(Cross-site request forgery,中文为跨站请求伪造)是一种利用网站可信用户的权限去执行未授权的命令的一种恶意攻击。通过伪装可信用户的请求来利用信任该用户的网站,这种攻击方式虽然不是很流行,但是却难以防范,其危害也不比其他安全漏洞小。 本文将简要介绍CSRF产生的原因以及利用方式,然后对如何避免这种攻击方式提供一些可供参考的方案,希望广大程序猿们都能够对这种攻击方式有所了解,避免自己开发的应用被别人利用。 CSRF也称作one-click attack或者session riding,其简写有时候也会使用XSRF。 什么是CSRF? 简单点说,CSRF攻击就是 攻击者利用受害者的身份,以受害者的名义发送恶意请求。与XSS(Cross-site scripting,跨站脚本攻击)不同的是,XSS的目的是获取用户的身份信息,攻击者窃取到的是用户的身份(session/cookie),而CSRF则是利用用户当前的身份去做一些未经过授权的操作。 CSRF攻击最早在2001年被发现,由于它的请求是从用户的IP地址发起的,因此在服务器上的web日志中可能无法检测到是否受到了CSRF攻击,正是由于它的这种隐蔽性,很长时间以来都没有被公开的报告出来,直到2007年才真正的被人们所重视。 CSRF有哪些危害 CSRF可以盗用受害者的身份,完成受害者在web浏览器有权限进行的任何操作,想想吧,能做的事情太多了。 以你的名义发送诈骗邮件,消息 用你的账号购买商品 用你的名义完成虚拟货币转账 泄露个人隐私 … 产生原理以及利用方式 要完成一个CSRF攻击,必须具备以下几个条件: 受害者已经登录到了目标网站(你的网站)并且没有退出 受害者有意或者无意的访问了攻击者发布的页面或者链接地址 (图片来自网络,出处不明,百度来的😂) 整个步骤大致是这个样子的: 用户小明在你的网站A上面登录了,A返回了一个session ID(使用cookie存储) 小明的浏览器保持着在A网站的登录状态,事实上几乎所有的网站都是这样做的,一般至少是用户关闭浏览器之前用户的会话是不会结束的 攻击者小强给小明发送了一个链接地址,小明打开了这个地址,查看了网页的内容 小明在打开这个地址的时候,这个页面已经自动的对网站A发送了一个请求,这时候因为A网站没有退出,因此只要请求的地址是A的就会携带A的cookie信息,也就是使用A与小明之间的会话 这时候A网站肯定是不知道这个请求其实是小强伪造的网页上发送的,而是误以为小明就是要这样操作,这样小强就可以随意的更改小明在A上的信息,以小明的身份在A网站上进行操作 利用方式 利用CSRF攻击,主要包含两种方式,一种是基于GET请求方式的利用,另一种是基于POST请求方式的利用。 GET请求利用 使用GET请求方式的利用是最简单的一种利用方式,其隐患的来源主要是由于在开发系统的时候没有按照HTTP动词的正确使用方式来使用造成的。对于GET请求来说,它所发起的请求应该是只读的,不允许对网站的任何内容进行修改。 但是事实上并不是如此,很多网站在开发的时候,研发人员错误的认为GET/POST的使用区别仅仅是在于发送请求的数据是在Body中还是在请求地址中,以及请求内容的大小不同。对于一些危险的操作比如删除文章,用户授权等允许使用GET方式发送请求,在请求参数中加上文章或者用户的ID,这样就造成了只要请求地址被调用,数据就会产生修改。 现在假设攻击者(用户ID=121)想将自己的身份添加为网站的管理员,他在网站A上面发了一个帖子,里面包含一张图片,其地址为http://a.com/user/grant_super_user/121 <img src=”http://a.com/user/grant_super_user/121″/> 设想管理员看到这个帖子的时候,这个图片肯定会自动加载显示的。于是在管理员不知情的情况下,一个赋予用户管理员权限的操作已经悄悄的以他的身份执行了。这时候攻击者121就获取到了网站的管理员权限。 POST请求利用 相对于GET方式的利用,POST方式的利用更加复杂一些,难度也大了一些。攻击者需要伪造一个能够自动提交的表单来发送POST请求。 // 只要想办法实现用户访问的时候自动提交表单就可以了。 如何防范 防范原理 防范CSRF攻击,其实本质就是要求网站能够识别出哪些请求是非正常用户主动发起的。这就要求我们在请求中嵌入一些额外的授权数据,让网站服务器能够区分出这些未授权的请求,比如说在请求参数中添加一个字段,这个字段的值从登录用户的Cookie或者页面中获取的(这个字段的值必须对每个用户来说是随机的,不能有规律可循)。攻击者伪造请求的时候是无法获取页面中与登录用户有关的一个随机值或者用户当前cookie中的内容的,因此就可以避免这种攻击。 防范技术 Synchronizer token pattern 令牌同步模式(Synchronizer token pattern,简称STP)是在用户请求的页面中的所有表单中嵌入一个token,在服务端验证这个token的技术。token可以是任意的内容,但是一定要保证无法被攻击者猜测到或者查询到。攻击者在请求中无法使用正确的token,因此可以判断出未授权的请求。 Cookie-to-Header… Continue reading 防范 CSRF 跨站请求伪造

想写无Bug的安全代码?看防御性编程的艺术

为什么开发者不编写安全的代码?我们在这并不是要再一次讨论「整洁代码」。我们要从纯粹的实用观点出发,讨论软件的安全性和保密性。是的,因为不安全的软件不仅无用,而且还可怕。我们来看看什么是不安全的软件。 1996年6月4日,欧洲航天局的 Ariane 5 Flight 501 在起飞后 40 秒被引爆。因为导航软件里的一个 bug,这个价值 10 亿美金的运载火箭不得不自毁。 1991年2月25日,MIM-104 Patriot(爱国者)里的一个软件错误使它的系统每一百小时有三分之一秒的时钟偏移,导致定位拦截入侵导弹失败。结果伊拉克的飞毛腿导弹击中宰赫兰(沙特阿拉伯东北部城市)的一个美军军营,28 人死亡,100 多人受伤。 其他案例,请参见《Bug 引发的 18 次重大事故》。 这应该能够说明编写安全软件的重要性了,尤其在特定的环境中。当然也包括其他用例中,我们也应该意识到我们的软件 bug 会导致什么后果。 防御性编程初窥 为什么我认为在特定种类的工程中,防御性编程是解决这些问题好办法? 抵御那些不可能的事,因为看似不可能的事也会发生。 防御性编程中有很多防御方式,这也取决于你的软件项目所需的「安全」级别和资源级别。 防御性编程是防御式设计的一种形式,用来确保软件在未知的环境中能继续运行。防御性编程的实践往往用于需要高可用性、安全性、保密性的地方。—— 维基百科 我个人相信这种方法适合很多人参与的大型、长期的项目。例如,一个需要大量维护的开源项目。 我们来探索一下我提出的关键点,来完成一个防御性编程的实现。 永远不要相信用户输入 设想你总是获取到你不想要的东西。因为像我们说过的,我们预期的是异常情况的出现,(所以)要时刻防备用户输入以及通常会传入你系统的东西,这是你成为一个防御性程序员的方法。试着做到尽可能的严格,确保输入的值就是你所期望的值。 进攻是最好的防守 设置白名单而不是黑名单。举个例子,当你验证图像扩展名时,不要检查非法的类型,而是检查合法的类型并排除其他类型。在 PHP 有无数的开源校验库可以让你的工作变简单。 进攻是最好的防守。共勉 数据库抽象化 在 OWASP Top 10 Security Vulnerabilities 排首位的是注入攻击。这意味着有些人(很多人)还没有使用安全的工具来查询数据库。请使用数据库抽象包或库。在 PHP 里你可以使用 PDO 来确保基本的注入攻击防范。 不要重复发明轮子 你不用框架(或微框架)吗?好吧恭喜你,你喜欢毫无理由地做额外的工作。这并不仅跟框架有关,也意味着你可以方便地使用已经存在的、经过测试的、受万千开发者信任的、稳定的新特性,而不是你只为了自己从中受益而制作的东西。你自己创建方法的唯一原因是你需要的东西不存在,或存在但不符合你的需求(性能差、缺失特性等等)。 这就是所谓的智能代码重用。拥抱它吧。 不要相信开发者 防御性编程与防御性驾驶相关联。在防御性驾驶中,我们假设周围的每个人都可能犯错。所以我们要留意别人的行为。相同概念也适用于防御性编程,我们作为开发者不要相信其他开发者的代码。我们同样也不要相信我们的代码。… Continue reading 想写无Bug的安全代码?看防御性编程的艺术

百亿互金平台救火故事

多年前,又是周六客服打电话过来,平台官网不能访问,app完全无法打开,客户在QQ群和微信群中各种反馈,说平台是不是跑路了?客服的多条400热线完全被打爆,电话已经接不过来… 前言 一直以来总是想以什么方式去记录下自己在互金行业的这段经历,趁着自己还记得清楚,还能找到一些资料原型,一方面可以分享出来供大家参考,但是更重要就是多年以后我可以根据这些文章回忆起来自己的那段激情岁月。 想了很久但一直没有实施,后来觉得应该从架构的角度来梳理一篇文章,就写《从零到百亿互联网金融架构发展史》这篇文章;最后认为只有实战出来的东西以及解决问题的过程,才是工作中最宝贵的经验,应该把它分享出来,在梳理的过程中觉得有三起事故比较有代表性就整理出了下面这三篇文章,本篇文章从整体来回忆一下一路走过来所经历过的救火故事。 一次生产事故的优化经历 一次 DNS 缓存引发的惨案 一个脚本引发的血案 作为一个互联网金融平台,涉及到用户资金,任何的服务(资金)差错用户都是不可容忍的,用户不懂什么是数据库,不知道什么网络不通,就是一会看不到钱在app里面展示都会觉得不安。在已经有很多P2P公司跑路的前提下,用户个个已经被锻炼成为福尔摩斯侦探,每天打开app查看收益,监控着平台一切,甚至半夜升级断网十分钟,也会被用户察觉,直接就发到群里面,更有甚者直接在QQ群或者微信群中你们的技术行不行! 我们常说的互联网工作经验,一方面是开发经验,但其实更重要的是处理问题的能力。那么处理问题的能力怎么来呢,就是不断的去解决问题,不断的去总结经验,其中处理生产环境中问题的经验更甚,因为在处理生产环境中对个人的压力和临危应变的能力要求最高,你不但需要面临千万个用户反馈,客服不时得催促而且旁边可能就站了N个领导在看着你,一副你行不行的样子要求立刻马上解决问题!这个时候你的操作就非常重要,稍有不慎便会引发二次生产事故。 说了这么多,只是想说明,生产事故对技术综合能力要求颇高,更是锻炼处理问题能力最佳时机!下面给大家介绍我们从零开发到现在百亿交易量所遇到的几次关键事故,有大有小挑出一些比较有代表性的事件来分享。 并发满标 公司系统刚上线的时候,其实没有经历过什么大量用户并发的考验,结果公司做了一个大的推广,涌入了一批用户来抢标,共1000万的标的几乎都在10秒之内搞定,大概会有上万左右的用户会同时去抢标,平均每秒大概有千人左右的并发,满标控制这块没有经过大的并发测试,上来之后就被打垮了,导致得结果是什么呢,1000万的标的,有可能到一千零几万满标,也有可能会九百多万就满标,也就说要不就是多了一些,要不就是少了一些,就满标了。 这就会很尴尬,因为借款用户就借款一千万整,那么多出来的钱既不能给用户退回了,因为用户好不容易才抢上了,无端退了用户也闹;少了也是问题,用户借款一千万,少了几十万也不行,如果短得少了可以想办法找一些有钱的客户直接给买了,多了就必须重新放出来让用户投资,非常影响士气,这个问题困扰了我们有一段时间。 购买标的流程图,不知道大家是否能根据此图发现问题呢? 超募 为何会产生超募?在最早前的版本中没有使用乐观锁来控制,如果在最后购买的用户一单出现并发,就会出现超募,比如最后剩余30000份的购买份额,因为并发量特别大,可能同时会有十几个用户拿到了剩余30000份余额的可购买额度,有的买1000份、有的买上3000份、有的买上20000份都会驱动满标,所以最后导致了超募。 针对这个问题,主要是引入了memcached乐观锁的概念(底层主要是cas、gets两个命令),在发标的时候存入标的总份额,当用户购买的时候首先去锁定用户购买的份额,因为乐观锁的原因,如果同时有两个用户拿到份额的时候保证只有一个最后可以更新成功(锁定份额),(锁定份额)失败直接返回,这样就保证了在入口的时候就直接屏蔽了部分并发的请求。 少募 为何产生少募?少募是可能1000万的标的突然到980万就给满标了,这是因为在超募情况下我们完善了代码,用户一进来首先就是锁定购买份额,只有锁定购买份额才能进行下面的流程,如果锁定购买份额失败直接返回,这样虽然保证了在1000万份额在购买初期必须每一个用户只能锁定一份,但是在高并发的情况下,因为购买流程中有十几个分支,每一个分支失败就会退回锁定的份额,这样就会导致这样的现象,就是可能是并发一上来,马上就满标了,过了一会进度就回退回来了。 少募主要是因为分支失败回退导致的,一方面我们分析了容易导致回退热点,因为在用户抢标的时候会给用户实时的展示标的进度,在很早的版本中直接就是存入到一个标的进度表里面,并且采用了乐观锁,如果并发一高就频繁的更新失败导致回退,因此优化了标的进度这块,直接去掉了标的进度表,实时根据查询来展示标的进度(可以有延迟,有缓存);另一方面在回退份额的时候在次判断试下memcached的份额和标的的状态,如果份额不为零并且标的状态是满标,马上自动更新状态保证后续用户可以立即购买再次驱动满标。 做了以上的两种优化后,我们还遇到了其它的一些小问题,在不断的优化过程中,终于稳定下来;在后期版本中将考虑使用MQ队列或者redis队列来处理抢标更合理对用户也更公平一些。 黑客攻击 2015年应该是互联网行业受黑客攻击最多的一年吧,各互金公司都深受其害,其中我就记得网贷之家有一段时间被黑客攻击的太厉害,连续几天网站都无法打开。当然了我们也未能幸免,什么DDOS攻击、SQL注入、寻找系统漏洞等都几乎都经历过了,有的黑客还比较好,应该是出于善意或者展示自己,将漏洞放到乌云上面或者漏洞盒子里面让厂商来修复。但更多的是一些黑产完全就是威胁、敲诈想捞一笔钱,先看看下面这位吧: 这个家伙潜伏到我们公司的客户群里面,冒充我们的客户代表将头像和资料替换成一样,然后给群里所有的客服让他们发送我们内部的后台地址,想通过这种方式来寻找突破口,当然了这个算是里面的小菜鸟吧。 DDOS攻击 DDOS攻击我们也是遇到了很多次,确实也没有比较好办法,最后都是通过一些笨办法来尽量的避免,先说说我们的经历吧。有一次我正在敲代码,客服QQ又闪烁了起来,还没来得及打开查看信息,客服的经理电话就直接打了过来,我立刻就有一种不祥的预感,说官网打不开了,后台也登录不了。 挂了电话,我在本机进行了测试果然不行,立刻准备登录VPN查看服务器各项指标,结果登录不上去,马上上楼找运维经理,他也登录不上,刚准备给机房打电话的时候,机房来电话了,说我们的一个IP正经历着1G多的流量访问,问我们是否正在做什么活动,刚话没有说完就说流量已经到5G,不到一分钟之后流量已经到达18G之多。因为我们的机房和集团公用了一个宽带入口,结果陆续的集团上面反馈他们的网站、服务也都出现了问题,机房方面害怕引起更大的冲击,直接把我们官网对外的IP封掉,集团的其它业务也才慢慢都恢复了过来,我们也紧急的更换了外网IP,重新切换了域名解析才恢复。 事后我们根据apache分析了日志,流量来自N多个不同的IP地址根本无法应对,也正式因为这次攻击也才让我们领导重视了起来,将我们公司的机房网络层和公司集团彻底分离,这样的话不管那方受到大流量攻击都不会相互影响,我们也想了一些笨办法,因为上次我们更换了外网IP之后攻击也就停止了,那么我们认为肯定是针对我们外网来攻击的,所有我们就多准备了6个外网IP,当监控到对某一个外网进行攻击的时候马上切换到另一个外网地址,就这样跟他们玩,可以起到非常有限的一点作用,如果黑客真的想跟我们玩,这个办法就像是小孩子捉迷藏。 周年庆的DDOS攻击 还有一次我们正在做周年庆活动,突然有人在QQ群里面给我们客服说了一句,叫你们的技术负责人来找我,然后我们的网站就挂了,我还保留了当时的一个截图如下: 完了之后客服就来找我,然后按照往常的策略处理完之后,我根据客服给我的QQ号码加上了那个人,开口就来吓我,我依稀记当年的对话如下: 黑客:你是平台的技术负责人吗? 我:算是吧 黑客:你信不信我可以让你们官网在5秒之内挂掉? 我:…(沉默,还真害怕又把官网搞挂了) 黑客:你们的官网漏洞很大 我:如果有好的建议请您赐教 黑客:你们的服务器是不是什么防护软件都没有装? 我:…(继续沉默,这会在想不会是那个安全厂商来推广产品的吧,当然我们基础的防护肯定有) 黑客:我们有非常多的肉鸡,想攻击谁,几秒之内肯定搞定 我:… 黑客:我们已经给很多互联网金融行业做了渗透测试,花点钱帮买你们平安,保证以后不会在出事情 我:… 黑客:免费的策略也有很多,比如360、百度云的安全产品可以免费低档10G左右的流量 ……(中间省略) 黑客:我说了这多,你们也是不是给包烟钱,表示表示。 …… 后来也和领导进行了商议,坚决不能给他们钱,不能助涨这种嚣张气焰,实在不行就报警! 曝光一下当年使用的假QQ号,刚查了下变了个头像和描述,如下: 后来我一直在想为什么DDOS攻击总是喜欢根据外网IP来攻击呢,慢慢好像是理解了如果针对域名来攻击的话,那不就是攻击到域名商的服务器了吗,一般域名商比较强大,黑客不太搞的定,也确实没有必要。当然记的前一段时间,某著名域名服务商被攻击,导致国外twitter等著名的互联网公司访问不断到达半天以上,还是很严重的。但是对于我们这些小公司,倒不至于搞这么大的动作。 到底如何正确的防止DDOS攻击: 第一种方案,隐藏服务器外网地址,服务器前端加CDN中转,免费的有百度云加速、360网站卫士、加速乐、安全宝等,如果资金充裕的话,可以购买高防的盾机,用于隐藏服务器真实IP,域名解析使用CDN的IP,所有解析的子域名都使用CDN的IP地址。此外,服务器上部署的其他域名也不能使用真实IP解析,全部都使用CDN来解析。 第二种方案,买一些安全产品来进行流量清洗,主要是阿里云、腾讯云这种大厂商提供的一种服务。… Continue reading 百亿互金平台救火故事

如何用 OllyDbg 的跟踪功能分析虚拟机保护

虚拟机保护已经是现代保护壳不可缺少的一环,虽然逆向方也发展出各种插件帮助分析,但只针对特定某款,通用性的方法却不多见。我总在想,既然虚拟机的结构是固定的,如果有一款工具能够记录指令流,那么按图索骥,也许能发展出一套通用的分析方法来。其实OD(OllyDbg)就有记录指令流的功能,叫跟踪(trace),也许是效果不好或者操作不便,用的人甚至知道的人不多。先介绍下怎么用。 OD的跟踪功能原理很简单,就是每一步都自动下单步断点,然后记录断下来的指令信息。这项功能涉及到几项设置,第一项是缓存大小,不难想象,跟踪得到的这一些列的指令记录是需要占地方存储的,占多大可以设置,位置在调试选项(Debugging options)->跟踪(Trace),如图1。 图1 第一项就是缓存的大小,内存允许的话,自然是多多益善,毕竟缓存越大,允许记录的信息越多。第二项是记录的内容,跟踪会自动记录地址模块等信息,此外可以选择是否记录指令、ESP和标志位的信息。设置位置紧接着缓存大小,见图2,可以按需勾选,本文只需要记录指令即可。最后一项是在调试(DEBUG)菜单中打开Trace。 图2 现在Trace已经设置完毕了,按下Ctrl+F12,查看Trace窗口,应该已经开始记录执行过的指令。否则请检查前述设置和操作是否正确。 那么,虚拟机保护要怎么入手分析呢?前面我提到,虚拟机是有固定结构的,既然要分析,那对应的找到这些结构应该就可以了。传统保护虚拟机的结构其实很简单,大致可以看成一只章鱼,有三个部分,分别是init(头),Dispatch(身)和Handle(触须),如图3: 图3 Init主要完成虚拟机初始化工作,例如申请内存填写初始值之类,每次进入虚拟机,这个“头部”通常只执行一次。Dispatch是虚拟机的主体,可以看成一个主循环,它是每一条虚拟机指令的开始之处,也是结束之处,负责读取虚拟机指令,进入具体handle解释等工作。Handle就是虚拟机的“指令”了,实际完成各项虚拟机指令的功能。 我曾写过一篇《基于虚拟机的软件保护技术》较为详细的介绍过虚拟机保护技术,对基本结构还不太熟的同学,此文会对上述概念有更详细的说明。 现在,我们就要在具体的软件中找这只“章鱼”了。以一个CrackMe为例,首先清理所有断点,打开Trace,Ctrl+F12跟踪步过运行,看到程序跑起来了,F12暂停,看Trace的窗口如下(图4): 图4 记录是从下往上看的,可以看出,在程序空间的最后一条支流,是00401534的一个call,调用了DialogBoxInDirectParamA,这是一个调出系统对话框的API,其中有一个参数DlgProc用来指明消息回调函数的位置,我们直接在反汇编窗口查看这个API,发现回调函数是0x401572(图5): 图5 0x401572处代码不长,有好几条Call,但大部分都是系统Call,只有一处调用了程序空间的函数,这个函数就是虚拟机的入口。到这里,我们对虚拟机的分析的工作才刚刚开始。 首先对虚拟机的入口下断,然后重新运行程序。目的是保证能够正确找到init。现在应该端在虚拟机的入口处,如下图: 图6 这是个非常简单的虚拟机,有经验的同学也许可以一眼就看出来图6包含了Init和Dispatch分别在哪里。当然也可以用Trace快速找出虚拟机的各个结构。现在去掉断点,打开Trace,Ctrl+F12跟踪步过,这时程序会跑起来,多点击几下按钮,目的是让主要分支得到更充分的执行(即增加获得执行的次数),然后F12暂停。回到Trace窗口,对着任意一行程序空间的指令点击右键,选择模块统计,结果如下图: 图7 统计是以代码段来划分的,第一栏显示的是这段代码在刚才的跟踪执行中执行的次数,第二栏显示了某个代码段的首地址。我们先找执行了一次的指令首地址。可以找到第5行的地址就是虚拟机的入口地址,点击在反汇编窗口跟随,可以看到这段代码是从0x00401060到0x004010B9,这就是init: 00401060 $ 55 push ebp 00401061 . 8BEC mov ebp, esp 00401063 . 81C4 D0FEFFFF add esp, -0x130 00401069 . C745 E4 00000>mov dword ptr [ebp-0x1C], 0x0 00401070 . C745 E8 00000>mov dword ptr… Continue reading 如何用 OllyDbg 的跟踪功能分析虚拟机保护

解决PKIX问题:unable to find valid certification path to requested target

话说前几天在测试服务器上遇到了这么个异常 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 就是说找不着安全证书啥的等等烂码七糟的一大堆 接着就拜Google大神,发现一篇文章能被N个人转来转去的,关键文章还不怎么靠谱 后来找到了一个办法,幸运的是在测试环境一弄, 这个问题看上去就被解决了 我们要做的就是将所要访问的URL的安全认证证书导入到客户端 下面是获取安全证书的一种方法 /* * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions… Continue reading 解决PKIX问题:unable to find valid certification path to requested target

[转]openssl的证书格式转换

证书转换 PKCS 全称是 Public-Key Cryptography Standards ,是由 RSA 实验室与其它安全系统开发商为促进公钥密码的发展而制订的一系列标准,PKCS 目前共发布过 15 个标准。 常用的有: PKCS#7 Cryptographic Message Syntax Standard PKCS#10 Certification Request Standard PKCS#12 Personal Information Exchange Syntax Standard X.509是常见通用的证书格式。所有的证书都符合为Public Key Infrastructure (PKI) 制定的 ITU-T X509 国际标准。 PKCS#7 常用的后缀是: .P7B .P7C .SPC PKCS#12 常用的后缀有: .P12 .PFX X.509 DER 编码(ASCII)的后缀是: .DER .CER .CRT X.509 PAM 编码(Base64)的后缀是: .PEM… Continue reading [转]openssl的证书格式转换

Docker 笔记二:安装Nginx

docker pull nginx I’d like to install nginx as a load balance server. http { include mime.types; default_type application/octet-stream; #定义日志格式 #log_format main ‘$remote_addr – $remote_user [$time_local] $request ‘ # ‘”$status” $body_bytes_sent “$http_referer” ‘ # ‘”$http_user_agent” “$http_x_forwarded_for”‘; #access_log off; access_log logs/access.log; client_header_timeout 3m; client_body_timeout 3m; send_timeout 3m; client_header_buffer_size 1k; large_client_header_buffers 4 4k; sendfile on; tcp_nopush on;… Continue reading Docker 笔记二:安装Nginx

Docker 笔记一:安装Tomcat

  docker pull tomcat Run the default Tomcat server (CMD [“catalina.sh”, “run”]): $ docker run -it –rm tomcat:8.0 You can test it by visiting http://container-ip:8080 in a browser or, if you need access outside the host, on port 8888: $ docker run -it –rm -p 8888:8080 tomcat:8.0 You can then go to http://localhost:8888 or http://host-ip:8888… Continue reading Docker 笔记一:安装Tomcat

PHP中“==”运算符的安全问题

前言 PHP是一种通用的开源脚本语言,它的语法混合了C,Java,以及Perl等优秀语言的语法。除此之外,它还提供了大量的函数库可供开发人员使用。但是,如果使用不当,PHP也会给应用程序带来非常大的安全风险。 在这篇文章中,我们将会对PHP应用程序中经常会出现的一些问题进行深入地分析,尤其是当我们使用“==”(比较运算符)来进行字符串比较时,可能会出现的一些安全问题。虽然近期有很多文章都围绕着这一话题进行过一些探讨,但我决定从“黑盒测试”的角度出发,讨论一下如何利用这个问题来对目标进行渗透和攻击。首先,我会对引起这个问题的根本原因进行分析,以便我们能够更加深入地理解其工作机制,这样才可以保证我们能够尽可能地避免这种安全问题的发生。 问题的描述 在2011年,PHP官方漏洞追踪系统发现,当字符串与数字在进行比较的时候,程序会出现某些非常奇怪的现象。从安全的角度出发,这个问题实际上并不能算是一个安全问题。比如说,你可以看到下面这段代码: php > var_dump(‘0xff’ == ‘255’); bool(true) 实际上,当使用类似“==”这样的比较运算符进行操作时,就会出现这样的情况。上面这个例子中出现的问题不能算是一个漏洞,因为它是PHP所提供的一种名为“类型转换”的功能。从本质上来分析,当我们使用特定的比较运算符(例如== , !=, <>)来进行操作时,PHP首先会尝试去确定参与比较的数据类型。但是这样的一种类型转换机制将有可能导致计算结果与我们预期的结果有较大出入,而且也会带来非常严重的安全问题。安全研究专家在该问题的完整披露报告中写到:这种类型转化机制将有可能导致权限提升,甚至还会使程序的密码验证过程变得不安全。 Gynvael写过一篇关于这一话题的经典文章,PHP等号运算符“==”所涵盖的数据类型非常广泛,我们给大家提供了一个较为完整的比较参考列表,并给出了一些示例,具体内容如下所示: “1.00000000000000001” == “0.1e1” → bool(true) “+1” == “0.1e1” → bool(true) “1e0” == “0.1e1” → bool(true) “-0e10” == “0” → bool(true) “1000” == “0x3e8” → bool(true) “1234” == ” 1234″ → bool(true) 正如你所看到的,当我们使用“==”来比较这些数字字符串时,参与比较的就是字符串中数字的实际大小,从安全的角度出发,这就是一个非常有趣的问题了。在这种情况下,你可以使用科学计数法来表示一个数字,并将其放在一个字符串中,PHP将会自动把它作为一个数字类型来处理。我们之所以会得到这样的输出类型,是因为PHP使用了一种哈希算法(通常使用十六进制数值表示)来进行处理。比如说,如果一个数字为0,那么在进行松散比较的过程中,PHP会自动对其类型进行转换,但其值永远为0。对于一个给定的散列算法而言,密码就有可能会变成可以被替换的了。比如说,当密码的哈希值被转换成使用科学计数法来表示的数字时,将有可能正好与其他的密码哈希相匹配。这样一来,即使是一个完全不同的密码,也有可能可以通过系统的验证。但有趣的是,当某些采用科学计数法表示的数字在进行比较的时候,结果可能会让你意想不到: “18372e0” == “492372e0000” → bool(false) “2e6” ==… Continue reading PHP中“==”运算符的安全问题

NSA 是如何破解大量加密信息的?

近几年有谣言说 NSA 可以解密已加密网络中的大部分数据。在 2012 年,James Bamford 发布了一篇 文章,引用了匿名的 NSA 前成员的说法,他证实“NSA已经取得了计算力的突破性进展,他们有能力破解当前已公开的加密算法”。斯诺登公布的文档也暗指像一些额外的线索和文档显示,NSA已经建立了大量的基础设备来拦截和解密 VPN 流量,它至少能解密一些 NSA 想要知道的 HTTPS 和 SSH 连接。 然而,对于这些超前的工作是如何运作的,技术小组是如何判断后门或逻辑缺陷的等问题,这些文档都没有说明。2015 年 10 月 13 日,在 ACM CCS 会议的安全研究分会场,我们和 12 个同行发布了一篇技术谜题揭秘报告。 Diffie-Hellman 秘钥交换算法,是我们推荐使用的防御监听的算法。它是现代密码学的基石,VPN、HTTPS 网站、邮件和许多其他的协议都用在 Diffie-Hellman。我们的报告显示,通过数理理论的交汇和糟糕的协议实现,许多现实世界里的 Diffie-Hellman 用户在面对国家级攻击时都是脆弱的。这个事实稍微有点讽刺。 如果读者里有技术狂人,就会发现一些问题:如果客户端和服务端要使用 Diffie-Hellman,它们首先需要协定一个特殊形式的大素数。为什么不能每个人都用同样的素数?似乎不用问什么原因。实际上,许多应用倾向于使用标准的或者硬编码的素数。但算法从数学家到实现者之间,会丢失一个非常重要的细节:攻击者可以执行一个单点大规模计算来破解大素数,使用该大素数的个人连接很容易丢失。 你要问计算量有多大?大概是整个二战时期破解英格玛的计算规模(相较于那时候的计算量而言)。甚至连估算难度都很棘手,因为这个算法涉及到的内容太复杂,但我们有论文给出了一些保守的估算。对于最常用的 Diffie-Hellman(1024位),花了几亿美元来建造专门的破译机器,这能够每年破解一个 Diffie-Hellman 素数。 对情报机构而言,这值得么?一旦少量的大素数被滥用,那他们可解密的连接,将会很可观。破译一个通用的 1024 位大素数,将让NSA 能解密全球三分之二的 VPN 和四分之一的 SSH 服务器。破解两个1024 位大素数,将能够被动监听上百万个 HTTPS 网站中的20%。总而言之,在大规模计算上的一次投资,使它能够监听数以兆计的加密连接。 NSA 能够负担这些投资。在斯诺登泄露的部分文件里,有一份 2013 年的黑色预算的申请,文件显示 NSA 已经将“发展突破性的密码分析能力以打击敌对方密码系统和利用网络流量”提上了日程。它显示了… Continue reading NSA 是如何破解大量加密信息的?

10 分钟服务器安全设置,Ubuntu安全设置入门

Bryan Kennedy 的《5分钟服务器安全设置》很好地介绍了对多数服务器攻击的防御对策。我们对他的方法做了一些修改,记录下来,作为推广我们的流程和最佳实践的一部分。还增加一些额外的解释,年轻的工程师们应该可以从中受益。 我每天上午检查 logwatch 邮件的时候,看到那些成百上千的登录尝试,几乎没有成功的,完全就像是一种享受。(有很多非常令人无语,比如用 1234 做 root 密码反反复复的登录)。这篇入门文章适用于 Debian/Ubuntu服务器,这是我们最喜欢的服务器发行版,通常我们这些服务器只是作为 docker 容器的宿主机,不过原理仍然适用。下一次我们再深入讲解如何保护专门用作 docker 宿主机的服务器。 在大规模系统上,当然最好是用 Ansible 或 Shipyard 这类工具完全自动化配置。不过偶尔的,你只是搭建一台独立服务器或为一个 Ansible recipe 准备基准设置,这就是本文要涵盖的内容。 声明:本文仅仅是入门和基础,你需要根据自己的需求来扩展。 重要的事先说 我们还没给 root 设密码呢,密码要随机、要复杂。我们用一种密码管理软件的密码生成器,调至最复杂设定。PW 管理软件将密码加密保存,并且由一个很长的主密码保护着。这里提供了多项冗余措施——长、复杂、随机的密码 + 加密保存/另一个长密码保护。不管你是用 PW 管理软件或其他手段,要妥善保管密码并且要加密保存。你只有在忘了 sudo 密码时才会用到这个密码。 # passwd * 注:在 HN 和 Redit 上有很多关于 root 密码的讨论,值得一读。 下一步就需要更新软件库并升级系统、应用最新的补丁。我们后面有个章节专门介绍如何自动安装安全更新。 apt-get update apt-get upgrade 添加用户 永远不要以 root 登录服务器。在用户名方面我们跟 Bryan… Continue reading 10 分钟服务器安全设置,Ubuntu安全设置入门

用了ZAP,你的软件就安全了吗?

近来几年,很多大型网站频发安全事件,比如2011年众所周知的CSDN密码泄露事件,2014年eBay也因受到攻击造成用户密码和个人数据泄露,Web安全逐渐进入人们的视野,安全测试也逐渐成为了软件测试中非常重要的一部分。 提到安全测试,很多人应该都会想到ZAP,ZAP(Zed Attack Proxy)是OWASP提供的一款免费Web安全漏洞扫描工具,用户可以通过设置浏览器和ZAP的Proxy,在开发过程或测试过程中自动检测Web应用程序是否存在安全漏洞,ZAP还会提供扫描结果的风险等级,修复建议以及一些参考文档,下图就是ZAP扫描后的一个用户界面。 除了自动扫描功能,ZAP也支持手动安全测试,通过在数据发送到服务器之前手动修改请求信息来测试Web应用程序是否存在安全漏洞。 很多人会有这样的疑惑,ZAP能否扫描出所有的安全漏洞?ZAP扫描出的安全漏洞和安全等级是否可靠?用了ZAP,软件是不是就安全了? ZAP局限性 首先虽然ZAP的自动扫描功能非常强大,但对于OWASP Top 10中的某些项或者Top 10以外的一些安全漏洞,想要通过ZAP扫描检测出来是非常困难的,比如Top 10中的A5 “Security Misconfiguration” 就很难通过扫描检测出来,所以ZAP所能扫描到的安全漏洞只是OWASP Top 10的一个子集。 其次,ZAP扫描后的安全报告,还是需要结合实际项目进行分析才能确定其有效性和安全等级,比如我们在项目中曾经用ZAP扫描出了 “Cookie set without HttpOnly flag” 的安全隐患,推荐的解决方案是将所有的Cookie都设置成HttpOnly,但现实的情况是项目中前端AJAX需要携带这个Cookie来给后端发送请求,如果设置了这个flag,那么我们正常的请求也会失败,所以这个漏洞对我们来说就是无效的,或者说我们是不应该修复的。 另外因为Web应用程序往往比较复杂,会有很多组成部分,比如前端、服务器端、数据库等,各层分别使用了不同的框架、语言,而且经常会引入一些第三方的库、框架或者模块,每一个环节都有可能存在安全隐患,所以仅仅依赖ZAP是不够的,比如针对第三方组件的安全测试,就可以借助OWASP提供的另外一款工具Dependency Check。 通过分析实际项目中发现的安全问题,我们发现缺陷大体上如下分布: 安全问题可以归为两大类: 一类是比较有共性的,即可以抛开业务上下文,软件之间共通的一些问题,常见的比较严重的安全隐患,如XSS攻击,CSRF攻击等,ZAP可以帮我们扫描出大多数的问题。 另一类是针对业务需求的,比如非授权的账户是否不能访问/修改他们没有权限的信息等等,对于这一类问题,离开具体的业务上下文,是很难测试的,因为什么样的用户具有什么样的权限往往是业务领域的知识,换句话说,这一类问题的测试重点是看正常的用户能否按照业务需求所期望地正常使用系统,怎么区分evil user并阻止其对系统的使用和破坏,需要很强的业务背景。 举一个简单的例子,比如一个Web系统有两种角色,管理员和普通账户,业务需求是管理员可以修改所有人的所有信息,普通账户只能看到和修改自己的信息,如果普通账户张三可以通过一些非正常手段修改李四的信息,或者非系统的用户(evil user)通过某些方式可以看到系统内账户的个人信息,这些都是严重的安全缺陷,而且这一类的缺陷所占比率比较大,但是都没有办法通过ZAP扫描出来,也没有办法脱离对业务知识的了解来进行测试。 安全内建 ZAP扫描,针对业务上下文的用户权限测试(不能局限于界面,还要通过其他一些方式比如修改请求)以及evil user的用户场景测试,可以覆盖绝大多数的Web安全缺陷,但是正如我们没有办法将质量注入一个已经成型的产品一样,安全也是同样的道理。 如果我们在软件已经编码完成之后再引入安全检查和测试,那么软件的安全质量已经确定,后期的修复只能解决已经发现的安全漏洞,不能让软件更加安全,而且对于这些安全缺陷,发现得越晚,修复的成本就会越高。 所以为了开发安全质量较高的产品,除了选择好的工具以及增加业务背景下的安全测试,还非常有必要将安全检查和测试提前,在软件开发各个过程中引入安全实践。 微软提出的SDL(Security Development Lifecycle)就是这样的理念,SDL提出了很多软件开发过程中非常好的的安全活动,比如需求分析阶段的“最小权限原则”,开发阶段“弃用不安全的函数”,以及测试阶段可以使用“模糊测试”等等,其核心理念就是将软件安全的考虑集成在软件开发的每一个阶段,从需求,设计,编码,测试,到最后的发布整个过程中,下图是一个简化版的SDL流程图,完整的SDL还包括前期的培训,发布后的响应等: ThoughtWorks提出的BSI(Build Security In),即安全内建,强调的也是安全提前的理念,结合敏捷软件开发实践,将安全融入到用户故事的生命周期中,引入安全验收条件, 不同角色(业务人员、开发人员,测试人员以及客户)在用户故事的每个阶段对安全验收条件进行沟通,检查,验证,确保在用户故事交付之前满足了定义的安全验收条件,下图就是用户故事的生命周期图以及在各个阶段哪些角色会参与哪些安全活动的一个简单介绍: 在保证用户故事满足了安全需求的基础上,基于迭代/发布还会有一些整体的功能级别的验证,做到真正的安全内建。 以上两种理念强调的都是把安全作为跟功能一样重要的考虑因素,在软件开发的各个阶段进行沟通和反复验证,很多实践经验也表明,将安全活动作为软件开发过程的一部分来执行,其安全效益要大于临时的或者零散的安全活动。 结论 所以从安全测试的选择来看,我们不能单一依赖某种工具,比如ZAP扫描,而应该多加入一些基于业务需求的安全测试,多从攻击者的角度思考问题,更重要的是,可靠的安全测试只能避免安全漏洞造成更大的危害和影响,并不能打造安全的产品,真正的安全产品必定需要整个软件开发过程中每个环节的保障,需要从业务分析阶段就将安全作为重要的考虑因素,将安全实践融入到整个软件开发过程中,所有角色共同参与,这样才能做到真正的安全内建。 相关文章 Redis 未授权访问缺陷可轻易导致系统被黑 Cookies 的跨域脚本攻击 –… Continue reading 用了ZAP,你的软件就安全了吗?

内建安全的软件开发

1. 传统安全实践面临着严峻的挑战 随着互联网应用、移动应用爆发式的增长,伴随而来的黑客攻击事件也是层出不穷。仅在过去的2015年里,被公开报道的数据泄露安全事件就有约3930起,将近7.36亿条数据被泄漏。显而易见的是,如果某家企业被爆出安全问题,对企业造成的影响不仅仅只是名誉、财务上的损失,还会遭受法律诉讼,陷入竞争不利的局面。安全已经是企业不可忽视的问题。 近年来,黑客攻击的趋势已经发生了显著的改变,由最初的针对网络、操作系统以及服务器的攻击,已经转变为针对应用程序的攻击。根据Garnter的调研报告显示,有将近80%的安全漏洞发生在应用层。为了应对新的安全威胁,企业也做出了各种尝试,例如为员工提供安全培训、设立安全规范文档、部署Web应用防火墙、建立安全监控中心、利用安全渗透测试寻找安全漏洞等等。经过一些列的努力,取得的成果也是比较显著的,例如老生常谈的SQL注入攻击,其全球范围内的漏洞数量呈现出了非常显著的下降趋势,如图1-1所示。 图 1-1 SQL 注入漏洞数量趋势 然而并不是所有发生在应用程序中的安全漏洞的数量都得到了有效抑制,例如跨站脚本攻击漏洞的数量似乎并不受安全措施数量的影响,如图1-2所示。 图 1-2 XSS 漏洞数量趋势 一个现象是,企业为应对应用安全问题采取了各种措施,虽然有一定成效但是也有或多或少的问题,如图1-3所示,随着安全措施数量的增加,应用中的安全漏洞的数量不再显著减少。似乎无论如何努力,开发出来的应用中始终有安全漏洞。 图 1-3 安全措施和安全漏洞数量的关系 除此之外,企业还面临着更多的困境: 安全漏洞总是很晚才被发现出来,造成的结果是安全漏洞的修复成本高昂。 未能检查出隐藏在应用中的安全漏洞,含有安全缺陷的应用被发布到生产环境中,这将增加企业面临的安全风险。 某些安全措施容易被误解为是团队的负担 开发团队人员安全技能有所缺失,应用的安全性过度依赖于应用安全团队 2. 为何安全漏洞如此难以消除? 为消除安全漏洞,企业采取了不少措施,然而一个不争的事实是,企业主要依赖于Web应用防火墙(Web Application Firewall,下文简称WAF)和渗透测试(或安全审计)。然而问题在于,这两种措施固然有效,但是也存在着明显的不足。 2.1 WAF是把双刃剑 WAF主要的职责是阻挡攻击,为开发团队争取修复漏洞的时间。换言之,只要应用中存在安全问题的代码没有被修复,漏洞就会一直存在,一旦WAF规则被绕过,或者配置不当,反而会将应用置于更高的安全风险当中。此外,误报和漏报始终是WAF无法彻底解决的问题,与此同时,随着应用规模的扩大,业务逻辑复杂度的增加,对于WAF的管理维护难度也在不断增加。 2.2 渗透测试让企业面临两难的境地 渗透测试确实能发现安全漏洞,但是也存在着明显的不足。首先是太晚才能得到安全问题的反馈,因为通常而言,渗透测试会被安排在产品上线发布之前进行,此时如果检查出安全漏洞,企业反而会面临两难的境地:修复安全漏洞之后再发布产品,或者强行发布包含安全漏洞的产品。同修复业务缺陷一样,修复安全漏洞也是越晚修复成本越高,开发团队需要投入更多的时间和人力,而这可能导致产品推迟发布,错失市场机会;如果强行发布含有安全漏洞的产品,又将增加被黑客攻击利用的风险。 2.3 抛开现象看本质,问题的根源在于缺乏高效的安全反馈机制 应用中的安全漏洞是在开发过程当中由于各种原因被引入的,然而回顾现有的安全措施就会发现,其中大量的措施发生在应用程序开发过程之外,例如WAF、安全监控发生在产品上线之后,渗透测试需要等待开发完毕后才能进行,而安全培训、安全规范只能起到预防作用。尽管各种安全措施都能为开发团队提供不同程度的安全反馈信息,然而问题在于,大量的安全措施都发生在开发过程之外,距离安全问题被引入的时间点之间有很长的距离,因此安全问题不能及时的反馈给开发团队。 此外,由于不少安全措施的成本高、耗时长,因此难以持续性的为开发团队提供安全反馈。例如聘请第三方安全公司对应用进行安全渗透测试的价格较高,且往往需要几天甚至更多时间才能收到安全报告。 3. 更好的解决安全问题 安全漏洞本质上是软件质量缺陷,安全性是软件质量的重要组成部分,而现如今应用安全面临的问题和多年以前软件测试面临的问题极其相似。当时人们在开发软件的时候,采取的做法往往是在软件开发临近结束之时集中性的进行测试,修复发现的质量缺陷,结果是当时的软件质量普遍不高,不少项目因此失败。 为了提高软件质量,开发团队采取了一些措施,例如将测试介入的时间点提前,尽早进行测试,甚至是先写测试后写实现代码,与此同时也大量采用自动化测试来加快测试执行速度,采用构建流水线持续关注软件质量,并且每位团队成员都对软件质量负责,而不再认为只是测试人员的职责。这些措施之所以能够显著提高软件质量,关键在于它们能够更加高效的为开发团队提供软件质量相关的反馈信息,使得开发团队能够基于反馈结果迅速进行改进。 同理,要更好的解决安全问题,开发团队应当建立起一个高效的安全反馈机制,在开发过程中引入一些安全活动,尽早开始收集安全反馈信息,加快获取安全反馈的速度,在整个开发过程中持续性的关注应用的安全性,与此同时团队成员共同来承担安全职责。我们将这些在实践中总结出来的经验命名为内建安全的软件开发方式(Build Security In DnA,下文简称BSI),从源头上尽早、尽快、持续性的,以团队共同协作的方式发现并解决安全问题。 图 3-1 内建安全的软件开发方式 (Build Security In) 3.1 尽早获取安全反馈 越早获取到安全反馈信息,越有利于开发团队以更低的成本将其修复。一个反面例子是,安全问题在早期就已经引入了,但是只能通过后期的渗透测试才能暴露出来,安全反馈信息经历了很长一段时间才能反馈给开发团队。与其依赖于后期的渗透测试,不如在开发过程当中引入一些适当的安全实践,比如在分析业务需求的同时主动分析安全需求,将其作为质量验收标准在团队内明确出来,再比如,针对每次代码提交都对其进行安全评审、测试人员在测试业务功能的同时还对安全性进行验证。通过这种方式,使得团队能够尽快得知应用的安全状况,而不必依赖于很晚才能提供安全反馈的渗透测试。 图… Continue reading 内建安全的软件开发

SQL 注入,永不过时的黑客技术

TalkTalk的信息泄漏事件导致约15万人的敏感信息被暴露,涉嫌造成这一事件的其中一名黑客使用的并不是很新的技术。事实上,该技术的「年纪」比这名15岁黑客还要大两岁。 [译注:TalkTalk是英国电话和宽带供应商,这件信息安全事故发生在2015年10月份,当时这件事情还挺轰动的,上了新闻头条,其中一名黑客年仅15岁。] 这项技术就是大名鼎鼎的SQL注入,所谓SQL注入就是黑客在网站的提交表单数据中输入恶意命令从而获取数据的方法。它曾经被用来窃取世界卫生组织员工的信息,偷过华尔街日报数据,甚至还攻击过美国联邦政府机构。 “这是最简单的黑客技术”,w0rm 告诉 Motherboard[译者注:Motherboard就是这篇文章原文所在网站],他是一名匿名黑客,声称对华尔街日报的攻击负责。整个攻击过程只用了几个小时。 但是,正因为它是比较简单的技术,同时经常被用来从公司或者政府机构窃取数字信息,所以SQL注入攻击应该相对来说比较容易防范才对。 但为何到了2015年,SQL注入攻击仍然能导致最大规模的信息泄漏事件呢? 有迹可循的最早SQL注入攻击的记录大概是Jeff Forristal在黑客杂志Phrack上发表的文章。Forristal当时是rain.forest.puppy的掌舵人[译者注:rain.forest.puppy是一个安全咨询组织,或者说,是个黑客团队?:)],他目前在网络安全公司Bluebox,负责移动安全方面的CTO。 “微软声称,你看到的都不是问题,所以不用费心去处理它” [译者注:这是有人给微软报告SQL server这个漏洞时,微软的回复] SQL, 全称为结构化查询语言,是一种用来管理数据库的编程语言。本质上说,他就是被网站用来从数据库中提取一些数据来处理或者展示给用户的。 但是Forristal发现,当输入特定的命令时,会导致服务器泄漏信息。“用户可能捎带一些自己的SQL语句”,他写道。 在Phrack的1998年12月份期刊上,Forristal发表了微软的SQL server的一系列SQL注入的问题。当Forristal的同事们向微软反馈此问题时,“他们的回答是:好了,别闹了”,他写道,“他们说,你看到的都不是问题,所依别费心去处理了” SQL注入发展到今天,已经过去了15年,在OWASP组织每三年发表一次的OWASP的Top 10问题上,SQL注入攻击经常坐上榜首的位置。OWSAP全称是开放式Web应用程序安全项目(Open Web Application Security Project),它是一个监控网站面临哪些安全威胁的非盈利性组织。 Phrack现在的logo “SQL注入经常是第一威胁,主要反映在相关攻击事件的数量上,同时还有一些其他因素导致它如此频发,” Troy Hunt在Motherboard的一次电话采访中如是说道,Troy Hunt是攻击检测网站haveibeenpwned.com的创始人[译者注:感觉像是一个社工库]。 “当你访问一个网页时,你发出一个请求,然后渲染服务器返回的数据”, Hunt介绍,“举个例子,你看一篇新闻,在地址栏上使用id=‘1’来发出请求时,服务器返回编号为1的文章,把id改成2的时候,服务器返回编号为2的文章” 但是,“使用SQL注入攻击,攻击者可能会将ID字段改成一个其他什么东西,导致服务器做一些意料之外的事情”,Hunt继续说到,比如返回一些隐私数据。 一次攻击也许只返回一条或者一段信息,于是攻击者就“不断重复攻击,一次又一次,想干几次干几次,直到他们获取到所有数据为止”,Hunt说。 显然,这需要一段比较长的时间,所以,黑客一般会使用自动化工具。其中比较具有代表性的事Havij,“这是最流行的脚本小工具,因为它支持Windows操作系统,而且还有个图形界面”, Mustafa AI-Bassam通过在线聊天工具和Motherboard如此描述,他是一名安全研究员,同时还是一名LulzSec黑客组织的前成员。 另一个经常被用到的工具是 sqlmap 。“它可以爬取网站的页面,就像搜索引擎的爬虫,寻找网站中所有输入表单,然后提交一些可能导致MySQL语法错误的数据”, AI-Bassam继续介绍。 当攻击者找到一个攻击点,接下来就很容易自动化开搞了。 sqlmap的界面 “他们会使用Google来搜索那些典型的容易受到SQL注入脚本攻击的URL”, AI-Bassam说。“他们还经常使用脚本来检查所有URL,用自动化的方法来试探是否存在漏洞” “你甚至可以教一个4岁的孩子来做这种事情[译者注:汗~~我还不如个4岁的孩子]”, AI-Bassam补充道,强调这整个过程简单到令人发指的地步。确实,Hunt就曾经上传过一个视频,视频上显示他是怎么教他3岁的儿子用Havij来实施SQL注入攻击的[译者注:这是真爱啊,我坚决不会让我女儿走上计算机这条不归路] “你把要攻击的URL输入进来,然后所有数据就出来了”,Hunt向Motherboard介绍道。在YouTube上有太多教程来介绍如何实施SQL注入攻击了。 事实上,已经有很多解决方案被网站开发人员用来防止SQL注入攻击了和避免客户信息或者公司信息泄漏了。而且那些解决方案一经存在好几年了。 所有这些解决方案的核心都是采用“prepared statments” (预编译声明?): 当SQL语句在数据库中执行是,绝对不能直接执行用户的输入。 如果这些解决方案直接有效,那为何SQL注入攻击还是这么猖獗呢? “使用prepared staement的好处是它们可以从语义层面上杜绝任何在开发者意料之外的输入,这些输入可以通过构造一些SQL语法,让数据库查询语句从任意一张数据表中获取一条额外的数据”,Mike… Continue reading SQL 注入,永不过时的黑客技术