文章首发于先知社区一次.Net代码审计

0x01目录架构

Global.asax用于处理应用程序级别的事件,例如应用程序启动(Application_Start)、会话启动(Session_Start)、应用程序错误(Application_Error)等。

Web.config这是 ASP.NET 应用程序的主要配置文件,用于定义应用程序的配置设置,例如数据库连接字符串、身份验证方式、自定义错误页面等。

bin文件夹放置了编译好的Dll文件,是后端服务接口代码的存放位置

image-20240629094146602

0x02审计

SQL盲注——GetByName方法

Login.aspx是管理后台进行登陆的代码文件,对应GBLab.Web.dllLogin方法

image-20240629094811984

image-20240629094857197

将该GBLab.Web.dll文件放入ILSpy中反编译

image-20240629095137582

在登陆时候传入的username参数以及password参数分别是txtUserNametxtPassword

image-20240629095626759

通读一下方法代码,GetByName的作用大概是进行数据库查询判断有没有这个username,看看有没有过滤'"这些符号吧

Trim函数代码

public string Trim()
{
return TrimHelper(2);
}

TrimHelper函数代码

private string TrimHelper(int trimType)
{
int num = Length - 1;
int i = 0;
if (trimType != 1)
{
for (i = 0; i < Length && (char.IsWhiteSpace(this[i]) || IsBOMWhitespace(this[i])); i++)
{
}
}
if (trimType != 0)
{
num = Length - 1;
while (num >= i && (char.IsWhiteSpace(this[num]) || IsBOMWhitespace(this[i])))
{
num--;
}
}
return CreateTrimmedString(i, num);
}

这些代码并没有修改参数值,当trimType不等零时,进行num自减,它的意思应该是要去掉字符串后方的空白字符以及Bom空白字符,那怎么能过滤恶意的Sql参数呢?

根据GetByname函数,其会进行SQL语句的拼接,后会通过FindAll进行SQL语句的执行

public static T_User GetByName(string username)
{
EntityList<T_User> entityList = Entity<T_User>.FindAll("select * from T_User where F_Account='" + username.DefaultIsNullOrEmpty("") + "'");
if (entityList.Count == 0)
{
return null;
}
return entityList[0];
}

总结一下,GetByName进行SQL语句的查询,将查询的数据赋给byName,但是这个登陆功能点不会直接给我们回复(只有登录成功或失败),就是一个盲注注入点

Burp进行推叠时间盲注测试

admin';WAITFOR DELAY '00:00:10';--/**/

image-20240629104806244

这个功能点测试完了拥有SQL盲注,登陆进去之后会请求/Manage/Index接口,要看这个接口的代码逻辑还是需要寻找路由

image-20240630164529816

Asp.net程序中,拥有区域路由配置以及全局路由配置,区域路由配置允许为应用程序的不同部分定义独立的路由规则

Asp.net应用程序中Global.asax文件是Asp.net程序的入口点,通过它可以找到路由配置

image-20240630164708713

image-20240630165623368

全局路由代码,将接口{controller}/{action}/{id}映射到相应的控制器和动作方法

routes.MapRoute("Default", "{controller}/{action}/{id}", new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
}

GBLab.Web.dll文件中发现区域路由代码,管理Manage接口

image-20240630171820326

登陆之后的/Manage/Index接口逻辑由GBLab.Web.Areas.Manage.Views.dllIndexController类的Index方法定义

image-20240630172134791

T_User类两个方法,一个没有引入参数,另一个带入的后端生成的SessionID,Sql注入无了

image-20240630233814455

现在看来T_User对于数据库的操作挺多的,那我们直接就在T_User类中查询select以及where等关键字,通过这种方式看看能不能找出其他Sql注入漏洞

通过select关键字查询出的第一个方法是GetByName方法,这个就是当时登陆时出现的SQL注入方法,这里我把反编译的C#代码保存到一个文件夹下了,使用notepad++全局查询发现在LoginUserController类中也使用了GetByName方法

image-20240701000013357

image-20240701000036071

这个功能点在页面超时时出现

image-20240701000202367

Burp测试一下payload(同上)

image-20240701000506988

继续查询select关键字,看下一个方法

SQL注入——ConfirmName方法

下一组方法是ConfirmName,直接拼接sql语句

image-20240701001124302

全局搜索T_User.ConfirmName,发现两个方法均在Action_Edit_Add方法中调用,只不过一个是添加用户,一个是编辑用户

image-20240701001209186

image-20240701001232449

方法引用的参数只被DefaultIsNullOrEmpty处理了一下

image-20240701001440187

添加用户,Burp截包

image-20240701003844315

image-20240701003945434

可测试后发现这个接口代码编译的有些问题,正常传参都会提示错误

image-20240701004725625

测试编辑用户功能点吧

image-20240701005014959

image-20240701005519043

根据select关键字查询发现下一个方法是ConfirmName_ClassId,但是这个方法没有其他方法的调用

image-20240704093714330

GetItemList方法没有将参数带入sql语句中

image-20240705102329055

接下来两个函数都做了参数类型限制,int类型参数

image-20240705102615515

SQL注入——GetPager方法

然后寻找了Where关键字发现了GetPager函数,该函数接收strWhere,带入了SQL条件

image-20240705110554549

image-20240705110846420

看看谁调用了它吧

image-20240705111510593

image-20240705111544175

pager定义的类中,strWhere参数是string类型,貌似有戏

image-20240705111642336

修改请求包插入payload,获得sql注入一枚

image-20240705135800073

image-20240705135822345

然后在T_User类中发现了三个update语句,怀疑有Sql注入

image-20240705161349234

还是一样的套路,看看那个方法调用

image-20240705161600953

image-20240705161531267

乖乖,还是这个UserController

image-20240705161911845

可这个类方法没有获取前端传递的参数,没有其他方法的调用,算是一个废方法

看完了这个类,发现其实T_User.cs这个代码为UserController.cs这个代码类服务,而UserController.cs直接对应前端,构成后端服务接口类,用来处理用户操作

可还有部门操作,角色操作等类,这些类中每个方法的代码逻辑基本上是一样的,例如ConfirmName在每个Controller类都出现了,并且也定义了很多次

image-20240705163753039

image-20240705164018869

每个定义的方法也就改了改表名,该有sql注入的逻辑代码同样在其他方法类中出现

image-20240705164127332

image-20240705164140182

其他Controller类的sql注入原理也是这样,我在这里就不复现了,找找其他漏洞吧

文件上传漏洞

还记得文章初始时显示得目录架构吗?最令我关注得只有一个代码文件!那就是关于文件上传的UploadNewHandler.ashx

image-20240705165114988

代码文件指向JQueryUploadDemoUploadNewHandler方法

image-20240705165218388

UploadNewHandler方法通过GetFiletypeName定义文件后缀名

image-20240705170740003

ILSpy中查看一下GetFiletypeName函数,这个方法获取两个参数,第一个参数是HttpPostedFile.FileName获取的文件名,第二个参数.jpg

image-20240708142635893

那就是妥妥的文件上传漏洞,没有任何限制

传个一句话木马

image-20240708143746114

哥斯拉连接成功

image-20240708143913594