Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
создание своей nulled CMS на примере DLE |

31.05.2008, 22:26
|
|
Участник форума
Регистрация: 16.06.2007
Сообщений: 104
Провел на форуме: 178647
Репутация:
143
|
|
создание своей nulled CMS на примере DLE
На сегодняшний день существует множество популярных коммерческих CMS: DLE , SLAED CMS Pro, bitrix и др. Я не буду сейчас подробно разъяснять чем отличаются коммерческие движки от открытых, скажу лишь только, что поддержка у них намного лучше, да и безопасность тоже - хотя это мое личное мнение. Отдельной стороной стоят нуленые cкрипты. Статус Nulled данные скрипты получают после исключения из их кода защит и систем контроля, оставленных разработчиками, к примеру привязка к домену, запрос ключа регистрации при установке, ограничение времени использования и тп…
Вопрос стоит ли использовать Nulled движки зависит от самого пользователя, если вы хотите безопасный скрипт на неограниченном количестве сайтов - дерзайте. При этом правда потеряется непосредственное обновление с сайта разработчиков, но это не сильно страшно, всегда можно и вручную заплатки ставить или скачать новую зануленую версию. К тому же если вы решите напичкать свой двиг модулями, то обновления затрут их, так что добрая половина пользователей вообще не используют эту функцию, а остальная часть использует лицензию 
В последнее время участилось распространение фейковых дистрибутивов, с бекдором внутри. Собственно добрые дядьки нулили нулили, а злые впихивали туда свой код и распространяли на файлообменниках. В принципе, чтобы самому создать Nulled версию - достаточно хорошо знать PHP, ну и плюс пару тройку часов свободного времени и несколько банок пива. А что что делать тем кто плохо знает PHP и не хочет левый "null"? - читать дальше.
Есть еще один способ эффективного понимания процесса нуления. Многие движки распространяются в исходниках, некоторые с закрытыми или шифрованными исходниками ( к примеру DLE Demo).
И так, рассмотрим "чистый" способ создания nulled скриптов на примере DLE 7.0. Для этого лицензию всетаки надо приобрести, чтоб получить открытый код CMS, ну можно также скачать в инете или, что еще лучше спросить у друга, который эту лицензию приобрел (без ключа-то она такое же демо) : еще нужна программа для визуального сравнения текстовых документов на предмет изменений в них - подойдет WinMerge (аналогичные есть и под линь, к примеру KDiff3), собственно сама нуленая версия для сравнения ( использовалась от MID team) и кой-какое знание PHP.
И так, приступим:
Открываем WinMerge - создаем новый проект, в левой стороне указываем папку с "демо" версией DLE (допустим C:\temp\dle\demo\), в правой c нуленой версией от МИДа (C:\temp\dle\nulled\).
Как видно изменений много, но если присмотреться львиная чать изменена не намного, вставлен копирайт от MID. Значительному изменению подверглись только несколько файлов: в папке \upgrade\index.php, addnews.php, dboption.php, functions.inc.php, \engine\inc\init.php, main.php, options.php, updates.php.
Рассмотрим их содержимое более подробней.
1. \upgrade\index.php - тут надо удалить строчку с двумя переменными -
PHP код:
$_D = ROOT_DIR; $_F = ENGINE_DIR;
- они не нужны.
2. addnews.php - тут убрать ограничение на добавление новостей (просто удалить этот кусок)
PHP код:
if ($lic_tr) {
$row = $db->super_query("SELECT COUNT(*) as count FROM " . PREFIX . "_post");
$stats_news = $row['count'];
$row = $db->super_query("SELECT COUNT(*) as count FROM " . PREFIX . "_comments");
$count_comments = $row['count'];
if ($stats_news > 200) die("Licence not Found!");
if ($count_comments > 500) die("Licence not Found!");
}
3. dboption.php - убираем условие, отвечающее за привязку к домену
PHP код:
if ($domen_hash == "" OR $domen_hash != $config['key']) {$row = $db->super_query("SELECT COUNT(*) as count FROM " . PREFIX . "_comments");if ($row['count'] > 555) die("\114\151\143\455\156\455\145\40\156\157\164\40\106\157\165\156\144!");}
4. в functions.inc.php - удаляем переменные $_F, $_D и условие
PHP код:
if(!$_F OR !$_D) exit();
function echoheader($image, $header_text){
global $PHP_SELF, $skin_header, $member_db, $user_group, $_F, $_D;
$skin_header = preg_replace("/{header-text}/", $header_text, $skin_header);
$skin_header = preg_replace("/{user}/", $member_db[2], $skin_header);
$skin_header = preg_replace("/{group}/", $user_group[$member_db[1]]['group_name'], $skin_header);
if(!$_F OR !$_D) exit();
echo $skin_header;
}
Должно получиться следующие
PHP код:
function echoheader($image, $header_text){
global $PHP_SELF, $skin_header, $member_db, $user_group;
$skin_header = preg_replace("/{header-text}/", $header_text, $skin_header);
$skin_header = preg_replace("/{user}/", $member_db[2], $skin_header);
$skin_header = preg_replace("/{group}/", $user_group[$member_db[1]]['group_name'], $skin_header);
echo $skin_header;
}
5. main.php - изменяем переменную $licence
PHP код:
$licence = ($lic_tr) ? $lang['licence_trial'] : $lang['licence_full'];
На
PHP код:
$licence = "Nulled by NickName";
Далее удаляем условие, когда активируется ключ.
PHP код:
if ($lic_tr) {
echo <<<HTML
<SCRIPT LANGUAGE="JavaScript">
function dle_activation (){
document.getElementById( 'result_info' ).innerHTML = '{$lang['nl_sinfo']}';
var dle_key = ajax.encodeVAR( document.getElementById('sitekey').value );
var varsString = "dle_key=" + dle_key;
ajax.setVar("activation", 'yes');
ajax.requestFile = "{$config['admin_path']}";
ajax.element = 'dle-activation';
ajax.method = 'POST';
ajax.sendAJAX(varsString);
return false;
}
</script>
HTML;
echo"<br /><table width=\"100%\"align=center><tr><td style='padding:3px; border:1px dashed rgb(190,190,190); background-color:lightyellow;' class=main>
<div id=\"dle-activation\">$lang[trial_info]<br /><br /><b>$lang[trial_key]</b><span style=\"padding-left:7px;\"><input class=\"edit\" type=\"text\" size=\"55\" name=\"sitekey\" id=\"sitekey\"> <input class=\"edit\" type=\"button\" onClick=\"dle_activation(); return false;\" value=\"$lang[trial_act]\"></span><div id=\"result_info\" style=\"color:red;\"><br /></div></div>
</td></tr><tr><td> </td></tr></table>";
}
6. Ковыряем options.php
Удаляем условие, отвечающее за ограничение на комментарии и новости
PHP код:
if ($lic_tr) {
$row = $db->super_query("SELECT COUNT(*) as count FROM " . PREFIX . "_post");
$stats_news = $row['count'];
$row = $db->super_query("SELECT COUNT(*) as count FROM " . PREFIX . "_comments");
$count_comments = $row['count'];
if ($stats_news > 501) die("Licence not Found!");
if ($count_comments > 1001) die("Licence not Found!");
}
7. updates.php - убираем функцию обновления скрипта
заменяем
PHP код:
$data = @file_get_contents("http://www.dle-news.ru/extras/updates.php?version_id=".$_REQUEST['versionid']."&key=".$config['key']);
if (!strlen($data)) echo $lang['no_update']; else echo $data;
на
PHP код:
$data = "нельзя - движок нуленый";
echo $data;
8. и самый большой подводный камень - это init.php. Этот файлик очень хитрожо…в общем зашифрован он. Тестить бум на сервере, копируем весь "мусор" в index.php и будем запускать из браузера (я использовал денвер). Посмотрев теперь index.php по внимательней можно найти строчку
PHP код:
$_D=strrev('edoced_46esab');eval($_D( "тут какой-то код")
если ее прочитать задом наперед то получится base64_decoded : вот тут то и начинает попахивать жареным. Копаем дальше… Функция strrev переводит сроку в обратном направлении. Расшифровываем переменную $_D в BASE64 (использовал онлайн дешифратор, таких скриптов куча)- получилось:
PHP код:
$_X=base64_decode($_X);$_X=strtr($_X,'O/bpuw3kM6B2txD1.RoX]lVY >JAEGTfz7K
QH=js}ZqUce8v5nm<[9a4i0CrW{NghdILPySF','iC
vfF>zeSE7P5nqlAt.wWDOmKubdU}=3M{Rkcx92JhLZgX06yrpQTG< VajIB1][Y48sH/oN');$_R=ereg_replace('__FILE__',"'".$_F."'",$_X);eval($_R);$_R=0;$_X=0;
что видим… переворачивается 'edoced_46esab' слева направо, таким образом получая 'base64_decode', выполняется переменная под eval, собственно это и есть ключ к расшифровке.
Таксь, уже близко - чую запашок горелого, если это не на кухне - тогда скрипт наш скроро сдастся.
Видно, что нешифрованный код будет находиться в переменной $_X, а не в $_R.
Поэтому изменим его: eval($_R); заменим на print base64_encode($_X);
Должно получиться следующее:
PHP код:
$_X=base64_decode($_X);$_X=strtr($_X,'O/bpuw3kM6B2txD1.RoX]lVY >JAEGTfz7K
QH=js}ZqUce8v5nm<[9a4i0CrW{NghdILPySF','iC
vfF>zeSE7P5nqlAt.wWDOmKubdU}=3M{Rkcx92JhLZgX06yrpQTG< VajIB1][Y48sH/oN');$_R=ereg_replace('__FILE__',"'".$_F."'",$_X);print base64_encode($_X);$_R=0;$_X=0;
Шифруем в BASE64 и вставляем обратно, потом запускаем скрипт из браузера, нам выдаст опять шифровку в BASE64, вставляем ее в декодер и видим примерно тот же исходник которой был до этого, кроме одного но - ключ уже будет другой. Копируем дешифрованный код в наш скрипт полностью все заменяя (возможно придется убрать знак "?>" вначале), далее делаем такие же манипуляции с $_D как и выше, раскодируем - заменяем eval($_R); на print base64_encode($_X); -кодируем, заменяем в файле, запускаем в браузере - нам опять выдает закодированный код - только теперь если его раскодировать получим наш исходник : Вот такая у него мега кул защита…
Если скачать демо версию, то большинство файлов (если не все) там закодированы также, так что если есть энтузиазм и банка пива - дерзайте, возможно превратить demo в полноценную версию (можно написать скрипт, чтоб все это вручную не проделывать), ну или использовать готовый null.
Приступим непосредственно к ковырянию в коде и извлечению ненужных функций.
Удаляем ограничение на новости:
PHP код:
if (($mod != "editnews" AND $mod != "main" AND $mod != "") AND $lic_tr) {
$row = $db->super_query("SELECT COUNT(*) as count FROM " . PREFIX . "_post");
$stats_news = $row['count'];
$row = $db->super_query("SELECT COUNT(*) as count FROM " . PREFIX . "_comments");
$count_comments = $row['count'];
if ($stats_news > 100) msg("info","error", $lang['trial_limit']);
if ($count_comments > 200) msg("info","error", $lang['trial_limit']);
}
Удаляем ограничения на домен:
PHP код:
$domen_hash = explode('.', $_SERVER['HTTP_HOST']);
$count_key = count($domen_hash) - 1;
unset ($domen_hash[$count_key]);
if (end($domen_hash) == "com" OR end($domen_hash) == "net") $count_key --;
$domen_hash = $domen_hash[$count_key-1];
$domen_hash = md5(md5($domen_hash."780918"));
$lic_tr = true;
if ($domen_hash == $config['key']) $lic_tr = false;
if ($_REQUEST['activation'] == "yes") { dle_activation (convert_unicode($_REQUEST['dle_key']), $domen_hash, $config); exit;}
и Удаляем активацию скрипта на сервере:
PHP код:
function convert_unicode($t, $to = 'windows-1251')
{
$t = preg_replace( '#%u([0-9A-F]{1,4})#ie', "'&#' . hexdec('\\1') . ';'", $t );
$t = urldecode ($t);
$t = @html_entity_decode($t, ENT_NOQUOTES, $to);
return $t;
}
function send_activation ($query,$others=''){
$host='dle-news.ru';
$path='/extras/activate.php';
$post="POST $path HTTP/1.1\r\nHost: $host\r\nContent-type: application/x-www-form-urlencoded\r\n{$others}User-Agent: Mozilla 4.0\r\nContent-length: ".strlen($query)."\r\nConnection: close\r\n\r\n$query";
$h=@fsockopen($host,80, $errno, $errstr, 30);
if (!$h) {
$r = @file_get_contents("http://".$host.$path."?".$query);
}
else
{
fwrite($h,$post);
for($a=0,$r='';!$a;){
$b=fread($h,8192);
$r.=$b;
$a=(($b=='')?1:0);
}
fclose($h);
}
if (stristr( $r, "antw:activated" )) return "1";
if (stristr( $r, "antw:denied" )) return "0";
return "-1";
}
function dle_activation($key, $domen_hash, $config){
include (ROOT_DIR.'/language/'.$config['langs'].'/adminpanel.lng');
$config['charset'] = ($lang['charset'] != '') ? $lang['charset'] : $config['charset'];
$domain = urlencode(strip_tags ($_SERVER['HTTP_HOST']));
$key = strip_tags ($key);
$buffer = send_activation ("domain={$domain}&key={$key}&site_key={$domen_hash}&c_id=5411");
switch ($buffer) {
case "-1" :
$buffer = $lang['trial_act1'];
break;
case "0" :
$buffer = $lang['trial_act2'];
break;
case "1" :
$config['key'] = $domen_hash;
$handler = fopen(ENGINE_DIR.'/data/config.php', "w");
fwrite($handler, "<?PHP \n\n//System Configurations\n\n\$config = array (\n\n");
foreach($config as $name => $value)
{
fwrite($handler, "'{$name}' => \"{$value}\",\n\n");
}
fwrite($handler, ");\n\n?>");
fclose($handler);
$buffer = $lang['trial_act3'];
break;
default:
$buffer = $lang['trial_act4'];
}
@header("Content-type: text/css; charset=".$config['charset']);
echo $buffer;
die ();
}
extract($_REQUEST, EXTR_SKIP);
замечания: вышеописанный способ работает с версией 7.0, для версии 7.2 нужно подправить init.php - там привязка к домену запихана в функцию. еще 2 файла редактировать необязательно - это editnews.php и editusers.php. тут нужно убрать условие также отвечающее за привязку к домену и проверке ключа, в принципе и с этим нормально работает...
PHP код:
if ($domen_hash == "" OR $domen_hash != ........................);}
но я за чистоту кода
Данный способ позволяет лишний раз убедится в чистоте занулленого движка и по возможности создать свою версию nulled, к тому же приведенный выше способ подойдет наверняка и к другой версии, не думаю что разработчики каждый раз переписывают модули лицензии .
Вся описанная информация предоставляется исключительно к ознакомлению и размышлению. Никакая часть данного материала не может быть использована во вред, в обратном случае, автор не несет какой-либо ответственности за возможный ущерб, причиненный материалами статьи.
спициально для antichat.ru
Последний раз редактировалось SchmeL; 19.08.2008 в 01:53..
Причина: ошибки исправил и подкорректировал для новой версии
|
|
|
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|