Last active
May 5, 2021 04:45
-
-
Save shinh/242786e2f6a38f9f50803e64a1882715 to your computer and use it in GitHub Desktop.
DEF CON CTF 2021 Qual back-to-qoo
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 | |
# qoo_run.rb の結果を ruby qoo.rb log として食べさせると secret を出すやつ | |
c1s = [] | |
c2s = [] | |
p1s = [] | |
wins = [] | |
msgs = [] | |
no_changes = [] | |
File.readlines(ARGV[0] || 'qoo2.log').each do |line| | |
if line =~ /Your competitor bets on (\d+)/ | |
c1s << $1.to_i | |
end | |
if line =~ /zardus's competitor bets on (\d+), you bet on (\d+)/ | |
c2s << $1.to_i | |
p1s << $2.to_i | |
end | |
if line =~ /\[-\] OK/ | |
no_changes << 1 | |
end | |
if line =~ /\[-\] ZZZ/ | |
no_changes << 0 | |
end | |
if line =~ /Win|Lose/ | |
wins << (($& == "Win") ? 1 : 0) | |
end | |
if line =~ /zardus receives from adamd: \d+:(\d)/ | |
msgs << $1.to_i | |
end | |
end | |
p [c1s.size, c2s.size, wins.size, msgs.size, p1s.size, no_changes.size] | |
# p c1s | |
# p c2s | |
# p p1s | |
# p wins | |
# p msgs | |
key_str = '' | |
t = 0 | |
c1s.zip(c2s, p1s, wins, msgs, no_changes).each do |c1, c2, p1, win, msg, nc| | |
if c2 == 1 | |
measure = "H|Q>" | |
else | |
measure = "|Q>" | |
end | |
#p2 = (c1*c2) ^ p1 | |
if win == 1 | |
p2 = (c1*c2) ^ p1 | |
else | |
p2 = (c1*c2) ^ p1 ^ 1 | |
end | |
sec = c2 == msg ? 1 : 0 | |
puts "turn=#{t} m=#{measure} c1=#{c1} c2=#{c2} c1*c2=#{c1*c2} p1=#{p1} p2=#{p2} sec=#{sec} nc=#{nc} win=#{win} chk=#{(p1^p2)==(c1*c2)}" | |
if sec == 1 | |
# if c2 == 1 | |
# key_str += '?' | |
# else | |
# key_str += p2.to_s | |
# end | |
# rotate してない & base が 0 だったら信用できて、残り 32bit くらい総当たり、という問題だと思ってた | |
#if nc == 1 && msg == 0 | |
#if nc == 1 && c2 == 0 | |
# ……が、なんか rotate した後の measure も信用できて、フラグは取れたけどよくわからん | |
if nc == 1 || true | |
key_str += p2.to_s | |
else | |
key_str += '?' | |
end | |
end | |
t += 1 | |
end | |
puts "#{key_str.count("?")} / #{key_str.size}" | |
puts key_str | |
p key_str.each_char.map{|c| | |
c == '?' ? 2 : c.to_i | |
}.to_a | |
#num = 0 | |
#refs.zip(msgs).each do |r, m| | |
# if r == m | |
# #puts "hm" | |
# num += 1 | |
# end | |
#end | |
#p num | |
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
# まあおおむね勝てるやつ | |
require_relative 'ctfutils' | |
serv = ARGV[0] || "back-to-qoo.challenges.ooo" | |
pipe = popen("nc #{serv} 5000") | |
bets = [] | |
num_wins = 0 | |
128.times do |t| | |
m = pipe.wait_until(/competitor bets on /) | |
bet = pipe.get.to_i | |
STDERR.puts "[-] bet=#{bet}" | |
bets << bet | |
# このへん調節して勝率落として rotate の頻度を落とそうとしていました | |
#if num_wins + (128 - t) * 0.75 > 108 && bet == 0 | |
#if bet == 0 | |
if false | |
STDERR.puts "[-] OK 0" | |
#pipe.puts "0" | |
pipe.puts "2" | |
pipe.puts "0" | |
else | |
STDERR.puts "[-] ZZZ #{num_wins}/#{t+1}" | |
pipe.puts "2" | |
pipe.puts bet + 1 | |
#pipe.puts 2 - bet | |
end | |
m = pipe.wait_until(/(Win|Lose)/) | |
if m[0] =~ /Win/ | |
num_wins += 1 | |
end | |
end | |
STDERR.puts "[-] #{num_wins}" | |
pipe.puts "" | |
pipe.puts "" | |
pipe.puts "" | |
pipe.interactive |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment