在当前 HTTPContext 中生成新的 ASP.NET 会话

2023-12-07

对我们正在开发的一些产品进行渗透测试的结果是,当时看似“容易”解决的问题却变得棘手。

当然不是应该的,我的意思是为什么会这样为当前生成一个全新的会话HTTPContext有那么难吗?奇怪!不管怎样——我写了一个厚颜无耻的小实用程序类来“就这么做”:

(对代码格式/突出显示/Visual Basic I 表示歉意must做错事了)


Imports System.Web
Imports System.Web.SessionState

Public Class SwitchSession

    Public Shared Sub SetNewSession(ByVal context As HttpContext)
        ' This value will hold the ID managers action to creating a response cookie
        Dim cookieAdded As Boolean
        ' We use the current session state as a template
        Dim state As HttpSessionState = context.Session
        ' We use the default ID manager to generate a new session id
        Dim idManager As New SessionIDManager()
        ' We also start with a new, fresh blank state item collection
        Dim items As New SessionStateItemCollection()
        ' Static objects are extracted from the current session context
        Dim staticObjects As HttpStaticObjectsCollection = _
            SessionStateUtility.GetSessionStaticObjects(context)
        ' We construct the replacement session for the current, some parameters are new, others are taken from previous session
        Dim replacement As New HttpSessionStateContainer( _
                 idManager.CreateSessionID(context), _
                 items, _
                 staticObjects, _
                 state.Timeout, _
                 True, _
                 state.CookieMode, _
                 state.Mode, _
                 state.IsReadOnly)
        ' Finally we strip the current session state from the current context
        SessionStateUtility.RemoveHttpSessionStateFromContext(context)
        ' Then we replace the assign the active session state using the replacement we just constructed
        SessionStateUtility.AddHttpSessionStateToContext(context, replacement)
        ' Make sure we clean out the responses of any other inteferring cookies
        idManager.RemoveSessionID(context)
        ' Save our new cookie session identifier to the response
        idManager.SaveSessionID(context, replacement.SessionID, False, cookieAdded)
    End Sub

End Class

它对于请求的其余部分工作良好,并正确地将自身标识为新会话(例如HTTPContext.Current.Session.SessionID返回新生成的会话标识符)。

令人惊讶的是,当下一个请求到达服务器时,HTTPContext.Session (an HTTPSessionState对象)用正确的方式标识自己SessionID,但是有IsNewSession set to True,并且为空,丢失前一个请求中设置的所有会话值。

所以前面一定有什么特别的地方HTTPSessionState从初始请求中删除的对象,这里的事件处理程序,那里的回调,处理跨请求保存会话数据的东西,或者只是我缺少的东西?

有人有什么魔法可以分享吗?


我想分享我的魔法。事实上,不,它还没有神奇。我们应该更多地测试和改进代码。 我只在 with-cookie、InProc 会话模式下测试了这些代码。将这些方法放入您的页面中,并在需要重新生成 ID 的位置调用它(请将您的 Web 应用程序设置为“完全信任”):

void regenerateId()
{
    System.Web.SessionState.SessionIDManager manager = new System.Web.SessionState.SessionIDManager();
    string oldId = manager.GetSessionID(Context);
    string newId = manager.CreateSessionID(Context);
    bool isAdd = false, isRedir = false;
    manager.SaveSessionID(Context, newId, out isRedir, out isAdd);
    HttpApplication ctx = (HttpApplication)HttpContext.Current.ApplicationInstance;
    HttpModuleCollection mods = ctx.Modules;
    System.Web.SessionState.SessionStateModule ssm = (SessionStateModule)mods.Get("Session");
    System.Reflection.FieldInfo[] fields = ssm.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
    SessionStateStoreProviderBase store = null;
    System.Reflection.FieldInfo rqIdField = null, rqLockIdField = null, rqStateNotFoundField = null;
    foreach (System.Reflection.FieldInfo field in fields)
    {
        if (field.Name.Equals("_store")) store = (SessionStateStoreProviderBase)field.GetValue(ssm);
        if (field.Name.Equals("_rqId")) rqIdField = field;
        if (field.Name.Equals("_rqLockId")) rqLockIdField = field;
        if (field.Name.Equals("_rqSessionStateNotFound")) rqStateNotFoundField = field;
    }
    object lockId = rqLockIdField.GetValue(ssm);
    if ((lockId != null) && (oldId !=null)) store.ReleaseItemExclusive(Context, oldId, lockId);
    rqStateNotFoundField.SetValue(ssm, true);
    rqIdField.SetValue(ssm, newId);
}

我一直在挖掘 .NET 源代码(可在http://referencesource.microsoft.com/netframework.aspx),并发现如果不破坏会话管理机制的内部结构,我就无法重新生成 SessionID。所以我就是这么做的 - 破解 SessionStateModule 内部字段,这样它将把当前的 Session 保存到一个新的 ID 中。也许当前的 HttpSessionState 对象仍然具有以前的 Id,但 AFAIK SessionStateModule 忽略了它。当它必须将状态保存在某处时,它只是使用内部 _rqId 字段。我尝试过其他方法,例如将 SessionStateModule 复制到具有重新生成 ID 功能的新类中(我计划用此类替换 SessionStateModule),但失败了,因为它当前引用了其他内部类(如 InProcSessionStateStore)。使用反射进行黑客攻击的缺点是我们需要将应用程序设置为“完全信任”。

哦,如果您确实需要 VB 版本,请尝试以下操作:

Sub RegenerateID()
    Dim manager
    Dim oldId As String
    Dim newId As String
    Dim isRedir As Boolean
    Dim isAdd As Boolean
    Dim ctx As HttpApplication
    Dim mods As HttpModuleCollection
    Dim ssm As System.Web.SessionState.SessionStateModule
    Dim fields() As System.Reflection.FieldInfo
    Dim rqIdField As System.Reflection.FieldInfo
    Dim rqLockIdField As System.Reflection.FieldInfo
    Dim rqStateNotFoundField As System.Reflection.FieldInfo
    Dim store As SessionStateStoreProviderBase
    Dim field As System.Reflection.FieldInfo
    Dim lockId
    manager = New System.Web.SessionState.SessionIDManager
    oldId = manager.GetSessionID(Context)
    newId = manager.CreateSessionID(Context)
    manager.SaveSessionID(Context, newId, isRedir, isAdd)
    ctx = HttpContext.Current.ApplicationInstance
    mods = ctx.Modules
    ssm = CType(mods.Get("Session"), System.Web.SessionState.SessionStateModule)
    fields = ssm.GetType.GetFields(System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance)
    store = Nothing : rqLockIdField = Nothing : rqIdField = Nothing : rqStateNotFoundField = Nothing
    For Each field In fields
        If (field.Name.Equals("_store")) Then store = CType(field.GetValue(ssm), SessionStateStoreProviderBase)
        If (field.Name.Equals("_rqId")) Then rqIdField = field
        If (field.Name.Equals("_rqLockId")) Then rqLockIdField = field
        If (field.Name.Equals("_rqSessionStateNotFound")) Then rqStateNotFoundField = field
    Next
    lockId = rqLockIdField.GetValue(ssm)
    If ((Not IsNothing(lockId)) And (Not IsNothing(oldId))) Then store.ReleaseItemExclusive(Context, oldId, lockId)
    rqStateNotFoundField.SetValue(ssm, True)
    rqIdField.SetValue(ssm, newId)

End Sub
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在当前 HTTPContext 中生成新的 ASP.NET 会话 的相关文章

随机推荐

  • .prev(选择器)不起作用

    这是问题所在 实时复制 CSS div border 1px solid black HTML div div br div div br div class test Should have a blue border div br di
  • 如何垂直移动JApplet内的图像?

    我已经在 J Applet 中显示了一个图像 球 现在我希望图像以垂直方式 上下 移动 问题是我不知道该怎么做 有人对这个问题有想法吗 您需要将该图像的位置设置为某个计算值 意味着您使用时间 速度和其他限制来计算垂直位置 如何设置该位置取决
  • Ljava.lang.Object;无法转换为 [Ljava.lang.Integer

    我编写了一个泛型类 下面是该类的构造函数 我想做这样的事情 如行中所写 elements E new Object size 因为我不知道运行时的泛型类型 所以它会抛出异常 public class Stack
  • (x==0) 能比 (0==x) 更有效吗? [复制]

    这个问题在这里已经有答案了 可能的重复 if flag 0 和 if 0 flag 哪个执行得更快 我通常将平等条件写为 if 0 x 正如很多人所做的那样 而不是 if x 0 这样当我不小心输入 而不是 时 编译器会告诉我 有人告诉我
  • 在 C# 中将字符串转换为位图

    我想将字符串转换为位图或可以在像素框中显示的内容 我的字符串看起来像这样 string rxstring 0100100100200200200300300300400400400500500500600600600700700700800
  • 递归调用函数以获取用户输入

    我正在尝试制作一个石头剪刀布游戏 并正在尝试验证输入 def player1 x raw input please select Rock r Paper p Scissors s lower if x r or x p or x s or
  • 将 HTML 片段附加到 Angular 6 中的视图

    我从对外部系统的http请求中获取了一段html代码 我应该在我的角度应用程序的视图中显示它 准确地说 这是我必须显示的 html 片段 每个请求和响应都会有点不同 div div 我使用不同的解决方案建议 例如innerHtml 但它们都
  • 当可变字段是等式的一部分时如何实现 IEquatable - GetHashCode 问题

    我在我的应用程序中使用实体框架 我用实体的部分类实现了IEquatable
  • 浮点比较特定

    我有一个关于浮点比较的具体问题 我知道由于精度问题 不建议使用 比较 但在这种特定情况下 我想知道在所有情况 编译器中 此语句是否都成立 float a 1 02f float b 1 02f if a b print true else
  • 如何忽略 xml 命名空间?

    我有一个测试 xml 文件 如下所示
  • 如何使用 PHP 将网页放入变量中

    我想从网上下载一个页面 当您使用像 Firefox 这样的简单浏览器时 这是允许的 但是当我使用 file get contents 时 服务器拒绝并回复说它理解该命令 但不允许此类下载 那么该怎么办 我想我在一些脚本 在 Perl 上 中
  • Java 中的 HashMap 实现。桶索引计算是如何进行的?

    我正在研究实施HashMap在Java中 我陷入了困境 怎么样indexFor函数计算 static int indexFor int h int length return h length 1 Thanks 哈希本身是通过以下方式计算的
  • 自定义 ArrayAdapter 上的可点击行

    我为 ListView 制作了一个自定义 ArrayAdapter 以便使用某些元素自定义列表的行 我遇到的问题是我无法选择一个项目 单击时没有任何反应 我必须在自定义 ArrayAdapter 中实现它吗 它只有一个构造函数和一个 get
  • 如何在母版页标题中包含jquery而不出现路径问题?

    我已经尝试过这个 scripts jquery 1 5 1 min js gt gt
  • 是否可以通过 url 将文件上传到应用程序引擎上的云存储而不写入磁盘?

    要将文件从url上传到云存储系统 通常需要将该文件下载到服务器上 然后将其上传到云存储 对于大文件 可能需要将文件写入磁盘而不是内存 由于应用程序引擎不支持在磁盘上写入 因此还有其他选项可以在应用程序引擎上执行此操作吗 我知道托管虚拟机是一
  • 无法在 WinForms 设计器中选择 Infragistics 控件

    我刚刚升级了 2006 年至 2011 年一个项目的 Infragistics 控件 现在 如果我打开包含任何 Infragistics 控件的表单的设计器 Infragistics 控件将显示在表单设计器下方的单独面板中 并且我无法在设计
  • CTR 中的 AES 如何与 PyCrypto 一起用于 Python?

    我正在使用 python 2 7 1 我想在 CTR 模式下使用 AES 进行加密 我为 python 安装了 PyCrypto 库 我写了以下代码 secret os urandom 16 crypto AES new os urando
  • 如何使用本地构建的 nuget 包进行调试?

    我们有几个项目使用共享的公共库 内部的 非公共的 C net 项目 使用 Visual Studio 设置作为解决方案 Solution A gt Common Library Nuget Package Solution B 一般来说 这
  • 单击按钮 Javascript 即可触发文件下载,其中包含 DOM 中的内容

    我想下载一个从 DOM 元素创建的文件 因此 用户单击网页上的按钮 它会调用 JavaScript 方法 该方法可以获取 DOM 元素的内容并提示用户下载 我能够获取 Javascript Var 中 DOM 元素的内容 但不确定如何进一步
  • 在当前 HTTPContext 中生成新的 ASP.NET 会话

    对我们正在开发的一些产品进行渗透测试的结果是 当时看似 容易 解决的问题却变得棘手 当然不是应该的 我的意思是为什么会这样为当前生成一个全新的会话HTTPContext有那么难吗 奇怪 不管怎样 我写了一个厚颜无耻的小实用程序类来 就这么做