shellphish / how2heap

A repository for learning various heap exploitation techniques.
MIT License
7.2k stars 1.14k forks source link

"Complete Setup" doesn't work -> version `GLIBC_2.34' not found #178

Closed goreil closed 6 months ago

goreil commented 6 months ago

When following the Complete-Setup guide to setup a docker environment, it produces the following error:

When attempting to run ./glibc_run.sh 2.30 ./malloc_playground -u -r or just ./malloc_playground it returns: version `GLIBC_2.34' not found, same as Issue #169

The issue here is that we are using the Dockerfile from https://github.com/pwndbg/pwndbg which in turn uses ubuntu:22.04.

Workaround

After the command git clone https://github.com/pwndbg/pwndbg edit pwndbg/Dockerfile and replace jammy (ubuntu 22.04) with focal (ubuntu 20.04)

-ARG image=mcr.microsoft.com/devcontainers/base:jammy
+ARG image=mcr.microsoft.com/devcontainers/base:focal
Kyle-Kyle commented 6 months ago

it is fixed in the latest commit https://github.com/shellphish/how2heap/commit/8e4af70029a4d017a425cf0ea8e056f682cc9425 please let me know if you still encounter any issues. And thank you for letting me know the issue.

Kyle-Kyle commented 6 months ago

you should be able to just ./glibc_run.sh <libc_version> <binary> -d to launch the target binary in the target glibc

goreil commented 6 months ago

Hi @Kyle-Kyle ! Thank you for the quick fix!

However after testing it on Ubuntu 22.04 I noticed a few issues: 1.../glibc_run.sh 2.30 ./malloc_playground -d -p does not actually link the correct libc now:

ldd ./malloc_playground
    [...]
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (system libc instead of ./glibc_versions/2.30/x64/lib/ld-2.30.so)
  1. pwndbg is no longer included in the complete setup.

I would like to work on this by creating a new Dockerfile that includes pwndbg and fixes the afformentioned issues. Does that work for you?

Kyle-Kyle commented 6 months ago

I'm a bit confused about how you are using it. Are you using it inside the docker container? In the latest complete setup, it is the binary on the host that's supposed to be patched to use custom glibc. Installing pwndbg is not part of the workflow anymore (pwndbg was installed in the docker container, since you don't need to work inside the container now, you don't need to install pwndbg inside it)

goreil commented 6 months ago

Hi, thank you for asking. I'm sorry for the confusion I caused.

All the following commands were run on my Host machine:

$ lsb_release -a
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.4 LTS
Release:    22.04
Codename:   jammy

My problem is:

The setup as described in the README.md does not work. It only works after making additional changes.

1. Running README.md script:

I first ran the script as described in the README.md

git clone https://github.com/shellphish/how2heap
cd how2heap

# the next command will prepare the target binary so it runs with
# the expected libc version
./glibc_run.sh 2.30 ./malloc_playground -d -p

# now you can play with the binary with glibc-2.30
# and even debug it with the correct symbols
readelf -d -W malloc_playground | grep RUNPATH # or use checksec
readelf -l -W malloc_playground | grep interpreter
gdb -q -ex "start" ./malloc_playground

This fails at ./glibc_run.sh 2.30 ./malloc_playground -d -p with the message

Create binaries by make
readelf: Error: 'malloc_playground': No such file
readelf: Error: 'malloc_playground': No such file
[...] 

This fails because of this line in ./glibc_run.sh, which requires malloc_playground to exist.

120 if [ ! -f $TARGET ]; then
121     echo "Create binaries by make"
122     exit
123 fi

2. Attempt to run by adding make clean all

I Add the line make clean all so the file exists and glibc_run.sh can work

git clone https://github.com/shellphish/how2heap
cd how2heap

# [I added the following command otherwish ./glibc_run.sh will not work properly as explained earlier
make clean all

# the next command will prepare the target binary so it runs with
# the expected libc version
./glibc_run.sh 2.30 ./malloc_playground -d -p

# now you can play with the binary with glibc-2.30
# and even debug it with the correct symbols
readelf -d -W malloc_playground | grep RUNPATH # or use checksec
readelf -l -W malloc_playground | grep interpreter
gdb -q -ex "start" ./malloc_playground

Result:

[+] Building 0.1s (11/11) FINISHED                                             docker:default
 => [internal] load build definition from Dockerfile                                     0.0s
 => => transferring dockerfile: 350B                                                     0.0s
 => [internal] load metadata for docker.io/library/ubuntu:20.04                          0.0s
 => [internal] load .dockerignore                                                        0.0s
 => => transferring context: 2B                                                          0.0s
 => [1/7] FROM docker.io/library/ubuntu:20.04                                            0.0s
 => CACHED [2/7] RUN apt-get update && apt-get install -y binutils git make vim gcc pat  0.0s
 => CACHED [3/7] RUN pip3 install requests                                               0.0s
 => CACHED [4/7] RUN git clone --depth 1 https://github.com/shellphish/how2heap /root/h  0.0s
 => CACHED [5/7] RUN git config --global --add safe.directory "*"                        0.0s
 => CACHED [6/7] WORKDIR /root/how2heap                                                  0.0s
 => CACHED [7/7] RUN bash                                                                0.0s
 => exporting to image                                                                   0.0s
 => => exporting layers                                                                  0.0s
 => => writing image sha256:0f8a8ccfb8535af26ef20dfa3e079af55c4120c4940ee9ff0fd25d41c73  0.0s
 => => naming to docker.io/library/how2heap_docker                                       0.0s
./malloc_playground It's ready for discovering

$ ldd ./malloc_playground
    linux-vdso.so.1 (0x00007ffd877ad000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000078cc1d400000)
    /lib64/ld-linux-x86-64.so.2 (0x000078cc1d669000)

The culprit seems to be that the function only calls make but doesn't link the correct binary.

 85 function prep_in_docker () {
        [...]
107         docker run --rm -it -v $HOW2HEAP_PATH:/root/how2heap how2heap_docker make clean >/    dev/null
108         docker run --rm -it -v $HOW2HEAP_PATH:/root/how2heap how2heap_docker make >/dev/null
109 }

3. Getting it to work

To fix this a user can again run on host

sudo chown $USER:$USER ./malloc_playground
./glibc_run.sh 2.30 ./malloc_playground

Then the correct libc version is linked

ldd ./malloc_playground
    linux-vdso.so.1 (0x00007ffceb5d0000)
    libc.so.6 => ./glibc_versions/2.30/x64/lib/libc.so.6 (0x000076dd85e38000)
    ./glibc_versions/2.30/x64/lib/ld-2.30.so => /lib64/ld-linux-x86-64.so.2 (0x000076dd86033000)
goreil commented 6 months ago

While the current setup works, it requires a few additional steps that are not immediatly described in the README.md.

While I understand that the target audience are tech-savvy hackers, I nonetheless believe a simple setup, as the previous setup with Docker before https://github.com/shellphish/how2heap/commit/8e4af70029a4d017a425cf0ea8e056f682cc9425 will be quite helpful.

As a proposal, I created a pull request #179 , but I'm open to discussion.

goreil commented 6 months ago

Hi please don't take this the wrong way. I love this repository and it has helped me a lot in understanding heap exploitation.

I want to contribute by creating a docker setup that works out of the box with additional tools like pwntools and pwndbg included.

Kyle-Kyle commented 6 months ago

Hi please don't take this the wrong way.

Definitely not. I was just not sure why the patch didn't solve the issue. And thank you for figuring out the issue. I'll update the README for now and wait for your PR to the Makefile :)

Kyle-Kyle commented 6 months ago

I double-checked. You are right. It doesn't work in a fresh installation. I just created a quick patch. Can you please check whether it works for you? https://github.com/shellphish/how2heap/tree/fix/complete_setup

The reason why I am against including pwndbg in the Dockerfile in this project is that it should be in a tool-neural way so that people can choose to use their favorite heap debugging tool to learn these. instead of bound to pwndbg.

goreil commented 6 months ago

Your patch (https://github.com/shellphish/how2heap/tree/fix/complete_setup) works on my machine. Thank you!

I understand your reasoning for excluding pwndbg. I'll close the pull request.

As far as I'm concerned this issue will be solved with your new patche and can be closed when the patch is applied.