金和OA SignUpload SQL注入分析
字数 1207 2025-08-22 22:47:30
金和OA SignUpload SQL注入漏洞分析与教学文档
1. 漏洞概述
金和OA系统中的SignUpload.ashx接口存在SQL注入漏洞,攻击者可通过构造恶意请求利用该漏洞执行任意SQL语句,可能导致数据库信息泄露、数据篡改等安全风险。
2. 资产识别
FOFA搜索语法:
body="JHSoft.Web.AddMenu" || app="金和网络-金和OA" || app="Jinher-OA"
3. 漏洞分析
3.1 漏洞入口
漏洞位于JHSoft.Web.Ask命名空间下的SignUpload类中的ProcessRequest方法。
3.2 关键代码分析
3.2.1 ProcessRequest方法
// 检查token和filename参数是否为空
if (!string.IsNullOrEmpty(context.Request.QueryString["token"])
&& !string.IsNullOrEmpty(context.Request.QueryString["filename"]))
{
// 获取token和filename参数
string _token = context.Request.QueryString["token"];
string _fileName = context.Request.QueryString["filename"];
// 分割token
string[] array = _token.Split(new char[] { '_' });
if (array.Length > 1)
{
string text2 = array[0]; // 可控参数
string value = array[1];
// 调用getDocInfo方法,text2直接拼接到SQL语句中
DataTable docInfo = this.getDocInfo(text2);
// ...后续处理...
}
}
3.2.2 getDocInfo方法
private DataTable getDocInfo(string AskID)
{
StringBuilder stringBuilder = new StringBuilder();
// 直接拼接AskID参数到SQL语句中,形成SQL注入漏洞
stringBuilder.Append("SELECT * FROM Ask_Doc WHERE AskID='" + AskID + "'");
// 获取数据库操作对象
IDBOperator idboperator = DBOperatorFactory.GetDBOperator();
// 执行SQL语句
return idboperator.ExecSQLReDataTable(stringBuilder.ToString());
}
3.3 SQL执行流程
getDocInfo方法构造SQL语句- 通过
DBOperatorFactory.GetDBOperator()获取数据库操作对象 - 调用
ExecSQLReDataTable方法执行SQL ExecSQLReDataTable方法设置回调函数并调用ExecSQLExecSQL方法根据是否在事务中调用ExecSQLInTrans或ExecSQLNotInTrans- 最终通过
SqlDataAdapter.Fill方法执行SQL查询
3.4 关键问题
- 参数未过滤:
AskID参数直接拼接到SQL语句中,未进行任何过滤或参数化处理 - 无权限验证:在执行SQL前未对用户权限进行充分验证
- 错误处理不当:可能暴露数据库错误信息
4. 漏洞利用
4.1 漏洞验证POC
GET /C6/Jhsoft.Web.ask/SignUpload.ashx?token=1%3BWAITFOR+DELAY+%270%3A0%3A%201%27+--%20and%201=1_123_123&filename=1
4.2 利用方式
- 时间盲注:通过
WAITFOR DELAY判断注入是否成功 - 联合查询:获取数据库信息
- 数据提取:通过错误回显或时间差获取敏感数据
5. 修复建议
5.1 临时解决方案
- 对
SignUpload.ashx接口进行访问限制 - 在Web应用防火墙(WAF)中添加规则拦截恶意请求
5.2 彻底修复方案
- 参数化查询:修改
getDocInfo方法,使用参数化查询
private DataTable getDocInfo(string AskID)
{
string sql = "SELECT * FROM Ask_Doc WHERE AskID=@AskID";
SqlParameter[] parameters = {
new SqlParameter("@AskID", SqlDbType.VarChar) { Value = AskID }
};
IDBOperator idboperator = DBOperatorFactory.GetDBOperator();
return idboperator.ExecSQLReDataTable(sql, parameters);
}
- 输入验证:对
token参数进行严格验证 - 最小权限原则:数据库连接使用最小必要权限账户
- 错误处理:避免将数据库错误信息返回给客户端
6. 深入理解
6.1 漏洞成因
该漏洞是典型的"拼接SQL"导致的注入漏洞,根本原因是开发人员未遵循安全编码规范,直接将用户可控参数拼接到SQL语句中。
6.2 调用链分析
ProcessRequest (获取参数)
→ getDocInfo (拼接SQL)
→ DBOperatorFactory.GetDBOperator (获取数据库操作对象)
→ ExecSQLReDataTable (执行SQL)
→ ExecSQL (执行命令)
→ SqlDataAdapter.Fill (填充数据)
→ ExecuteReader (执行查询)
6.3 防御思路
- 白名单验证:对输入参数进行严格格式验证
- ORM框架:使用Entity Framework等ORM框架避免SQL拼接
- 存储过程:使用存储过程并参数化调用
- 安全审计:定期进行代码安全审计和渗透测试
7. 总结
金和OA SignUpload SQL注入漏洞是一个典型的一阶SQL注入漏洞,由于缺乏输入验证和参数化查询导致。开发人员应始终遵循安全编码规范,对所有用户输入进行严格验证,并使用参数化查询来防止SQL注入攻击。