Created
August 25, 2012 12:44
-
-
Save danopia/3465087 to your computer and use it in GitHub Desktop.
IRC bot to run a Stripe CTF2 level8 cracking command automatically. Integrates with XChat.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
$server = 'irc.stripe.com' | |
$channel = '#level8' | |
$nick = 'FlagBot' | |
$chanfile = '~/.xchat2/xchatlogs/NETWORK-\#level8.log' | |
$sshpath = '[email protected]' | |
$command = 'ruby bot.rb' | |
$store = './flags.rb' | |
$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 #{$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})\/?\b/ | |
puts "<< <#{nick}> #{message}" | |
server, user = $1.to_i, $2 | |
if $known[server] && $known[server][user] | |
info = $known[server][user] | |
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 | |
end | |
end | |
until STDIN.closed? | |
sleep 1 until $queue.any? | |
info = $queue.shift | |
$known[info[:server]] ||= {} | |
if $known[info[:server]][info[:user]] | |
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.to_f] | |
info[:delta] = 0.0 | |
info[:chunks] = [] | |
i = 0 | |
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" | |
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.to_f | |
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.to_f | |
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 | |
File.open $store, 'a' do |f| | |
f.puts "add(#{info.inspect})" | |
end | |
add info | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment