php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76519 include function access file written after question mark (?)
Submitted: 2018-06-22 10:06 UTC Modified: 2018-06-22 17:26 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: ziyahan at netsparker dot com Assigned:
Status: Not a bug Package: Filesystem function related
PHP Version: 7.0.30 OS: Ubuntu
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: ziyahan at netsparker dot com
New email:
PHP Version: OS:

 

 [2018-06-22 10:06 UTC] ziyahan at netsparker dot com
Description:
------------
a few days ago, a bug disclosure has been published:
https://mp.weixin.qq.com/s?__biz=MzIzMTc1MjExOQ==&mid=2247485036&idx=1&sn=8e9647906c5d94f72564dec5bc51a2ab&chksm=e89e2eb4dfe9a7a28bff2efebb5b2723782dab660acff074c3f18c9e7dca924abdf3da618fb4&mpshare=1&scene=1&srcid=0621gAv1FMtrgoahD01psMZr&pass_ticket=LqhRfckPxAVG2dF%2FjxV%2F9%2FcEb5pShRgewJe%2FttJn2gIlIyGF%2FbsgGmzcbsV%2BLmMK#rd


In disclosure, researcher use question mark (?) to bypass validity mechanism of phpmyadmin, however this trick can be used also in pure PHP script. 

I really don't understand how php interpreter evaluates question mark that given as param to include function.

I have a code like below:

<?php
$page = $_REQUEST["target"];
if(strpos($page,"ziyahan.txt")===0) {
include $page;
}

?>

It does not seem bypassable first, however I realize that a weird payload can bypass this

?target=ziyahan.txt%3f/../../../../../../../../etc/passwd

I cannot understand how the payload has an affect there?

It seems a bug.






Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-06-22 10:27 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2018-06-22 10:27 UTC] cmb@php.net
This does not look like a bug at all.  You are checking if $page
*starts* with "ziyahan.txt", and it does.  This is certainly
insufficient to validate a user supplied filename which you intend
to pass to include.

A properly configured open_basedir setting should prevent the
inclusion of etc/passwd, though.
 [2018-06-22 10:28 UTC] requinix@php.net
-Assigned To: cmb +Assigned To:
 [2018-06-22 10:28 UTC] requinix@php.net
That is a simple path traversal attack. https://www.google.com/search?q=path+traversal+attack

The %3f and %253f is used to trick phpMyAdmin's checkPageValidity() into allowing the path. Why it even allows for anything other than a strict whitelist, let alone for question marks in the *filename*, I don't know...

The question mark is not required for your proof of concept.
?target=ziyahan.txt/../../../../../../../../etc/passwd
 [2018-06-22 11:41 UTC] ziyahan at netsparker dot com
Hi again,

There is a wrong assumption here.

If OS would be Windows, you're right, payload can be considered OK.

It is because in Windows, you will be able to access test/../../../file.txt, even if the directory test does not exist

However, the OS that I worked on is Ubuntu.

Yes, question mark is not mandatory. 

http://VULNERABLE_HOST/test/lfi.php?target=wrong.php../../../../../../../etc/passwd

However, the file, wrong.php, does not exist actually:) 

How can I access the file /etc/Password by using the payload above?

It seems weird, a bug.

IF you don't think so, please explain how it can be possible?
 [2018-06-22 11:52 UTC] ziyahan at netsparker dot com
BTW, I forgot to say. For the case below:

http://VULNERABLE_HOST/test/file.php?target=file.txt../../../../../../../etc/passwd

I can reach /etc/passwd either way, existence of file.txt does not matter!
 [2018-06-22 11:55 UTC] spam2 at rhsoft dot net
please inform yourself about path traversal attacks

it's in doubt the underlying operating system which you can blame but to be honest: if you accept ../../ without test realpath() at your own you have nobody to blame but yourself
 [2018-06-22 12:05 UTC] ziyahan at netsparker dot com
Are you serious?

Do I look a one discuss here LFI?

I am only trying to understand how the scenario below is possible:

<?php
include("wrong.php../../../../../../../etc/passwd");
?>

How can it return /etc/passwd

In bash, you can try this command ie, cat wrong.php../../../../../etc/passwd

Another imporant thing is that,

"require" function does not evaluate the same payload in a same way.

Could you please investigate the issue instead of judging me.
 [2018-06-22 14:10 UTC] requinix@php.net
Google, ziyahan. https://www.google.com/search?q=path+traversal+attack

PHP is not examining each part of the path. It shouldn't need to. /x/../foo should always end up at /foo because that's how paths work.
realpath() is the way to examine each part. realpath(/file/../foo) will fail.

And yes, Linux does not allow /file/../foo. But Windows does.
 [2018-06-22 17:26 UTC] ajf@php.net
I don't think the dismissiveness of each other's positions here is helpful.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 02:01:28 2024 UTC