xss attack on a php page - php

In my security course teacher gave us a challenge to do so that we can practice with xss on a dummy website.
This website is composed by 2 php pages.
The first is called xss.php, and this is the code
<html>
<head>
<title>Equations</title>
</head>
<body>
<center>
<?php
if (isset($_POST['result'])){
$result = $_POST['result'];
if (intval($result) == 1){
echo "<h1>Ok, you are able to solve simple equations </h1><br>";
}
if (intval($result) == 0) {
header("Location: error.php?error=Type numbers!");
}
if (intval($result) != 1){
echo "<h1>Wrong result! Try again.</h1>";
}
}
else { ?>
<h1>Can you solve equations?</h1>
<h2>x^2 - 2*x + 1</h2>
<form method=POST action="xss.php">
<table>
<tr> <td>x:</td> <td><input type=text name=result></td> </tr>
</table>
<input type=submit value=Submit />
</form>
</center>
</body>
</html>
<?php }
?>
the second is error.php, and it's this:
<html>
<head>
<title>Error</title>
</head>
<body>
<center>
<h1>Error: <?php echo $_GET["error"]; ?></h1>
<center>
</body>
</html>
the request is to redirect someone to another website (I'll call it "http://whatever.com/" ). When I start the challenge I'm in xss.php and the only thing I can do is writing something in the input form (the one with name=result). What can I write?? Thank you

An XSS attack is one in which the page allows allows users to inject script blocks into the rendered HTML. So, first you must figure out how to do that. For instance, if the input from the user gets displayed on the page and it isn't html escaped then a user could do the following:
User enters :
<script>alert('testing');</script>
Following that, if when when viewing the page an alert is shown then the page is vulnerable to XSS.
Therefore if the user enters JavaScript as follows:
<script>window.location.href = "http://www.whatever.com";</script>
The user would be redirected.

You can pass by "error" GET variable a javascript code to redirect the page for whatever you want.
To do it,you'll access
error.php?error=<script>window.location.href="http://youpageurl.com";</script>
Then you have to be redirected to "yourpageurl.com" website

Related

Random Number Resets

My random number generates on page load, but seems to reset when the user clicks the "Guess" button. I still have a lot of building to go with this, but at the end I want the user to be able to make multiple guesses to guess the random number. I want it to generate when the page first comes up and stay the same until correctly guessed. I'm not sure what I'm doing wrong and just starting this program. If you answer, please also explain, as I'm trying to learn what I'm doing. Thank you!
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>PHP Homework 2</title>
<link rel="stylesheet" href="styles/styles.css">
</head>
<body>
<section id="main">
<h1>Play the Guessing Game!</h1>
<section id="left">
<h2>Take a Guess!</h2>
<form action="mine.php" method="post">
<div id="guessBox">
<label id="guessLB">Your Guess:</label>
<input id="guessTB" class="num" type="number" name="guessTB" max="1000" min="1">
</input>
</div>
<input type="submit" id="guessButton" name="guessBTN" value="Guess" />
</form>
</section>
<section id="right">
<h2>Game Stats</h2>
<?php
if(isset($_POST['guessTB']))
{
$randomNum = $_POST['guessTB'];
}
else
{
$randomNum = rand(1,100);
}
echo "<p>Random Number: $randomNum</p>";
?>
</section>
</section>
</body>
</html>
UPDATE: My HTML has remained the same, and I'm posting my new PHP code. But I used a session and wrote some more. However, I've come across two problems:
1) If I refresh the page, I get an error that says that the first instance of $randomNum below the session_start(); is unidentified.
2) It seems that it remembers my very last guess in the game. If I close out the page and reopen it, I immediately get one of the messages that my guess was too high or too low, even before making a guess. Any advice is appreciated!
<?php
session_start();
$randomNum = $_SESSION['randomNum'];
$guess = $_POST['guessTB'];
if(!isset($_SESSION['randomNum']))
{
$_SESSION['randomNum'] = rand(1,1000);
}
else
{
if($guess < $randomNum)
{
echo "<p>Your Guess is Too Low! Try Again!</p>";
}
else if($guess > $randomNum)
{
echo "<p>Your Guess is Too High! Try Again!</p>";
}
else
{
echo "<p>You Won!</p>";
$_SESSION = array();
session_destroy();
}
}
echo "<p>Guess: $guess</p>";
echo "<p>Random Number: $randomNum</p>";
?>
What you can do is use sessions. On every load check if you set it in the session and if it's not set, generate new number and set it, then check what the user input and compare the two numbers. This could also be done with cookies. Another thing you can do is use js. On load store the generated number in some js variable and don't use a form. On button click get the value of the input field and compare with the one you store in the variable.

Form won't pass hidden value

I'm working on a database-driven quiz that lets users select a series of answers, then submit the results via a form. It was working great, when it suddenly blew up, and I haven't been able to find the problem.
So before I get into the more complex stuff, I'd like to go back to square one and just make something simple work - like passing a hidden value to another page that echoes that value.
Here's the code for my first page # mysite/form.php:
<html>
<head>
</head>
<body>
<!-- g1/form.php -->
<div id="quiz" rel="key">
<form action="form2.php" method="post" id="quiz">
<input type="hidden" name="PreviousURL" id="url" />
<input type="submit" value="Submit Quiz" />
</form>
</div><!-- quiz-container -->
</body>
</html>
And here's the code for the second page:
<html>
<head>
</head>
<body>
<?php ini_set('display_errors', 1);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
echo $_POST['PreviousURL'];
}
echo 'XXX';
?>
</body>
</html>
I also tried moving the closing bracket, like this:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
}
echo $_POST['PreviousURL'];
echo 'XXX';
In both cases, when I click the submit button and am forwarded to form2.php, I see "XXX," but there's no value for $_POST['PreviousURL'].
I must have accidentally deleted or modified something, because it seems so simple, and it worked fine before. Can anyone tell me what the problem is?
there isn't a value for the hidden input.
In your form script you have missed out the value="" from the hidden input. This is the reason why nothing is displaying on the second page.

Using multiple PHP files while avoiding redirect loop and resubmission

So I am pretty new to PHP, I have done and learnt lots of console based experience so I'm not a full beginner to programming. But I decided to learn how to database because its always fascinated me, and I've learnt the basic HTML and CSS and JS, and now basic PHP and SQL, but putting into action is getting weird on me.
I've figured out how to manipulate and make databases through PHP code and stuff like that, but they were all simple things and in one file, I am going for a bigger project and I need to put all the PHP's in separate files, this is the problem.
say my 'index.php' file is so:
<!DOCTYPE html>
<html>
<head>
<?php include 'other.php' ?> //Problem 1
</head>
<body>
<FORM method="POST" action="other.php">
<INPUT type="text" name="textTest" value="<?php print $input; ?>">
<INPUT type="submit" name="subTest" value="TEST" >
</FORM>
</body>
</html>
and my 'other.php' is :
<?php
$input = "";
if (isset ($_POST['subTest']))
{
$input = $_POST['textTest'];
//header("Location : index.php");
}
header("Location: index.php"); //Problem 2
?>
so my problems:
Problem 1, if I don't include the 'other.php' file, there is an error when I try print the: value = "print $input"
Problem 2, if I don't redirect with 'header', it obviously doesn't redirect and go back to the 'index.php' which I want to happen. BUT with it there, it causes a TOO_MANY_REDIRECT error. I found this is a problem caused by the include which can't be removed for Problem 1 reasons.
Problem 3, I found out I could move the 'header' function to where it is commented out, but then the value="..." doesn't stay on submit.
Problem 4, if I completely get rid of the 'header' redirect, and change the form's action to 'index.php', then I get the 'Confirm Form Resubmission' thing I want to avoid.
So I hope that is a mouthful someone understands and can help with, and thankyou in advanced.
include does what it sounds like, it includes the file into the parent, essentially the same as copy and pasting the content into it.
So to fix your problem, 1st change the forms action to index.php (so it posts to its self), and remove the redirect all together:
<?php include 'other.php' ?>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<FORM method="POST" action="index.php">
<INPUT type="text" name="textTest" value="<?php print $input; ?>">
<INPUT type="submit" name="subTest" value="TEST" >
</FORM>
</body>
</html>
other.php:
<?php
$input = "";
if (isset ($_POST['subTest'])){
$input = $_POST['textTest'];
}
Note that i also moved the include to the 1st line in index.php, before any html output.
This is not strictly required in this instance, but is a good practice, as you are unable to set headers (eg for a redirect) after the response body is sent to the output stream
EDIT
If you want to avoid form resubmits on refresh, then you are correct that you would need to submit to a seperate endpoint and redirect.
To do that you would need to pass the posted data back to the index file, as the redirect is a new (GET) request, so the post data is lost.
The two main ways to do that would be with SESSION or URL parameters.
I'll show how to do it with parameters:
Dont include the destination file:
<?php
//get value from url parameter, or set to empty string if parameter not present
$input = isset($_GET['input'])? $_GET['input'] : '';
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<FORM method="POST" action="other.php">
<INPUT type="text" name="textTest" value="<?php print $input; ?>">
<INPUT type="submit" name="subTest" value="TEST" >
</FORM>
</body>
</html>
Then append the required data to the redirect url as parameters
other.php:
<?php
$input = "";
if (isset ($_POST['subTest'])){
$input = $_POST['textTest'];
header("Location: index.php?" . http_build_query(['input'=>$input]));
die(); //always stop execution after redirect
}
//if post data not sent, something went wrong, so set $input parameter to error message
header("Location: index.php?" . http_build_query(['input'=>'No Data posted']));
die(); //always stop execution after redirect
In other.php at the last line try require-ing the index.php instead of redirrecting.
Also remove the inclusion of other.php in index.php .
$input = "";
if (isset ($_POST['subTest']))
{
$input = $_POST['textTest'];
}
require_once 'index.php';
?>

Does action attribute in html forms interfere with what's stored in $_SESSION global variable?

Suppose, I have two pages: page01.php and page02.php (their code is presented below).
If I leave action attribute in the form on page01.php empty (i.e. action=""), then access page01.php, fill in the form, press submit, then access page02.php - it all works fine (i.e. $_SESSION variable stores the data submitted on page01.php and can be accessed and viewed on page02.php as expected).
However, when I try to make the form send the user to page02.php (by changing the action atrribute to action="page02.php") it looks like the $_SESSION global variable doesn't store data from page01.php.
My question is: does this happen because the user is redirected to page02.php immediately upon submission of form and the code between php tags on page01.php does not get executed?
I'm aware I can use $_GET or $_POST on page02.php to achieve the desired behavior, but I'm just trying to understand the way action attribute and $_SESSION interact. Thank you.
Page01.php:
<html>
<head>
<title>Page 01</title>
</head>
<body>
<h1>Please fill this form</h1>
<form action="" method="post">
Name: <input name="username">
<input type="submit" value="send">
</form>
<?php
session_start();
if(isset($_POST['username'])) {
$_SESSION['username']=$_POST['username'];
}
?>
</body>
Page02.php:
<html>
<head>
<title>Page 02</title>
</head>
<body>
<h1>Another temporary page is working</h1>
<?php
session_start();
$expectedName = "Bob";
if($_SESSION['username'] == $expectedName) {
echo "Welcome, Bob!";
}
else {
echo "Access denied. You are ". $_SESSION['username'] . ", not Bob.";
}
?>
</body>
action attribute is attribute you specify where the script that will need to be run after submitting.
so if you want user to be redirected after form has been submitted, you use header() function.

Session variables not passing to next file

So I've searched this site about this issue and tried what has been suggested and still no luck. I thought maybe it was my 'server' (On my tablet using KSWEB, no computer right now) so I created 2 simple files to share a session variable between the two and it worked fine. I have no idea why this isn't working for these two. I'm trying to create a login page (an insecure one, I know). The error function USED to work (this is what gets me), and now it doesn't. The files are below. I only included the top portion of admin.php because I've commented out the rest. It really shouldn't matter. Right now, if you submit the form without entering anything into the admin prompt, an error should display next to the asterisk saying "Admin needs to be filled out". Despite my best efforts, this doesn't work anymore and I'm completely stumped as to why.
Login.php
<?php
session_start();
?>
<html>
<head>
<style>
.error {color: #FF0000;}
</style>
<script>
function submitForm()
{
document.adminform.submit();
}
</script>
</head>
<?php echo $_SESSION["adminErr"];?>
<h2>Administrator login page</h2>
<form method="post" action="admin.php" name="adminform">
Admin: <input type="text" name="admin" style="position:absolute; left:100px">
<span class="error" style="position:absolute; left:285px">*<?php echo $_SESSION["adminErr"];?></span>
<br><br>
Password: <input type="password" name="password" style="position:absolute; left:100px">
<span class="error" style="position:absolute; left:285px">*<?php echo $_SESSION["passwordErr"];?></span>
<br><br>
<button onclick="submitForm()">Submit</button>
</form>
<br><br><br>
<p><?php echo $_SESSION["flogin"];?></p>
</html>
<?php
session_destroy();
?>
Admin.php
<?php
session_start();
if ($_SERVER["REQUEST_METHOD"] == POST)
{
if (empty($_POST["admin"])) // Check to make sure Admin field is filled out
{
$_SESSION["adminErr"] = "Admin field must filled"; // Set error if not filled
header("location:login.php"); // Return to login page
}
}
?>
Don't destroy the session at the end of the file..
</html>
<?php
session_destroy();
?>
Also you should put exit; after each header('Location: ...');.
When sending the header, the browser recognized to change the location but the script does not end. The browser in fact, would not even have to follow the header, it can also just go on with the script. You have to stop the script because the headers do not exit the script.
instead of
<button onclick="submitForm()">Submit</button>
use
<input type="submit" value="Submit">
Then put a check before echoing
<?php echo isset($_SESSION["adminErr"])? $_SESSION["adminErr"]: "not set" ;?>
further debugging:
var_dump($_POST);
var_dump($_POST["admin"]);
var_dump($_SESSION);
var_dump($_SESSION["adminErr"]);

Categories