I am initiating and doing a basic penetration testing course and have come across one doubt.

For example in this URL: http://webapp.thm/index.php=?page=1

I get that I am requesting the index.php file in the server and I am specifying that I want to view page 1 as a value of the parameter.

But in this other URL: http://webapp.thm/get.php?file=/etc/passwd

I am having trouble understanding this request because I am requesting get.php (which is already a file) and the parameter file is accesing a different file /etc/passwd.

My question is what does the get.php file contain in this case or is it a function? because it seems to me that it is function retrieving the /etc/passwd, but I know that it is not a function, so I am kind of confused about what the get.php means.

got a picture describing it from the course:

enter image description here

  • 7
    looks like they are trying to exploit some backend code that just spits out a file according to the path you give it. (If someone were lazy they might code a page like that, and if their configuration somehow allowed access to etc/passwd it'd just blindly serve up the file as a download.... usually they'd try to traverse though... something like "../../etc/passwd" Commented Feb 21, 2023 at 22:43
  • 2
    @pcalkins, if someone were feeling mean, they'd serve up a fake /etc/passwd.
    – Mark
    Commented Feb 24, 2023 at 1:23
  • If we're being pedantic (which computers are) then index.php=?... is quite a different request from index.php?.... I'd be curious if that's the actual URL provided or a typo.
    – smitelli
    Commented Feb 24, 2023 at 23:21

7 Answers 7


I am requesting get.php(which is already a file)

HTTP is not about requesting files, but about requesting resources specified by the URL. These resources might be a static file returned by the web server but they might also be created dynamically based on the URL.

In this specific case you are not requesting the contents of the file get.php to be returned, but you request the program get.php to be executed. And file=/etc/passwd is processed by this program - how exactly depends on the program. Based on your description the program will likely take it as a parameter file with the value /etc/passwd, open the file and return it as response. If this succeeds, this is known as a Local File Inclusion vulnerability (LFI).


Without knowing the code of get.php it is impossible to answer what it really does. May be it will interpret the parameter as a path and will read the content of the given file and return it. Or may be it will download this file. Or may be get.php has content like following

<?php echo "Hello World!"; ?>

and will ignore any parameters and thus is absolutely harmless.

Show us the contents of get.php. Then we can tell what can be the result of sending request to get.php.


It all depends on the web server. When you request an address like http://webapp.thm/index.php?page=1 (I'm assuming the extra = was a typo) your browser opens a connection to webapp.thm port 80, and sends a data packet like this:1

GET /index.php?page=1 HTTP/1.1
Host: webapp.thm
User-Agent: AwesomeBrowser/1.0 (like Firefox)
Accept-Language: en
... more metadata and cookies go here ...

This is the only part that's standardized. What the server does with this request, is up to the server. A very basic server would look for a page called /index.php?page=1 and give a 404 response because there isn't one. A slightly more sophisticated server would know that everything after ? is parameters for the page and not part of the filename, so it would look for a page called /index.php.

However, we can infer this is not a very basic server. The .php file extension strongly indicates2 this server is using a piece of software called PHP, which is a script interpreter that generates HTML pages on-demand based on PHP scripts. There's no general way to know this - you have to have some basic familiarity with what PHP is. You could probably find it out by Googling the .php file extension.

When a server with PHP installed gets a request for a file it recognizes as a PHP file, it does not simply send the file contents to the client, like an HTML file. Instead, it runs the script. Whatever the script outputs is then sent to the client. If it's written to do so, the script has the ability to access various information, like the current date and time, the client's IP address, the User-Agent, Accept-Language and other metadata, cookies, ? parameters and so on. It runs on the server, so it can access databases and other files stored on the server.

And so you have the possibility that someone wrote a script that has a vulnerability. For example, I once wrote a simple script download.php so that /download.php?file=foo.zip would increment the download counter for foo.zip and then send the contents of foo.zip. The script looks approximately like this:

$file = $_GET["file"]; // access the ?file= parameter

// not showing how is_valid_filename is defined
if (!is_valid_filename($file) || !file_exists($file)) {
    Header("Content-Type: text/plain");
    print "error";
} else {

    $db = open_database();
    db_query($db, "update downloads where filename=? set counter=counter+1", [$file]);

    Header("Content-Type: application/octet-stream");
    readfile($file); // outputs the contents of the file

If that script did not validate the filename as a valid filename to download, it would be possible that someone could request /download.php?file=/etc/passwd and get the contents of /etc/passwd because the script would call readfile("/etc/passwd"); which is supposed to send the contents of /etc/passwd to the client. This has nothing to do with the client, the server, or HTTP, really - it would have everything to do with a faulty script. In hindsight this script could have used an HTTP redirect instead of readfile - that would be even safer.

1 In HTTP/1.1 this is literally the data packet. It's not a human-readable translation - the packet is human-readable by itself. HTTP/2.0 uses a non-human-readable format to make it faster, but it basically sends the same data.

2 There's no guaranteed connection between the .php file extension and the PHP software. It's just a convention. They could choose to configure their copy of PHP so that files with .script or .html extensions run the PHP software, and they could choose to configure some other software to use .php extensions. But it is a strong indication.

  • This is the only correct answer. The part after the domain is passed to the webserver and that decides what to do with it. Everything else is assumptions based on conventions. Most likely, it'll execute get.php and pass in the rest as a parameter, but due to rewrite rules and other server stuff, that isn't guaranteed to be the case.
    – Tom
    Commented Feb 24, 2023 at 11:07
  • 2
    @Tom: Formally, you are absolutely right. But if you like nitpicking so much, then why don't you say that the question makes no sense at all, because there is no such TLD as thm, thus the website webapp.thm does not exist and the request cannot be sent anywhere and it makes no sense to ask what the server will do?
    – mentallurg
    Commented Feb 24, 2023 at 23:13
  • Tom is right that we don't know 100% what the server does, but we can make some good guesses. Commented Feb 25, 2023 at 1:46
  • @mentallurg If we're nitpicking that much, then it says webapp.thm, not webapp.thm. – so it doesn't matter whether there's a thm TLD, since this isn't a fully-qualified domain name, and it can be resolved locally. (We can nitpick further still, and question why any assumptions are being made about the configuration of the DNS root. There are already relatively-popular alternative DNS roots out there, so that's not even unresonable.)
    – wizzwizz4
    Commented Feb 25, 2023 at 1:48
  • @mentallurg obvious example domain is obvious
    – Tom
    Commented Feb 25, 2023 at 9:45

GET parameters are delimited by ? for the first parameter, and & for the following, i.e. example.com/foo.bar?firstparam=value&secondparam=value.

The HTTP protocol does not place any meaning on parameter names or contents. Thus, the parameter name file has no special meaning, and the parameter value /etc/passwd has no special value.

It's up to the http server (or program executed by the http server) what to do with parameters. It can be silently discarded, executed as verbatim or verified by some process.

  • 2
    If you're talking about the HTTP protocol, it doesn't place any meaning on ? or & at all. HTTP sees a resource of foo.bar?firstparam=value&secondparam=value on a host of eample.com. The HTTP server is likely to separate that into foo.bar and firstparam=value&secondparam=value, and run a process which is likely to separate that into firstparam=value and secondparam=value, but from the outside, all of this is just an informed guess. The HTTP server could instead decide to read a local file called foo-firstparam_value-seconparam_value.html.
    – IMSoP
    Commented Feb 23, 2023 at 17:08
  • 4
    See RFC2616, section 3.2.2: http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]] . Path and Query is part of HTTP/1.1 protocol.
    – vidarlo
    Commented Feb 23, 2023 at 17:43
  • 1
    Interesting. I wonder why they bothered putting that in there, since the "query" part is never mentioned again in that document, and the distinction between with and without it appears to have no effect on the rest of the protocol whatsoever. It is very relevant to other standards, such as HTML Forms, but an HTTP request itself sees only the Host header and the full relative path, each as opaque strings.
    – IMSoP
    Commented Feb 23, 2023 at 22:38
  • 1
    Incidentally, RFC 2616 is doubly obsoleted; the current definition of HTTP/1.1 is RFC 9110 and RFC 9112. They likewise distinguish a "query" part in the syntax definition, but give it no semantic distinction, or list any further parsing rules regarding keys and values.
    – IMSoP
    Commented Feb 23, 2023 at 23:00
  • 1
    Pedantically, if you want "original", you should quote RFC 2068 (from 1997) or RFC 1945 (for HTTP/1.0). More relevantly, none of these specs define how to parse the "query" section of the URL into parameters, even if they strongly imply that the path and query parts should be treated separately in some undefined way. From a security perspective, this seems relevant: an entirely compliant server can use an entirely different convention for parsing the "path+query" part of the URL, and it is human interpretation that allows patterns in that interpretation to be spotted and exploited.
    – IMSoP
    Commented Feb 23, 2023 at 23:23

The parameter that you're sending with filename in it is being handled by the backend logic in file get.php most probably the logic would be to return the contents of the file mentioned in the file parameter.

The logic could be something else as well, but here this seems to be an attack vector for LFI,local file inclusion to fetch the /etc/passwd file from the function or logic mentioned in get.php


It is up to the webserver how it handles a URL, it might serve a file directly, but it might also run some script.

php is a server side scripting language. In a typical configuration, when a file with the extension ".php" is requested, the server will not send the file directly but will instead pass the request to the php implementation.

The php implementation will read through the file looking for <?php and ?> tags. Text outside of these tags will be served to the client directly. Text within these tags however will be interpreted as php code and executed on the server with it's output being passed to the client.

file= is a query parameter which can be used by the php code, what it does with that parameter is up to the code. Perhaps for some reason they decided to just write a php script that serves the contents of a file. Perhaps the script combines the content of the file with a website template to produce a formatted page.

If the code is well-written it will perform some serious validation on that parameter before using it to actually load a file.

but a lazy or inexperienced programmer may neglect to perform any validation before passing the users filename to the file open API. Or they may perform inadequate violation, for example they may check the path doesn't start with '/' but forget to check for '..' or vice-versa.

This can give the attacker a way to read (possibly mangled versions of) files that they were not supposed to be able to access. On a modern system /etc/passwd will give the attacker a list of users and their IDs. On some systems it may also give them password hashes, though this is increasingly rare.


php is a script programming language that allows the web server to run programs for the client and send back the results. For it to be exploitable in the way your course expects get.php contains a PHP script something like

echo file_get_contents($_GET['file']);

php is truly a great language for writing exploitable code. The shorter

system("cat $_GET[file]");

does the same gets you a shell injection too.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .