原理
根据微软文档,.suo是CompoundFile类文件,在打开.suo文件时会调用VS Package上的LoadUserOptions方法,使用Structured Storage Viewer打开攻击者制作的恶意.suio可以找到如下,很容易看出里面有一段序列化数据
根据文章披露的Microsoft.Visual.dll,在其内找到如下代码,即在OnLoadOptions方法中会调用VsToolboxService.LoadOptions并把数据作为stream参数传进去
// Microsoft.VisualStudio.VSCorePackage
// Token: 0x06000108 RID: 264 RVA: 0x00003C5C File Offset: 0x00001E5C
protected override void OnLoadOptions(string name, Stream stream)
{
if (name.Equals(typeof(VsToolboxService).Name))
{
VsToolboxService vsToolboxService = this.GetService(typeof(IToolboxService)) as VsToolboxService;
if (vsToolboxService != null)
{
vsToolboxService.LoadOptions(stream);
}
}
}
// Microsoft.VisualStudio.Toolbox.VsToolboxService
// Token: 0x06000289 RID: 649 RVA: 0x0000B23C File Offset: 0x0000943C
internal void LoadOptions(Stream stream)
{
BinaryReader binaryReader = new BinaryReader(stream);
BinaryFormatter binaryFormatter = new BinaryFormatter();
int num = binaryReader.ReadInt32();
for (int i = 0; i < num; i++)
{
string category = binaryReader.ReadString();
int num2 = binaryReader.ReadInt32();
for (int j = 0; j < num2; j++)
{
string text = this.Links.Read(stream);
VsToolboxService.ToolboxItemContainer toolboxItemContainer = (VsToolboxService.ToolboxItemContainer)binaryFormatter.Deserialize(stream);
if (text != null && File.Exists(text))
{
toolboxItemContainer.LinkFile = text;
this.Links.TrackLink(text);
this.Items.GetFilteredList(category).Add(toolboxItemContainer);
}
}
}
}
很容易看出里面通过binaryFormatter.Deserialize直接反序列化了相关数据,这就是很经典的反序列化执行代码。
如何制作恶意.suo
在Microsoft.VisualStudio.VSCorePackage类中存在OnSaveOptions,调用SaveOptions保存序列化数据,而CompoundFile可以通过OpenMCDF处理,或者直接把现有的.suo里面的序列化数据进行替换也可。
protectedoverridevoidOnSaveOptions(string name, Stream stream)
{
if (name.Equals(typeof(VsToolboxService).Name))
{
VsToolboxService vsToolboxService = this.GetService(typeof(IToolboxService)) as VsToolboxService;
if (vsToolboxService != null)
{
vsToolboxService.SaveOptions(stream);
}
}
}
internalvoidSaveOptions(Stream stream)
{
try
{
IEnumToolboxTabs enumToolboxTabs = null;
long position = stream.Position;
int num = 0;
int num2 = 0;
IVsToolbox vsToolbox = this.VsToolbox;
if (vsToolbox != null)
{
BinaryWriter binaryWriter = new BinaryWriter(stream);
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryWriter.Write(0);
string[] array = newstring[1];
if (this._links != null && this._links.ContainsLinks)
{
NativeMethods.ThrowOnFailure(vsToolbox.EnumTabs(ref enumToolboxTabs));
try
{
uint num3;
NativeMethods.ThrowOnFailure(enumToolboxTabs.Next(1U, array, ref num3));
long position3;
while (num3 == 1U)
{
string text = array[0];
num++;
binaryWriter.Write(text);
IEnumToolboxItems enumToolboxItems;
NativeMethods.ThrowOnFailure(vsToolbox.EnumItems(text, ref enumToolboxItems));
long position2 = stream.Position;
binaryWriter.Write(0);
try
{
IDataObject[] array2 = new IDataObject[1];
uint num4;
NativeMethods.ThrowOnFailure(enumToolboxItems.Next(1U, array2, ref num4));
while (num4 == 1U)
{
IDataObject dataObject = array2[0];
VsToolboxService.ToolboxDataObject toolboxDataObject = dataObject as VsToolboxService.ToolboxDataObject;
if (toolboxDataObject != null)
{
VsToolboxService.ToolboxItemContainer toolboxItemContainer = toolboxDataObject.ToolboxItemContainer;
string linkFile = toolboxItemContainer.LinkFile;
if (linkFile != null && this.Links.Write(linkFile, stream))
{
binaryFormatter.Serialize(stream, toolboxItemContainer);
num2++;
}
}
num4 = 0U;
NativeMethods.ThrowOnFailure(enumToolboxItems.Next(1U, array2, ref num4));
}
position3 = stream.Position;
stream.Position = position2;
binaryWriter.Write(num2);
num2 = 0;
stream.Position = position3;
}
catch
{
}
enumToolboxItems = null;
num3 = 0U;
NativeMethods.ThrowOnFailure(enumToolboxTabs.Next(1U, array, ref num3));
}
position3 = stream.Position;
stream.Position = position;
binaryWriter.Write(num);
stream.Position = position3;
}
catch
{
}
}
binaryWriter.Flush();
}
}
catch
{
}
}
其他
本文无意对APT样本进行分析,dump出样本,需要的可在https://github.com/Chestnuts4/APT_simple/blob/main/Ocean_Lotus/mal.dll下载
参考
sln任意代码执行的几种方式(evilsln)# Solution User Options (.suo) FileEvilSln
原文始发于微信公众号(闲聊趣说):如何进行suo投毒
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论