PDA

Просмотр полной версии : SQL-Inj Strings Converter


L0rd_Ha0S
06.11.2007, 01:59
Вот, написал конвертер строк в ASCII и НЕX вид. Может быть полезен при проведении sql-инъекций, когда в запросы надо вставить данные в виде char(104,101,108,108,111) или в hex - 0x68656c6c6f. Создан с целью экономии времени. (Что он успешно делает) :)

Пользоваться так:
haos@localhost(23:49:49)~ $ sql-conv
Usage: sql-conv 'String for converting'
haos@localhost(23:49:58)~ $ sql-conv 'Hello, World!'

Source string ==> Hello, World!

ASCII string ===> char(72,101,108,108,111,44,32,87,111,114,108,100,3 3)

HEX string =====> 0x48656c6c6f2c20576f726c6421

haos@localhost(23:50:11)~ $

Исходники лежат тут: http://lanham.nm.ru/sources/

Upd(10 Nov 2007):
P.S. писал для себя, тут выложил только потому , что это может кому-либо пригодиться.

/* sql-conv.c
Author: L0rd_Ha0S (forum.antichat.ru)
Description: Converting strings to ASCII and HEX codes. For SQL-Inj.
Date: 7 Nov, 2007 21:00
Charset for comments: UTF-8
Version: 0.2
Compiling: gcc -o sql-conv sql-conv.c
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <malloc.h> // Needed by Windows. Uncomment this if you use Windows.

void usage(const char *ProgramName);
void word2hex(const char *SourceString, char *ResultBuffer, int string_length);
void word2ascii(const char *SourceString, char *ResultBuffer, int string_length);

int main(int argc, char *argv[])
{
if (argc < 2) // Проверка параметров
usage(argv[0]);

const char *SqlString = argv[1]; // сохраняем исходную строку в SqlString
const int SqlStringLength = strlen(SqlString); // вычисляем длину переданной строки
char *buffer; // будет хранить указатель на нашу память

if (SqlStringLength == 0){
printf(" Source string is empty!\n");
exit (1);
}
else
printf("\n Source string ==> %s\n", SqlString); // выводим исходную строку

/* Выделяем область памяти, в которой будет храниться результирующая строка. Размер выделяемой памяти равен
выражению SqlStringLength*4, т.к. ascii-вид строки(в текстовом виде) будет занимать размер исходя из
=> 1 символ = 3 символа(max) + 1 символ запятой + символ \0. Но т.к. последний символ печатается без запятой,
то место запятой займет символ \0. Для хранения hex-вида(в текстовом представлении) нужно ещё меньше памяти.
Поэтому будем выделять память по-максимуму, т.е. по ascii-виду - SqlStringLength*4 */

if ((buffer = (char *) malloc(SqlStringLength*4)) == 0 ){
printf(" malloc() is failed!\n");
exit (1);
}

memset(buffer, 0, SqlStringLength*4); // заполняем нашу память нулями
word2ascii(SqlString, buffer, SqlStringLength);
printf("\n ASCII string ===> char(%s)\n", buffer);

memset(buffer, 0, SqlStringLength*4); // очищаем буфер для вызова word2hex()
word2hex(SqlString, buffer, SqlStringLength);
printf("\n HEX string =====> %s\n\n", buffer);

free(buffer); // Освобождаем память, которую мы использовали для хранения результата

exit (0);
}

/* usage() */

void usage(const char *ProgramName)
{
printf(" Usage: %s \'String for converting\'\n", ProgramName);
exit (0);
}

/* Функция word2hex() конвертирует переданную ей строку в hex вид, результат сохраняется в выделенной для этого
области памяти. Принимает 3 параметра: 1й - указатель на строку, которую нужно отконвертировать,
2й - указатель на область памяти, где будет храниться результат выполнения, 3й - длина исходной строки в символах (strlen()) */

void word2hex(const char *SourceString, char *ResultBuffer, int string_length)
{
int i; // счётчик символов
char buf_tmp[3]; // буфер, хранящий текстовое значение hex-кода символа.

for (memcpy(ResultBuffer, "0x", sizeof("0x")) && (i = 0); i < string_length; i++){
snprintf(buf_tmp, sizeof("%x"), "%x", SourceString[i]);
strcat(ResultBuffer, buf_tmp);
}
}

/* Функция word2ascii() конвертирует переданную ей строку в ascii вид, результат сохраняется в выделенной для этого
области памяти. Принимает 3 параметра: 1й - указатель на строку, которую нужно отконвертировать,
2й - указатель на область памяти, где будет храниться результат выполнения, 3й - длина исходной строки в символах (strlen()) */

void word2ascii(const char *SourceString, char *ResultBuffer, int string_length)
{
int i; // счётчик символов
char buf_tmp[5]; // буфер, хранящий текстовое значение hex-кода символа.

for (i = 0; i < string_length; i++){
if (i != (string_length - 1)){
if (SourceString[i] < 100){
snprintf(buf_tmp, sizeof("%2d,"), "%2d,", SourceString[i]);
strcat(ResultBuffer, buf_tmp);
}
else{
snprintf(buf_tmp, sizeof("%3d,"), "%3d,", SourceString[i]);
strcat(ResultBuffer, buf_tmp);
}
}
else{
if (SourceString[i] < 100){
snprintf(buf_tmp, sizeof("%2d"), "%2d", SourceString[i]);
strcat(ResultBuffer, buf_tmp);
}
else{
snprintf(buf_tmp, sizeof("%3d"), "%3d", SourceString[i]);
strcat(ResultBuffer, buf_tmp);
}
}
}
}

:)

L0rd_Ha0S
06.11.2007, 18:21
To [x26]VOLAND:
А Gui зделать никак?
Честно говоря, не думаю что ради вывода из трёх строчек стоит писать GUI, к тому же программа потеряет свою переносимость, и будет заточена именно под конкретную ОС. Этот исходник будет работать и на *nix, и на винде.
Это не релиз наикрутейшей проги, которой не хватает только gui. Я её писал в первую очередь для себя, чтобы избавить себя от гемора, а так как я пользуюсь только Линуксом, то мне было удобней сделать её именно в консольном варианте, ибо консоль у меня запущена всегда. Если у меня будет время, я подумаю над тем, как примотать к нему GUI, а пока я могу предложить сделать это тебе. ;)

guest3297
06.11.2007, 21:41
Очень слабо...

L0rd_Ha0S
08.11.2007, 01:20
Написал новую версию. Все переписано по-новому. Теперь функции сохраняют результат в памяти, а не выводят его на stdout, так что при желании гуи прикрутить не составит большого труда (кому надо). В первом посте обновил исходник на вторую версию. При компиляции под виндой, не забудьте раскомментировать строку
#include <malloc.h>Работоспособность проверена на Linux, FreeBSD(tnx Alexsize), Windows(Vista, на остальных значит тоже будет работать)

P.S. Просьба к людям более опытным чем я - посмотрите исходник (вторую версию), мож найдете какие ошибки, может что-то можно сделать проще чем у меня. Всё-таки опыта у меня пока не так много, так что буду благодарен за любые замечания.

Обе версии лежат здесь:
http://lanham.nm.ru/sources/

KEZ
08.11.2007, 02:04
ОНА ЧТО, НЕ НА ДЕЛФИ??? :eek: :eek: :eek: :eek: :eek: :eek: :eek: :eek: :eek: :eek:

L0rd_Ha0S
08.11.2007, 03:07
ОНА ЧТО, НЕ НА ДЕЛФИ??? :eek: :eek: :eek: :eek: :eek: :eek: :eek: :eek: :eek: :eek:
Как видишь =)

guest3297
08.11.2007, 16:18
Скомпилил под Вистой с через lcc, всё работает на ура.
Крут парень. Главно что под вистой =)

__mad
08.11.2007, 18:38
тоже самое только чутка покороче)
#include <stdio.h>

int main(int argc,char**argv)
{
if (argc != 2){printf("%s <string>\n",argv[0]);return(1);}
for(printf("Source -> %s\n",argv[1]),printf("Hex -> 0x"),argv[0]=argv[1];*argv[1];*argv[1]++)
printf("%x",*argv[1]);
for(printf("\nAsci -> Char(%d",*argv[0]),*argv[0]++;*argv[0];*argv[0]++)
printf(",%d",*argv[0]);
return(printf(");\n"));
}

Shred
08.11.2007, 18:55
эх и я тада влеплю свои 5 коп на асп дот нет :)
в TextBox3 - вписываем строку
в TextBox4 - выводица код типа char(116,101,115,116)

сорц обработки бутона

TextBox4.Text = "";
string sin2 = TextBox3.Text;
string temp = "";
for (int i = 0; i < sin2.Length; i++)
temp += String.Format("{0:d},", (int)sin2[i]);
if (temp == "") return;
temp = temp.Remove(temp.Length - 1);
TextBox4.Text = "char(" + temp + ")";

всё это щастье вист тута :)
http://shred-11.iis7.parking.ru

KEZ
08.11.2007, 20:51
char *buffer;
//...
memset(buffer, 0, sizeof(buffer)); // заполняем нашу память нулями


Чел? А ты в курсе, что sizeof(char*) == 4. или 8 на 64-битных пл-х. но никак не количеству байт, которые ты передавал malloc'у.
Я просто не понимаю, если ты основ С не знаешь, то почему бы не писать на делфи?

Forcer
08.11.2007, 22:04
if (argc < 2) // Проверка параметров
usage(argv[0]);

const char *SqlString = argv[1]; // сохраняем исходную строку в SqlString
const int SqlStringLength = strlen(SqlString); // вычисляем длину переданной строки
char *buffer; // будет хранить указатель на нашу память

в Си объявление переменных должно находиться до любого выполняемого кода.

__mad
08.11.2007, 22:21
а что будет если после?:d

Forcer
08.11.2007, 22:28
__mad
А ты типа не знаешь? :-) В зависимости от компилятора. VS2005 гневно ругается, например, и отказывается компилировать.

__mad
08.11.2007, 22:58
что то я отсал от жизни :)
я пользуюсь gcc , там всё норм)
а vc6 незамечал такого...)

KEZ
08.11.2007, 23:07
Чего ты не замечал? Он про C говорит, а не про С++.
Ни один C-компилятор не допускает обьявлений после кода.

__mad
08.11.2007, 23:12
ну так и я про C, а не про С++ в gcc без проблем компилится : D даж предупреждений нету...
зы gcc расшифровывается не C++ : D а GNU project C and C++ compiler ;)

DWORD
08.11.2007, 23:13
Чего ты не замечал? Он про C говорит, а не про С++.
Ни один C-компилятор не допускает обьявлений после кода.
gcc это компилятор С. Он допускает, подтверждаю. КЕЗ, почему ты так категоричен?

KEZ
08.11.2007, 23:36
GCC значит это позволяет. Но по стандарту C все обьявления должны быть сделаны ДО первого оператора. Боюсь сейчас сильно напиздить. Во всяком случае, для C это стандарт _оформления_. Как найду ISO стандарты - отпишу. Меня шокировало если честно, что gcc это допускает.

DWORD
08.11.2007, 23:40
КЕЗ, честно говоря я тоже всегда так думал (про стандарт). Но на форуме (по-моему васм.ру) недавно прочитал про то, что есть какие-то поправки, и, согласно новому стандарту, переменные можно объявлять в теле функции.

L0rd_Ha0S
09.11.2007, 03:32
:eek: :eek: :eek: :eek: Думал сюда никто не заходит, а тут вон сколько понаписали....
тоже самое только чутка покороче)
только что - покороче :)

char *buffer;
//...
memset(buffer, 0, sizeof(buffer)); // заполняем нашу память нулями

Чел? А ты в курсе, что sizeof(char*) == 4. или 8 на 64-битных пл-х. но никак не количеству байт, которые ты передавал malloc'у.

o_O Да, как-то не задумывался над этим, спасибо. Поправлю сейчас.
Я просто не понимаю, если ты основ С не знаешь, то почему бы не писать на делфи?
Я ведь написал, что опыта у меня МАЛО! Основы в голову сразу не ложатся, понимание приходит со временем. Не будь таким критичным, на ошибках учатся. Теперь я буду делать одной ошибкой меньше. А на счёт делфи... Делфи под Линуксом... Как-то нет желания.

в Си объявление переменных должно находиться до любого выполняемого кода.

Это правило хорошего тона - объявлять все переменные вначале программы. Переменная может быть объявлена в любом месте программы до её непосредственного использования. У меня все переменные объявлены ДО их непосредственного использования. Я намерено их объявил после проверки параметров. Зачем мне их объявлять перед функцией usage()? Ни одна из этих переменных ей не используется. usage() завершит выполнение программы если нет параметров, если же они есть, выполнение продолжится. Только в случае, если параметры заданы имеет смысл объявлять эти переменные.

Кстати, gcc не позволяет делать объявления после кода.
#include <stdio.h>

int main(){

char* buffer = "Hello, World!\n";
printf("%s", buffer);

return 0;
}
haos@localhost(01:33:40)~/Projects/test $ gcc -o test test.c
haos@localhost(01:35:42)~/Projects/test $ ./test
Hello, World!
haos@localhost(01:35:44)~/Projects/test $
#include <stdio.h>

int main(){

printf("%s", buffer);
char* buffer = "Hello, World!\n";

return 0;
}
haos@localhost(01:36:50)~/Projects/test $ gcc -o test test.c
test.c: In function ‘main’:
test.c:5: error: ‘buffer’ undeclared (first use in this function)
test.c:5: error: (Each undeclared identifier is reported only once
test.c:5: error: for each function it appears in.)
haos@localhost(01:37:07)~/Projects/test $

Forcer
09.11.2007, 12:13
Должен признать, я был не прав. Смотрим: http://ru.wikipedia.org/wiki/Си_(язык_программирования) . Читаем про С99.
отсутствие ограничений на объявление локальных переменных (как и в С++);
несколько новых библиотечных функций, таких как snprintf;
Интерес к поддержке новых особенностей С99 в настоящее время смешан. В то время как GCC и некоторые другие компиляторы в настоящее время поддерживают большую часть новых особенностей С99, компиляторы компаний Borland и Microsoft не делают этого, причём похоже, что две эти компании и не думают их добавлять.

Вообщем вот. Соответственно VS2005, которой я пользуюсь, ничего из этого и не поддерживает. Будем надеяться что в 2008-й внесены изменения :-)

KEZ
09.11.2007, 12:18
#include <stdio.h>

int main(){

printf("%s", buffer);
char* buffer = "Hello, World!\n";

return 0;
}


мда, ну что ещё сказать. но все-таки скажу. речь идет об объявлении переменных
до ПЕРВОГО ЛЮБОГО выполненого оператора, а не объявлении переменных до оператора, их ИСПОЛЬЗУЮЩЕГО. второй случай - вообще некорректен вообще для всех языков.


Это правило хорошего тона - объявлять все переменные вначале программы. Переменная может быть объявлена в любом месте программы до её непосредственного использования.

Это обязательное правило С, во всяком случае его первого стандарта. Только не программы, а ф-ии. А в любом месте она может быть объявлена в С++.
У каждого правила "хорошего тона" есть объяснение, почему оно хорошее, а другое не хорошее. Какое объяснение у этого "правила" ? Я не вижу ничего удобного или эффективного в том, что бы нелогично намешать все обьявления в начале, особенно, если у тебя сотни переменных, а после этого будет стоять сразу же if (!param) return;.

и ещё, советую юзать g++ а не gcc

Forcer, а ты используй MinGW

L0rd_Ha0S
10.11.2007, 03:33
и ещё, советую юзать g++, а не gcc
Можно узнать - почему именно g++? Чем он лучше gcc?

KEZ
10.11.2007, 06:08
Потому что на некоторых системах (наверное старые версии) gcc не понимает .cpp и компилирует их как .c - код.
Поэтому проще сразу g++ использовать, что бы не было проблем.

L0rd_Ha0S
10.11.2007, 23:12
gcc по умолчанию не подключает стандартную библиотеку C++.
Во всяком случае старые версии. Так попробуй:
gcc -o test test.cpp -lstdc++
кстати, у gcc получается меньший размер бинарника.