Lesson
Plan Title: How to
Perform Silent Transactions Attacks.
Concept /
Topic To Teach:
This lesson
teaches how to perform silent transactions attacks.
How the
attacks works:
Any system that
silently processes transactions using a single submission is dangerous to the
client. For example, if a normal web application allows a simple URL
submission, a preset session attack will allow the attacker to complete a
transaction without the user’s authorization. In Ajax, it gets worse: the
transaction is silent; it happens with no user feedback on the page, so an
injected attack script may be able to steal money from the client without
authorization.
General
Goal(s):
This is a
sample internet banking application - money transfer page.
It shows
below your balance, the account you are transferring to and amount you will
transfer.
The application uses AJAX to submit the transaction after doing some basic
client side validations.
Your goal is to try to bypass the user's authorization and silently execute the
transaction.
Figure 1 AJAX Security - Silent transaction attacks
Solution:
This web
application uses JavaScript on the client to initiate a transaction for
transferring money. Examining the HTML source reveals that two JavaScript
functions are being used:
<script>
function
processData(){
var accountNo =
document.getElementById('newAccount').value;
var amount =
document.getElementById('amount').value;
if ( accountNo == ''){
alert('Please enter a valid account number to
transfer to.')
return;
}
else if ( amount == ''){
alert('Please enter a valid amount to
transfer.')
return;
}
var balanceValue =
document.getElementById('balanceID').innerText;
balanceValue = balanceValue.replace( new
RegExp('$') , '');
if ( parseFloat(amount) >
parseFloat(balanceValue) ) {
alert('You can not transfer more funds than
what is available in your balance.')
return;
}
document.getElementById('confirm').value = 'Transferring'
submitData(accountNo,
amount);
document.getElementById('confirm').value = 'Confirm'
balanceValue
= parseFloat(balanceValue) - parseFloat(amount);
balanceValue
= balanceValue.toFixed(2);
document.getElementById('balanceID').innerText
= balanceValue + '$';
}
function
submitData(accountNo, balance) {
var url =
'/WebGoat/attack?Screen=74&menu=1150&from=ajax&newAccount='+
accountNo+ '&amount=' + balance +'&confirm=' +
document.getElementById('confirm').value;
if (typeof
XMLHttpRequest != 'undefined') {
req = new
XMLHttpRequest();
} else if
(window.ActiveXObject) {
req = new
ActiveXObject('Microsoft.XMLHTTP');
}
req.open('GET', url, true);
req.onreadystatechange = callback;
req.send(null);
}
function
callback() {
if (req.readyState == 4) {
if (req.status == 200) {
var result = req.responseText ;
var resultsDiv =
document.getElementById('resultsDiv');
resultsDiv.innerHTML = '';
resultsDiv.innerHTML
= result;
}}}
</script>
The function
processData() is called when the user fills out an account number and an amount
to transfer. The function processData() will check if the user has sufficient
balance before initiating the transaction. After validation of the balance, the
JavaScript function submitData(accountNo, balance) is called which actually
submits the required information, target account number and the amount to
transfer, to the back-end web application.
If you are
able to call this JavaScript function submitData(accountNo, balance) from the
browser, you are able to bypass the client-side validation and execute this
transaction silently, without an additional approval or digital signature of
the user.
The latest
generation of browsers allows to call JavaScript from the address bar, using
javascript:function();. Try to execute: javascript:submitData(1234556,11000);
Figure 2 Follow the hints....
Figure 3 HTTP Request generated from Javascript function submitData(123456,110000);
Figure 4 Lesson completed
Solution by Erwin Geirnaert | ![]() |