Challenge 1
Task : Register and login with an email-id John_Doe@somemailinator.com
Vulnerability/Vulnerabilities Identified
- Insufficient Validation performed for authentication
- Development code left in production
Applicable root cause(s)
The code for approving a user was left inside resend.asp, allowing anyone to approve his/her own account easily by faking a request. This was probably done during development stage of the application, as a means of easy activation of accounts, but was left commented out in the javascript, leading to easy exploitation
There was insufficient validation performed in validating the user. There was no check performed to see if 1. the user is logged in and 2. the user is an admin user
Inspite of both these conditions being false, the user could approve any other email.
Approach Adopted
After studying resend.asp and seeing the following javascript code :
function submitted() {
email = document.getElementById('email_id').value;
if (email == '') {
alert('Email Address cannot be empty');
return false;
} else {
//boolean is_approved
return true;
}
return false;
}
We tried to submit the form with another element, called “is_approved” with its value set to “true” and the user account was approved.
Suggested Remediation
- Remove the approval code from
resend.asp
- Remove the
is_approval
variable reference from resend.asp
The offensive code snippet for (1)
above would be something like :
<?php
if($_POST('is_approved')==true){
$email_id = $mysqli->escape_string($_POST['email']);
$mysqli->query("UPDATE users set approved=1 WHERE email_id = '$email_id'");
}
Similarly (2)
above can be fixed by shortening the javascript validation code to :
function submitted() {
email = document.getElementById('email_id').value;
if (email == '') {
alert('Email Address cannot be empty');
return false;
} else {
return true;
}
return false;
}
Challenge 2
Task : Find hidden credentials in the application and login with them
Vulnerability/Vulnerabilities Identified
- Hidden Credentials left in application data
Applicable root cause(s)
The credentials for the hidden user account were left in the images of various books. This was probably due to poor joke being played by the developers. Also possible is that the application developer was trying to leave himself a backdoor in the application.
Approach adopted (steps with screenshots)
- After getting a hint of hidden credentials, we looked in various places and found certain books of importance (‘Base64 Encoded’, and
Secret
) - We analyzed these book’s covers and found that they contained base 64 encoded versions of a hidden username and password.
- We attempted to login with these credentials, and found that only one of them worked.
Suggested remediation with sample code snippet
- Update the book cover picture of these books with the credentials removed.
Challenge 3
Task: Buy at least one copy of each book costing more than 800 credit points
Vulnerability/Vulnerabilities Identified
- Insufficient Validation on user input
- Unnecessary user input ###Application Root Cause A user is allowed to specify the cost of the book while purchasing it. ###Approach adopted (steps with screenshots)
- We looked at the javascript code of
books.asp
where the purchase is made and found the following snippet :
function purchase(bid, cost) {
$.ajax({
url: 'checkout.asp?book_id=' + bid + '&action=checkin',
success: function(msg) {},
});
$.ajax({
url: 'purchase.asp?book_id=' +
bid +
'&action=purchase&book_cost=' +
cost,
success: function(msg) {
alert(msg);
history.go(0);
},
});
}
-
We found that the application was sending a get request to
purchase.asp
with the fieldsbook_id
,purchase
, andbook_cost
. -
The application also sent a request to
checkout.asp
to make sure that the book was checked out (See Generic Vulnerability 1 for more details on this) -
We checked all the books and found the following books had cost above 800:
- (66) : XPATH - 9245
- (64) : WPA 2 - 2345
- (35) : IT ACT 2008 - 2000
- (56) : SQL Injection - 990
- (59) : Symmetric Encryption - 888
-
We performed a GET request to
purchase.asp?action=purchase&book_id=66&book_cost=-10000
allowing us to buy the first book in the list and raise our credits by 10000. -
The other books were bought with similar GET requests to the following urls :
purchase.asp?action=purchase&book_id=64&book_cost=0
purchase.asp?action=purchase&book_id=35&book_cost=0
purchase.asp?action=purchase&book_id=56&book_cost=0
purchase.asp?action=purchase&book_id=59&book_cost=0
Suggested remediation with sample code snippet
Do not allow a user to specify cost for a book by himself. Sample Code Snippet Change
<?php
$cost = $_GET['cost'];
//Validation integer
$mysqli->query("INSERT INTO purchase(book_id,cost) VALUES($id,$cost)");
to
<?php
$result = $db->query("SELECT cost from books where book_id = $id");
$row = $result->fetch_assoc();
$cost = $row['cost'];
$db->query("INSERT INTO purchase(book_id,cost) VALUES($id,$cost)");
Challenge 5
Vulnerability/Vulnerabilities Identified
- SQL Injection
Applicable root cause(s)
The application does not validate the book_id
field for a request to checkout.asp
sufficiently
Generic 1
Vulnerability Identified
- Weak/Guessable Password ###Applicable Root Cause The password for the user
cctc
was very weak ###Approach adopted - Running on the shell :
cd /home/ ls cctc student
- We knew that there was a user called cctc on the system, so we tried guessing the password :
logout debian login: cctc Password: cctc
- Also all mail for root user is being forwarded to the
cctc
user since the directory/var/mail/root
does not exist. mail
command gave us access to all forwarded mail forroot
user (Attach Screenshot Here)
Generic 2
Vulnerability/Vulnerabilities Identified
- Client Side Script for Checkout ###Applicable root cause(s) A click on the purchase button is supposed to do two things :
- Checkout the book.
- Purchase the book.
It does so by sending out two requests to checkout.asp and purchase.asp
Both of these requests can be forged individually by an attacker.
Also Async javascript code is vulnerable
Approach adopted (steps with screenshots)
- A person could purchase a book, without checking it in, by simply making a request to
purchase.asp
The async code is given below :
function purchase(bid, cost) {
$.ajax({
url: 'checkout.asp?book_id=' + bid + '&action=checkin',
success: function(msg) {},
});
$.ajax({
url: 'purchase.asp?book_id=' +
bid +
'&action=purchase&book_cost=' +
cost,
success: function(msg) {
alert(msg);
history.go(0);
},
});
}
A side-effect of using ajax in such a sensitive environment is that you do not control the order of requests performed. Here, a request to purchase.asp
may get completed before checkout.asp
, which may have caused problems if the code was written out properly.
Suggested remediation with sample code snippet
Instead of the client sending out two requests, there should be a single request to purchase.asp
, which should automatically checkin the book, before purchasing it. Use:
<?php
//purchase.asp
$id = $_GET['book_id'];
checkout($id);
purchase($id);
Instead of :
<?php
purchase($_GET['id']);