Opened 5 years ago

Closed 3 years ago

#15138 closed task (fixed)

Investigate TBB 4.5 hardening (e.g. DEP/ASLR) on all Platforms

Reported by: tom Owned by: boklm
Priority: Medium Milestone:
Component: Applications/Quality Assurance and Testing Version:
Severity: Normal Keywords: tbb-security, tbb-testcase, ff38-esr, tbb-hardened, TorBrowserTeam201610
Cc: gk, mcs, michael, boklm, arthuredelstein Actual Points:
Parent ID: Points:
Reviewer: Sponsor: SponsorU

Description (last modified by gk)

Look at the hardening flags (e.g. DEP/ASLR) on all platforms for 4.5. If any platform doesn't have it, figure out why.

Child Tickets

Change History (27)

comment:1 Changed 5 years ago by gk

Cc: gk added

comment:2 Changed 5 years ago by mcs

Cc: mcs added

comment:3 Changed 5 years ago by gk

#13056 is the remaining ticket for Linux we currently have complaining about missing stack canaries on some libs. Then there is the missing PIE for Go binaries which we probably can't fix at the moment as the Go developers think that's not worth the effort (see: #10935, specifically comment 13). For details see the warnings at e.g. http://test-reports.tbb.torproject.org/reports/r/4.5a4-build3-Fedora20-x86_64/tor-browser-linux64-4.5a4_ar.tar.xz.html.

comment:4 Changed 5 years ago by gk

Keywords: tbb-4.5-alpha removed

It would be nice to have all the remaining things fixed for 4.5 but I doubt that will happen as it probably involves quite some fiddling with the build system(s). And who knows what comes up if one looks closer at the bundles we have (for OS X e.g.). Removing the tbb-4.5-alpha tag therefore.

comment:5 Changed 5 years ago by gk

Description: modified (diff)
Summary: Investigate TBB 4.5 DEP/ASLR on all PlatformsInvestigate TBB 4.5 hardening (e.g. DEP/ASLR) on all Platforms

comment:6 Changed 5 years ago by michael

Cc: michael added

comment:7 Changed 5 years ago by tom

++gk

I have some builds going to try and figure out if it will be easy to enable the stack smashing flags.

The hardening-check tool on Linux (part of hardening-includes on Debian/Ubuntu) can be used to do some stuff automatically.

https://wiki.debian.org/HardeningWalkthrough#Testing_your_packages_after_conversion

A one-liner is:

hardening-check -q ` find . | xargs -- file | \grep ELF | cut -d " " -f 1 | sed  's/://' | tr '\n' ' ' `

I used it to double-check the tor-qa test results (at http://test-reports.tbb.torproject.org/reports/r/4.5a4-build3-Fedora20-x86_64/ ), and they agree. I think the Pluggable Transports can be whitelisted as being expected to fail the stack canary and RELRO tests.

To be redundant, it yielded the following warnings (identical on x32 and x64). While having the stack smashing protection would be nice, I believe that to exploit a stack smash you would also need to bypass ASLR. (There may another way, but nothing is coming to mind immediately.)

./Browser/libmozalloc.so:
 Stack protected: no, not found!

./Browser/libnssckbi.so:
 Stack protected: no, not found!
 Fortify Source functions: no, only unprotected functions found!

./Browser/libplc4.so:
 Stack protected: no, not found!
 Fortify Source functions: no, only unprotected functions found!

./Browser/libplds4.so:
 Stack protected: no, not found!
 Fortify Source functions: no, only unprotected functions found!

./Browser/libsmime3.so:
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/libstdc++.so.6:
 Stack protected: no, not found!
 Fortify Source functions: no, only unprotected functions found!


And the following known PT stuff:

./Browser/TorBrowser/Tor/PluggableTransports/fte/cDFA.so:
 Stack protected: no, not found!
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/Crypto/Util/_counter.so:
 Stack protected: no, not found!
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/Crypto/Cipher/_ARC4.so:
 Stack protected: no, not found!
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/Crypto/Cipher/_CAST.so:
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/Crypto/Cipher/_AES.so:
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/Crypto/Cipher/_DES3.so:
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/Crypto/Cipher/_XOR.so:
 Stack protected: no, not found!
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/Crypto/Cipher/_Blowfish.so:
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/Crypto/Cipher/_DES.so:
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/Crypto/Cipher/_ARC2.so:
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/Crypto/Hash/_MD2.so:
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/Crypto/Hash/_MD4.so:
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/Crypto/Hash/_RIPEMD160.so:
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/meek-client-torbrowser:
 Position Independent Executable: no, normal executable!
 Stack protected: no, not found!
 Read-only relocations: no, not found!
 Immediate binding: no, not found!

./Browser/TorBrowser/Tor/PluggableTransports/twisted/runner/portmap.so:
 Stack protected: no, not found!

./Browser/TorBrowser/Tor/PluggableTransports/twisted/python/sendmsg.so:
 Fortify Source functions: no, only unprotected functions found!

./Browser/TorBrowser/Tor/PluggableTransports/twisted/python/_initgroups.so:
 Stack protected: no, not found!

./Browser/TorBrowser/Tor/PluggableTransports/twisted/test/raiser.so:
 Stack protected: no, not found!

./Browser/TorBrowser/Tor/PluggableTransports/obfs4proxy:
 Position Independent Executable: no, normal executable!
 Stack protected: no, not found!
 Read-only relocations: no, not found!
 Immediate binding: no, not found!

./Browser/TorBrowser/Tor/PluggableTransports/zope/interface/_zope_interface_coptimizations.so:
 Stack protected: no, not found!

./Browser/TorBrowser/Tor/PluggableTransports/meek-client:
 Position Independent Executable: no, normal executable!
 Stack protected: no, not found!
 Read-only relocations: no, not found!
 Immediate binding: no, not found!

comment:8 Changed 5 years ago by tom

4.5a4-build3 is good on Windows with regards to DEP/ASLR. I confirmed this using VMMap and Process Explorer, checked that everything was DEP and ASLR enabled and checked that the PTs were not ASLR enabled.

You can check the status of DEP and ASLR in an auotmated fashion on Linux using the python-pefile module (that's what it's named on apt on Ubuntu) and the below python script which I got from http://security.stackexchange.com/a/43690 and edited a little. (It does require the files to be unpacked though, and I didn't look into how to do that on Linux. Wine may be able to run the installer/unpacker though?.)

As far as stack canaries go, it's possible to build a signature for them and look at the executables to see if they have it, but I couldn't find one for /GS (Visual Studio-compiled) binaries, so it's even less likely one exists for gcc-for-windows cross-compiled binaries. I will try and identify manually if this compiler option is missing as I get my build machine back up and building, but as before, it's not as big a deal as missing DEP or ASLR.

#!/usr/bin/env python

import argparse
import os
import pefile


class DllFlags:
    def __init__(self):
        self.IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = False
        self.IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = False
        self.IMAGE_DLLCHARACTERISTICS_NO_BIND = False
        self.IMAGE_DLLCHARACTERISTICS_NO_SEH = False
        self.IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = False
        self.IMAGE_DLLCHARACTERISTICS_NX_COMPAT = False
        self.IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = False
        self.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = False


def get_dll_characteristics(path):
    foo = DllFlags()

    pe = pefile.PE(path, fast_load=True)
    dll_characteristics = pe.OPTIONAL_HEADER.DllCharacteristics

    if dll_characteristics > 0:
        if dll_characteristics >= 32768:
            foo.IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = True
            dll_characteristics -= 32768

        if dll_characteristics >= 8192:
            foo.IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = True
            dll_characteristics -= 8192

        if dll_characteristics == 2048 or dll_characteristics > 2080:
            foo.IMAGE_DLLCHARACTERISTICS_NO_BIND = True
            dll_characteristics -= 2048

        if dll_characteristics == 1024 or dll_characteristics > 1056:
            foo.IMAGE_DLLCHARACTERISTICS_NO_SEH = True
            dll_characteristics -= 1024

        if dll_characteristics == 512 or dll_characteristics > 544:
            foo.IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = True
            dll_characteristics -= 512

        if dll_characteristics == 256 or dll_characteristics > 288:
            foo.IMAGE_DLLCHARACTERISTICS_NX_COMPAT = True
            dll_characteristics -= 256

        if dll_characteristics >= 128:
            foo.IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = True
            dll_characteristics -= 128

        if dll_characteristics == 64:
            foo.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = True
            dll_characteristics -= 64

    return foo


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('dir', help='Directory to scan')
    args = parser.parse_args()

    dep_enabled = []
    dep_disabled = []

    aslr_enabled = []
    aslr_disabled = []

    for root, dirs, files in os.walk(args.dir):
        for f in files:
            try:
                bar = get_dll_characteristics(os.path.join(root, f))
            except:
                continue

            if bar.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE:
                aslr_enabled.append(os.path.join(root, f))
            else:
                aslr_disabled.append(os.path.join(root, f))

            if bar.IMAGE_DLLCHARACTERISTICS_NX_COMPAT:
                dep_enabled.append(os.path.join(root, f))
            else:
                dep_disabled.append(os.path.join(root, f))

    print "ASLR Enabled: "
    print "=============="
    for i in aslr_enabled:
        print i
    print ""

    print "ASLR Disabled: "
    print "==============="
    for i in aslr_disabled:
        print i
    print ""

    print "DEP Enabled: "
    print "============="
    for i in dep_enabled:
        print i
    print ""

    print "DEP Disabled: "
    print "=============="
    for i in dep_disabled:
        print i
    print ""

comment:9 Changed 5 years ago by tom

On OSX I ran vmmap and confirmed the stack is not executable and I diffed the memory locations between different executions (and reboots) on 10.10. I confirmed ASLR is enabled and moved everything around for the firefox process. Checking the other features, like stack canaries, will be difficult and similar to Windows.

comment:10 Changed 4 years ago by mikeperry

Keywords: TorBrowserTeam201504 added; TorBrowserTeam201503 removed

comment:11 in reply to:  8 Changed 4 years ago by cypherpunks

Replying to tom:

As far as stack canaries go, it's possible to build a signature for them and look at the executables to see if they have it, but I couldn't find one for /GS (Visual Studio-compiled) binaries, so it's even less likely one exists for gcc-for-windows cross-compiled binaries. I will try and identify manually if this compiler option is missing as I get my build machine back up and building, but as before, it's not as big a deal as missing DEP or ASLR.

It's possible to detect stack protection for gcc-for-windows cross-compiled binaries if libssp-0.dll was dynamically linked (like it does TorBrowser for Windows), then binaries with protected functions imports __stack_chk_fail and __stack_chk_guard from it.

comment:12 Changed 4 years ago by cypherpunks

for /GS (Visual Studio-compiled) binaries

It's possible to use hex-string pattern, not long-term solution, but for the same version of VS it should to generate the same opcodes if secure cookies used for function.
Like for x86, it generates:

mov     eax, ___security_cookie_at_xxxxxxxx
xor     eax, ebp
mov     [ebp+xx], eax

it is "A1 xx xx xx xx 33 C5 89 45 xx". Possible false positive results. Kludgy, buggy, but possible.

comment:13 Changed 4 years ago by cypherpunks

It's possible to use hex-string pattern

Impossible. VS generated different opcodes for another dll, failed test. Ignore it.

comment:14 Changed 4 years ago by mikeperry

Cc: boklm added
Keywords: TorBrowserTeam201505 tbb-testcase ff38-esr added; TorBrowserTeam201504 removed

boklm - Can you convert as much of this to test cases as possible to guard against regressions in the ff38-esr rebase?

comment:15 Changed 4 years ago by mikeperry

Keywords: TorBrowserTeam201505 removed

comment:16 Changed 4 years ago by gk

Keywords: tbb-hardening added

comment:17 Changed 4 years ago by gk

Keywords: tbb-hardened added; tbb-hardening removed

comment:18 Changed 3 years ago by gk

Component: Applications/Tor BrowserApplications/Quality Assurance and Testing
Keywords: TorBrowserTeam201606 added
Owner: changed from tom to bokm
Severity: Normal
Sponsor: SponsorU
Status: newassigned
Type: defecttask

Now that we have tests for all OSes running, boklm, could we get tests that make sure DEP/ASLR is enabled on things we build?

comment:19 Changed 3 years ago by cypherpunks

Owner: changed from bokm to boklm

comment:20 Changed 3 years ago by gk

Keywords: TorBrowserTeam201607 added; TorBrowserTeam201606 removed

comment:21 Changed 3 years ago by gk

Keywords: TorBrowserTeam201608 added; TorBrowserTeam201607 removed

Moving items to August 2016.

comment:22 Changed 3 years ago by gk

Keywords: TorBrowserTeam201609 added; TorBrowserTeam201608 removed

Tickets for September.

comment:23 Changed 3 years ago by arthuredelstein

Cc: arthuredelstein added

comment:24 Changed 3 years ago by gk

Keywords: TorBrowserTeam201610 added; TorBrowserTeam201609 removed

Moving SponsorU items to October.

comment:25 Changed 3 years ago by boklm

Commit 3178db78b764cdc6b731aaab6ef128d39af88369 is adding a test otool_PIE which is using otool -hv to check that executables included in the OSX bundle are PIE.

In Tor Browser 6.5a3, it reports that the following files are not PIE:

  • Contents/MacOS/Tor/PluggableTransports/meek-client
  • Contents/MacOS/Tor/PluggableTransports/obfs4proxy
  • Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container
  • Contents/MacOS/firefox
  • Contents/Resources/webapprt-stub
  • Contents/MacOS/updater.app/Contents/MacOS/updater
  • Contents/MacOS/Tor/PluggableTransports/meek-client-torbrowser

We have ticket #20439 to fix the firefox binaries. The other files (meek-client, meek-client-torbrowser, obfs4proxy) are golang programs. I will add an exception for the golang programs, as the Go linker does not support PIE according to https://trac.torproject.org/projects/tor/ticket/10935#comment:13.

comment:26 Changed 3 years ago by boklm

We now have the following tests in our testsuite:

comment:27 Changed 3 years ago by gk

Resolution: fixed
Status: assignedclosed

I think we are done here.

Note: See TracTickets for help on using tickets.