Update for hacking using RDP on Windows RDP remote servers.
If you are trying to access a physical smart card on a Windows server or desktop computer, be aware that this feature is known to be restricted, as mentioned in the MSDN documentation:
Doc: https://learn.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardestablishcontext
If the client attempts a smart card operation in a remote session, such as a client session running on a terminal server, and the operating system in use does not support smart card redirection, this function returns ERROR_BROKEN_PIPE.
To address this issue, we have confirmed that this behavior still occurs. By analyzing the DLL at the assembly level, we can bypass this function by applying an NOP (no-operation) instruction or forcing the EBX register to return a fixed value, effectively overriding the default behavior.
For reference, see this blog post:
http://lifayk.blogspot.com/2012/07/windows-smart-card-subsystem-and-remote.html
However, note that the post was written in 2012 and is now outdated. After further investigation using WinDbg to list functions from the SCard service by:
x WinSCard!*
x *!*
Referring to the blog post mentioned earlier, we found that several functions—InTSMethodWithContext, InTSRedirectModeWithContext, and WinStationIsSessionRemoteable, it was no longer exist. This means we need to reanalyze and trace the feature again.
bm WinSCard!SCardEstablishContext
bm WinSCard!SCardListReadersA
bm WinSCard!RedirectionContextIsLocal*
mov ebx, 1
ret
mov ebx, 1
ret
eb 7a876245 B0 01
namespace WinSCardTest
{
class Program
{
[DllImport("winscard.dll")]
private static extern int SCardTransmit(IntPtr hCard,
IntPtr pioSendPci,
byte[] pbSendBuffer,
int cbSendLength,
IntPtr pioRecvPci,
byte[] pbRecvBuffer,
ref int pcbRecvLength);
// Scope values for the SCardEstablishContext function
private const uint SCARD_SCOPE_USER = 0; // User scope
private const uint SCARD_SCOPE_TERMINAL = 1; // Terminal scope
private const uint SCARD_SCOPE_SYSTEM = 2; // System scope
// Return codes for the function (commonly used ones)
private const int SCARD_S_SUCCESS = 0x00000000; // Success
// Importing the SCardEstablishContext function
[DllImport("winscard.dll")]
private static extern int SCardEstablishContext(
uint dwScope, // Scope of the resource manager context
IntPtr pvReserved1, // Reserved, must be null
IntPtr pvReserved2, // Reserved, must be null
out IntPtr phContext // Handle to the established resource manager context
);
[DllImport("winscard.dll")]
private static extern int SCardListReaders(
IntPtr hContext,
string mszGroups,
byte[] mszReaders,
ref int pcchReaders);
[DllImport("winscard.dll")]
private static extern int SCardReleaseContext(IntPtr hContext);
[DllImport("winscard.dll", CharSet = CharSet.Auto)]
public static extern int SCardConnect(
IntPtr hContext,
string szReader,
uint dwShareMode,
uint dwPreferredProtocols,
ref IntPtr phCard,
ref uint pdwActiveProtocol
);
static void Main(string[] args)
{
IntPtr hContext = IntPtr.Zero;
int result = SCardEstablishContext(SCARD_SCOPE_SYSTEM, IntPtr.Zero, IntPtr.Zero, out hContext);
if (result != SCARD_S_SUCCESS)
{
Console.WriteLine($"SCardEstablishContext failed with error: 0x{result:X}");
Console.WriteLine("Test - 3");
Console.ReadLine();
return;
}
Console.WriteLine("SCardEstablishContext succeeded.");
// Get the size of the buffer for the reader names
int readerListSize = 0;
result = SCardListReaders(hContext, null, null, ref readerListSize);
if (result != SCARD_S_SUCCESS)
{
Console.WriteLine($"SCardListReaders failed to get size with error: 0x{result:X}");
SCardReleaseContext(hContext);
Console.WriteLine("Test - 2");
Console.ReadLine();
return;
}
// Allocate buffer to hold the reader names
byte[] readerList = new byte[readerListSize];
result = SCardListReaders(hContext, null, readerList, ref readerListSize);
if (result != SCARD_S_SUCCESS)
{
Console.WriteLine($"SCardListReaders failed to get readers with error: 0x{result:X}");
SCardReleaseContext(hContext);
Console.WriteLine("Test - 1");
Console.ReadLine();
return;
}
// Convert the null-separated list to a string array
string readerNames = Encoding.ASCII.GetString(readerList).TrimEnd('\0');
string[] readers = readerNames.Split('\0');
Console.WriteLine("Available Readers:");
foreach (string reader in readers)
{
Console.WriteLine($"- {reader}");
}
SCardReleaseContext(hContext);
Console.WriteLine("Test");
Console.ReadLine();
ConnectToSmartCard("InfoThink USB Reader 0");
Console.WriteLine("Test");
Console.ReadLine();
}
public static IntPtr ConnectToSmartCard(string readerName)
{
IntPtr hContext = IntPtr.Zero;
uint dwScope = 0; // SCARD_SCOPE_USER (0) or SCARD_SCOPE_SYSTEM (1)
int result = SCardEstablishContext(0, IntPtr.Zero, IntPtr.Zero, out hContext);
if (result != 0) // SCARD_S_SUCCESS = 0
{
throw new Exception("SCardEstablishContext failed with error code " + result);
}
IntPtr hCard = IntPtr.Zero;
uint pdwActiveProtocol = 0;
uint dwShareMode = 2; // SCARD_SHARE_SHARED
uint dwPreferredProtocols = 3; // SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1
// 嘗試連接到指定的讀卡器
result = SCardConnect(hContext, readerName, dwShareMode, dwPreferredProtocols, ref hCard, ref pdwActiveProtocol);
if (result != 0)
{
throw new Exception("SCardConnect failed with error code " + result);
}
// 釋放上下文資源
SCardReleaseContext(hContext);
return hCard;
}
}
}
After investigating, I decided to mute the exception pop in WinSCard!SCardListReadersA.
eb 6249cd91 90 90 90 90
Common Error Troubleshooting
TL; DR
- find e8353dffff in DLL and modify to 9090909090
- find e87b11ffff, move to next commend you will see "8ac7", modify 8ac7 to B001
- WinDBG
- 0101 Editor (for dll)
- Tiger VNC
沒有留言:
張貼留言