Post on 15-May-2015
description
“select * from customers order by ” + injection + “ asc”
Read-only exploitable? Not really… › Can’t UNION with anything else › Can’t add columns
We can tell or guess… › Number of columns › Column names
Even if we know the DB layout, we can’t get info out with ORDER BY
CASE expressions allowed in ORDER BY › site.co.za/?o=case when 1=2 then ID else
Address end
Which we can use to extract data! › CASE WHEN expr THEN value [ELSE value] END
There’s actually a second CASE syntax, too › expr can be a SQL statement
site.co.za/?o=case when (select top 1 substring(username,1,1) from users)=‘a’ then ID else Address end
Assuming all data items are lowercase › And assuming that we go in alphabetical
order
Then: › 56 queries to return “john” › 65 queries to return “martin” › 119 queries to return “johenius”
Extend to uppercase+digits+special › “K1ngArthur!” would take a few hundred
queries.
Binary-search (courtesy Wikipedia) › BSearch(A[0..N-1], v, l, h):
if (h < l) return -1 // not found m = low + ((h - l) / 2) if (A[m] > v) return BSearch(A, v, l, m-1) else if (A[m] < v) return BSearch(A, v, m+1, h) else return m // found
site.co.za/?o=case when (select top 1 username from users) <= candidate then ID else Address end
How do we find candidates? Strings aren’t numbers! › Create ordered alphabet › Create stringnumber conversion funcs
Trivial, aside from big-numberness
What are our initial bounds? › Minimum is 0 › Maximum can be found by binary-search on
length
How do we order our alphabet? › Initially, I thought to do it via built-in
lexicographic comparison.. … which fails for certain cases due to SQL
collation differences › Use ordering queries to initialize alphabet
instead This can take ~300 queries for a ~90-character
alphabet. Amortised over total number of queries Or, make a guess and run against local server
Comparisons done by SQL engine › Case-insensitive generally › COLLATION matters! › ‘mooo’ < ‘moo’’a’, but ‘mooo’ > ‘moo’’z’,
according to SQL Server › Solution/workaround: compare as binary
Running into WAFs and other protections › “\e[<zmo~~~~~~” is detected as an attack
So is “Lor,w&#$Jo..” Go lower? Go higher? No way of knowing.
› Workaround: remove “<“ and “&” from alphabet. Better ideas welcome!
Alphabet must be complete › Or you must be a better SQL ninja than I am
How do we get to the next record? › Can’t use SELECT LIKE – we don’t know what
the next record looks like › If DB supports RowID, and you can use it, use it › Otherwise…
“… where [targetCol] not in (‘foo’, ‘bar’, …)”
Binary search is O(log2(n)) at best, and O(log2(n)+1) at worst › However, a single iteration may cause two
requests
How good is this news? › This is a lot of complexity! It’d better be
worth it…
1
10
100
1000
10000
Binary-search
Simple
0
500
1000
1500
2000
2500
3000
Binary-search
Simple
0.0x
1.0x
2.0x
3.0x
4.0x
5.0x
6.0x
7.0x
8.0x
joh
n
ha
rry
1337
ha
x0r
Gu
ess
Ag
ain
zon
go
rob
ert
Sara
hJe
ssic
aPa
rke
dH
ere
m0r
on
z
O'N
eill
joh
nsm
ith
sally
p@
ssw
0rd
7
Ve
ryLo
ng
Pass
wo
rd,P
rett
yMu
ch
Un
cra
cka
ble
dro
ng
o
love
1977
An
dG
otA
Tic
ket
~R
_Us!
!
Kern
3l'O
'Ne
ill
Speedup
4x minimum speedup, 6x average speedup › The difference between waiting 6 minutes or
1 minute
Can be adapted trivially to extract integer, floating-point, GUID, etc › Extremely good at approximating answer
Good way to exploit ORDER BY, which has traditionally been considered a difficult injection point
Use only when necessary! › Relies on a 1-bit side-channel; smuggling
data out this way is going to be slow.
Gets slower with each record › Amount of data sent increases › GET length limits you; POST is best
Wasteful due to ordering queries, unless: › More than 2 records are to be extracted › Collation is guessed, and local server used
Many more optimisations possible › Better SQL › Adaptive SQL
Pattern-matched row exclusion Adaptive querying once sufficient unique
characters have been discovered
› Fewer queries Possible to use “<=” only, given that binary-
search is best-case O(log2(n))
› Collation tables instead of ordering queries
Technique can be generalized to suit any data extraction area › Necessary: comparison operation result › XPath? Efficient GUID extraction? Dates?
Could be used as a n-bit channel › where n = number of ORDER BY clauses that
return different results
Needs testing; ‘tis merely a PoC. › I know there are some minor bugs…
Will I continue with this? Probably not. cinyc.s – AT – gmail.com