Zine.net online

Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc
w Szukaj

mgrzeg.net - Admin on Rails :)

[UPDATED] Zabawy z LSA - wydłubywanie haseł usług + tool.

Tekst ten dedykuję Grzesiowi Tworkowi i Pauli Januszkiewicz, których tegoroczna sesja na MTS natchnęła mnie do tego, żeby opisać parę poruszonych tam tematów na blogu.

Na pewno wielokrotnie zastanawialiście się nad tym, w jaki sposób zapisać jakąś tajemną informację tak, żeby nikt niepowołany nie mógł się do niej dobrać. Weźmy dla przykładu automatyczne logowanie do systemu.

Winlogon jakiego nie znamy?

W ramach swojego wsparcia technicznego, Microsoft proponuje rozwiązanie polegające na edycji zawartości klucza rejestru, a mianowicie HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon i ustawieniu:

  • DefaultUserName - nazwa użytkownika, dla którego ma zachodzić automatyczne logowanie;
  • DefaultPassword - hasełko użytkownika wpisanego w DefaultUserName;
  • AutoAdminLogon - 1 oznacza, że ma zachodzić automatyczne logowanie, 0 - nie.

I wszystko w porządku, gdyby nie to, że hasełko w DefaultPassword jest wpisane jawnym tekstem i dostępne bez większego problemu dla każdego, kto może odczytać zawartość tego klucza. Bezpieczeństwo takiego rozwiązania pozostawię każdemu do samodzielnej oceny. Moment! - ktoś może powiedzieć - przecież jest bezpieczniejsze rozwiązanie!

A i owszem!

Podczas swojego startu, proces Winlogon sprawdza zawartość wspomnianego wyżej klucza i na jego podstawie podejmuje decyzję o automatycznym logowaniu. Jednak chwilę wcześniej Winlogon sięga do LSA po DefaultPassword i jeśli coś dostanie w odpowiedzi, to nie omieszka z tego skorzystać, zamiast wpisu w rejestrze. Prawdę powiedziawszy, Microsoft zaleca tę właśnie metodę jako sposób ochrony hasła DefaultPassword.

LsaStorePrivateData - odsłona pierwsza

Jednak co to znaczy, że Winlogon sięga do LSA po DefaultPassword? Otóż upraszczając, wywoływana jest funkcja LsaRetrievePrivateData z biblioteki advapi32.dll z próbą odczytania wartości Sekretu dla klucza 'DefaultPassword'.

Sekretu? A cóż to takiego???

Podsystem Lsass udostępnia mechanizm umożliwiający zapisywanie wrażliwych danych do 'zasobnika LSA' w postaci zaszyfrowanej oraz na żądanie dostęp do tych danych. I tak: żeby zapisać interesujące nas dane, wystarczy użyć funkcji LsaStorePrivateData, gdzie w postaci parametrów przekazujemy parę klucz - wartość, czyli np. 'DefaultPassword' i 'Pa$$w0rd', natomiast do wyłuskania zapisanych danych należy skorzystać ze wspomnianej wcześniej funkcji LsaRetrievePrivateData z parametrem określającym klucz.
Microsoft podzielił dane, które możemy w ten sposób zapisywać na 4 grupy:

  • dane lokalne - nazwy z tej grupy rozpoczynają się prefiksem 'L$'. Dane lokalne można odczytać tylko na komputerze, na którym te dane są przechowywane. Dodatkowo wpadają tu dane, których nazwy zaczynają się od '$machine.acc', 'SAC', 'SAI', 'SANSC', żeby wymienić tylko kilka;
  • dane globalne - tu nazwy rozpoczynają się od prefiksu 'G$'. Dane globalne utworzone na kontrolerze domeny są replikowane na pozostałe kontrolery domeny;
  • dane komputera - ich nazwy rozpoczynają się od 'M$'. Zgodnie z dokumentacją dostęp do nich ma wyłącznie system operacyjny. Do tej grupy trafiają również nazwy zaczynające się od 'NL$', lub '_SC_';
  • dane prywatne - te nie wymagają żadnego przedrostka. Są dostępne z zewnętrznych komputerów, ale nie są replikowane w domenie.

Warto zwrócić uwagę na dane komputera (machine data), które możemy zapisywać korzystając z LsaStorePrivateData, natomiast nie możemy odczytywać przy wykorzystaniu LsaRetrievePrivateData.

Poniższe fragmenty kodu pokazują, jak korzystać z obu funkcji przy użyciu P/Invoke. Jest to właściwie przeniesienie przykładowego kodu do zmiany DefaultPassword do środowiska .NET. Można również skorzystać z przykładowego kodu do funkcji LsaRetrievePrivateData w ramach pinvoke.net.

public static string RetrieveData(string secretName)
{
  string secretValue = "";
  long retcode = 0;
  IntPtr zero = Marshal.AllocHGlobal(0);
  Win32.LSA_UNICODE_STRING systemName = new Win32.LSA_UNICODE_STRING();
  IntPtr policyHandle = IntPtr.Zero;
  Win32.LSA_OBJECT_ATTRIBUTES objectAttributes = new Win32.LSA_OBJECT_ATTRIBUTES();
  objectAttributes.Length = 0;
  objectAttributes.RootDirectory = IntPtr.Zero;
  objectAttributes.Attributes = 0;
  objectAttributes.SecurityDescriptor = IntPtr.Zero;
  objectAttributes.SecurityQualityOfService = IntPtr.Zero;
  retcode = Win32.LsaNtStatusToWinError(Win32.LsaOpenPolicy(ref systemName, ref objectAttributes, (int) Win32.LSA_AccessPolicy.POLICY_CREATE_SECRET, out policyHandle));
  if (retcode == 0)
  {
    IntPtr secretData;
    Win32.LSA_UNICODE_STRING[] lsa_unicode_stringArray = new Win32.LSA_UNICODE_STRING[] { new Win32.LSA_UNICODE_STRING() };
    lsa_unicode_stringArray[0].Buffer = Marshal.StringToHGlobalUni(secretName);
    lsa_unicode_stringArray[0].Length = (ushort)(secretName.Length * 2);
    lsa_unicode_stringArray[0].MaximumLength = (ushort)((secretName.Length + 1) * 2);
    Win32.LsaRetrievePrivateData(policyHandle, lsa_unicode_stringArray, out secretData);
    if (secretData != IntPtr.Zero)
    {
      Win32.LSA_UNICODE_STRING lsa_unicode_string2 = (Win32.LSA_UNICODE_STRING)Marshal.PtrToStructure(secretData, typeof(Win32.LSA_UNICODE_STRING));
      secretValue = Marshal.PtrToStringAuto(lsa_unicode_string2.Buffer);
    }
    Win32.LsaClose(policyHandle);
  }
  Win32.FreeSid(zero);
  return secretValue;
}

public static long StoreData(string secretName, string secretData)
{
  long retcode = 0;
  IntPtr zero = Marshal.AllocHGlobal(0);
  Win32.LSA_UNICODE_STRING systemName = new Win32.LSA_UNICODE_STRING();
  IntPtr policyHandle = IntPtr.Zero;
  Win32.LSA_OBJECT_ATTRIBUTES objectAttributes = new Win32.LSA_OBJECT_ATTRIBUTES();
  objectAttributes.Length = 0;
  objectAttributes.RootDirectory = IntPtr.Zero;
  objectAttributes.Attributes = 0;
  objectAttributes.SecurityDescriptor = IntPtr.Zero;
  objectAttributes.SecurityQualityOfService = IntPtr.Zero;
  retcode = Win32.LsaNtStatusToWinError(Win32.LsaOpenPolicy(ref systemName, ref objectAttributes, (int) Win32.LSA_AccessPolicy.POLICY_CREATE_SECRET, out policyHandle));
  if (retcode == 0)
  {
    Win32.LSA_UNICODE_STRING[] lsa_unicode_stringArray = new Win32.LSA_UNICODE_STRING[] { new Win32.LSA_UNICODE_STRING() };
    lsa_unicode_stringArray[0].Buffer = Marshal.StringToHGlobalUni(secretName);
    lsa_unicode_stringArray[0].Length = (ushort)(secretName.Length * 2);
    lsa_unicode_stringArray[0].MaximumLength = (ushort)((secretName.Length + 1) * 2);
    Win32.LSA_UNICODE_STRING[] privateData = new Win32.LSA_UNICODE_STRING[] { new Win32.LSA_UNICODE_STRING() };
    privateData[0].Buffer = Marshal.StringToHGlobalUni(secretData);
    privateData[0].Length = (ushort)(secretData.Length * 2);
    privateData[0].MaximumLength = (ushort)((secretData.Length + 1) * 2);
    Win32.LsaStorePrivateData(policyHandle, lsa_unicode_stringArray, privateData);
    Win32.LsaClose(policyHandle);
  }
  Win32.FreeSid(zero);
  return retcode;
}

Do tego niezbędne importy na potrzeby P/Invoke

internal static class Win32
{
  [DllImport("advapi32")]
  public static extern IntPtr FreeSid(IntPtr pSid);
  [DllImport("advapi32.dll")]
  public static extern uint LsaClose(IntPtr ObjectHandle);
  [DllImport("advapi32.dll")]
  public static extern uint LsaNtStatusToWinError(uint status);
  [DllImport("advapi32.dll")]
  public static extern uint LsaOpenPolicy(ref LSA_UNICODE_STRING SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, int DesiredAccess, out IntPtr PolicyHandle);
  [DllImport("advapi32.dll")]
  public static extern uint LsaRetrievePrivateData(IntPtr PolicyHandle, LSA_UNICODE_STRING[] KeyName, out IntPtr PrivateData);
  [DllImport("advapi32.dll", SetLastError = true)]
  public static extern uint LsaStorePrivateData(IntPtr PolicyHandle, LSA_UNICODE_STRING[] KeyName, LSA_UNICODE_STRING[] PrivateData);

  public enum LSA_AccessPolicy : long
  {
    POLICY_AUDIT_LOG_ADMIN = 0x200L,
    POLICY_CREATE_ACCOUNT = 0x10L,
    POLICY_CREATE_PRIVILEGE = 0x40L,
    POLICY_CREATE_SECRET = 0x20L,
    POLICY_GET_PRIVATE_INFORMATION = 4L,
    POLICY_LOOKUP_NAMES = 0x800L,
    POLICY_NOTIFICATION = 0x1000L,
    POLICY_SERVER_ADMIN = 0x400L,
    POLICY_SET_AUDIT_REQUIREMENTS = 0x100L,
    POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x80L,
    POLICY_TRUST_ADMIN = 8L,
    POLICY_VIEW_AUDIT_INFORMATION = 2L,
    POLICY_VIEW_LOCAL_INFORMATION = 1L
  }

  [StructLayout(LayoutKind.Sequential)]
  public struct LSA_OBJECT_ATTRIBUTES
  {
    public int Length;
    public IntPtr RootDirectory;
    public Win32.LSA_UNICODE_STRING ObjectName;
    public uint Attributes;
    public IntPtr SecurityDescriptor;
    public IntPtr SecurityQualityOfService;
  }

  [StructLayout(LayoutKind.Sequential)]
  public struct LSA_UNICODE_STRING
  {
    public ushort Length;
    public ushort MaximumLength;
    public IntPtr Buffer;
  }
}

I przykładowe użycie może wyglądać następująco:

static void Main(string[] args)
{
  StoreData("alamakota", "ala ma kota");
  string s = RetrieveData("alamakota");
  Console.WriteLine(s);
}

Uzbrojeni w maszynkę do odczytywania i zapisywania sekretów możemy już swobodnie ustawiać sobie DefaultPassword i usunąć odpowiedni element w kluczu Winlogon w rejestrze. Nareszcie bezpieczni!

Lsa(Store | Retrieve)PrivateData internals

Po pierwszej euforii nadchodzi chwila refleksji: 'A gdzie właściwie zapisywane są te dane?'. W dokumentacji do obu funkcji, Microsoft twierdzi, że:

"The data stored by the LsaStorePrivateData function is not absolutely protected. However, the data is encrypted before being stored, and the key has a DACL that allows only the creator and administrators to read the data."

Z jednej strony mamy zaufanie do systemu, że zadba o nasze dane, z drugiej - okazuje się, że wcale nie jest tak różowo. Otóż okazuje się, że dane przekazane przez LSASS zapisywane są w rejestrze, w gałęzi HKLM\Security\Policy\Secrets. Standardowo tylko system ma dostęp do tego klucza, więc jeśli chcecie się do niego dobrać, to musicie to zrobić w kontekście konta systemowego. W systemach przed Vistą najprościej skorzystać z polecenia systemowego at:

>at 10:23 /interactive regedit.exe

albo, już niezależnie od systemu i jeszcze prościej, z sysinternalsowego psexec:

>psexec -i -s regedit.exe

Przykładowa zawartość sekretu zapisanego wcześniej opisanymi metodami wygląda tak, jak to przedstawia Rysunek 1.

Rysunek 1. Przykładowy sekret :)

Przeglądając zawartość klucza HKLM\SECURITY\Policy\Secrets możemy znaleźć wiele podkluczy, których nazwy zaczynają się od L$, M$, ale także w formacie SCM:{GUID}, o których nie będę się rozpisywał.
Naszą uwagę przykują jednak klucze o nazwach zaczynających się na _SC_.

Sekrety usług

Jeśli postanowimy, żeby któraś z usług uruchamiana była z konta innego niż systemowe, to zostaniemy poproszeni o wprowadzenie nazwy użytkownika i hasła, w ramach którego usługa ma startować. Jest to jednorazowa czynność i musimy tylko pamiętać o tym, że gdy zmienimy hasło dla tego użytkownika, to musimy ponownie odwiedzić zakładkę 'Logowanie', gdzie ponownie będziemy musieli wprowadzić nasze dane. Zapewne zastanawialiście się kiedyś, gdzie przechowywane są te informacje i czy można się do nich jakoś dobrać. No właśnie, ciekawe, nie? :)

Weźmy dla przykładu usługę Telnet (jeśli jeszcze ją mamy w systemie, a w przypadku braku, możemy wybrać sobie inną ofiarę, której zepsucie nic nam nie zaszkodzi ;)) i ustawmy logowanie z dowolnego konta.

Rysunek 2. Zakładka logowanie dla usługi Telnet.

Zajrzyjmy teraz na chwilę do książki Marka Russinovicha i Davida Solomona o internalsach windowsów, a dokładniej do rozdziału poświęconemu uruchamianiu usług. Interesuje nas w szczególności fragment:

"SCM [Service Control Manager] zapisuje dane o usługach uruchomionych na koncie innym niż systemowe poprzez wywoływanie funkcji Lsass LsaLogonUser. Funkcja LsaLogonUser standardowo wymaga hasła, ale SCM sygnalizuje dla Lsass, że hasło jest przechowywane 'sekretnie' w kluczu HKLM\SECURITY\Policy\Secrets w rejestrze. [..] Kiedy SCM wywołuje LsaLogonUser, ukreśla typ logowania jako logowanie usługi, tak by Lsass szukał hasła w podkluczu Secrets o nazwie _SC_<nazwa usługi>. SCM poleca Lsass, by ten przechowywał hasło logowania w sekrecie, podczas gdy SCP konfiguruje informacje logowania usługi." [2]

Aha! Tu Cię mamy!

Mr Jingle podpowiada mi w tym momencie, że czuje już zapach hasła.

Po modyfikacji ustawień logowania dla usługi Telnet, w sekretach w rejestrze pojawił się dodatkowy podklucz, _SC_TlntSvr. To by potwierdzało słowa Wielkich Autorów, więc nie czekając długo na dalsze zachęty, łapię szybko za kod do wydłubywania sekretów i dopisuje w mainie krótką linijkę, dla testu:

static void Main(string[] args)
{
  string s = RetrieveData("_SC_TlntSvr");
  Console.WriteLine(s);
}

Kompiluję, uruchamiam i... nic :(. Po prostu pusta linia. No tak, przecież sekrety zaczynające się od _SC_ należą do kategorii systemowych, a te można tylko zapisywać, odczytywanie nie działa. Upewniam się jeszcze, czy sam mogę utworzyć sekret systemowy i później go odczytać:

static void Main(string[] args)
{
  StoreData("M$alamakota", "ala ma kota");
  string s = RetrieveData("M$alamakota");
  Console.WriteLine(s);
}

i oczywiście znowu puściutko. Dla pewności sprawdzam jeszcze wcześniejszy kod i przy zapisie do 'alamakota', odczyt działa prawidłowo. A więc tak, jest bezpiecznie!

W tym momencie Mr Jingle trąca mnie nosem. 'Nie, to nie może być takie proste!' - odpowiadam. Sięgam jednak po otwarty regedit, eksportuję do pliku zawartość klucza HKLM\SECURITY\Policy\Secrets\_SC_TlntSvr\CurrVal, zmieniam '_SC_TlntSvr' na 'alamakota' i importuję. Potem uruchamiam wcześniej przygotowany kod i ... na konsoli wypisuje się hasełko, wklepane wcześniej sumiennie w oknie ustawień logowania usługi Telnet.

Uwagi końcowe

Podsystem LSA umożliwia zapisanie zaledwie 4096 sekretów, z czego połowa zarezerwowana jest dla systemu operacyjnego. Przechowywanie sekretów z udziałem LSA dostępne jest od Windows NT 4.0 i obecnie Microsoft nie zaleca korzystania z opisanych metod do zapisywania swoich sekretów. Począwszy od Windows 2000 dostępny jest interfejs ochrony danych DPAPI z metodami CryptProtectData i CryptUnprotectData, jednak w tym przypadku to programista musi zadbać o przechowywanie wrażliwych danych, co - jak widać - może być jednak lepszym rozwiązaniem. Trzeba również pamiętać, że większość z opisanych metod wymaga odpowiednich przywilejów, dostępnych praktycznie rzecz biorąc wyłącznie dla administratorów systemów.

Z oczywistych względów nie udostępniam gotowego narzędzia, a jedynie opisuję technikę.
[Edit: Postanowiłem jednak udostępnić prostą wersję programu, ktory wykonuje opisane w tekście czynności. Wszystko oczywiście wyłącznie do celów 'edukacyjnych'. W przyszłości zamierzam rozwijać to narzędzie o kolejne elementy, które postaram się sumiennie opisywać na blogu. Program wymaga zainstalowanego .NET Framework w wersji 2.0 oraz uruchamianie z konta systemowego.
]

Od dawien dawna dostępne jest narzędzie, które wyłuskiwało sekrety systemowe korzystając z dll injection, jednak od pewnego czasu ta technika zastosowana do Lsass powoduje załamanie tego procesu i wymusza reset komputera.

Sprawdziłem opisaną metodę na Windows 2000 Server, Windows XP oraz Windows Vista, wszędzie z tym samym rezultatem.

Źródła (podaję polskie tłumaczenia, dostępne jeszcze na rynku - są tańsze od oryginałów i znośnie przetłumaczone):

1. 'Bezpieczny kod. Tworzenie i zastosowanie' - Michael Howard i David LeBlanc. (Ech, czas kupić kolejne wydanie tej rewelacyjnej książki!)
2. 'Microsoft Windows 2000 od środka' - David A. Solomon, Mark E. Russinovich. (Tu też już jest kolejne wydanie i naprawdę nie wiem, czemu go jeszcze nie mam w swojej biblioteczce!)

Opublikowane 16 października 2008 17:35 przez mgrzeg
Filed under: , ,

Attachment(s): http://zine.net.pl/Misc/SAPD.zip

Powiadamianie o komentarzach

Jeżeli chciałbyś otrzymywać email gdy ta wypowiedź zostanie zaktualizowana, to zarejestruj się tutaj

Subskrybuj komentarze za pomocą RSS

Komentarze:

 

brejk said:

No stary, aleś się dokopał. Niby proste, niby oczywiste, ale ile po drodze trzeba wiedzieć, ile przeczytać. Grasz dwie ligi wyżej normalnie. Szacunek.

PS. Mr Jingle wymiata :D

października 16, 2008 18:16
 

Wojciech Gebczyk said:

:-) Dobry stary internalywoy Michal :P Ze tez chcialo ci sie schodzic tak nisko ;-)

Ja dodam o gotowcach w .NET (ProtectedData i ProtectedMemory)

http://blogs.msdn.com/shawnfa/archive/2004/05/05/126825.aspx

http://blogs.msdn.com/shawnfa/archive/2004/05/17/133650.aspx

października 16, 2008 21:27
 

Tomek said:

hmmm .. no że sekrety LSA można odczytać z uprawnieniami administratora tudzież przez wstrzyknięcie kodu do procesu LSA to już jakoś w latach 90'ych pokazano :). Dla dev i jego aplikacji tak jak piszesz DPAPI jest rozwiazaniem .. ale przyklady kodu ladne i pouczajace :).

Co do kupowania nowej wersji Windows Internals .. wstrzymaj sie .. .5'th edition na horyzoncie. Ewentualnie jak zakupie 5'th to moge ci 4'th podarowac :)

października 17, 2008 16:34
 

Bysza said:

Było sobie narzędzie LSAdump. Co ono komu szkodziło? ;)

Od dawna nie działa. Może by się komuś przydało?

Czasem na teście lub środowisku deweloperskim trochę kombinuję i zdarza mi się zapomnieć hasła do konta, na którym pracuje serwis.

Zmiana hasła na koncie, a potem aktualizacja go w kilku serwisach bywa nużąca.

Czy dałoby radę wypuścić powyższe narzędzie w szeroki świat? :)

października 17, 2008 21:37
 

mgrzeg said:

@Bysza: Marek, nie mam przekonania, czy to puszczac. Chociaz coraz wiecej osob mowi mi, ze nic w tym zlego...

Jak znajdzie sie jeszcze paru chetnych w komentarzach, to puszcze wersje edukacyjna online.

października 17, 2008 22:09
 

mgrzeg said:

@Tomek: Chetnie lykne :) Na razie wystarczy mi wersja 4; 5 kupie sobie za 5 lat ;). Zatem czekam z niecierpliwoscia na kolejna edycje :D

@Wojtek: Napisalbys cos o tym, jakis tutorial by wystarczyl. To dosyc chodliwy temat, wiec moze przelam sie i maznij cos? ;)

@brejk: dzieki za dobre, acz niezasluzone slowa. Ale zawsze to milo :) A Mr Jingle wlasnie toczy szpulke ;)

października 17, 2008 22:14
 

Ww.CodeSculptor said:

Ten tekst powstał w nawiązaniu do artykułu Michała Grzegorzewskiego [ Zabawy z LSA - wydłubywanie haseł

października 21, 2008 16:55
 

Wojciech Gebczyk said:

Michal:

A tak to "o so chodzi" z tym textem? Mam wrazenie ze probujesz opisac jakas slabosc/dziure Windowsa. Ale sam napisales ze potrzeba Adminowych uprawnien aby wydlubac to i owo. Ale jak masz Admina to po co ci to jak masz wtey dostep do wszystkiego chyba...

listopada 3, 2008 13:22
 

mgrzeg said:

Wojtek: hmm... a wpadniesz na spotkanie grupy windowsowej w srode 12 listopada do MSu jakos po 18-ej? Jest szansa, ze pokaze tool w akcji (o ile sie uda ;)) i moze wyniknie jakas dyskusja, w czasie ktorej powiem co o tym sadze :)

listopada 5, 2008 01:14
 

Wojciech Gebczyk said:

niestety nie bede mogl byc w srode :-(

Moze objasnisz mi to przy okazji spotkania wg.net

listopada 5, 2008 16:10
 

Quch said:

Witam serdecznie :]

Mam pytanie do autora bo nie wiem czy dobrze zrozumiałem temat (jestem adminem a nie programistą, więc proszę o wybaczenie ;)

Po krótce - przykładowo konfiguruję dowolną usługę aby uruchamiała się na koncie admina a nie na koncie systemowym i po restarcie usługi sapd.exe powinien to hasło "wyciągnąć" i wypisać w konsoli? Nieudany test przeprowadziłem na Viście - komunikat zwrotny: "Secret for this service doesn't exist in the registry!". Dlaczego tak a nie inaczej? :)

listopada 6, 2008 15:39
 

Wojciech Gebczyk said:

Moze sprobuj uruchomic program wyciagajacy haslo z uprawnieniami Administratora. Moze przyczyna lezec w Vistowej wirtualizacji rejestru(http://msdn.microsoft.com/en-us/library/aa965884.aspx).

listopada 6, 2008 16:28
 

mgrzeg said:

@Quch:

- program musi byc uruchomiony w kontekscie systemu. Najlepiej przygotowac sobie konsole korzystajac z psexec (opisalem w tekscie)

- nazwa uslugi musi sie pokrywac z ta, ktora jest na zakladce 'ogolne' w ustawieniach uslugi i figuruje jako 'Nazwa uslugi'. Dla przykladu w przypadku uslugi Telnet nazwa to 'TlntSvr'.

- haslo jest do wyciagniecia juz bezposrednio po klknieciu 'OK' w oknie wlasciwosci uslugi, nie potrzebne sa zadne dodatkowe operacje.

Sprawdzalem program na 32-bit viscie biznes i brykalo :) Poprosilem tez pare osob o testy u siebie i na vistach 64-bit tez brykalo :). Na spotkaniu WGUiSW 12-ego zamierzam sprawdzic, czy zadziala na w2k8 - zapraszam! :)

Nie twierdze, ze program jest kuloodporny, bo taki nie jest. Jest pewnie rowniez malo informacyjny :(. Jest bardzo prosty, a reflektorem mozna podejrzec realizacje idei, ktorej nie zaciemnialem dodatkowym kodem.

W razie co prosze o kontakt mailem (mgrzeg at gmail kropa com), lub na skajpie: m.grzegorzewski, bardzo chetnie zapoznam sie z przypadkiem, kiedy program nie dziala!!! :)))

Na koniec przykladowe uruchomienie:

-----------

C:\>SAPD.exe TlntSvr

SAPD v 0.0.1.0 - Service account password dumper

Copyright (c) Michal Grzegorzewski 2008 @ zine.net.pl

Dumps account password from specified windows service.

See http://zine.net.pl/ for more .net and Windows technical information and tool

s.

length of the secret (# of bytes): 44 bytes

Secret's content:

alamakota

-----------

czyli haslem dla uslugi telnet jest alamakota.

Powodzenia!!! :)

listopada 6, 2008 19:35
 

Quch said:

Okej - już wszystko działa - zły kontekst :)

listopada 10, 2008 22:33
 

sosenki said:

no ok ale czy istnieje jakiś sposób aby sie przed takim odczytem uchronic?

Jakies ustawienie restrykcji na rejestr albo cos?

marca 2, 2010 16:32
 

mgrzeg said:

@sosenki: Obawiam sie, ze metody wprost nie ma. Trzeba albo napisac wlasnego SCM i samemu zadbac o bezpieczenstwo hasel, albo uniemozliwic dostep do kluczy rejestru uslug. To stara technologia i chyba lepiej nie zdawac sie na nia za bardzo, juz lepiej puszczac wszystko w kontekscie kont systemowych o bardzo niskich przywilejach, a potem samemu zadbac w kodzie o zmiane zetonu, korzystajac ze sprawdzonych rozwiazan. Choc, co zapewne Paula zademonstruje w nastepnym odcinku o technikach hakerskich, siegajac do mojego przykladu wydlubywania hasla z cpau (jeden z wpisow z listopada 2009 na blogu), to nie jest takie proste i rowniez tu mozna sie latwo nadziac :( Niestety, przy pewnej wiedzy i determinacji osoby, ktora chce sie dowiedziec czegos, co chcielismy ukryc, staje sie to baaardzo trudne, albo wrecz niewykonalne.

kwietnia 25, 2010 22:40
 

sosenki said:

ok dzięki mgrzeg za odpowiedz - zadałem jeszcze to pytanie na virtual - study - rozwnież dzięki za reply - odwiedzałem Twojego bloga codziennie w oczekiwaniu na odpowiedz:D

pozdrawiam

kwietnia 28, 2010 15:58
 

sosenki said:

a i mam jeszcze pytanie:

czasami secrety są wyświetlane jako dziwne znaki: buźki,domki,koła, kwadraty, puste prostokąty, gwiazdki itd. Sądzę ze program nie radzi sobie ze znakami specjalnymi. W jaki sposób odczytac te znaki?

pozdrawiam

maja 6, 2010 12:41

Co o tym myślisz?

(wymagane) 
(opcjonalne)
(wymagane) 

  
Wprowadź kod: (wymagane)
Wyślij

Subskrypcje

W oparciu o Community Server (Personal Edition), Telligent Systems