Add files via upload

This commit is contained in:
May 2024-09-06 23:05:57 +00:00 committed by GitHub
commit 0aebfd413f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 503 additions and 0 deletions

166
device_ticket.bat Normal file
View File

@ -0,0 +1,166 @@
<# :
@REM BSD 3-Clause License
@REM
@REM Copyright(c) 2023, echnobas
@REM All rights reserved.
@REM
@REM Redistribution and use in source and binary forms, with or without
@REM modification, are permitted provided that the following conditions are met:
@REM
@REM 1. Redistributions of source code must retain the above copynotice, this
@REM list of conditions and the following disclaimer.
@REM
@REM 2. Redistributions in binary form must reproduce the above copynotice,
@REM this list of conditions and the following disclaimer in the documentation
@REM and/or other materials provided with the distribution.
@REM
@REM 3. Neither the name of the copyholder nor the names of its
@REM contributors may be used to endorse or promote products derived from
@REM this software without specific prior written permission.
@REM
@REM THIS SOFTWARE IS PROVIDED BY THE COPYHOLDERS AND CONTRIBUTORS "AS IS"
@REM AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@REM IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@REM DISCLAIMED. IN NO EVENT SHALL THE COPYHOLDER OR CONTRIBUTORS BE LIABLE
@REM FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
@REM DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
@REM SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
@REM CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
@REM OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
@REM OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@echo off &chcp 850 >nul &pushd "%~dp0"
fltmc >nul 2>&1 || (
powershell Start-Process -FilePath "%~f0" -ArgumentList "%cd%" -verb runas >NUL 2>&1
exit /b
)
set "psScript=%~f0"
powershell -nop -c "& ([ScriptBlock]::Create((Get-Content """$env:psScript""" -Raw)))" & exit /b
: #>
###################################### SUBLICENSE BEGIN ######################################
# BSD 3-Clause License
#
# Copyright(c) 2019, Tobias Heilig
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copynotice, this
# list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copynotice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyholder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYHOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYHOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
try {
& {
$ErrorActionPreference = 'Stop'
[void] [impsys.win32]
}
}
catch {
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
namespace impsys {
public class win32 {
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool CloseHandle(
IntPtr hHandle);
[DllImport("kernel32.dll", SetLastError=true)]
public static extern IntPtr OpenProcess(
uint processAccess,
bool bInheritHandle,
int processId);
[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool OpenProcessToken(
IntPtr ProcessHandle,
uint DesiredAccess,
out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool DuplicateTokenEx(
IntPtr hExistingToken,
uint dwDesiredAccess,
IntPtr lpTokenAttributes,
uint ImpersonationLevel,
uint TokenType,
out IntPtr phNewToken);
[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool ImpersonateLoggedOnUser(
IntPtr hToken);
[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool RevertToSelf();
}
}
"@
}
$winlogonPid = Get-Process -Name "winlogon" | Select-Object -First 1 -ExpandProperty Id
if (($processHandle = [impsys.win32]::OpenProcess(
0x400,
$true,
[Int32]$winlogonPid)) -eq [IntPtr]::Zero) {
$err = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
Write-Error "$([ComponentModel.Win32Exception]$err)"
Exit $err
}
$tokenHandle = [IntPtr]::Zero
if (-not [impsys.win32]::OpenProcessToken(
$processHandle,
0x0E,
[ref]$tokenHandle)) {
$err = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
Write-Error "$([ComponentModel.Win32Exception]$err)"
Exit $err
}
$dupTokenHandle = [IntPtr]::Zero
if (-not [impsys.win32]::DuplicateTokenEx(
$tokenHandle,
0x02000000,
[IntPtr]::Zero,
0x02,
0x01,
[ref]$dupTokenHandle)) {
$err = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
Write-Error "$([ComponentModel.Win32Exception]$err)"
Exit $err
}
if (-not [impsys.win32]::ImpersonateLoggedOnUser(
$dupTokenHandle)) {
$err = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
Write-Error "$([ComponentModel.Win32Exception]$err)"
Exit $err
}
###################################### SUBLICENSE END ######################################
Add-Type -AssemblyName System.Security
$key = "registry::HKEY_USERS\S-1-5-19\Software\Microsoft\IdentityCRL\Immersive\production\Token\{D6D5A677-0872-4AB0-9442-BB792FCE85C5}"
$ticket = (Get-ItemProperty -Path $key)."DeviceTicket"
$raw = ([Text.Encoding]::Unicode).GetString([Security.Cryptography.ProtectedData]::Unprotect($ticket[4..$ticket.length], $Null, [Security.Cryptography.DataProtectionScope]::LocalMachine)) -replace "^.*?t\=" -replace "\&p\=.*"
Set-Content -NoNewline -Path dev_tik.txt -Value "$raw"

70
kh_editlic.py Normal file
View File

@ -0,0 +1,70 @@
import sys
import random
import struct
import time
import binascii
import hashlib
tlv_types = {
"SignedBlock": 0x14,
"DeviceLicenseExpirationTime": 0x1f,
"PollingTime": 0xd3,
"LicenseExpirationTime": 0x20,
"ClepSignState": 0x12d,
"LicenseDeviceId": 0xd2,
"UnkBlock1": 0xd1,
"LicenseId": 0xcb,
"HardwareId": 0xd0,
"UnkBlock2": 0xcf,
"UplinkKeyId": 0x18,
"UnkBlock3": 0x0,
"UnkBlock4": 0x12e,
"UnkBlock5": 0xd5,
"PackageFullName": 0xce,
"LicenseInformation": 0xc9,
"PackedContentKeys": 0xca,
"EncryptedDeviceKey": 0x1,
"DeviceLicenseDeviceId": 0x2,
"LicenseEntryIds": 0xcd,
"LicensePolicies": 0xd4,
"KeyholderPublicSigningKey": 0xdc,
"KeyholderPolicies": 0xdd,
"KeyholderKeyLicenseId": 0xde,
"SignatureBlock": 0xcc,
};
def encode_tlvblock(type, data):
return struct.pack("<II", tlv_types[type], len(data)) + data
extradata = None
lic_file = sys.argv[1]
new_pfn = sys.argv[2].lower()
out_lic = sys.argv[3]
if len(sys.argv) >= 5:
extra_file = sys.argv[4]
with open(extra_file, "rb") as f:
extradata = f.read()
with open(lic_file, "rb") as f:
data = f.read()
data += encode_tlvblock("PackageFullName", new_pfn.encode("utf-16-le") + b"\x00\x00")
basic_pol = 0x0a
if "addon" in new_pfn:
basic_pol = 0x00
lic_info = struct.pack("<HHIBB", 5, 1, int(time.time()), basic_pol, 1)
data += encode_tlvblock("LicenseInformation", lic_info)
data += encode_tlvblock("LicenseId", random.randbytes(16))
data += encode_tlvblock("LicenseEntryIds", b"\x01\x00" + hashlib.sha256(new_pfn.encode("utf-16-le")).digest())
data += encode_tlvblock("LicenseExpirationTime", b"\x00\x00\x00\x00")
if extradata:
data += extradata
with open(out_lic, "wb") as f:
f.write(data)

125
resignlic.py Normal file
View File

@ -0,0 +1,125 @@
from bs4 import BeautifulSoup
from xml.etree import ElementTree as ET
from base64 import b64decode, b64encode
from datetime import datetime
from time import time
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
from Crypto.Signature import PKCS1_v1_5
from ecdsa import SigningKey
from copy import copy
import argparse, re
# TODO: Implement SPLicenseBlock parser
CLIPUP_ECC_KEY_PEM = """-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPJp69Tr9nAvAHi3B
2dr5jenY4MkTwy4L/ahplSNxvgahRANCAATC/nluDYXrQHgi9STrd2kEhS4cKfTD
URm5vYGwUG1Jxva69OJEUiF2sfMhYGnCDYHrLM5ndcA0s43ie1+z3y1t
-----END PRIVATE KEY-----"""
clipup_eckey = SigningKey.from_pem(CLIPUP_ECC_KEY_PEM, hashfunc=SHA256.new)
def xml_open(xmlf):
with open(xmlf) as f:
cont = f.read()
return BeautifulSoup(cont, "xml")
def xml_save(xml, path):
with open(path, "wb") as f:
f.write(canonicb(xml))
def iso_date(t):
return datetime.fromtimestamp(t).isoformat() + "Z"
def sha256(s):
return SHA256.new(s).digest()
def b64sencode(s):
return b64encode(s).decode()
def b64ssencode(s):
return b64sencode(s.encode())
def b64sdecode(s):
return b64decode(s).decode()
def hashb64(s):
return b64sencode(sha256(s))
def canonicb(x):
return ET.canonicalize(str(x), strip_text=True).encode()
def decode_tsl(tsl, log=False):
if tsl.SPLicenseBlock:
licblock = b64decode(tsl.SPLicenseBlock.text)
else:
licblock = None
pubkey = clipup_eckey.get_verifying_key()
sig_inf = tsl.SignedInfo
sig_inf.attrs["xmlns"] = "http://www.w3.org/2000/09/xmldsig#"
sig_val = b64decode(tsl.SignatureValue.text)
sig_data = canonicb(sig_inf)
try:
valid = pubkey.verify(sig_val, sig_data)
except:
valid = False
if log:
print("TSL Information:")
print(f"Valid: {valid}")
return licblock, valid
def resign_lic(tsl, licblock=None):
sig_tag = copy(tsl.License.Signature)
tsl.License.Signature.decompose()
if licblock:
if tsl.License.SPLicenseBlock is None:
tsl.License.append(tsl.new_tag("SPLicenseBlock"))
tsl.SPLicenseBlock.string = b64sencode(licblock)
hash = hashb64(canonicb(tsl))
sig_tag.SignedInfo.DigestValue.string = hash
sig_tag.SignedInfo.attrs["xmlns"] = "http://www.w3.org/2000/09/xmldsig#"
sig = b64sencode(clipup_eckey.sign_deterministic(canonicb(sig_tag.SignedInfo)))
del sig_tag.SignedInfo.attrs["xmlns"]
sig_tag.SignatureValue.string = sig
tsl.License.append(sig_tag)
return tsl
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("mode", help="Mode: encode, decode")
parser.add_argument("license", nargs="?", default="", help="Data/path")
parser.add_argument("licblock", help="Type: tslraw, tslconv, ticket")
parser.add_argument("--output", "-o", help="Output path", default="edit.xml")
args = parser.parse_args()
licblock = None
tsl = xml_open(args.license)
if args.mode == "encode":
with open(args.licblock, "rb") as f:
licblock = f.read()
tsl = resign_lic(tsl, licblock)
xml_save(tsl, args.output)
elif args.mode == "decode":
licblock_out, valid = decode_tsl(tsl, log=False)
if licblock_out and args.licblock:
with open(args.licblock, "wb") as f:
f.write(licblock_out)

142
splicenseblock.hexpat Normal file
View File

@ -0,0 +1,142 @@
#include <std/mem.pat>
struct UTF16CStr {
char16 data[while(std::mem::read_unsigned($, 2) != 0x0)];
char16 terminator[[hidden]];
};
enum LicenseType : u16 {
Unknown = 0,
App = 1,
Lease = 2,
Device = 3,
Dev = 4,
Lob = 5,
Upgrade = 6,
};
bitfield BasicPolicies {
lease_required : 1;
is_primary : 1;
expired : 1;
is_device_locked : 1;
padding : 12;
};
struct LicenseInformation {
u16 version;
LicenseType type;
s32 issued;
BasicPolicies policies;
};
// SHA256 of PFN (lowercase)
struct LicenseEntryId {
u8 data[32];
};
enum PolicyType : u8 {
NONE = 0x01,
STRING = 0x11,
BINARY = 0x31,
DWORD = 0x41,
MULTI_SZ = 0x71
};
struct Policy {
u16 something1[[hidden]];
u16 something2[[hidden]];
u8 pad0[[hidden]];
PolicyType type;
u16 pad1[[hidden]];
u16 priority;
u16 name_sz;
u16 data_sz;
char16 name[name_sz / 2];
u32 end = $ + data_sz;
match (type) {
(PolicyType::STRING): {
UTF16CStr data;
}
(PolicyType::DWORD): {
u32 data;
}
(PolicyType::MULTI_SZ): {
UTF16CStr data[];
}
(_): {
u8 data[while($ < end)];
}
}
u16 terminator[[hidden]];
};
enum BlockType : u32 {
SignedBlock = 0x14,
DeviceLicenseExpirationTime = 0x1f,
PollingTime = 0xd3,
LicenseExpirationTime = 0x20,
ClepSignState = 0x12d,
LicenseDeviceId = 0xd2,
UnkBlock1 = 0xd1,
LicenseId = 0xcb,
HardwareId = 0xd0,
UnkBlock2 = 0xcf,
UplinkKeyId = 0x18,
UnkBlock3 = 0x0,
UnkBlock4 = 0x12e,
UnkBlock5 = 0xd5,
PackageFullName = 0xce,
LicenseInformation = 0xc9,
PackedContentKeys = 0xca,
EncryptedDeviceKey = 0x1,
DeviceLicenseDeviceId = 0x2,
LicenseEntryIds = 0xcd,
LicensePolicies = 0xd4,
KeyholderPublicSigningKey = 0xdc,
KeyholderPolicies = 0xdd,
KeyholderKeyLicenseId = 0xde,
SignatureBlock = 0xcc,
};
struct TLVBlock {
BlockType type;
u32 size;
u32 end = $ + size;
match (type) {
(BlockType::SignedBlock): {
TLVBlock block[while($ < end)];
}
(BlockType::DeviceLicenseExpirationTime | BlockType::PollingTime | BlockType::LicenseExpirationTime): {
s32 time;
}
(BlockType::PackageFullName): {
UTF16CStr name;
}
(BlockType::LicenseInformation): {
LicenseInformation information;
}
(BlockType::LicenseEntryIds): {
u16 count[[hidden]];
LicenseEntryId ids[count];
}
(BlockType::LicensePolicies): {
Policy policies[while($ < end)];
}
(BlockType::SignatureBlock): {
u16 something0[[hidden]];
u16 origin;
u8 data[while($ < end)];
}
(_): { u8 data[size]; }
}
};
TLVBlock blocks[while($ < std::mem::size())] @ 0;