审计方式是黑盒+白盒的方式
这个注入是黑盒也能挖出来的
点开这里是发现没有内容可选择的,一开始还以为是系统有问题,输入用户名(用户名最多只能输入4个字符),发现burp里面出现一条数据包
这条数据包感觉是在判断该用户名是否存在,因为用户名的表单最多只能输入4个字符,所以这是决定跑一下四位数字
跑出两个用户名,来到浏览器输入用户名
发现刚刚没有内容的表单此时自己有了内容,根据数据包路径(/Home/UserDepartment?username=8888)找到代码,使用Visual Studio打开,前台的代码位于Controllers\HomeController.cs
找到UserDepartment方法
根据代码里的注释其实已经很明了了,方法是使用 HTTP GET 方法来获取用户部门信息,并返回 JSON 格式的数据。不过还调用了Account.UserDepartment(),要继续跟进去的,需要反编译dll
使用Dnspy打开bin目录下对应的dll,反编译后找到UserDepartment方法
代码解释
通过 [HttpGet] 标记指定该方法用于处理 GET 请求。
用户部门获取:调用 Account.UserDepartment(username) 方法,传入用户名 username 作为参数,该方法返回用户的部门信息。
使用 Json 方法将部门信息以 JSON 格式返回,并指定允许 GET 请求访问该结果。
跟进Account.UserDepartment() 方法
代码创建了一个User类的实例对象user,再调用user 类的GetUserKeShi()方法,传入username参数后返回List对象,继续跟user.GetUserKeShi()方法
代码大概意思就是
创建了一个 Msg 类的实例对象 msg,用于存储方法执行的结果和消息。构建一个 SQL 查询语句,通过连接 x_keshi 表和 x_yonghukeshi 表,根据 yonghuid 字段与传入的 userid 进行匹配筛选用户所属的部门信息。
创建一个 MobileDataEntityDAL 类的实例对象 mobileDataEntityDAL,用于操作数据库并将查询结果转换为 X_keshi 对象。
使用 DBHelper.SqlHelper 方法执行 SQL 查询语句,将查询结果存储在 DataSet 对象 dataSet 中。同时,将数据库连接字符串指定为 MobileDataBaseLink.Mobile,传入 msg 对象以获取执行结果和错误消息,并使用 CommandType.Text 指定查询类型为文本。
创建一个 List 对象 list,用于存储查询结果的部门信息
可以看到值传进GetUserKeShi()方法之后,未做任何过滤就拼接到SQL语句中执行了
最开始的UserDepartment()方法通过GET方法接受到username之后也未做任何过滤,所以此处是存在SQL注入的
数据库为Oracle
成功执行延时语句
Sqlmap直接跑也是可以的
这个注入是通过审计发现的,因为上面发现GetUserKeShi()方法存在注入,此处全局搜索GetUserKeShi()方法
发现 Controllers\HomeController.cs里还有一处,直接利用即可
/home/UserModules?username=
这里本来是想看看有没有绕过的漏洞,结果发现通过login()方法一直跟
通过 [HttpPost] 标记指定该方法用于处理 POST 请求。
调用 Account.Login(username, password, department, "") 方法,传入用户名、密码、部门和空字符串作为参数进行用户登录验证。该方法返回一个 Msg 对象,用于表示登录结果。
将登录结果的 Result 属性赋值给 result 变量,用来判断用户登录是否成功。
根据登录结果的 Result 值进行不同的处理。
如果登录成功,则判断是否提供了 area 参数。如果有,则在原来的 area 值后添加斜杠,然后重定向到对应的页面(比如 "Home/Index")。
如果登录失败,则使用动态调用的方式设置 ErrorMessage 属性为登录结果的字符串描述,并返回视图。
最后,根据处理结果返回对应的 ActionResult 对象。
-----继续跟进Account.Login()方法
该方法接受四个字符串类型的参数,分别是 username(用户名)、password(密码)、department(部门)和 yiyuanID(医院ID),其中 yiyuanID 参数有默认值空字符串。
首先创建一个 User 对象,并将其赋值给 user 变量。
调用 user.Login(username, password) 方法执行用户登录操作,并将返回的结果赋值给 msg 变量,msg 是一个 Msg 对象。
从 msg 对象的 Result 属性获取登录结果(布尔值),并将其赋值给 result 变量。
处理登录成功的情况:
如果登录成功,则将 msg 对象的 MsgObjectContent 属性转换为 Res_Login 类型的对象,并将其赋值给 loginInfo 变量。
判断 department 是否为空或空字符串,如果是,则使用 loginInfo.Depid 作为默认部门。
根据部门ID查找对应的部门信息,将结果赋值给 entity 变量。
如果找不到对应的部门信息,并且 department 不为 null,则设置 msg 对象的 Result 属性为 false,添加一条提示信息,并返回 msg 对象。
如果找到了部门信息,则继续执行后续步骤。
配置医院ID:判断 yiyuanID 是否为空或空字符串,如果是,则从配置文件中获取名为 "yiyuanid" 的设置值,并将其赋值给 yiyuanID 变量。
根据登录信息和部门信息创建一个 UserInfo 对象,并设置其属性值。
使用 SessionHelper.SetInfoCache(info) 方法将用户信息缓存。
使用 SessionHelper.SetUserToolCache(info) 方法将用户工具缓存。
返回 msg 对象。
-----继续跟进user.Login()方法
该方法接受两个字符串类型的参数,分别是 userid(用户ID)和 password(密码)。
首先创建一个空的 Msg 对象,并将其赋值给 msg 变量。
调用 ValidateUser(userid, password) 方法对用户进行验证,并将返回的结果赋值给 msg 对象。
从 msg 对象的 Result 属性获取验证结果(布尔值),并将其赋值给 result 变量。
处理验证成功的情况:
如果验证成功,则将 msg 对象的 MsgObjectContent 属性转换为 X_yonghu 类型的对象,并将其赋值给 yonghu 变量。
设置 msg 对象的 Result 属性为 true。
调用 InsertLoginLogin(yonghu) 方法插入登录日志,并将返回的结果赋值给 loginlog 变量。
调用 InitLoginInfo(yonghu, loginlog) 方法初始化登录信息,并将返回的结果赋值给 msg 对象的 MsgObjectContent 属性。
处理验证失败的情况:
如果验证失败,则将 msg 对象的 Result 属性设置为 false。
继续返回 msg 对象。
-----继续跟进ValidateUser()方法
跟到最后发现代码中直接将比较的密码值硬编码在代码中,好开发^0^
使用前期收集到的账号可直接用该密码登陆
因为前期发现账号限制最长为4位,所以想收集账号即使并不难,而且也没有验证码做限制
.net语言找上传点,可以全局搜索关键函数SaveAs()
通过搜索发现有5处
打开\Areas\BackStage\Controllers\ArtConfigController.cs
上传文件使用的是UploadImage()方法
找到对应的dll进行反编译
发现代码是没有做任何过滤的
通过Directory.Exists方法检查指定的路径是否存在。如果路径不存在,则通过Directory.CreateDirectory方法创建该路径。
使用base.Request.Files.Count检查是否有文件被上传。如果有文件被上传,则获取上传的文件对象,并将其转换为Image对象。
通过ImageConvert.MakeThumbnail方法,将图像进行缩略处理。
根据用户提供的name参数判断是否为空或null,如果为空,则生成一个唯一的文件名,以GUID和原始文件的扩展名组合而成;如果不为空,则直接使用用户提供的文件名作为保存的文件名。
使用img.Save方法将处理后的图像保存到指定的路径下,路径由Path.Combine方法组合而成。
最后,通过Json方法将保存的文件名以JSON格式返回,并指定允许GET请求访问该结果。
根据文件路径,找到对应页面
因为存在该漏洞的代码文件并不是编辑器目录下,所以选择下面上传功能
看路径可以确定是我们刚刚打开的文件\Areas\BackStage\Controllers\ArtConfigController.cs里面UploadImage()方法
直接上传即可
经过测试还有其余四个点均可直接上传
感觉这套源码其实是挺老的,感觉应该还是有其它漏洞,但是水平有限,只能找到这些漏洞,虽然上传点都在后台,不过配合前台的注入和逻辑漏洞组合拳,杀伤力应该还是有的。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!