Skip to content

Commit adcb668

Browse files
committed
add uwsgi rce doc chinese.
1 parent 3fdfdfe commit adcb668

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

python/uwsgi_rce_zh.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# uWSGI 远程代码执行漏洞
2+
3+
| 风险级别 | 严重 |
4+
| --- | --- |
5+
| 影响范围 | uWSGI 1.9及以上(最新2.0.15),生产网测试网络有大量机器开启uWSGI端口 |
6+
| 修复方案 | 不要将uWSGI端口暴露,建议绑定在127.0.0.1上。 |
7+
8+
## 背景
9+
uWSGI是一个经常被使用的应用容器,通常情况下由于WSGI是Python实现的标准,所以uWSGI经常作为Python应用容器启动。但实际上uWSGI同样也支持加载Perl/Ruby/Go等应用。
10+
11+
uWSGI除了是应用容器的名称之外,它和Fastcgi之类的一样,也是前端server与后端应用容器之间的一个交流标准。目前nginx,apache也支持uwsgi协议进行代理转发请求。
12+
13+
## 漏洞成因
14+
经过研究其协议和源码实现,我们发现在uwsgi的协议中,允许传递一些魔术变量,这些变量通常都是可以起到动态调整参数的作用。其中有一个参数`UWSGI_FILE`,可以用来忽略原有uWSGI绑定App,动态设定一个新的文件进行加载执行。
15+
16+
这里本身就是一个LFI的漏洞,可以任意执行本地存在的任何文件。同时,由于uWSGI程序中默认注册了一系列schemes,导致此问题可以更被放大。
17+
18+
```c
19+
void uwsgi_setup_schemes() {
20+
uwsgi_register_scheme("emperor", uwsgi_scheme_emperor);
21+
uwsgi_register_scheme("http", uwsgi_scheme_http);
22+
uwsgi_register_scheme("data", uwsgi_scheme_data);
23+
uwsgi_register_scheme("sym", uwsgi_scheme_sym);
24+
uwsgi_register_scheme("section", uwsgi_scheme_section);
25+
uwsgi_register_scheme("fd", uwsgi_scheme_fd);
26+
uwsgi_register_scheme("exec", uwsgi_scheme_exec);
27+
uwsgi_register_scheme("call", uwsgi_scheme_call);
28+
uwsgi_register_scheme("callint", uwsgi_scheme_callint);
29+
}
30+
31+
static char *uwsgi_scheme_exec(char *url, size_t *size, int add_zero) {
32+
int cpipe[2];
33+
if (pipe(cpipe)) {
34+
uwsgi_error("pipe()");
35+
exit(1);
36+
}
37+
uwsgi_run_command(url, NULL, cpipe[1]);
38+
char *buffer = uwsgi_read_fd(cpipe[0], size, add_zero);
39+
close(cpipe[0]);
40+
close(cpipe[1]);
41+
return buffer;
42+
}
43+
```
44+
45+
46+
47+
这其中很多都是危险协议,尤其注意到其中有`exec`协议,可以直接通过刚才的`UWSGI_FILE`变量传参,导致远程执行系统命令。
48+
49+
## 漏洞利用
50+
由于uWSGI和php的fastcgi会默认绑定本地端口不一样,它是允许绑定端口直接对外的。因此需要找到一个可以访问到的uWSGI端口(uwsgi协议),对其发送uWSGI协议的payload即可。
51+
52+
例如,目标主机上是类似如下:
53+
54+
`uwsgi --socket :8001 --module project.wsgi`
55+
56+
执行利用程序:
57+
58+
```shell
59+
$ python uwsgi_exp.py -u x.x.x.x:8001 -c "echo '111' >/tmp/test"
60+
[*]Sending payload, wish you luck.
61+
HTTP/1.1 200 OK
62+
Content-Type: text/html
63+
64+
.......
65+
```
66+
在目标主机上查看,即可发现命令已被执行,`/tmp/test`文件已经存在。
67+
68+
```shell
69+
$ cat /tmp/test
70+
111
71+
```

0 commit comments

Comments
 (0)