164 lines
3.9 KiB
C
164 lines
3.9 KiB
C
/**
|
|
* Copyright 2012, 2013 Nick Galbreath
|
|
* nickg@client9.com
|
|
* BSD License -- see COPYING.txt for details
|
|
*
|
|
* This is for testing against files in ../data/ *.txt
|
|
* Reads from stdin or a list of files, and emits if a line
|
|
* is a SQLi attack or not, and does basic statistics
|
|
*
|
|
*/
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
#include "libinjection.h"
|
|
#include "libinjection_sqli.h"
|
|
|
|
void print_string(stoken_t* t);
|
|
void print_var(stoken_t* t);
|
|
void print_token(stoken_t *t);
|
|
|
|
void print_string(stoken_t* t)
|
|
{
|
|
/* print opening quote */
|
|
if (t->str_open != '\0') {
|
|
printf("%c", t->str_open);
|
|
}
|
|
|
|
/* print content */
|
|
printf("%s", t->val);
|
|
|
|
/* print closing quote */
|
|
if (t->str_close != '\0') {
|
|
printf("%c", t->str_close);
|
|
}
|
|
}
|
|
|
|
void print_var(stoken_t* t)
|
|
{
|
|
if (t->count >= 1) {
|
|
printf("%c", '@');
|
|
}
|
|
if (t->count == 2) {
|
|
printf("%c", '@');
|
|
}
|
|
print_string(t);
|
|
}
|
|
|
|
void print_token(stoken_t *t) {
|
|
printf("%c ", t->type);
|
|
switch (t->type) {
|
|
case 's':
|
|
print_string(t);
|
|
break;
|
|
case 'v':
|
|
print_var(t);
|
|
break;
|
|
default:
|
|
printf("%s", t->val);
|
|
}
|
|
printf("%s", "\n");
|
|
}
|
|
|
|
void usage() {
|
|
printf("\n");
|
|
printf("libinjection sqli tester\n");
|
|
printf("\n");
|
|
printf(" -ca parse as ANSI SQL\n");
|
|
printf(" -cm parse as MySQL SQL\n");
|
|
printf(" -q0 parse as is\n");
|
|
printf(" -q1 parse in single-quote mode\n");
|
|
printf(" -q2 parse in doiuble-quote mode\n");
|
|
printf("\n");
|
|
printf(" -f --fold fold results\n");
|
|
printf("\n");
|
|
printf(" -d --detect detect SQLI. empty reply = not detected\n");
|
|
printf("\n");
|
|
}
|
|
|
|
int main(int argc, const char* argv[])
|
|
{
|
|
size_t slen;
|
|
char* copy;
|
|
|
|
int flags = 0;
|
|
int fold = 0;
|
|
int detect = 0;
|
|
|
|
int i;
|
|
int count;
|
|
int offset = 1;
|
|
int issqli;
|
|
|
|
sfilter sf;
|
|
|
|
if (argc < 2) {
|
|
usage();
|
|
return 1;
|
|
}
|
|
while (1) {
|
|
if (strcmp(argv[offset], "-h") == 0 || strcmp(argv[offset], "-?") == 0 || strcmp(argv[offset], "--help") == 0) {
|
|
usage();
|
|
return 1;
|
|
}
|
|
if (strcmp(argv[offset], "-m") == 0) {
|
|
flags |= FLAG_SQL_MYSQL;
|
|
offset += 1;
|
|
}
|
|
else if (strcmp(argv[offset], "-f") == 0 || strcmp(argv[offset], "--fold") == 0) {
|
|
fold = 1;
|
|
offset += 1;
|
|
} else if (strcmp(argv[offset], "-d") == 0 || strcmp(argv[offset], "--detect") == 0) {
|
|
detect = 1;
|
|
offset += 1;
|
|
} else if (strcmp(argv[offset], "-ca") == 0) {
|
|
flags |= FLAG_SQL_ANSI;
|
|
offset += 1;
|
|
} else if (strcmp(argv[offset], "-cm") == 0) {
|
|
flags |= FLAG_SQL_MYSQL;
|
|
offset += 1;
|
|
} else if (strcmp(argv[offset], "-q0") == 0) {
|
|
flags |= FLAG_QUOTE_NONE;
|
|
offset += 1;
|
|
} else if (strcmp(argv[offset], "-q1") == 0) {
|
|
flags |= FLAG_QUOTE_SINGLE;
|
|
offset += 1;
|
|
} else if (strcmp(argv[offset], "-q2") == 0) {
|
|
flags |= FLAG_QUOTE_DOUBLE;
|
|
offset += 1;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* ATTENTION: argv is a C-string, null terminated. We copy this
|
|
* to it's own location, WITHOUT null byte. This way, valgrind
|
|
* can see if we run past the buffer.
|
|
*/
|
|
|
|
slen = strlen(argv[offset]);
|
|
copy = (char* ) malloc(slen);
|
|
memcpy(copy, argv[offset], slen);
|
|
libinjection_sqli_init(&sf, copy, slen, flags);
|
|
|
|
if (detect == 1) {
|
|
issqli = libinjection_is_sqli(&sf);
|
|
if (issqli) {
|
|
printf("%s\n", sf.fingerprint);
|
|
}
|
|
} else if (fold == 1) {
|
|
count = libinjection_sqli_fold(&sf);
|
|
for (i = 0; i < count; ++i) {
|
|
print_token(&(sf.tokenvec[i]));
|
|
}
|
|
} else {
|
|
while (libinjection_sqli_tokenize(&sf)) {
|
|
print_token(sf.current);
|
|
}
|
|
}
|
|
|
|
free(copy);
|
|
|
|
return 0;
|
|
}
|