Captured Windows 8 KMS Activation Network Traffic

Discussion in 'Windows 8' started by Dhilip89, Aug 14, 2012.

  1. Jachra

    Jachra MDL Member

    Apr 5, 2010
    184
    55
    10
    #181 Jachra, Sep 26, 2012
    Last edited by a moderator: Apr 20, 2017
    @CODYQX4

    You can override the Execute event with your own code in a derived class. In there you must use your KMS code to determine what goes back to the client.

    Code:
            /// <summary>
            /// Can be over-ridden in a derived class to handle the incomming RPC request, or you can
            /// subscribe to the OnExecute event.
            /// </summary>
            public virtual byte[] Execute(IRpcClientInfo client, byte[] input)
            {
                RpcExecuteHandler proc = _handler;
                if (proc != null)
                {
                    return proc(client, input);
                }
                return null;
            }
    
    I also found some VB.Net code that can be converted to C# that you can use to communicate over TCP/IP:

    Code:
    Public Class Form1
            Private listener As System.Net.Sockets.TcpListener
            Private listenThread As System.Threading.Thread
         
            Private clients As New List(Of ConnectedClient) 'This list will store all connected clients.
         
            Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
                listener = New System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 43001) 'The TcpListener will listen for incoming connections at port 43001
                listener.Start() 'Start listening.
                listenThread = New System.Threading.Thread(AddressOf doListen) 'This thread will run the doListen method
                listenThread.IsBackground = True 'Since we dont want this thread to keep on running after the application closes, we set isBackground to true.
                listenThread.Start() 'Start executing doListen on the worker thread.
            End Sub
         
            Private Sub doListen()
                Dim incomingClient As System.Net.Sockets.TcpClient
                Do
                    incomingClient = listener.AcceptTcpClient 'Accept the incoming connection. This is a blocking method so execution will halt here until someone tries to connect.
                    Dim connClient As New ConnectedClient(incomingClient, Me) 'Create a new instance of ConnectedClient (check its constructor to see whats happening now).
                    AddHandler connClient.dataReceived, AddressOf Me.messageReceived
                    clients.Add(connClient) 'Adds the connected client to the list of connected clients.
         
                Loop
            End Sub
         
            Public Sub removeClient(ByVal client As ConnectedClient)
                If clients.Contains(client) Then
                    clients.Remove(client)
                End If
            End Sub
         
            Private Sub messageReceived(ByVal sender As ConnectedClient, ByVal message As String)
                'A message has been received from one of the clients.
                'To determine who its from, use the sender object.
                'sender.SendMessage can be used to reply to the sender.
         
                Dim data() As String = message.Split("|"c) 'Split the message on each | and place in the string array.
                Select Case data(0)
                    Case "CONNECT"
                        'We use GetClientByName to make sure no one else is using this username.
                        'It will return Nothing if the username is free.
                        'Since the client sent the message in this format: CONNECT|UserName, the username will be in the array on index 1.
                        If GetClientByName(data(1)) Is Nothing Then
                            'The username is not taken, we can safely assign it to the sender.
                            sender.Username = data(1)
                        End If
                    Case "DISCONNECT"
                        removeClient(sender)
                End Select
         
            End Sub
         
            Private Function GetClientByName(ByVal name As String) As ConnectedClient
                For Each cc As ConnectedClient In clients
                    If cc.Username = name Then
                        Return cc 'client found, return it.
                    End If
                Next
                'If we've reached this part of the method, there is no client by that name
                Return Nothing
            End Function
        End Class
    
    Public Class ConnectedClient
            Private mClient As System.Net.Sockets.TcpClient
         
            Private mUsername As String
            Private mParentForm As Form1
            Private readThread As System.Threading.Thread
            Private Const MESSAGE_DELIMITER As Char = ControlChars.Cr
         
            Public Event dataReceived(ByVal sender As ConnectedClient, ByVal message As String)
         
            Sub New(ByVal client As System.Net.Sockets.TcpClient, ByVal parentForm As Form1)
                mParentForm = parentForm
                mClient = client
         
                readThread = New System.Threading.Thread(AddressOf doRead)
                readThread.IsBackground = True
                readThread.Start()
            End Sub
         
            Public Property Username() As String
                Get
                    Return mUsername
                End Get
                Set(ByVal value As String)
                    mUsername = value
                End Set
            End Property
         
            Private Sub doRead()
                Const BYTES_TO_READ As Integer = 255
                Dim readBuffer(BYTES_TO_READ) As Byte
                Dim bytesRead As Integer
                Dim sBuilder As New System.Text.StringBuilder
                Do
                    bytesRead = mClient.GetStream.Read(readBuffer, 0, BYTES_TO_READ)
                    If (bytesRead > 0) Then
                        Dim message As String = System.Text.Encoding.UTF8.GetString(readBuffer, 0, bytesRead)
                        If (message.IndexOf(MESSAGE_DELIMITER) > -1) Then
         
                            Dim subMessages() As String = message.Split(MESSAGE_DELIMITER)
         
                            'The first element in the subMessages string array must be the last part of the current message.
                            'So we append it to the StringBuilder and raise the dataReceived event
                            sBuilder.Append(subMessages(0))
                            RaiseEvent dataReceived(Me, sBuilder.ToString)
                            sBuilder = New System.Text.StringBuilder
         
                            'If there are only 2 elements in the array, we know that the second one is an incomplete message,
                            'though if there are more then two then every element inbetween the first and the last are complete messages:
                            If subMessages.Length = 2 Then
                                sBuilder.Append(subMessages(1))
                            Else
                                For i As Integer = 1 To subMessages.GetUpperBound(0) - 1
                                    RaiseEvent dataReceived(Me, subMessages(i))
                                Next
                                sBuilder.Append(subMessages(subMessages.GetUpperBound(0)))
                            End If
                        Else
         
                            'MESSAGE_DELIMITER was not found in the message, so we just append everything to the stringbuilder.
                            sBuilder.Append(message)
                        End If
                    End If
                Loop
            End Sub
         
            Public Sub SendMessage(ByVal msg As String)
                Dim sw As IO.StreamWriter
                Try
                    SyncLock mClient.GetStream
                        sw = New IO.StreamWriter(mClient.GetStream) 'Create a new streamwriter that will be writing directly to the networkstream.
                        sw.Write(msg)
                        sw.Flush()
                    End SyncLock
                Catch ex As Exception
                    MessageBox.Show(ex.ToString)
                End Try
                'As opposed to writing to a file, we DONT call close on the streamwriter, since we dont want to close the stream.
            End Sub
         
        End Class
     
  2. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,813
    45,776
    150
    #182 CODYQX4, Sep 26, 2012
    Last edited: Apr 12, 2019
    .
     
  3. dedificator

    dedificator MDL Novice

    Jul 29, 2009
    9
    41
    0
    #183 dedificator, Sep 26, 2012
    Last edited: Sep 26, 2012
    So, couple of things .....

    First of all: mentioned above decompiled code IS NOT RELATED to KMS activation at all!!!
    They are not SBOXes ... but fragments from precomputed keyschedule - every block of 256 bytes has all possible values 0..255 in mixed order, as result in every block will be exactly one '0'
    There (in sppsvc, osppsvc) are totally 3 similar hash functions with 3 different resulting keyschedules (however algos are identical) and only third of them is used in hash computation
    So don't waste your precious time :)

    Second: Signature algorithm itself is Rijndael based and works EXACTLY as i wrote in my previous posts.

    I can give full working C# code for KMS computations (really tested), but i don't think that publishing for general availability source code of this sort will be reasonable. So maybe PM :D


    And last .... in W8 KMS operations are ported from plugin library (sppobjs in W7) to special COM object proxy SppExtComObj (very interesting thing internally).
    P.S. in this proxy RPC KMS function semantics are slightly changed, but this seems be only due to use of more recent midl compiler

    About RPC comm - simple listening on tcp CAN be used because of very simple RPC req/resp with basic RPC packet parsing .. but this can be a little complicated .. how about mixed mode .net dll (can be coded in managed C++)?
     
  4. dedificator

    dedificator MDL Novice

    Jul 29, 2009
    9
    41
    0
    @CODYQX4:

    Speaking about KMS RPC server - the most apropriate way to integrate it into C# app will be use of PInvoke interop.
    This is elegant way how to use Win32 API functions, only trouble can be callback function pointers in RPC structs ..

    Second acceptable approach can be full-blown C# RPC client/server protocol parser library, but, in my opinion, it's total overkill :)

    I'll try to do some experiments with this (i have large experience with PInvoke)...
     
  5. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,813
    45,776
    150
    #185 CODYQX4, Sep 26, 2012
    Last edited: Apr 12, 2019
    .
     
  6. jarod75

    jarod75 MDL Novice

    Oct 29, 2009
    27
    21
    0
    You seem to have done a great part of the job ...

    Can you explain and point us to the correct functions (name it, it's help & everybody have IDA), corrects dlls... in some words: Share with us what you know about the processes ...

    For example, what is the role of SUB_58258D ?

    Thanks
     
  7. dedificator

    dedificator MDL Novice

    Jul 29, 2009
    9
    41
    0
    Yep, RpcLibrary is PInvoke implementation too.
    And it is overkill for our target, KMS needs in about fourth part of RpcLibrary.

    I will compile KMS server/client interface in C++ with midl compiler and then port it to C#/PInvoke.
     
  8. Lacius

    Lacius MDL Member

    Oct 22, 2010
    110
    90
    10
    Any progress?
     
  9. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,813
    45,776
    150
    #189 CODYQX4, Oct 15, 2012
    Last edited: Apr 12, 2019
    .
     
  10. FreeStyler

    FreeStyler MDL Guru

    Jun 23, 2007
    3,563
    3,853
    120
    Yes that should be the better, smaller and less resource exhausting method. I do not call myself much of a coder, but if you can come up with something, please share ;)
     
  11. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,813
    45,776
    150
    #191 CODYQX4, Oct 15, 2012
    Last edited: Apr 12, 2019
    .
     
  12. FreeStyler

    FreeStyler MDL Guru

    Jun 23, 2007
    3,563
    3,853
    120
    MIDL definition?
     
  13. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,813
    45,776
    150
    #193 CODYQX4, Oct 15, 2012
    Last edited: Apr 12, 2019
    .
     
  14. 100

    100 MDL Expert

    May 17, 2011
    1,354
    1,590
    60
    Just an idea for client emulation: Since KMS also activates downlevel clients, it's probably a good idea to analyze requests from Vista or 7, since these might use a simpler protocol than Windows 8.
     
  15. FreeStyler

    FreeStyler MDL Guru

    Jun 23, 2007
    3,563
    3,853
    120
    Should be easier indeed, as it uses RPC protocol v4 (unencrypted)
     
  16. BobSheep

    BobSheep MDL Guru

    Apr 19, 2010
    2,329
    1,381
    90
  17. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,813
    45,776
    150
    #199 CODYQX4, Oct 17, 2012
    Last edited: Apr 12, 2019
    .
     
  18. Jachra

    Jachra MDL Member

    Apr 5, 2010
    184
    55
    10
    You need at least Wireshark to capture the network traffic.