Skip to content

Instantly share code, notes, and snippets.

@danopia
Created August 25, 2012 12:44

Revisions

  1. danopia revised this gist Aug 25, 2012. 1 changed file with 38 additions and 17 deletions.
    55 changes: 38 additions & 17 deletions FlagBot.rb
    Original file line number Diff line number Diff line change
    @@ -1,31 +1,49 @@
    #!/usr/bin/env ruby

    qdbus = 'qdbus org.xchat.service /org/xchat/Remote org.xchat.plugin.'
    context = `#{qdbus}FindContext "irc.stripe.com" "#level8"`.strip.to_i
    `#{qdbus}SetContext #{context}`
    def say stuff; puts ">> #{stuff}"; `#{qdbus}Command "say #{stuff}"`; end
    def action stuff; puts ">> #{stuff}"; `#{qdbus}Command "me #{stuff}"`; end
    $server = 'irc.stripe.com'
    $channel = '#level8'
    $nick = 'FlagBot'
    $chanfile = '~/.xchat2/xchatlogs/NETWORK-\#level8.log'
    $sshpath = 'user-hawkwarded@level02-4.stripe-ctf.com'
    $command = 'ruby bot.rb'
    $store = './flags.rb'

    say 'FlagBot reporting for duty... hopefully'
    $qdbus = 'qdbus org.xchat.service /org/xchat/Remote org.xchat.plugin.'
    context = `#{$qdbus}FindContext "#{$server}" "#{$channel}"`.strip.to_i
    `#{$qdbus}SetContext #{context}`
    def say stuff; puts ">> <#{$nick}> #{stuff}"; `#{$qdbus}Command "say #{stuff}"`; end
    def action stuff; puts ">> * #{$nick} #{stuff}"; `#{$qdbus}Command "me #{stuff}"`; end

    say "#{$nick} reporting for duty!"

    $queue = []
    $known = {}

    def add info
    p info
    $known[info[:server]] ||= {}
    $known[info[:server]][info[:user]] = info
    end
    require $store

    Thread.new do
    ircin = IO.popen 'tail -f -n 0 ~/.xchat2/xchatlogs/NETWORK-\#level8.log'
    ircin = IO.popen "tail -f -n 0 #{$chanfile}"
    toggle = false
    while line = ircin.gets
    next if toggle = !toggle # skip every other, because it's dupped
    next unless line.strip =~ /^([A-Z][a-z]{2}) ([0-9]{1,2}) ([0-9]{1,2}):([0-9]{2}):([0-9]{2}) <([^>]+)>\t(.+)$/
    nick, message = $6, $7
    next if nick.include? 'FlagBot'
    next unless message =~ /https:\/\/level08-([0-9]+).stripe-ctf.com\/user-([a-z]{10})\/?/
    next unless message =~ /https:\/\/level08-([0-9]+).stripe-ctf.com\/user-([a-z]{10})\/?\b/
    puts "<< <#{nick}> #{message}"
    server, user = $1.to_i, $2

    if $known[server] && $known[server][user]
    info = $known[server][user]
    say "#{nick}: Hey, I know you! I solved your flag in #{info[:delta].to_i} seconds, just #{(Time.now - info[:times].last).to_i / 60} minutes ago."
    Thread.new do
    sleep 1
    say "#{nick}: Hey, I know you! I solved your flag in #{info[:delta].to_i} seconds, just #{(Time.now.to_i - info[:times].last).to_i / 60} minutes ago."
    end
    else
    $queue << {:server => server, :user => user, :nick => nick}
    end
    @@ -39,15 +57,16 @@ def action stuff; puts ">> #{stuff}"; `#{qdbus}Command "me #{stuff}"`; end
    $known[info[:server]] ||= {}

    if $known[info[:server]][info[:user]]
    info.merge! $known[info[:server]][info[:user]]
    say "#{info[:nick]}: Hey, I know you! I solved your flag in #{info[:delta].to_i} seconds, just #{(Time.now - info[:times].last).to_i / 60} minutes ago."
    info = $known[info[:server]][info[:user]].merge info
    say "#{info[:nick]}: Hey, I know you! I solved your flag in #{info[:delta].to_i} seconds, just #{(Time.now.to_i - info[:times].last).to_i / 60} minutes ago."
    else
    info[:times] = [Time.now]
    info[:times] = [Time.now.to_f]
    info[:delta] = 0.0
    info[:chunks] = []

    i = 0

    cap = IO.popen "ssh user-hawkwarded@level02-4.stripe-ctf.com 'ruby bot.rb #{info[:server]} #{info[:user]}'"
    cap = IO.popen "ssh #{$sshpath} '#{$command} #{info[:server]} #{info[:user]}'"
    puts cap.gets
    puts cap.gets
    action "runs off to solve #{info[:nick]}'s flag :D"
    @@ -60,7 +79,7 @@ def action stuff; puts ">> #{stuff}"; `#{qdbus}Command "me #{stuff}"`; end

    id, chunk = $1.to_i, $2
    info[:chunks] << chunk
    info[:times] << Time.now
    info[:times] << Time.now.to_f

    count = info[:chunks].size
    if count == 1
    @@ -72,7 +91,7 @@ def action stuff; puts ">> #{stuff}"; `#{qdbus}Command "me #{stuff}"`; end
    puts line

    info[:flag] = $1
    info[:times] << Time.now
    info[:times] << Time.now.to_f
    info[:delta] = info[:times].last - info[:times].first
    info[:chunks] = info[:flag].scan /[0-9]{3}/

    @@ -83,7 +102,9 @@ def action stuff; puts ">> #{stuff}"; `#{qdbus}Command "me #{stuff}"`; end
    end
    end

    p info
    $known[info[:server]][info[:user]] = info
    File.open $store, 'a' do |f|
    f.puts "add(#{info.inspect})"
    end
    add info
    end
    end
  2. danopia created this gist Aug 25, 2012.
    89 changes: 89 additions & 0 deletions FlagBot.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,89 @@
    #!/usr/bin/env ruby

    qdbus = 'qdbus org.xchat.service /org/xchat/Remote org.xchat.plugin.'
    context = `#{qdbus}FindContext "irc.stripe.com" "#level8"`.strip.to_i
    `#{qdbus}SetContext #{context}`
    def say stuff; puts ">> #{stuff}"; `#{qdbus}Command "say #{stuff}"`; end
    def action stuff; puts ">> #{stuff}"; `#{qdbus}Command "me #{stuff}"`; end

    say 'FlagBot reporting for duty... hopefully'

    $queue = []
    $known = {}

    Thread.new do
    ircin = IO.popen 'tail -f -n 0 ~/.xchat2/xchatlogs/NETWORK-\#level8.log'
    toggle = false
    while line = ircin.gets
    next if toggle = !toggle # skip every other, because it's dupped
    next unless line.strip =~ /^([A-Z][a-z]{2}) ([0-9]{1,2}) ([0-9]{1,2}):([0-9]{2}):([0-9]{2}) <([^>]+)>\t(.+)$/
    nick, message = $6, $7
    next if nick.include? 'FlagBot'
    next unless message =~ /https:\/\/level08-([0-9]+).stripe-ctf.com\/user-([a-z]{10})\/?/
    puts "<< <#{nick}> #{message}"
    server, user = $1.to_i, $2

    if $known[server] && $known[server][user]
    info = $known[server][user]
    say "#{nick}: Hey, I know you! I solved your flag in #{info[:delta].to_i} seconds, just #{(Time.now - info[:times].last).to_i / 60} minutes ago."
    else
    $queue << {:server => server, :user => user, :nick => nick}
    end
    end
    end

    until STDIN.closed?
    sleep 1 until $queue.any?
    info = $queue.shift

    $known[info[:server]] ||= {}

    if $known[info[:server]][info[:user]]
    info.merge! $known[info[:server]][info[:user]]
    say "#{info[:nick]}: Hey, I know you! I solved your flag in #{info[:delta].to_i} seconds, just #{(Time.now - info[:times].last).to_i / 60} minutes ago."
    else
    info[:times] = [Time.now]
    info[:chunks] = []

    i = 0

    cap = IO.popen "ssh user-hawkwarded@level02-4.stripe-ctf.com 'ruby bot.rb #{info[:server]} #{info[:user]}'"
    puts cap.gets
    puts cap.gets
    action "runs off to solve #{info[:nick]}'s flag :D"

    while line = cap.gets
    line.strip!

    if line =~ /^Chunk ([1-4]) is ([0-9]+)$/
    puts line

    id, chunk = $1.to_i, $2
    info[:chunks] << chunk
    info[:times] << Time.now

    count = info[:chunks].size
    if count == 1
    say "#{info[:nick]}: #{count} chunk down on your flag ;D #{4 - count} to go!"
    else
    say "#{info[:nick]}: #{count} chunks down on your flag ;D #{4 - count} to go!"
    end
    elsif line =~ /^And the password is: ([0-9]{12})$/
    puts line

    info[:flag] = $1
    info[:times] << Time.now
    info[:delta] = info[:times].last - info[:times].first
    info[:chunks] = info[:flag].scan /[0-9]{3}/

    say "#{info[:nick]}: I know your flag! It only took /me/ #{info[:delta].to_i} seconds; how long will it take /YOU/? ;D"
    else
    puts line if i == 0
    i = i.succ % 25
    end
    end

    p info
    $known[info[:server]][info[:user]] = info
    end
    end