Blog

  • Vaizdo įrašas: pirmasis žvilgsnis į Ghidrą (NSA atvirkštinės inžinerijos įrankis)

    Šiandien, per RSA konferenciją, Nacionalinė saugumo agentūra išleido savo labai populiarią Ghidra atvirkštinės inžinerijos priemonių rinkinį. Apibūdinta kaip „programinės įrangos atvirkštinės inžinerijos (SRE) įrankių rinkinys“, „Ghidra“ skambėjo kaip kažkokia išmontavimo sistema. Prieš išleidžiant tikėjausi daugiau nei „Binary Ninja“, bet trūko derinimo programos. Maniau, kad įrankių rinkinys būtų idealus tiems, kurie domisi atbuline eiga, bet kuriems trūksta finansavimo IDA licencijai gauti.

    Akivaizdu, kad bus daug sąmokslų, susijusių su paleidimu. Jau mačiau daug nepagrįstų teiginių, kad Ghidra yra NSA užpakalinės durys. Manau, kad šis įrankis yra tiesiog investicija į ateities kartą. Suteikdami įrankius ir žinias, kurių reikia norint paskatinti žmonių domėjimąsi, pagerinate bendrą talentą. Daugiau talentų lems aukštesnės kokybės kandidatus į darbą, o tai gali sumažinti NSA įgūdžių trūkumą; GCHQ jau kurį laiką naudoja panašius metodus.

    Atsisiuntimo nuoroda: https://ghidra-sre.org/ghidra_9.0_PUBLIC_20190228.zip

    Galerija

  • Analysis of a VB Script Heap Overflow (CVE-2019-0666)

    Anyone who uses RegEx knows how easy it is to shoot yourself in the foot; but, is it possible to write RegEx so badly that it can lead to RCE? With VB Script, the answer is yes!

    In this article I’ll be writing about what I assume to be CVE-2019-0666. The March 2019 security patch fixes multiple bugs in the same code, so the CVE number is uncertain.

    Note: this bug was not found by me, I reverse engineered it from the March 2019 security patch.

    Binary Comparison

    Running a BinDiff between the pre and post patch VBScript.dll, we can see only a few changes are returned.

    Difference between VBScript before and after installing the latest patch.

    The two changes in the RegExp class caught my eye. It’s easy to see how a bug could occur in something as complex as a RegEx parser. Let’s start here.

    RegExp::AddRef

    Old AddRef on the left, updated one on the right.

    This change is very simple, but requires an understanding of reference tracking:

    • A reference to an object is created: the reference counter is incremented by 1.
    • A reference to an object is deleted: the reference counter is decremented by 1.
    • The reference counter reached 0: object can be deleted.

    Reference tracking is designed to prevent deallocation of in-use objects (use-after-free). An object will should never be deleted until all its’ references destroyed.

    The updated function causes the interpreter to exit if the reference count increments above 0x7FFFFFFF (the highest value of a signed integer). The reason for the update is to prevent a potential integer overflow.

    Theoretically, by creating enough references, one could loop the reference counter back around to zero. Once the counter is zero, the object could be freed while references still exist.

    In reality, to cause an integer overflow we’d have to create 4,294,967,296 references. Optimistically assuming a single reference is only 4 bytes, that’d require use around 17 GB of RAM. Though, we’d hit the interpreter memory limit long before.

    Alone, this bug is not a threat; however, in combination with another bug it could lead to use-after-free (UAF). For example: a reference leak.

    RegExpExec::ReplaceUsingCallable

    Note: this function is too large to embed in full, so I’ve just pulled out only the relevant changes.

    Change 1: the beginning of RegExpExec::ReplaceUsingCallable.

    The code now creates a copy of the memory pointed to by a6 (argument 6). To understand the reasoning for this, let’s look at the next modification.

    Change 2: somewhere in the middle of RegExpExec::ReplaceUsingCallable.

    The old code verified that a6 pointed to Buf1. Now there exists an additional check comparing Buf1 with the copyof *a6 made earlier (Buf2).

    The very existence of code validating that a6 points to Buf1 tells us something important: a6 should point to Buf1, but there’s a possibility it might not. Furthermore, the new check implies it may be possible to change Buf1 between the first and 2nd call to Exec.

    Already, I’m fairly sure we’re looking for a use-after-free. The update is now verifying that a6 still points to Buf1, and that Buf1’s content hasn’t changed.

    There’s a logical reason these two checks would co-exist: Buf1 is some allocated memory, which can be freed during the call to ReplaceUsingCallable(). Assume Buf1 was freed, and something else was allocated in its’ place: *a6 would still point to Buf1, but Buf1 would now contain different data. Now the code has been patched to also validate Buf1 remains unchanged.

    To understand the patched bug more, we need to understand RegExp.

    RegExp has a replace function which replaces one or more matches of a given pattern with a given value. Take this code for example:

    Set regex = New RegExp
    regex.Pattern = "a"
    regex.Global = False
    MsgBox regex.replace("aaa", "b")
    

    The above code would replace the first instance of “a” in the string “aaa” with “b”; therefore, MsgBox would output “baa”. Stepping through the call, I found that internally the replace() method calls ReplaceUsingString(). We need to get to ReplaceUsingCallable(), and I’m pretty sure i know how.

    ReplaceUsingCallable

    As the name implies, we can probably call replace() using a callable objected as a parameter. I did some more digging to figure out how [1].

    The following code does the same as the previous version, but invokes ReplaceUsingCallable() instead.

    Set regex = New RegExp
    regex.Pattern = "a"
    regex.Global = False
    MsgBox regex.replace("aaa", GetRef("lolRegex"))
    
    Function lolRegex(singleMatch, position, fullString)
        lolRegex = "b"
    End Function
    

    Basically, whenever the pattern gets matched the function “lolregex” gets called (this is known as a callback). The callback must return what ever we want the pattern to be replaced with (in our case “b”).

    Now I’m even more sure this is some kind of use-after-free. My guess is that during the callback we can free Buf1 and allocate something else at same address. But first, we must know what Buf1 is.

    Buf1 is passed as a function argument, so i set a breakpoint at the start of ReplaceUsingCallable(). My breakpoint was triggered, then I navigated to Buf1’s memory.

    The data contained in Buf1.
    Using WinDbg to verify that Buf1 is in fact allocated on the heap.

    Buf1 is allocated on the heap; there are also two “a” towards the end of the memory. Figuring the ‘a’s might be related to my RegEx pattern, I changed the pattern to “lolregex”.

    new data contained in Buf1

    Success! Now I know that Buf1 is related to my RegEx pattern.

    My callback is invoked in the middle of ReplaceUsingCallable(), so I decided to modify pattern there.

    Set regex = New RegExp
    regex.Pattern = "a"
    regex.Global = False
    MsgBox regex.replace("aaa", GetRef("lolRegex"))
    
    Function lolRegex(singleMatch, position, fullString)
        'Change the RegEx pattern during the callback
        regex.Pattern = "I probably shouldn't be allowed to do this"
        lolRegex = "b"
    End Function
    
    A wild error code appears.

    The script returned the error code 0x80004005. A single location returns
    0x80004005; it’s the pointer check from earlier.

    I set a breakpoint on the pointer check and inspected both *a6 and Buf1. Buf1 is still the address of my old RegEx pattern (which has now been deallocated). Unfortunately, *a6 is now set to null. Exploit this bugwould require setting *a6 back to the address of Buf1.

    Passing The Pointer Validation

    After a fair amount of reverse engineering, I found the problem: although setting regex.Pattern to a new value frees Buf1, it doesn’t allocate a new buffer.

    put_Pattern gets called when a value is assigned to the regex.Pattern.

    Digging deeper, I discovered the function RegExpComp::Compile() is responsible for creating Buf1. Unfortunately, we can’t explicitly call regex.compile() in VBScript (though in other languages it is possible).

    Due to the fact compile() is a VTable function, I can’t just look at XRefs to see where it gets invoked. Instead, I set a breakpoint at the start of Compile(); then I inspected the callstack.

    The call stack for Compile()

    Somewhat unsurprisingly, compile() gets invoked during a call to regex.replace(). By making a redundant call to replace() inside the callback, it’s possible to force compile my new pattern.

    Set regex = New RegExp
    regex.Pattern = "a"
    regex.Global = False
    MsgBox regex.replace("aaa", GetRef("lolRegex"))
    
    Function lolRegex(singleMatch, position, fullString)
        regex.Pattern = "I probably shouldn't be allowed to do this"
        call regex.replace("", "") 'force pattern compile but do nothing
        lolRegex = "b"
    End Function
    

    Now when I run my script the check fails again, but for a different reason.

    *a6 is set again, but not to the address Buf1.

    The problem here is simple: the new compiled pattern must be allocated at the same address as the old one. It’s not possible to explicitly decide where heap memory is allocated; however, there is a workaround.

    I’m not going to go too deep into how the heap works here. If you’d like a more in-depth understand, I suggest reading the original paper on “Heap Feng Shui” [2].

    When allocating small blocks of memory, the heap allocator uses an algorithm to select some free space.

    Heap Coaleasing

    Upon freeing a block, the heap allocator checks if either of the adjacent blocks are also free. If two neighboring blocks are free, the are merged into a larger block (coalescing).

    An example heap layout prior to Allocated Block 1 being freed.
    Upon freeing Allocated Block 1, the freed space is merged with Free Block 1 & 2.

    Coalescing is a problem when trying to exploit a use-after-free. If the block we need to reallocate is coalesced downwards, then the new buffer would be allocated at a lower address.

    To stop coalescing from occurring, we can abuse the low-fragmentation heap (LFH).

    Heap allocations are inherently slow, due to the fact the allocator must search for a free block to fit the requested size.

    The LFH improves performance by grouping together allocations of the same size. Let’s assume a 30 byte allocation is requested: if there’s a dedicated heap where all allocations are 30 bytes, then the allocator can simply return the 1st free block (no need to check the size). Because all blocks on the LFH must be the same size, coalescing is disabled.

    Windows XP and below do not support the LFH. Though, this isn’t a problem because such systems are easy to exploit via other heap exploitation techniques (due to lack of mitigations).

    LFH Allocation Order Randomization

    On Windows 8 and above, a new mitigation was introduced to further complicate UAF exploitation. The LFH now no longer allocates blocks consecutively, instead the order is randomized. The allocator holds a list of free blocks, picking one at random each time an allocation is requested.

    Luckily, LFH randomization is not a problem for us; I’ll explain why.

    When a UAF exploit fails to re-allocate the target address, 1 of 3 things usually occurs.

    1. the memory is left unallocated, in which case the program crashes trying to use uninitialized memory.
    2. the memory gets re-allocated by something else, in which case the program crashes trying to use some random data.
    3. the program performs sanity checks on the memory, failing safely if something unexpected is located there.

    Remember the pointer check we’re trying to bypass? It basically validates the memory was allocated by a call to RegExpComp::Compile (i.e. contains a valid RegEx pattern). If we fail to re-allocate the same address, we won’t bypass the pointer check, thus the program won’t crash!

    All we need to do is set up an exception handler, then just keep trying to allocate the new pattern at the old address. Whoever said security checks are bad for exploit developers?

    'Just keep swimming...
    On Error Resume Next
    
    Set regex = new RegExp
    regex.Global = False
    
    'Re-allocate the pattern 19 times to enable LFH for this size allocation
    For idx=0 To 19
        regex.Pattern = pattern
        call regex.Replace("", "")
    Next
    
    'Attempt to trigger the use-after-free up to 5000
    For idx=0 To 4999
        regex.Pattern = "aaaaa"
        retval = regex.Replace("aaaaabbbbb", GetRef("lolRegex"))
    
        'if function returns succesfully, then our use-after-free succeeded
        If retval Then
            MsgBox "Attempt number " & idx & " succeeded!", 48, "Great Success!!!"
            Exit For
        End If
    Next
    
    Function lolRegex(singleMatch, position, fullString)
        'replace pattern with one of same size so it goes on same LFH
        regex.Pattern = "bbbbb"
        call regex.Replace("", "") 'force pattern compile
        lolRegex = "c"
    End Function
    

    Running the new script, we’ll get something like this (even on Windows 10 with all heap mitigations enabled).

    Now the question is, how is this helpful? To use the LFH, both the old and new patterns must be equal size. Why would replacing one RegEx pattern with another one of the same size be exploitable? Well, in this case size doesn’t matter…

    I went looking for allocations made based on data contained in the pattern buffer. Next I narrowed down the allocations to those made before I replace the pattern buffer, but used afterwards. I found one.

    RegExpExec::Cgrp reads a variable from the compiled pattern called “Cgrp” (group).

    After looking into the compilation of the pattern, I came to understand that “Cgrp” is the number of groups in the RegEx pattern. The allocation is done prior to calling ReplaceUsingCallable(); therefore, persists throughout my reallocation of the pattern.

    RegExp::ReplaceUsingCallable() makes multiple calls to a function named
    RegExpExec::Exec(). Exec() is responsible for performing the actual pattern matching; inside is the following code.

    sets all bytes of the previously allocated group_array to 0xFF.

    The memset is done based on my pattern’s Cgrp value; which, I can change. If I recompiled the pattern with one of the same size, but with more regex groups, I’d overflow “group_array”.

    For example, the pattern “aaaaaa” contains 1 group, whilst “(a)(a)” contains 2 groups and is the same length. Due to the fact the memset sets the entire buffer, the size of the pattern in each group is irrelevant.

    In order to perform a successful heap overflow, there are some requirements.

    Firstly, RegExpExec::Exec() must be called after I replace the pattern buffer. This can be done by setting the RegExp.Global option to True.

    When Global is set, RegExp::ReplaceUsingCallable will replace every instance of the given pattern. The flow is as follows.

    1. Call RegExpExec::Exec() to see determine if there are any matches of the regex pattern in the source string.
    2. If a pattern match is found, invoke the supplied callback.
    3. Replace the match with the value returned by the callback.
    4. If global is set, enter a loop performing 1 – 3, until all matches are replaced.

    What I can do is set Global to True, then create a string which matches the original pattern at least twice. When the callback is called, I will replace the pattern with one of the same size, but containing more groups. Upon the second call to Exec(), a heap overflow will occur.

    After some calculation, I found a single and multi-group pattern of the same internal size. My malicious pattern contains 30 groups, whilst the original contains only 1.

    malicious_pattern = "(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)"
    original_pattern = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

    The finalized code will overflow the heap with invalid data, leading to a program crash. For demonstration, I’ve chained the bug with CVE-2019-0768, which allows execution of VBScript in IE11.

    
    lolregex
    
    
    
    
    
    
    

    Now, let’s visit the page using IE11 on a system without the March 2019 security patch! I used Windows 7 because most crashes are silent on Windows 10.

    Conclusion

    The exploit offers a decent out-of-bounds (OOB) write primitive, which can be targeted at either the general or low-fragmentation heap. With such a primitive, it’s possible to escalate to arbitrary read/write, thus RCE. For obvious reasons, I will not be providing any information on how to achieve a weaponized exploit.

    Interestingly, the “Enable ActiveX” prompt can be bypassed. Compiling the script into a safe-for-initialization ActiveX object leads to it being run immediately, without warning. Furthermore, the exploit can be triggered in any application that hosts the IE rendering engine. It may even be possible to trigger code execution from within an Office document, without macros enabled.

    Anyway, that’s all! Thank you for coming to my talk on how to write safe and secure RegEx!

    1. VBScript RegEx Callbacks –
      http://cwestblog.com/2011/07/18/vbscript-regexp-replace-using-a-callback-function/
    2. Heap Feng Shui –
      https://www.blackhat.com/presentations/bh-europe-07/Sotirov/Presentation/bh-eu-07-sotirov-apr19.pdf
  • CVE-2019-0708 („BlueKeep“) analizė – „MalwareTech“

    Aš sulaikiau šį rašymą, kol koncepcijos įrodymas (PoC) buvo viešai prieinamas, kad nepadarytų jokios žalos. Dabar, kai „github“ yra keletas atsisakymo teikti paslaugas PoC, skelbiu savo analizę.

    Kaip visada, pradėjau nuo pataisos modifikuotų dvejetainių failų BinDiff (šiuo atveju yra tik vienas: TermDD.sys). Žemiau matome rezultatus.

    TermDD.sys BinDiff prieš ir po pataisų.

    Dauguma pakeitimų pasirodė gana kasdieniški, išskyrus „_IcaBindVirtualChannels“ ir „_IcaRebindVirtualChannels“. Abiejose funkcijose buvo tas pats pakeitimas, todėl sutelkiau dėmesį į pirmąją, nes susiejimas greičiausiai įvyktų prieš surišant iš naujo.

    Originalūs IcaBindVirtualChannels yra kairėje, pataisyta versija yra dešinėje.

    Pridėta nauja logika, keičianti _IcaBindChannel iškvietimą. Jei palyginama eilutė yra lygi „MS_T120“, trečiasis _IcaBindChannel parametras nustatomas į 31.

    Atsižvelgiant į tai, kad pakeitimas įvyksta tik tuo atveju, jei v4+88 yra „MS_T120“, galime manyti, kad norint suaktyvinti klaidą, ši sąlyga turi būti teisinga. Taigi, mano pirmasis klausimas: kas yra „v4+88“?

    Žvelgdamas į IcaFindChannelByName logiką, greitai radau atsakymą.

    „IcaFindChannelByName“ viduje

    Naudodamiesi pažangiomis anglų kalbos žiniomis, galime iššifruoti, kad „IcaFindChannelByName“ suranda kanalą pagal jo pavadinimą.

    Atrodo, kad funkcija kartoja kanalų lentelę, ieškodama konkretaus kanalo. 17 eilutėje yra a3 ir v6+88 eilučių palyginimas, kuris grąžina v6, jei abi eilutės yra lygios. Todėl galime manyti, kad a3 yra kanalo pavadinimas, kurį reikia rasti, v6 yra kanalo struktūra, o v6+88 yra kanalo pavadinimas kanalo struktūroje.

    Remdamasis visa tai, kas išdėstyta aukščiau, padariau išvadą, kad „MS_T120“ yra kanalo pavadinimas. Toliau man reikėjo išsiaiškinti, kaip iškviesti šią funkciją ir kaip nustatyti kanalo pavadinimą į MS_T120.

    Nustačiau pertraukos tašką „IcaBindVirtualChannels“, ten, kur vadinama „IcaFindChannelByName“. Vėliau prisijungiau prie KPP su teisėtu KPP klientu. Kiekvieną kartą, kai suveikė pertraukos taškas, aš patikrinau kanalo pavadinimą ir skambučių krūvą.

    Skambučių paketas ir kanalo pavadinimas pirmą kartą skambinant į IcaBindVirtualChannels

    Pats pirmasis skambutis į IcaBindVirtualChannels skirtas kanalui, kurio noriu, MS_T120. Tolesni kanalų pavadinimai yra „CTXTW“, „rdpdr“, „rdpsnd“ ir „drdynvc“.

    Deja, pažeidžiamo kodo kelias pasiekiamas tik tada, kai „FindChannelByName“ pavyksta (ty kanalas jau yra). Tokiu atveju funkcija nepavyksta ir sukuriamas MS_T120 kanalas. Kad suaktyvinčiau klaidą, turėčiau antrą kartą iškviesti IcaBindVirtualChannels kanalo pavadinimu MS_T120.

    Taigi dabar mano užduotis buvo išsiaiškinti, kaip iškviesti IcaBindVirtualChannels. Skambučių krūvoje yra IcaStackConnectionAccept, todėl kanalas greičiausiai bus sukurtas prisijungus. Tiesiog reikia rasti būdą, kaip atidaryti savavališkus kanalus po prisijungimo… Galbūt teisėto KPP ryšio uostymas suteiktų šiek tiek įžvalgos.

    KPP ryšio sekos fiksavimas

    Kanalų masyvas, kaip matyti iš WireShark RDP analizatoriaus

    Antrame atsiųstame pakete yra keturi iš šešių kanalų pavadinimų, kuriuos mačiau, perduodamus „IcaBindVirtualChannels“ (trūksta MS_T120 ir CTXTW). Kanalai atidaromi tokia tvarka, kokia jie yra pakete, todėl manau, kad tai kaip tik tai, ko man reikia.

    Matant, kad MS_T120 ir CTXTW niekur nenurodyti, o atidaryti prieš kitus kanalus, manau, jie turi atsidaryti automatiškai. Dabar įdomu, kas nutiks, jei įdiegsiu protokolą ir pridėsiu MS_T120 prie kanalų masyvo.

    Perkėlus pertraukos tašką į tam tikrą kodą, tik tada, kai „FindChannelByName“ pavyksta, atlikau testą.

    Lūžio taškas pasiekiamas į kanalų masyvą įtraukus MS_T120

    Nuostabu! Dabar pažeidžiamo kodo kelias nukentėjo, man tereikia išsiaiškinti, ką galima padaryti…

    Norėdamas sužinoti daugiau apie kanalo veiklą, nusprendžiau išsiaiškinti, kas jį sukūrė. Nustačiau pertraukos tašką „IcaCreateChannel“, tada pradėjau naują KPP ryšį.

    Skambučių krūva, kai paveikiamas IcaCreateChannel lūžio taškas

    Po skambučių krūvos žemyn matome perėjimą iš vartotojo į branduolio režimą ntdll!NtCreateFile. Ntdll tiesiog pateikia branduolio pavyzdį, todėl tai neįdomu.

    Žemiau yra ICAAPI, kuris yra TermDD.sys vartotojo režimo atitikmuo. Skambutis pradedamas naudojant ICAAPI „IcaChannelOpen“, todėl tai tikriausiai yra „IcaCreateChannel“ vartotojo režimo atitikmuo.

    Kadangi „IcaOpenChannel“ yra bendra funkcija, naudojama visiems kanalams atidaryti, nusileisime dar vienu lygiu į „rdpwsx!MCSCreateDomain“.

    rdpwsx!MCSCreateDomain kodas

    Ši funkcija tikrai daug žadanti dėl kelių priežasčių: Pirma, ji iškviečia „IcaChannelOpen“ užkoduotu pavadinimu „MS_T120“. Antra, jis sukuria IoCompletionPort su grąžinta kanalo rankena (užbaigimo prievadai naudojami asinchroniniam įvesties / išvesties).

    Kintamasis pavadinimu „CompletionPort“ yra užbaigimo prievado rankena. Žvelgdami į xrefs prie rankenos, tikriausiai galime rasti funkciją, kuri tvarko įvesties / išvesties į prievadą.

    Visos nuorodos į „CompletionPort“

    Na, MCSIinitialize tikriausiai yra gera vieta pradėti. Inicijavimo kodas visada yra gera vieta pradėti.

    Kodas, esantis MCSIinitialize

    Gerai, todėl užbaigimo prievadui sukuriama gija, o įėjimo taškas yra „IoThreadFunc“. Pažiūrėkime ten.

    Užbaigimo prievado pranešimų tvarkytuvė

    „GetQueuedCompletionStatus“ naudojamas duomenims, išsiųstiems į užbaigimo prievadą (ty kanalą), gauti. Jei duomenys sėkmingai gauti, jie perduodami MCSPortData.

    Kad patvirtinčiau savo supratimą, parašiau pagrindinį KPP klientą su galimybe siųsti duomenis KPP kanalais. MS_T120 kanalą atidariau naudodamas anksčiau paaiškintą metodą. Kai atidariau, nustatau MCSPortData pertraukos tašką; tada išsiunčiau eilutę „MalwareTech“ į kanalą.

    Pertraukos taškas pasiektas MCSPortData, kai duomenys siunčiami į kanalą.

    Tai patvirtina, kad galiu skaityti / rašyti į MS_T120 kanalą.

    Dabar pažiūrėkime, ką MCSPortData daro su kanalo duomenimis…

    MCSPortData buferio tvarkymo kodas

    ReadFile nurodo, kad duomenų buferis prasideda nuo channel_ptr+116. Netoli funkcijos viršaus yra chanel_ptr+120 (4 poslinkis į duomenų buferį) patikrinimas. Jei dword nustatytas į 2, tada funkcija iškviečia HandleDisconnectProviderIndication ir MCSCloseChannel.

    Na, tai įdomu. Kodas atrodo kaip tam tikra tvarkytuvė, skirta susidoroti su kanalo prijungimo / atjungimo įvykiais. Išnagrinėjęs, kas paprastai suaktyvintų šią funkciją, supratau, kad MS_T120 yra vidinis kanalas ir paprastai nėra rodomas išorėje.

    Nemanau, kad mes čia turime būti…

    Būdamas šiek tiek smalsus, išsiunčiau duomenis, reikalingus skambučiui suaktyvinti, į MCSChannelClose. Be abejo, priešlaikinis vidinio kanalo uždarymas negali sukelti problemų, ar ne?

    O, ne. Mes sudaužėme branduolį!

    Oi! Pažvelkime į klaidų patikrinimą, kad geriau suprastume, kas atsitiko.

    Atrodo, kad kai mano klientas atsijungė, sistema bandė uždaryti MS_T120 kanalą, kurį jau buvau uždaręs (dėl to du kartus nemokama).

    Dėl kai kurių „Windows Vista“ pridėtų švelninimo priemonių dvigubai nemokamus pažeidžiamumus dažnai sunku išnaudoti. Tačiau yra kažkas geresnio.

    Kanalo valymo kodo vidinės dalys veikia, kai ryšys nutrūksta

    Viduje sistema sukuria MS_T120 kanalą ir susieja jį su ID 31. Tačiau kai jis susietas naudojant pažeidžiamą IcaBindVirtualChannels kodą, jis susiejamas su kitu ID.

    Kodo skirtumas prieš pataisą ir po jo

    Iš esmės MS_T120 kanalas susiejamas du kartus (vieną kartą viduje, tada vieną kartą mes). Dėl to, kad kanalas yra susietas pagal du skirtingus ID, gauname dvi atskiras nuorodas į jį.

    Kai kanalui uždaryti naudojama viena nuoroda, nuoroda ištrinama, kaip ir kanalas; tačiau kita nuoroda išlieka (žinoma kaip nenaudoti po to). Su likusia nuoroda dabar galima įrašyti branduolio atmintį, kuri mums nebepriklauso.

    2 dalis (kaip DoS paversti RCE): https://www.malwaretech.com/2019/09/bluekeep-a-journey-from-dos-to-rce-cve-2019-0708.html

  • „YouTube“ įsilaužimo mokymo programų politika yra problemiška

    Neseniai „YouTube“ pakeitė savo „įsilaužimo“ mokymo programų politiką į esminį visuotinį draudimą. Anksčiau toks turinys retkarčiais būdavo pašalinamas pagal platų „YouTube“ nuostatą „Žalingas ir pavojingas turinys“, draudžiančią vaizdo įrašus, „skatinančius neteisėtą veiklą“. Atnaujinta politika dabar konkrečiai taikoma mokomiesiems įsilaužimo vaizdo įrašams.

    Ankstesnė „YouTube“ politika tiesiog uždraudė „skatinti pavojingą ar nelegalią veiklą“, pateikiant kelis pavyzdžius.
    Naujojoje politikoje pateikiamas daug konkretesnis turinio sąrašas, įskaitant aiškų „mokomąjį įsilaužimą ir sukčiavimą“ draudimą.

    Viena iš pagrindinių problemų yra ta, kad įsilaužimo vadovėliai iš esmės nėra blogi. Egzistuoja didžiulė „YouTube“ bendruomenė, kurios tikslas – mokyti naujos kartos kibernetinio saugumo ekspertus.

    Jei paprašytumėte, kad kas nors atpažintų asmenį, įsilaužantį į namus, daugeliu atvejų jie galėtų tai padaryti. Visi žino, kad galima lipti pro atvirą langą, bet kiek gali atpažinti įsilaužėlį, įsilaužusį į svetainę? Tikriausiai labai mažai. Nežinant, ką tai daro įsilaužėliai ir kaip jie tai daro, kaip galima tikėtis, kad kas nors užkirs kelią jiems arba sustabdys? Atsakymas paprastas: jie negali.

    Taip pat nėra taip, kad ši politika yra tik atsargumo priemonė. Kody Kinzie, gerai žinomo „YouTube“ naudotojo ir „Blogger“, kuriančio švietimo saugos turinį, paskyra jau buvo sustabdyta.

    Nepaisant naujosios „YouTube“ politikos tikslo, naivu manyti, kad vidutiniai moderatoriai sugebės atskirti „gerą“ ir „blogą“ įsilaužimo vaizdo įrašą.

    „YouTube“ draudimas įsilaužti į mokymo programas yra tik maža dalis daug didesnės problemos: seniai paplitusio įsitikinimo, kad bet koks įsilaužimas yra blogas. Būtina suprasti, kad visos žinios apie įsilaužimą yra teisėtai naudojamos. Panagrinėkime kai kuriuos įsilaužimo įgūdžius, kurie paprastai, nors ir klaidingai, suprantami kaip neteisėti arba neetiški.

    • Sukčiavimas kredito kortelėmis
      Neetiška: vogti pinigus iš nieko neįtariančių žmonių.
      Etinis: sukurti sistemą, kuri leistų aptikti pavogtas kredito korteles ir užkirsti jai kelią.
    • DDoSing
      Neetiška: verslo trikdymas pašalinant jų el. prekybos svetaines iš interneto.
      Etiška: paslaugų, skirtų DDoS atakoms sumažinti, projektavimas ir testavimas.
    • Kenkėjiškų programų rašymas
      Neetiška: užkrėsti ir sunaikinti žmonių kompiuterius.
      Etiška: netikrų kenkėjiškų programų atakų modeliavimas, siekiant patikrinti jūsų organizacijos gebėjimą aptikti kenkėjiškų programų protrūkį ir į jį reaguoti.
    • Įsilaužimo į svetaines
      Neetiška: įsilaužimas į svetaines ir konfidencialių vartotojų duomenų vagystė.
      Etiška: svetainės programinės įrangos patikrinimas, ar nėra saugumo spragų, prieš pradedant ją naudoti plačiajai visuomenei.

    Mano asmeninis įsitikinimas yra tas, kad kalbant apie įsilaužimą svarbu ne tai, ko moko, o kaip ir kas. Kontekstas yra nepaprastai svarbus, ypač potencialiai jaunų ir įspūdingų paauglių auditorijai. Įsilaužimo vadovėliai visada bus prieinami, kad ir kas būtų, vienintelis tikras klausimas yra kur.

    Norėdamas papildyti savo mintį, apsilankiau gerai žinomame įsilaužimo forume. Aptariamas forumas nėra kokia nors slapta, tik pakvietimu skirta pogrindžio „darkweb“ nusikaltėlių slėptuvė: jame kalbama angliškai, registracija yra atvira visiems ir lengvai randama „Google“ ieškant įsilaužimo pamokų.

    Kenkėjiškos programos dažnai parduodamos forume, kur kai kurie vartotojai teigia, kad jos pardavimas nėra nei neteisėtas, nei neetiškas. Dažnas argumentas yra toks: ginklų gamintojai nėra laikomi atsakingais, kai vienas iš jų ginklų panaudojamas šaudant; todėl kenkėjiškų programų pardavėjai taip pat neturėtų būti. Argumentas yra labai ydingas, tačiau daugelis vartotojų jį reguliariai papagailo.

    Štai keletas komentarų gijoje apie vartotoją, sulaikytą už kenkėjiškų programų pardavimą.

    Štai ginčas dėl ginklo.
    Vėl tas pats ginčas dėl ginklo.
    Vėl ginčas su ginklu, bet labiau britiškas.

    Taigi, kaip pavogti žmonių kreditines korteles? Žinoma, bent jau sutariama, kad tai neetiška ir neteisėta. Na, štai atsakymas į giją, kurią vartotojas klausia, ar jie būtų areštuoti už kredito kortelių vagystę.

    Vartotojas teigia, kad jie nebūtų suimti, o auka tiesiog „atgautų pinigus iš banko“.

    Tada pateikiamas toks atsakymas į giją, kurią vartotojas klausia, kaip užsidirbti pinigų iš savo botneto (nelegaliai įsilaužtų kompiuterių rinkinio).

    Be kita ko, vienas vartotojas skatina užkrėsti aukas išpirkos programomis dėl jos „labai gero sėkmės rodiklio“.

    Nors galima ginčytis, forumas nėra blogas (jame tikrai yra daug etiškų vartotojų); tačiau lentoje gausu pavojingų ir klaidinančių patarimų.

    Reikia paklausti, kur mes, vaikai, norėtume sužinoti apie kompiuterių saugą?
    Tokios svetainės kaip „YouTube“, kur saugumo specialistai nukreips juos teisėto darbo, šešiaženklių atlyginimų ir griežtos etikos link?
    Arba šešėlinis forumas, kuriame jie ne tik susidurs su nusikaltimais, bet ir nusikaltėliais, kurie tiki, kad tai, ką jie daro, yra teisėta ir etiška?

    Daugelis nusikaltėlių ir buvusių nusikaltėlių įsilaužėlių pradėjo vaikystėje, domėjosi tik kompiuteriais. Ar neryškūs forumai, kuriuose norime, kad būtų lengvai pažeidžiami bendraamžių įtaka, susitinka? Ar politika, kuria siekiama slopinti švietimo turinį, baiminantis piktnaudžiavimo, verta sukurti tuos nusikaltėlius, kuriems siekiama užkirsti kelią?

  • DejaBlue: KPP krūvos perpildymo analizė

    2019 m. rugpjūtį „Microsoft“ paskelbė, kad pataisė KPP klaidų rinkinį, iš kurių dvi buvo užkrėstos. Kirminų klaidos, CVE-2019-1181 ir CVE-2019-1182, turi įtakos kiekvienai OS nuo Windows 7 iki Windows 10. Kyla painiavos dėl to, kuri CVE yra, nors gali būti, kad abu susiję su ta pačia klaida. Pažeidžiamas kodas yra ir RDP kliente, ir serveryje, todėl jį galima išnaudoti bet kuria kryptimi.

    BinDiff arba RDPCoreTS.dll (vienintelis su RDP susijęs failas pakeistas sistemoje Windows 7).

    Iš ankstesnio darbo su RDP manau, kad funkcijas DecodeFormatData ir SendFormatDataRequest galima iškviesti tik po autentifikavimo; paliekant tik išskleidimo funkciją.

    Nepataisytos ir pataisytos išskleidimo funkcijos palyginimas.

    Originalus kodas (kairėje) yra šiek tiek netvarka, nes jis buvo optimizuotas į vieną if teiginį. Atnaujintas kodas (dešinėje) yra šiek tiek mažiau netvarkingas ir turi tam tikrą papildomą patvirtinimą.

    24 eilutėje pridedamas kodas, kuris patikrina, ar v11 + 0x2000 yra mažesnis nei v11. Jei sąlyga teisinga, nustatomas klaidos kodas, dėl kurio vėliau funkcija nutraukiama. Galbūt klausiate, kaip čekis gali nepavykti. Kaip prie sveikojo skaičiaus pridėjus 0x2000 jis gali būti mažesnis nei anksčiau? Atsakymas yra: per sveikojo skaičiaus perpildymą.

    Nežymėtas sveikasis skaičius yra 4 baitai ir gali turėti bet kokią reikšmę nuo 0 iki 0xFFFFFFFF (4 294 967 295). Jei sveikasis skaičius padidinamas virš didžiausios vertės, jis sukasi iki nulio. Taigi, jei v11 buvo 0xFFFFFFFF, pridėjus 0x2000, galutinė vertė būtų 0x1FFF, kuri yra mažesnė nei pradinė.

    v11 naudojamas kaip krūvos paskirstymo, atliekamo naudojant „naują“ operatorių, dydis. Daroma prielaida, kad jei galime perpildyti v11, paskirstymas būtų mažesnis nei išspausti duomenys, o tai sukeltų krūvos perpildymą.

    Kad geriau suprasčiau, kaip išnaudoti sveikųjų skaičių perpildymą, turėjau žinoti, kokias vertes valdau ir kaip iškviesti pažeidžiamą funkciją. Norėdami tai padaryti, aš parodžiau DecompressUnchopper::DecompressUnchopper (DecompressUnchopper klasės inicijavimo funkcija). Tada aš ir toliau naudoju „xrefs to“, kad vaikščiočiau atgal, kol radau funkciją, kuri naudoja šią klasę. Galiausiai atėjau į CRdpDynVCMgr::HandleIncomingDvcData.

    Iš ankstesnio darbo su RDP (dokumentų skaitymo valandos) žinojau, kad DynVC buvo trumpinys „Dynamic Virtual Channel“. DVC sąsaja leidžia palaikyti ryšį tarp kliento ir serverio modulių ir palaiko neapdorotus ir suspaustus duomenis. Tikėtina, kad pažeidžiama „išskleidimo“ funkcija gali būti paveikta siunčiant suglaudintus duomenis.

    Jau turėdamas pasirinktinį KPP klientą, parašytą „BlueKeep“ išnaudojimui, pridėjau kodą, kad atidaryčiau DVC kanalą ir atsiųsčiau kai kuriuos bandymo duomenis.

    Siunčiama eilutė „MalwareTech123“ į DVC kanalą.

    Prijungęs derintuvą prie KPP serverio proceso, DecompressUnchopper::Decompress nustatiau pertraukos tašką ir paleidau savo kodą.

    DecompressUnchopper::Decompress lūžio taškas.

    rdx (2-asis argumentas) yra mano išsiųsti bandymo duomenys, o r8 (3-as argumentas) yra duomenų ilgis. Dabar, žinodamas funkcijos parametrus, galėjau išvalyti dekompiliuotą kodą.

    Išvalytas dekompresijos kodas.

    Dabar laikas pažiūrėti, ar galiu sukelti avariją.

    Siekdamas patikrinti pažeidžiamumą sudaužydamas RDP serverį, sukūriau kenkėjišką DVC paketą.

    Kenkėjiško DVC paketo kūrimas.

    Nustačiau lauką uncompressedSize į 1 – 0x2000 (0xFFFFE001), kad pridėjus 0x2000, jis būtų maždaug 1. Tada nustatiau, kad suspaustuose duomenyse būtų raidė „A”, kartojama 0x200 kartų, todėl turėtų susidaryti krūva. buferis perpildytas 0x1FF baitais.

    Puiku, dabar galiu įrašyti savavališkus savavališko dydžio duomenis į gretimus krūvos paskirstymus! Ši klaida yra galinga, nes objektų egzemplioriai saugomi toje pačioje krūvoje, todėl juos galima perrašyti.

    Pavyzdžiui, pakeičiau objekto VTable žymeklį, kad programa atliktų ptr skambutį adresu 0x1337133713371337.

  • BlueKeep: kelionė iš DoS į RCE (CVE-2019-0708)

    Dėl rimtos „BlueKeep“ pagrįsto kirmino pavojaus sulaikiau šį rašymą, kad išvengčiau laiko juostos pailginimo. Dabar, kai RCE (nuotolinio kodo vykdymo) koncepcijos įrodymas buvo išleistas kaip Metasploit dalis, manau, kad dabar galiu tai paskelbti saugu.

    Šis straipsnis bus mano ankstesnės analizės tęsinys.

    Kaip minėjau ankstesniame straipsnyje, galime atlaisvinti su MS_T120 kanalu susietą duomenų struktūrą. Vien struktūros atlaisvinimas nėra labai naudingas, o jos turinio kontrolė yra naudinga. Naudojant UAF (naudojimas po-nemokamas), tikslas yra išlaisvinti objektą, tada vietoj jo paskirti netikrą. Pakeitę tikro objekto turinį savo duomenimis, įgyjame platesnę kodo, naudojančio jį, valdymą. Tai, ką galime padaryti su savo netikra kanalo struktūra, visiškai priklauso nuo to, kam ši struktūra naudojama (apie tai pakalbėsime vėliau).

    Suaktyvinus UAF, MS_T120 kanalo struktūra panaikinama, bet vis tiek tinkama naudoti. Norėdami išnaudoti šį UAF, turime paskirstyti naujus duomenis tuo pačiu adresu, kuriame anksčiau buvo kanalo struktūra.

    Kanalų struktūros paskirstomos ne puslapių telkinyje. Norėdami užgrobti atlaisvintą struktūrą, turime turėti galimybę paskirstyti savavališkus duomenis ne puslapių telkinyje. Norėdami išsiaiškinti būdą, išanalizavau ExAllocatePool variantų (malloc branduolio atitikmens) iškvietimus.

    Idealiai atrodantis ne puslapių telkinio paskirstymas viduje IcaChannelIntputInternal.

    Tai iš esmės yra purškimo ant krūvos šventasis gralis. Duomenys, siunčiami į kanalą, yra saugomi Nepuslapių telkinyje, todėl galime atlikti bet kokio dydžio ne puslapių telkinio paskirstymą, kuriame yra bet kokių norimų duomenų!

    Vienintelis įspėjimas yra tai, kad šis paskirstymas yra skirtas IOCP eilei, iš kurios kanalo tvarkyklės apdoroja pranešimus. Kai pranešimas perskaitomas, jis pašalinamas iš eilės ir panaikinamas. Tačiau keletas tyrėjų nustatė, kad tam tikras kanalas niekada neskaito pranešimų iš eilės ir palieka juos paskirstyti tol, kol bus nutrauktas ryšys.

    Dabar, jei išsiunčiame tokio pat dydžio paskirstymus kaip kanalo struktūra, jis greičiausiai pateks į išlaisvinto kanalo paliktą skylę (tai vadinama krūvos purškimu). Norėdami padidinti sėkmingo paskirstymo tikimybę, galime atlikti tai, kas vadinama krūvos priežiūra, kad įsitikintume, jog niekas daugiau tuo adresu nepaskirtas; tačiau tai sudėtinga tema, kurioje daug rašinių, todėl čia nesileisiu į ją.

    Kanalo struktūrą, kurią galime pakeisti, grąžina funkcijos IcaFindChannel ir IcaFindChannelByName. Norint sužinoti, ką galima padaryti manipuliuojant šia kanalo struktūra, turėjau rasti, kur ji buvo naudojama. Atlikęs IcaFindChannel xref, radau šį kodą.

    Iškirpta iš IcaChannelInputInternal, funkcijos, kuri apdoroja virtualaus kanalo įvestį.

    Aukščiau pateiktas kodas patikrina, ar kanalo struktūros „vtable“ laukas yra ne nulis, tada, jei taip, atšaukia nuorodą ir atlieka netiesioginį iškvietimą į jį. Norėdami tai išnaudoti, turėtume nukreipti channel_struct->vtable į kokią nors mūsų valdomą atmintį, tada toje atmintyje išsaugoti žymeklį į mūsų apvalkalo kodą.

    RCE atminties išdėstymas turėtų atrodyti taip.

    Netiesioginis skambutis per netikrą VTable.

    Deja, yra tam tikrų problemų.

    1. Mums reikia netikros kanalo struktūros, kad būtų nurodyta netikra VTable, bet mes neturime netikros VTable adreso.
    2. Mums reikia netikros VTable, kad būtų nurodytas apvalkalo kodas, bet mes neturime apvalkalo kodo adreso.

    Bet nebijokite, visada yra išeitis!

    Kaip žmogus, dirbantis tik su „Windows 10“, iš pradžių ėjau sudėtingesniu keliu, tuo pačiu metu bandydamas apeiti ASLR (adresų erdvės išdėstymo atsitiktinį nustatymą) ir DEP (duomenų vykdymo prevenciją, AKA No Execute). Tai buvo tada, kai Ryanas Hansonas (@ryHanson) davė man tokią užuominą: „Tame purškime yra kažkas dar ypatingesnio. Atminkite, kad tai yra „Win7“.

    Žinoma! Tai „Windows 7“! Kalbant apie branduolio atmintį be puslapių, DEP nėra. Tiesiogine prasme galime tiesiog įrašyti apvalkalo kodą tiesiai į branduolį (atminkite, kad mano paaiškintas purškimo krūvos metodas leidžia mums paskirstyti savavališkus duomenis ne puslapių telkinyje).

    Patobulintas atminties išdėstymas dabar atrodo maždaug taip.

    Tiek VTable, tiek Shellcode gali būti tame pačiame atminties buferyje, nes jis yra RWX (skaitomas, rašomas, vykdomas).

    Mums nereikia ROP grandinės, kad galėtume įrašyti apvalkalo kodą į vykdomąją atmintį, kaip tai darytume vartotojo režimu, galime tiesiog išpurkšti jį į puslapių neturintį telkinį. Tik paskutinė problema: kaip gauti paskirstymo adresą, kad būtų galima nustatyti VTable žymeklį kanalo struktūroje?

    „Windows 7“ ir senesnėse versijose ne puslapių telkinys prasideda fiksuotu adresu (Nt!MmNonPagedPoolStart). Mes žinome, kur prasideda ne puslapių rinkinys, bet nežinome, kur ne puslapių rinkinyje yra mūsų apvalkalo kodas… Bet mes galime tai šiek tiek kontroliuoti.

    Atmintis be puslapių yra šventa, nes jos dydis yra ribotas dėl puslapių trūkumo. Dėl to branduolys paprastai vengia jo naudoti bet kam, ko nebūtinai turi būti. Tai reiškia, kad atminties naudojimas yra gana mažas.

    Ką galime padaryti, tai pasirinkti adresą (tarkime, 500 MB į puslapių neturintį telkinį), kuris greičiausiai nebus paskirstytas dėl mažo atminties naudojimo. Tada išpurškiame pakankamai apvalkalo kodo kopijų, kad užpildytume nepuslapių telkinį už mūsų pasirinkto adreso, todėl labai tikėtina, kad apvalkalo kodo kopija bus ten.

    Kadangi dauguma objektų, kurie dažnai skiriami ne puslapių telkinyje, yra labai maži, galime sukurti daug skylių, mažesnių nei mūsų apvalkalo kodo dydis (iki pasirinkto adreso), užtikrinant, kad ten būtų paskirstyti kiti skyrimai.

    Tada galime nustatyti VTable žymeklį savo netikrų kanalų struktūroje mūsų pasirinktu adresu, todėl apvalkalo kodas bus vykdomas kiekvieną kartą, kai kanalas gauna pranešimą.

    Viena iš priežasčių, kodėl šis pažeidžiamumas yra toks pavojingas, yra tai, kad nėra realių paveiktos sistemos mažinimo priemonių. DEP nebuvimas branduolyje ir daug gerai dokumentuotų statinių adresų reiškia, kad adreso nutekėjimo + ROP grandinės poreikis yra pašalintas. Be to, VTable buvimas jau suteikia savavališką vykdymo primityvą, todėl DoS paversti RCE reikia labai mažai.

    Šaukite nulis 0x0 ir Ryanas Hansonas už puikų darbą su „BlueKeep“, taip pat visiems, kurie sulaikė informaciją apie pažeidžiamumą, kad organizacijoms duotų mėnesių pataisyti.

  • Kaip radau savo pirmą „ZeroDay“ (KPP)

    Iki šiol niekada nebandžiau pažeidžiamumo tyrimo klaidų medžioklės dalies. Daugiau nei dešimtmetį tobulinu „Windows“ kenkėjiškas programas ir retkarčiais atlikdavau pataisų analizę, bet niekada nemačiau prasmės ieškoti klaidų pagrindinėje OS. Galų gale, yra pažeidžiamumo tyrinėtojų komandos, turinčios dešimtmečių patirtį, tikrinančios kiekvieną kodo colį, taigi kokia tikimybė, kad kažkas naujo, kaip aš, ką nors ras? Šansai atrodė neįmanomi, todėl niekada nesivarginau bandyti. Tik tada, kai pradėjau keisti BlueKeep pataisą, mano požiūris į klaidų medžioklę pradėjo keistis.

    2019 m. gegužės mėn. „Microsoft“ išleido precedento neturintį įspėjimą apie būsimą saugos pataisą. Po 2017 m. „WannaCry“ sukurto chaoso (kuriam buvo naudojamas pataisytas pažeidžiamumas, žinomas kaip „EternalBlue“), „Microsoft“ nerizikavo. Įspėjimas informavo apie būsimą didelio kirminų pažeidžiamumo pataisymą ir paskatino Windows naudotojus įdiegti pataisą, kai tik ji bus prieinama.

    Pati pataisyta klaida buvo niūri. Tai buvo išankstinio autentifikavimo RCE pažeidžiamumas, turintis įtakos visoms Windows versijoms iki Windows 8. Tiesą sakant, jis buvo toks blogas, kad Microsoft netgi išleido pataisas nutrauktoms operacinėms sistemoms, pvz., XP ir Server 2003. Nors galėjo būti lengva parašyti šią klaidą. Atsiradus ir išnykus dar vienam epiniam pažeidžiamumui, jis papasakojo apie esminius KPP trūkumus.

    Jei nesate susipažinę su „BlueKeep“ veikimu, labai rekomenduoju perskaityti mano rašymą čia.

    Greitas atnaujinimas: kad suaktyvintų „BlueKeep“, kenkėjiškas klientas prisijungia prie kanalo „MS_T120“, kuris naudojamas tik serverio viduje. Kanalo protokolas įgyvendina uždarymo užklausą, kurią klientas gali išsiųsti. Kadangi kanalas yra vidinis, serveris tikisi, kad jis bus uždarytas tik serveriui jį uždarius. Prieš laiką uždarydamas kanalą, klientas suaktyvina būseną „Naudoti po nemokamo naudojimo“, kurią galima išnaudoti.

    Pataisa ištaiso naudojimo po nemokamo naudojimo (UAF) sąlygą, pagerindama kanalo uždarymo užklausos tvarkymą, tačiau išryškina didesnę ir plačiau paplitusią problemą.

    KPP iš tikrųjų nėra vienas protokolas, o daugiau protokolų protokolas. Įdiegta kanalo sąsaja, leidžianti skirtingiems komponentams kalbėtis tarpusavyje taip, kaip jiems patinka. Pavyzdžiui, yra USB kanalas, garso kanalas ir grafikos kanalas. Kanalai paprastai skirstomi į dvi kategorijas, kurias vadinu „vidiniais“ ir „išoriniais“. Vidiniai kanalai skirti ryšiui tarp skirtingų KPP komponentų serveryje. Išoriniai kanalai skirti ryšiui tarp KPP kliento ir KPP serverio.

    Vidiniai kanalai yra šiek tiek numanoma pasitikėjimo riba. Tikimasi, kad juos naudos tik serveryje jau veikiantis kodas; todėl mažiau tikėtina, kad jie tinkamai tvarkys nepatikimus duomenis.

    „BlueKeep“ pabrėžė problema, kad KPP neskiria vidinių ir išorinių kanalų. Klientas gali tiesiog pereiti į bet kurį kanalą ir pradėti pliaukštelėti. Dėl to, kad pleistras buvo skirtas simptomams (UAF), o ne priežastims (faktas, kad vidiniai kanalai yra prieinami iš išorės), aš supratau, kad tai yra daugiau.

    „Windows 8“ KPP kodų bazė buvo visiškai pakeista, o tai reiškia, kad „BlueKeep“ trūkumas egzistavo tik „Windows 7“ ir senesnėse versijose. Maniau, kad nors „BlueKeep“ niekada neegzistavo, negalėjo pakenkti ištirti, ar naujasis KPP paketas patyrė tą patį esminį trūkumą kaip ir jo pirmtakas. Nusprendžiau sutelkti savo tyrimus į „Widows 10“ ir išplėtus visą „Windows“ versiją, naujesnę nei 8.

    Derindamas atvirkštinę inžineriją, dinaminę analizę ir „Google“ sudarau tvirtą žinomų KPP kanalų sąrašą. Tada aš peržiūrėjau protokolo dokumentus ir bandžiau išsiaiškinti, kurie kanalai buvo išoriniai arba po autentifikavimo, ir juos neįtraukiau. Galiausiai su sąrašu pradėjau dirbti tikrindamas kiekvieno kanalo atitinkamą tvarkyklę.

    Akį patraukė kanalas „rdpinpt“, nes tvarkymo kodas atrodo taip.

    Rdpinpt pranešimų tvarkymo kodas.

    Tik iš pirmo žvilgsnio jau labai aišku, kad mes čia neturime būti. Pirmoji eilutė nuskaito žymeklį į struktūrą iš „channel_msg + 12“, kuri yra vartotojo valdomi duomenys. Jokiomis aplinkybėmis klientas neturėtų turėti serverio atminties adresų (nes tai sugadintų ASLR), todėl tai yra raudona vėliavėlė. Negana to, gautas adresas nėra tikrinamas. Šis kodas tiesiog bando nuskaityti duomenis iš bet kurio jam perduoto adreso. Tai turėtų būti smagu.

    Kad išbandyčiau savo teoriją, turėjau užkoduoti RDP klientą, galintį prisijungti prie savavališkų kanalų ir siųsti savavališkus duomenis. Klientui rašyti prireiktų savaičių dėl KPP protokolo sudėtingumo, bet buvau pasiryžęs įrodyti savo teoriją. Ironiška, kad kodo parašymas užtruko daug ilgiau, nei man prireikė rasti pažeidžiamumą.

    Kodas, kurį parašiau norėdamas patikrinti klaidą.

    Klaidos suaktyvinimas turėtų būti gana paprastas. Man tereikia nusiųsti 20 baitų užklausą. Pirmieji du DWORD yra ignoruojami. 3-asis DWORD turi būti 12 (kad išlaikytumėte mouse_input_len patikrą). Tada paskutiniai 8 baitai yra adresas, kurį funkcija bandys perskaityti (aš nustačiau kaip 0x1337133713371337, kad būtų galima naudoti papildomai).

    Pirmoji kūdikio DoS

    Puiku! Atradimo metu „Microsoft“ mokėjo iki 10 000 USD už nuotolinį paslaugų atsisakymo išnaudojimą. Nusprendžiau nepranešti apie klaidą, nes norėjau sužinoti, ar galėčiau ją paversti kažkuo geresniu.

    Rdpinpt pranešimų tvarkymo kodas.

    Dar pažvelgęs į kodą pastebėjau, kad pranešimo ilgio laukas taip pat nebuvo patvirtintas. Nurodęs ilgesnį nei tikrasis pranešimo ilgis, galėčiau suaktyvinti ribų nuskaitymą (OOB). Problema buvo ta, kad adreso rodyklė yra 12 poslinkyje, o krūvos antraštė yra 16 baitų. Krūvos antraštėje nėra jokių adresų, todėl nebuvo jokio būdo į rodyklės lauką įvesti galiojantį adresą.

    Dar daugiau kasinėjęs radau tokį kodą:

    Vėliava, nurodanti, kaip tvarkoma užklausa

    Jei DWORD kanale_msg+1 nustatytas, vartotojo nurodyti adresai ir ilgis perduodami CTiMouse::SendInput. Ši funkcija iš esmės atlieka tą patį, kaip ir ankstesnis kodo fragmentas, bet iš branduolio. Dėl to, kad branduolys patvirtina vartotojo režimo adresus, funkcija sugenda, o ne sugrius RDP, jei adreso nėra. Jei adresas vis dėlto egzistuoja, branduolys bandys interpretuoti jo turinį kaip pelės įvesties paketą.

    Pelės įvesties paketo formatas

    Kol adreso duomenys laisvai atitinka šią supaprastintą pelės įvesties duomenų struktūrą, pelės būsena bus atitinkamai nustatyta. Iš esmės dabar turėtume susilpninti ASLR, nes galėsime saugiai patikrinti, ar adresas yra paskirtas, ar ne. Be to, mes taip pat galime nuotoliniu būdu nuskaityti parašus atmintyje, jei jis atitinka paketo specifikaciją. Galėtume sugadinti ASLR, išpurškę galiojančius pelės įvesties paketus, o tada naudodami klaidą, kad šiurkščiai atšauktume vieno atminties adresą.

    Nors tai nėra ypač naudinga, yra trečiasis naudojimas, kuris, mano nuomone, buvo visiškai linksmas. Jei adreso duomenys prasideda 0x00000000 arba 0x0001000, sistema perkels pelės žymeklį į bet kurią kitą reikšmę. Žymeklio padėtis rodoma per KPP, todėl iš tikrųjų galime nutekėti nedidelius atminties fragmentus per žymeklio padėtį, pavyzdžiui, kokią nors RDP Ouija plokštę.

    Šiuo metu turime savavališką skaitymą, OOB nuskaitymą ir informacijos nutekėjimą – visa tai atliekama iš tos pačios funkcijos. Kai kuriais atvejais mačiau, kaip žmonės buvo apdovanoti keliais CVE, nepaisant to, kad visi jie kilo dėl tos pačios pagrindinės problemos. Jei taip būtų šiuo atveju, premija galėtų siekti iki 30 000 USD. Deja, praėjus 4 mėnesiams po to, kai radau klaidas, DoS ir Info Leak klaidų dovana buvo sumažinta nuo 10 000 USD iki 1 000 USD. Kliento kodavimas užtruko mėnesį, o atbulinės eigos keitimas užtruko dar mėnesį, be to, turėčiau užtrukti kelias valandas, kol parašysiu pranešimą apie riktą, todėl nusprendžiau praeiti.

    Vietoj to, aš bendradarbiavau su kuo nors, kad padėtų man išsiaiškinti, ar galėtume suaktyvinti branduolio klaidą arba sujungti vieną iš klaidų į visą RCE.

    Pirmąją klaidą radau 2019 m. gruodžio mėn., praėjus 6 mėnesiams po „BlueKeep“ pataisos, ir nusprendžiau prie jos atsisėsti. 2020 m. rugsėjo mėn. apie klaidas pranešė kitas tyrėjas, todėl jos buvo pataisytos 2020 m. spalio mėn. saugos naujinime (arba taip manė Microsoft). Manau, kad priskirti CVE buvo CVE-2020-16927 ir CVE-2020-16896.

    Pleistras įdomus tuo, kad iš tikrųjų (kaip) sprendžia pagrindinę priežastį, o ne simptomus.

    Bandymas pataisyti

    Užuot tiesiog pataisęs OOB arba savavališkai nuskaitęs, kodas neleidžia klientui iš viso prisijungti prie vidinių kanalų. Deja, pleistras neveikia.

    CRdpDynVCMgr::IsFakeChannel() patikra iškviečiama iš CRdpDynVCMgr::CreateChannelInternal(), kuri iškviečiama „drdynvc“ kanalo inicijavimo metu. Tiesiog neprisijungę prie drdynvc kanalo, praleidžiame inicijavimą, todėl galime laisvai prisijungti prie uždraustų kanalų.

    Tik šio mėnesio saugos pataisa (2020 m. gruodžio mėn.) klaida buvo ištaisyta visam laikui. Funkcija IsFakeChannel() buvo perkelta į pagrindinį KPP inicijavimą, visiškai uždarant prieigą prie kanalų. Dėl to, kad galutinis pataisymas nebuvo įtrauktas į pataisos pastabas, reikėjo daug laužyti galvą, kad išsiaiškinčiau, kas tiksliai nutiko mano klaidai.

    Apskritai aš nesigailiu, kad nepranešiau apie klaidą, kai pirmą kartą ją radau. Nors šiek tiek pinigų būtų buvę gerai, man buvo daug smagiau pirmą kartą pasinerti į tikrą vabzdžių medžioklę. Nustebau, kad švaistydamas dienas atšaukdamas tokį viešą pažeidžiamumo pataisą, radau savo nulius. Tikiuosi, kad ateityje rasiu ką nors geresnio ir turėsiu daugiau laiko dirbti.

    Kriptografinis įrodymas (SHA 256):

    Sumaišyti duomenys: https://pastebin.com/ZazpTTbU

  • Išsamus žvilgsnis į įsilaužimą, aktyvią gynybą ir kibernetines markės raides

    Kibernetinio saugumo srityje daug diskutuojama apie galimybę privačiam sektoriui įsitraukti į aktyvią kibernetinę gynybą arba šnekamojoje kalboje „nulaužti atgal“. Siekiant ištirti arba įgalinti tai, buvo pristatyti keli namo įstatymų projektai, pvz., „Reagavimo į kibernetinę ataką galimybių aktas“ ir „Aktyvios kibernetinės gynybos tikrumo įstatymas“.

    Įsilaužimas atgal yra skėtinis terminas, apibūdinantis įvairias siūlomas Kompiuterinio sukčiavimo ir piktnaudžiavimo įstatymo (CFAA), kuris yra pagrindinis JAV įstatymas prieš kompiuterių įsilaužimą, išimčių. Šios išimtys leistų saugumo ekspertams užsiimti atsakomuoju įsilaužimu prieš nusikalstamus veikėjus tokiais tikslais kaip priskyrimas arba trikdymas.

    Nors Aktyviosios kibernetinės gynybos tikrumo (ACDC) įstatymas yra labai konkretus, bendresnė diskusija gerokai peržengia jo ribas. Nuomonių yra įvairių: nuo riboto įsilaužimo pagal iš anksto patvirtintą sritį iki visiško nemokamo visiems be išankstinio patvirtinimo ar priežiūros. Visai neseniai buvo pasirodę keli nuomonės straipsniai, raginantys skelbti „kibernetinius ženklus“, leidžiančius saugumo specialistams užsiimti privačia veikla.

    Pagrindinės ACDC įstatymo nuostatos leidžia gynėjams įsilaužti į užpuolikų valdomą infrastruktūrą šiais tikslais:

    1. Užpuolikų priskyrimas
    2. Atakų prieš aukos tinklą trikdymas
    3. Pavogtų aukos duomenų atkūrimas arba sunaikinimas
    4. Mokymasis apie užpuolikų elgesį, siekiant sukurti geresnę apsaugą

    Visų šių įsitikinimų esmė yra ta, kad išlyginę žaidimo sąlygas gynėjai galėtų geriau reaguoti į įsibrovimus ir atgrasyti nuo atakų.

    Baudžiamasis persekiojimas

    ACDC įstatyme vartojama kalba „kaip gynyba prieš patraukimą baudžiamojon atsakomybėn“, o tai reiškia, kad jis netrukdo pareikšti kaltinimus ar patraukti baudžiamojon atsakomybėn, o tiesiog veikia kaip galima gynyba teisme. Tai būtų panašu į tai, kaip savigyna gali netrukdyti jūsų suimtam ir apkaltintam, tik gali išvengti teistumo.

    Statistiškai tik apie 5 % federalinių bylų net patenka į teismą. Kibernetinių nusikaltimų bylos dažnai trunka metus ikiteisminio tyrimo etape ir gali kainuoti iki vieno milijono dolerių teisinių mokesčių. Be to, kaltę prisipažįstantiems kaltinamiesiems prokurorai siūlo žymiai mažesnes bausmes. Kaltinamiesiems dažnai geriau priimti tikrumą, o ne palikti savo likimą 12 atsitiktinių piliečių rankose. Laiko, išlaidų, rizikos ir emocinės naštos derinys lemia, kad daugelis nekaltų kaltinamųjų prisipažįsta kaltais, kad išvengtų teismo.

    ACDC akte taip pat konkrečiai teigiama, kad tai nėra gynyba nuo civilinių ieškinių, dėl kurių gali kilti daugybė problemų. Pavyzdžiui, aukos, kurioms nepavyko sumokėti išpirkos už išpirką reikalaujančių išpirkų dėl ACDC įjungtų sutrikimų, gali paduoti sutrikdytojams ieškinį, kad susigrąžintų nuostolius. Žalos taip pat gali reikalauti IPT, kuriuose yra užpuolikų infrastruktūra, kiti aktyvūs gynėjai ar net patys grėsmės veikėjai.

    Atsižvelgiant į visuotinį interneto pobūdį, tokie įstatymo projektai kaip ACDC įstatymas taip pat nesuteiktų jokios apsaugos nuo tarptautinės teisės. Jei aktyvūs gynėjai įsibrauna į užsienio sistemas arba JAV sistemas, priklausančias užsienio kompanijoms, jie vis tiek gali atsidurti karštame vandenyje.

    Nors daugelis didelių įmonių gali sau leisti pasinaudoti teisine gynyba ir apsaugoti darbuotojus nuo tiesioginio baudžiamojo persekiojimo, mažoms įmonėms, rangovams ir asmenims nepasisekė. Apskritai, šis aktas siūlo silpną apsaugą ir tiesiog suteiktų daugiau galių didelėms korporacijoms, kurios gali sau leisti ilgus teismo procesus.

    Interesų konfliktai

    Nors patraukimo baudžiamojon atsakomybėn riziką gali sumažinti ACDC įstatyme nustatytas reikalavimas gauti išankstinį Teisingumo departamento (DOJ) patvirtinimą, tai sukelia didelį interesų konfliktą.

    Teisėsaugos tikslas – rinkti žvalgybos duomenis, siekiant sulaikyti nusikaltėlius, o tai reiškia, kad užpuolikai yra stebimi kuo tyliau. Teisėsaugos operacijos gali užtrukti daug mėnesių ar metų, ir nors jos trumpuoju laikotarpiu gali mažai padėti aukoms, pagrindinių veikėjų areštas gali užkirsti kelią daugeliui tolesnių išpuolių.

    Kita vertus, nekoordinuota aktyvi gynyba yra daug trumparegiškas tikslas. Daugelis gynėjų sieks nutraukti individualius išpuolius prieš savo klientus ilgalaikio žvalgybos duomenų rinkimo sąskaita. Nors trikdymas gali būti geras, jis taip pat verčia užpuolikus tobulėti ir prisitaikyti, todėl tolesnis stebėjimas ir trikdymas tampa sunkesnis.

    Bet koks užpuolikų sistemų sutrikimas tikrai įspės užpuolikus apie pažeidimą. Negarantuojama, kad net pasyvus žvalgybos duomenų rinkimas identifikavimo tikslais liks nepastebėtas. Kuo daugiau įsibrovimų į užpuolikų sistemą, tuo didesnė tikimybė, kad užpuolikai pastebės. Nesant būdo koordinuoti ir sinchronizuoti privačios pramonės ir vyriausybės prieigos, atradimo rizika yra labai didelė.

    Tikriausiai teisėsaugos interesai būtų tiesiog atmesti visus aktyvios gynybos prašymus, nes jie kelia tiesioginę grėsmę jų pagrindinei misijai. Siūlomo pranešimo proceso nepakaktų tokiai rizikai sumažinti, ir viskas, kas nėra tiesioginė priežiūra, yra pasmerkta žlugti.

    Iškrypėliškos paskatos ir nesuderinamumas

    Įstatymai, tokie kaip ACDC įstatymas, sukurtų pelningą naują rinką, leidžiančią saugumo testavimo įmonėms teikti paslaugas, veikiančias kaip kibernetiniai samdiniai atakų aukų vardu. Nors daugelis įsilaužimo įgūdžių puikiai išverčiami į aktyvią kibernetinę gynybą, jie nepateikia viso vaizdo.

    Aktyvi kibernetinė gynyba įveda naujus kintamuosius, pvz., dekonflikto poreikį, kad būtų išvengta žalingų operacijų, išskyrus savo. Aktyvūs gynėjai turėtų elgtis atsargiai, kad netrikdytų tiek vidaus, tiek užsienio karinių ar žvalgybos operacijų. Jautrus tokių operacijų pobūdis reiškia, kad be tvirtų ryšių su karine ir žvalgybos bendruomene tai bus beveik neįmanoma. Be to, skirtingų tikslų ir finansinių paskatų derinys gali reikšti, kad privačios pramonės požiūriu nėra mažai noro net bandyti atskirti konfliktą.

    Kai kurie aspektai, susiję su prieiga prie užpuolikų valdomos infrastruktūros, yra šie:

    1. Ar aš rizikuoju užteršti ar sunaikinti rąstus, todėl kitiems bus sunkiau atskirti tikruosius užpuolikus nuo draugiškų įsibrovėlių?
    2. Ar šis infrastruktūros užpuolikas priklauso? Ar aš tikras, kad tai nėra pažeista sistema, IP adresas, kuris nuo to laiko pasikeitė, tarpinis serveris, klaidinga vėliavėlė ar šiuo metu nekontroliuojama teisėsaugos institucijų?
    3. Ar dėl mano veiklos gali pasikeisti užpuoliko elgesys, pvz., padidėti agresija, siekiant susigrąžinti nuostolius?
    4. Ar aš rizikuoju padaryti ką nors, kas gali paskatinti atradimą, sudeginti prieigą visiems arba užpuolikui keršyti?
    5. Ar iš šio įsibrovimo aš išvis galiu gauti ką nors naujo ir objektyviai naudingo?
    6. Ar tikėtina, kad niekas jau tyliai nedaro to, ką ketinu daryti (priskirti atakas, įspėti aukas, tobulinti saugumo gaires, pagrįstas užpuoliko elgesiu, trukdyti įsilaužimams)?

    Viskas tampa labai netvarkinga, kai potencialiai šimtai gynėjų bando priimti tuos pačius sprendimus, remdamiesi skirtinga įžvalga ir tikslais, mažai derindami vienas kitą arba visai nekoordinuodami. Greitai tai taps per daug virėjų scenarijumi.

    Ji jau egzistuoja

    Nors ne kiekvienas gali tiesiog paimti nešiojamąjį kompiuterį ir svaidyti rankomis į artimiausią grėsmės veikėją, aktyvi gynyba jau įprasta. Teisėsauga jau turi gebėjimų suteikti teisinę apsaugą privatiems asmenims ar įmonėms, padedančioms atlikti operacijas.

    „Botnet“ panaikinimas, kaip ir neseniai įvykę veiksmai prieš „Emotet“, yra tik vienas iš privačios pramonės aktyvios gynybos pavyzdžių.

    Emoteto panaikinimas buvo labai koordinuota operacija, kurioje dalyvavo pavieniai tyrėjai, privačios įmonės ir teisėsaugos agentūros iš devynių šalių. Operacijai vadovavo teisėsauga, siekdama išvengti pasikartojančių ar prieštaringų operacijų, tačiau ji labai rėmėsi privačios pramonės galimybėmis. Privataus sektoriaus ir vyriausybės sinergija leido taikyti įvairiapusį požiūrį, darantį didžiausią poveikį. Veiksmas apėmė visišką botneto perėmimą, platinimo kanalų ir veikėjų infrastruktūros uždarymą, taip pat tuo pačiu metu vykdomus teisėsaugos reidus, kuriais buvo siekiama sutrukdyti ateities rekonstrukcijai.

    Nepaisant ilgus metus trukusio planavimo ir vienos didžiausių kada nors vykdytų viešojo ir privataus sektoriaus operacijų, Emotet panaikinimas lėmė tik dešimties mėnesių prastovą. Dabar dešimties mėnesių gedimas nėra mažas žygdarbis. Operacija buvo didžiulė sėkmė ir tikriausiai išvengė milijardų dolerių žalos. Tačiau tai rodo, kad net geriausiai suplanuota ir gerai atlikta operacija gali padaryti tiek daug. Turime sutelkti dėmesį į stiprią įprastą gynybą, kuri papildytų esamą aktyvią gynybą, o ne sukurti skaitmeninius laukinius kibernetinių samdinių vakarus. Paskutinis dalykas, kurio mums reikia, yra didelės koordinuotos operacijos, kurias trikdo keletas prastai apgalvotų atakų, kurios yra tik nedidelis nepatogumas grėsmės veikėjams.

    Galbūt labiausiai iškalbinga tai, kad ne vienas asmuo, su kuriuo kalbėjausi teisėsaugos, kariuomenės, žvalgybos ar kibernetinių grėsmių žvalgybos srityse, nemanė, kad tokie teisės aktai yra gera idėja. Didžioji dalis paramos gauta iš kitų pramonės sričių, kuriose įsilaužimo meistriškumas yra įprastas, tačiau patirtis dirbant su realiais grėsmės veikėjais yra labai reta.

    Manau, kad didžioji dalis aktyvios kibernetinės gynybos pastangų atsirado dėl didėjančio nusivylimo dėl nuolat didėjančio kibernetinių atakų skaičiaus ir sunkumo. Daugelis mano, kad su jais kovoti daroma nepakankamai, bet kodėl taip yra? O ar aktyvi kibernetinė gynyba išsprendžia šią problemą?

    Imuniteto langas

    Šiuo metu vyriausybės gebėjimas reaguoti į kibernetines atakas yra labai akloji dėmė. Teisėsauga kovoja su elektroniniais nusikaltimais savo jurisdikcijoje, o kariuomenė ir žvalgybos bendruomenė taikosi į priešiškus valstybės veikėjus ir kitas grėsmes nacionaliniam saugumui. Bet kas atsitinka, kai grėsmės veikėjas nepatenka į nė vieną kategoriją?

    Imuniteto langas egzistuoja, kai grėsmės veikėjas yra apsaugotas nuo teisėsaugos jų gimtosios šalies; tačiau jie neatitinka nei valstybės veikėjų, nei grėsmės nacionaliniam saugumui slenksčio. Tai miela vieta, kurioje veikia daugelis išpirkos reikalaujančių veikėjų.

    Išpirkos reikalaujančios programinės įrangos naudotojai, gyvenantys JAV nedraugiškose šalyse, gali būti apsaugoti nuo baudžiamojo persekiojimo, jei nenutaikys savo gimtosios šalies ar jos sąjungininkų. Nors išpirkos reikalaujančios programos veikėjai, keliantys aiškią ir didelę grėsmę visuomenės saugumui, gali atsidurti Cyber ​​Command Et taikiklyje. al., iki tol jie iš esmės gali laisvai veikti nebaudžiami.

    Žinoma, leidus privačiai pramonei įsitraukti į aktyvią kibernetinę gynybą, šis langas gali būti uždarytas, nors ir brangiai. Tokia veikla keltų pavojų operacijoms prieš grėsmės veikėjus, jau pasiekiamus JAV vyriausybei, ir panaikintų bet kokią galimą naudą. Aktyvi kibernetinė gynyba taip pat gali būti vertinama kaip priimančiųjų šalių agresijos aktas, sukeliantis eskalavimą ir valstybės remiamų atsakomųjų veiksmų prieš JAV privačią pramonę potencialą.

    Ateities diskusija

    Idealiu sprendimu turėtų būti siekiama uždaryti imuniteto langą nepakenkiant teisėsaugos, karinėms ar žvalgybos operacijoms ir idealiu atveju drastiškai nepadidinant tokių agentūrų pasiekiamumo. Nors privačios pramonės aktyvi kibernetinė gynyba pati savaime neturėtų būti sprendimas, kai kuriose situacijose ji gali būti naudinga kaip paskutinė priemonė; tačiau tai turėtų būti daroma tik tiesiogiai prižiūrint vyriausybei.

    Kol kas tai palieku atvirą, nes dirbu prie tolesnio kūrinio. Sveikiname, jei taip toli pasiekėte.

  • Nigerijos skaitmeninė darbo užmokesčio apskaitos platforma „Bento“ plečiasi į Keniją, Ruandą ir Ganą, kad 2022 m. pateks į šešias kitas Afrikos rinkas – „TechCrunch“

    „Bento“, Nigerijos skaitmeninė darbo užmokesčio ir žmogiškųjų išteklių valdymo platforma, plečiasi į Ganą, Keniją ir Ruandą ir per ateinančius vienerius metus planuoja pradėti veiklą šešiose kitose Afrikos rinkose.

    Kitame plėtros etape „Bento“ iki kitų metų pabaigos planuoja Egiptą, Pietų Afriką, Ugandą, Tanzaniją, Angolą ir Etiopiją.

    Bento naudojasi darbo užmokesčio ir personalo valdymo rinka Afrikoje, kuri tradiciškai rėmėsi daug pastangų reikalaujančiais analoginiais procesais, kad išmokėtų atlyginimus. 2019 m. įkurtas startuolis padeda įmonėms automatizuoti atlyginimų ir kitų įstatymų numatytų perlaidų, įskaitant mokesčius ir pensijas, išmokėjimą.

    „Mums ir apmaudu, ir įdomu matyti, kad tiek daug įmonių naudoja analogiškus metodus savo darbo jėgai valdyti. Darbdaviai neturi prieigos prie vietoje pritaikytų pasaulinės klasės darbo užmokesčio ir žmogiškųjų išteklių valdymo įrankių, o darbuotojai negali lengvai pasiekti trečiųjų šalių paslaugų, kurios palengvintų gyvenimą. Kai pagalvoji, tavo atlyginimas lemia tavo gyvenimą, todėl kuriame operacinę sistemą, kuri turės didelį poveikį Afrikos žemynui ateinančioms kartoms“, – sakė „Bento“ įkūrėjas ir generalinis direktorius Ebun Okubanjo.

    „Bento“ teigė, kad jos platforma naudoja duomenis, siekdama išplėsti kredito sprendimus trečiosioms šalims (darbuotojams) ir kitas paslaugas, tokias kaip nedarbo draudimas, taupymas ir investicijos.

    Patentuotas startuolio kredito variklis, sukurtas bendradarbiaujant su Izraelio „Tarya“, užtikrina greitųjų paskolų išmokėjimą.

    Šiuo metu Nigerijoje „Bento“ aptarnauja daugiau nei 900 įmonių, įskaitant sveikatos priežiūros ir finansinių paslaugų įmones, tokias kaip „Hygeia“ ir „Tangerine Africa“, ir „Y Combinator“ remiamas pradedančias įmones „Paystack“, „Kobo360“, „Branch“ ir „LORI Systems“.

    „Pradedame nuo darbo užmokesčio ir žmogiškųjų išteklių valdymo, bet sparčiai pereiname prie 2.0 atlyginimo, kur iš naujo apibrėžiame darbo ir gyvenimo sankirtą ir keičiame žmonių uždirbimo, išlaidavimo ir skolinimosi būdus žemyne“, – sakė kitas „Bento“ įkūrėjas ir COO. Chidozie David Okonkwo.

    „Sėkmingai įkūrę produktų rinką Nigerijoje, vienoje iš sunkiausių Afrikos rinkų, džiaugiamės galėdami išplisti visame žemyne ​​ir išspręsti tikras problemas, su kuriomis, žinome, milijonai darbdavių ir darbuotojų kasdien susiduria. “, – sakė Okonkwo.

    „Bento“ plečiasi praėjus maždaug mėnesiui po to, kai „Workpay“, Nairobyje įsikūrusi darbo užmokesčio ir personalo valdymo įmonė, išsiplėtė į Nigeriją, kad apimtų mažas vidutines įmones Vakarų Afrikos regione. „Workpay“, „Y Combinator“ startuolis, yra tarp 50 įmonių Afrikoje, gavusių be nuosavybės finansavimą ir paramą iš „Google“. „Workpay“ teigė, kad jos platforma suteikia įmonėms galimybę atsiskaityti 15 valiutų visoje Afrikoje ir samdyti Afrikoje legaliai, nereikia steigti vietinio subjekto. Šiuo metu jos platforma palaiko 400 įmonių.

  • „Easol“ surinko 25 mln. USD už savo patirtį ir renginių rinkodarą, užsakymus ir mokėjimų platformą „TechCrunch“.

    Po COVID-19 pandemijos laipsniškai grįžtant turizmo ir kelionių sritims ir toliau kyla naujų įmonių, renkančių finansavimo etapais, banga, kad galėtų pasinaudoti naujomis galimybėmis rinkoje. Naujausioje plėtroje „Easol“, sukūrusi renginių ir programinę įrangą, kurią trečiųjų šalių įmonės gali naudoti prekiaujant ir parduoti užsakymus, įskaitant svetainių kūrimo priemonę, rezervavimo ir rezervavimo įrankius bei mokėjimo papildinius, surinko 25 mln. A serija, kurią ji naudos toliau kurdama savo programinės įrangos paketą, siekdama tapti vieno langelio principu patirčių organizatoriams.

    „Šiuo metu įgaliname [organizers] parduoti renginius, bet mes jų neplatiname“, – sakė generalinis direktorius Benas Simpsonas, kartu su žmona Lisa įkūręs startuolį Londone. „Manome, kad tai yra didžiulė galimybė, suteikianti kūrėjams galimybę gauti inventoriaus iš kitur ir išstumti savo į kitas vietas.

    Praėjusiais metais, po laikotarpio, kai Simpsonas teigė, kad dėl kelionių ir rinkimosi apribojimų 2020 m. negauna jokių pajamų, bendrovė smarkiai išaugo. Tais metais uždarius 4,5 mln. (ką Easol vadina „kūrėjais“) dešimt kartų, klientų skaičius išaugo 913%, operacijų skaičius išaugo 50 kartų, o išlaidos platformoje – 30 kartų. Ji užsibrėžė ambicingus tikslus patrigubinti savo augimą 2022 m.

    Jos programinė įranga naudojama maždaug 130 šalių, nors dauguma vartotojų, dalyvaujančių renginiuose, yra iš Šiaurės Amerikos ir Europos, sakė Simpsonas.

    Tai yra mastelio keitimo ir traukos skaičiai, kurie patraukia VC dėmesį, o šis paskutinis ratas turi tam tikrų pranašumų. „Tiger Global“ pirmauja A serijoje, kurioje taip pat dalyvauja ankstesni rėmėjai „Notion Capital“, „Foundation Capital“, „Y Combinator“ (Easol buvo S18 partijoje) ir „FMZ Ventures“, kuriai vadovauja Michaelas Zeisseris, buvęs „Alibaba“ JAV investicijų vadovas. (Zeisseris taip pat prisijungia prie valdybos.)

    Kelionių ir turizmo įmonės neabejotinai tapo vienais iš didžiausių gailesčio atvejų pandemijos metu: kai kurie perspektyviausi steigėjai ir įmonės netikėtai atsidūrė laisvajame kritime, kai jų klientai ir priklausomai nuo verslo modelio savo klientų klientai – tiesiog nustojo judėti ir daryti reikalus. Tačiau šis vakuumas taip pat paskatino keletą labai įdomių posūkių ir pastangų ieškoti verslo visiškai naujose vietose.

    „Peek“, vienas iš „Easol“ konkurentų patirčių valdymo erdvėje, daugiau dėmesio skyrė savo patirčių rinkai ir pradėjo teikti daugiau ir geresnių įrankių bei platesnių patarimų savo renginių valdymo klientams. Ji taip pat neseniai surinko reikšmingą 80 milijonų dolerių turą praėjusį mėnesį.

    Nors „Easol“ priekinėje dalyje gali atrodyti labai panašiai kaip „Peek“, jo veikimo principas labai skiriasi. Simpsonai įkūrė startuolį, prieš tai dalyvavę renginių organizavimo lygtyje, pradėdami ir vedę tokius renginius kaip „Rise“ – didžiulė slidinėjimo/klubo/muzikos konfigūracija Prancūzijos Alpėse. Benas sakė, kad kūrimas ir valdymas iškėlė daugybę organizacinių problemų, ypač susijusių su IT.

    Festivalis ne tik parduoda bilietus į renginius, bet ir valdo keltuvų leidimus ir įvairias apgyvendinimo galimybes, taip pat slidinėjimo patirtį ir įrangos nuomą. „Visą reikalą turėjome vykdyti penkiose skirtingose ​​platformose, – prisiminė jis, – o tai taip pat reiškė keletą atskirų operacijų mokesčių. Jie turėjo visą tą galią savo pusėje. Taigi jie sugalvojo planą. „O kas, jei visa tai sukurtume ir vykdytume, o ne imtume juokingų mokesčių, o sukurtume prenumeratos modelį su mažesniais mokesčiais? Tada kūrėjai galėtų pritaikyti kelionę iki galo, visą patirtį laikyti vienoje vietoje ir investuoti į savo augimą. (Šiuo metu kainodaros modelis yra pagrįstas trimis pakopomis, priklausomai nuo paslaugos lygio: 5 GBP per mėnesį, 54 GBP per mėnesį arba 207 GBP per mėnesį, siūlo daugybę skirtingų funkcijų ir komisinių skalę, kuri kinta priklausomai nuo to, kiek mokėti per mėnesį.)

    Visa tai yra pakankamai specializuota, pridūrė Lisa, kad jie nejautė, kad tai tikrai egzistuoja taip sudėtingai, kaip to reikėjo patirties kūrėjams. Ji teigė, kad taip jie nurodo kategoriją su atskiru terminu: „patirties komercija“. Jie paliko „Rise“, kuris tapo klientu, su kitais dabartiniais naudotojais, įskaitant „Wanderlust“, „Ibiza Rocks“, „Global Cycle Network“, „Untravelled Paths“ ir „Envision Festival“.

    Grąža padarė šias įmones patrauklias: „Easol“ teigia, kad renginyje, kurio apyvarta yra 2 mln. USD, naudojant „Easol“ programinę įrangą, o ne trečiųjų šalių įrankių derinį, kasmet galima sutaupyti daugiau nei 80 000 USD.

    „Easol rinkoje pirmaujanti platforma ir pramonės patirtis leidžia klientams įsivaizduoti ir parduoti unikalią patirtį vartotojams“, – pranešime teigė Evanas Feinbergas iš Tiger Global. „Manome, kad sparčiai besiplečiančioje patirties prekybos rinkoje „Easol“ yra pasirengusi užfiksuoti pernelyg didelį augimą, todėl džiaugiamės galėdami bendradarbiauti su Benu, Lisa ir „Easol“ komanda.