Chris Carter
7/7/2007 5:26:00 PM
On 7/7/07, ara.t.howard <ara.t.howard@gmail.com> wrote:
>
> On Jul 6, 2007, at 12:29 PM, jannis@harderweb.de wrote:
>
> > The method used in this captcha is very is to break. In fact I can
> > solve
> > the captchas 6 times as fast as it takes to generate them (locally)
> > in
> > only 63 lines of code. I do this by generating a regexp for each
> > possible
> > character. As the characters don't get damaged by the noise (as they
> > get
> > in most image bases captchas) this works all of the time.
>
>
> hmmm - not for me?
>
>
>
> cfp:~ > ruby a.rb
> user system total real
> generate: 0.140000 0.020000 0.170000 ( 0.178928)
> setup: 0.020000 0.000000 0.020000 ( 0.022138)
> break: Flatulent.version : 0.0.4
> a.rb:63: failed on attempt 1 (RuntimeError)
> from /opt/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
> from /opt/local/lib/ruby/1.8/benchmark.rb:377:in `report'
> from a.rb:63
> from /opt/local/lib/ruby/1.8/benchmark.rb:177:in `benchmark'
> from /opt/local/lib/ruby/1.8/benchmark.rb:207:in `bm'
> from a.rb:59
>
>
>
> cfp:~ > cat a.rb
> require 'flatulent'
> require 'benchmark'
> require 'flatulent'
>
> class Deflatulent
> def initialize font="big"
> font = Text::Figlet::Font.new(File.join(Flatulent.fontdir,font
> +".flf"))
> typesetter = Text::Figlet::Typesetter.new font
> letters = ('A'..'Z').to_a + ('1'..'9').to_a
> @lines_array = letters.map{|letter| [letter,
> gen_figlet_lines_array(typesetter[letter])] }
> end
>
> def deflatulent string
> if string =~ /<pre id='[a-zA-Z0-9_-]+_element' style='.*?'>(.*?)<
> \/ pre>/m
> string = $1
> [[/<\/?span>/,''],[" "," "],["<br>","\n"],["<","<"],
> [">",">"],[""",'"'],["&","&"]].each do |args|
> string.gsub!(*args)
> end
> end
>
> width = string.index("\n")
> string.tr!("\n","")
> solution = []
>
> @lines_array.each do |(letter,(length,lines))|
>
> re = "(?="
> lines.each{|line| re << line << ".{#{width-length}}" }
> re << ")"
>
> string.scan(Regexp.new(re, Regexp::MULTILINE)) do
> solution[$~.begin(0) % width] = letter
> end
> end
>
> solution.join
> end
>
> private
> def gen_figlet_lines_array string
> lines = string.split("\n")
> lines.shift while lines.first.strip.empty?
> lines.pop while lines.last.strip.empty?
>
> lines.each{|e|e[0,1]=""} while lines.all?{|e|e[0,1]==' '}
> lines.each{|e|e[-1,1]=""} while lines.all?{|e|e[-1,1]==' '}
>
> [lines[0].length,lines.map{|e|e.split('').map{|q|(q == ' ' ?
> '.' : Regexp.escape(q))}.join}]
> end
> end
>
> defl = html = code = nil
> pairs = Array.new(200)
>
> GC.disable
> i = 0
>
> begin
> Benchmark.bm(13) do |x|
> i += 1
> x.report("generate:") { flat = Flatulent.new; html = flat.form;
> code = flat.string }
> x.report("setup:") { defl = Deflatulent.new }
> x.report("break:") { raise "failed on attempt #{ i }" unless
> defl.deflatulent(html) == code }
> x.report("generate 200:") { 200.times{|index| flat =
> Flatulent.new; pairs[index] = [flat.form,flat.string] } }
> x.report("break 200:") { pairs.map{|(html,code)| raise unless
> defl.deflatulent(html) == code } }
> end
> ensure
> puts "Flatulent.version : #{ Flatulent.version }"
> end
>
>
> nevertheless, i'm not for one second claiming flatulent is ready for
> prime time. however, i will state that i think it's quite a bit of
> work if you use it in the intended way, which is for the html to make
> an ajax call to get the flatulent source because this make said
> source available only to javascript. no doubt someone could crack it
> from there, but the latest version adds vertical and horizontal
> offset to each char. my version is turning that source into a png.
> anyhow, the attention is welcome - but next time send a patch! ;-)
>
> -a
> --
> we can deny everything, except that we have the possibility of being
> better. simply reflect on that.
> h.h. the 14th dalai lama
>
>
>
>
>
Ara,
That is because you set defl and flat inside a block, without setting
the variables to nil before the block is executed, so they stay
existing for the actual decode stage.
--
Chris Carter
concentrationstudios.com
brynmawrcs.com