5

私のC#コードは、P/Invokeを介してWin32関数を呼び出すことによって偽装を使用しています

internal class Win32Native
{
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern int ImpersonateLoggedOnUser(IntPtr token);

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern int RevertToSelf();
}

try {
    var token = obtainTokenFromLogonUser();
    Win32Native.ImpersonateLoggedOnUser( token );
    throw new Exception(); // this is for simulation
    Win32Native.RevertToSelf()
} catch( Exception e ) {
    LogException( e );
    throw;
}

またAppDomain.CurrentDomain.UnhandledException、未処理のすべての例外をログに記録するハンドラーをインストールしました。

例外をログに記録するコードは、なりすましの有無にかかわらず正常に機能すると確信しています。

catchここで問題となるのは、上記のコードでは、入力されUnhandledExceptionておらず、呼び出されていないように見えることです。例外の唯一の痕跡は、イベントビューアのエントリです。

私がこのように追加した場合finally

try {
    var token = obtainTokenFromLogonUser();
    Win32Native.ImpersonateLoggedOnUser( token );
    try {
       throw new Exception(); // this is for simulation
    } finally {
        Win32Native.RevertToSelf()
    }
} catch( Exception e ) {
    LogException( e );
    throw;
}

catchその後、例外はハンドラーからとハンドラーからの両方で正常にログに記録されますUnhandledException

何が起こっていますか?偽装されているスレッドは、通常の例外処理を妨げますか?

4

2 に答える 2

3

LogExceptionのコードを見ていないとわかりませんが、そこで行っていることは、偽装/ログオンしているユーザーのコンテキストで行われている可能性があり、そのユーザーには実行するユーザー権限がありません。たとえば、ファイルへの書き込みなど、何をしていても、その時点でコードがクラッシュします。「自己復帰」した後にのみコードが機能するという事実は、これを裏付けているようです。

つまり、私が言いたいのは、例外が実際にキャッチによってキャッチされている可能性がありますが、LogExceptionは、誤ったユーザーのコンテキストで作業を行おうとしているために失敗しているということです。

これをテストするには、LogException内で、ロギングを試行する前に現在のコンテキストを「Self」に強制して、最初のスニペットが機能し始めるかどうかを確認してください。

于 2013-03-15T12:53:20.690 に答える
1

問題はロギングコードにあったことが判明しました。ある時点で、現在のプロセス開始時刻(Process.StartTime)を取得Access deniedし、偽装されたスレッドから呼び出されたときにそのコードが生成されるコードを追加しました。

Access is denied
System.ComponentModel.Win32Exception
at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited)
at System.Diagnostics.Process.GetProcessTimes()
at System.Diagnostics.Process.get_StartTime()
//our logging code here

「トレースリスナー」を使用してコードを呼び出し、「トレースリスナー」を介して書き込むSystem.Diagnostics.Trace.WriteLine() 前に呼び出されたロギングコードも成功し、後者のコードを介した書き込みのみが失敗しました。Process.StartTime

したがって、なりすましの有無にかかわらず、例外をキャッチすることに違いはありません。例外フィルターをインストールして、偽装されたコードのセキュリティコンテキストで呼び出されるようにすることも可能です。これにより、特権が昇格される可能性があります。後者の詳細はこちら

于 2013-03-18T09:12:29.683 に答える