nccgroup / asafw

Set of scripts to deal with Cisco ASA firmware [pack/unpack etc.]
BSD 3-Clause "New" or "Revised" License
96 stars 30 forks source link

How to disable aslr for the newest images? #8

Closed cq674350529 closed 5 years ago

cq674350529 commented 5 years ago

Hi, thanks your guys for providing these great tools. Recently, when I use asafw to deal with the newest image (e.g. asav9101.qcow2), trying to disable aslr is unsuccessful. The root cause is there is no echo 0 > /proc/sys/kernel/randomize_va_space inside the fileasa/scripts/rcS.common.

# tune the VM system
if sf_asa_is_ngfw; then
    echo 0 > /proc/sys/vm/overcommit_memory
else
    MemTotal=`awk '/^MemTotal:/ {print \$2}' /proc/meminfo`
    let MemThreshold=1024*1024
    #disable overcommit only for system with more than 1G memory
    if [ $MemTotal  -le $MemThreshold ]; then
         echo 0 > /proc/sys/vm/overcommit_memory
    else
         echo 2 > /proc/sys/vm/overcommit_memory
    fi
    echo 100 > /proc/sys/vm/overcommit_ratio
 fi
ulimit -s 1024

So I modify the disable_aslr() inside the file unpack_repack_bin.sh as follows:

sed -i 's/ulimit -s 1024/echo 0 > \/proc\/sys\/kernel\/randomize_va_space\nulimit -s 1024/' asa/scripts/rcS.common

The command works well and the file is changed as I want. But when I emulate the device with the repacked image inside GSN3, it seems the aslr is still on.

I notice there are some comments inside the disable_aslr() as follows. Does it mean the command echo 0 > /proc/sys/kernel/randomize_va_space added manually is also overriden?

log "DISABLE ASLR"
# we can't just add the following line
#echo "kernel.randomize_va_space = 0" >> etc/sysctl.conf.procps
# because it looks like rcS.common overrides our value later in the boot process
# so we just make the modification in rcS.common :)

By the way, I search randomize_va_space using grep inside rootfs and get no results except for asa/bin/lina.

Is there any other way to disable aslr? Debugging with aslr is annoying. Any advice would be appreciated! Thanks in advance.

saidelike commented 5 years ago

Thanks for your comment on ASAV 9.10.1 (https://software.cisco.com/download/home/286119613/type/280775065/release/9.10.1). Unfortunately I don't have this .qcow2 so can't replicate.

I would have done it the way you did it by adding a line in rcS.common. The comment indicates that we did not do it in etc/sysctl.conf.procps as it was too early in the boot step so instead we did it in rcS.common. It may be too early still on ASAV 9.10.1.

It may be that on the newest images the randomization is done differently because of a new Linux version?

Some ideas you can try:

cq674350529 commented 5 years ago

@saidelike Thanks for your suggestions. I'll have a try.

saidelike commented 5 years ago

I forgot to mention that we do accept Pull Requests.

cq674350529 commented 5 years ago

Ok, I'll do it when I figure it out. Currently, I mainly test the device with version asav962, for it has so many symbols. Migrating symbols to asav9101 using Bindiff or diaphora is too slow.

cq674350529 commented 5 years ago

Hi, I analyzed the Linux environment from the debug shell. It turned out that the permission of /proc/sys/kernel/randomize_va_space is read-only.

sh-4.3# ls -l /proc/sys/kernel/randomize_va_space
ls -l /proc/sys/kernel/randomize_va_space
-r--r--r-- 1 root root 0 Jan 11 09:48 /proc/sys/kernel/randomize_va_space

Trying to change the permission of the file also failed.

snipaste20190111_175243

Also, Using sysctl -w kernel.randomize_va_space=0 doesn't work.

The version of Linux kernel is Linux version 4.1.21-WR8.0.0.25_standard. But in my opinion, it has nothing to do with the Linux kernel.

After checking online, I still got no solution.

saidelike commented 5 years ago

Hi,

Good finding and very interesting. Below are a few ideas:

I am wondering in what ASA version the randomize_va_space file became read-only. One way to check if it is related to the Linux version would be to spawn other ASA versions from 9.9.x up until 9.10.1 and document when it changed.

I am wondering if there is any output in dmesg when you try to write to the randomize_va_space that would show the reason.

I am wondering if Cisco started to use SE Linux:

cq674350529 commented 5 years ago

@saidelike Thanks for your advice.

I am wondering in what ASA version the randomize_va_space file became read-only. One way to check if it is related to the Linux version would be to spawn other ASA versions from 9.9.x up until 9.10.1 and document when it changed.

There are only two asav9.9.x.qcow2 images available from the cisco official website, aka asav991.qcow2 and asav992.qcow2. I have tested on the image asav992.qcow2, and the current strategy (disabling ASLR) works well on that version.

I am wondering if there is any output in dmesg when you try to write to the randomize_va_space that would show the reason.

I have checked the output in dmesg. There is nothing related to this.

  • Since you realised randomize_va_space is read-only from the debug shell, I am wondering if Cisco added a rule to forbid write access to this file from lina

I have searched the strings randomize_va_space in the rootfs. There are only two matched results. One is lina, another is librte_eal.so.5.1. It seems they just read the file /proc/sys/kernel/randomize_va_space and pasre its contents.

  • I would double-check the randomize_va_space file is also read only from a serial shell

I also check the permission of file /proc/sys/kernel/randomize_va_space from serial shell. It's read-only too.

  • More generally i would investigate if there is any sign for additional mitigation in place like SE Linux

According to the scripts asa/scripts/waagent, I run the cmd which getenforce manually and get nothing. So it seems the SELinux is not available on the system.

    def isSelinuxSystem(self):
        """
        Checks and sets self.selinux = True if SELinux is available on system.
        """
        if self.selinux == None:
            if Run("which getenforce",chk_err=False):
                self.selinux = False
            else:
                self.selinux = True
        return self.selinux

Now I am wondering if it's related to the kernel. I'll try to figure it out. By the way, I have tested this with the newest image asav9-12-1.qcow2. It's the same with asav9101.qcow2.

Thanks again!

cq674350529 commented 5 years ago

Finally, I found a way to tackle this problem. In short, I use the kernel parameter norandmaps. It works well on the latest images such as asav9101.qcow2, asav9-12-1.qcow2.

refer: https://www.kernel.org/doc/html/v4.19/admin-guide/kernel-parameters.html norandmaps
Don't use address space randomization. Equivalent to echo 0 > /proc/sys/kernel/randomize_va_space

I'll create a pull request later.