Changes

Jump to: navigation, search

Gits2012teaser

2,875 bytes removed, 08:24, 22 October 2012
moved [[CTF/gits2012teaser]] to [[Gits2012teaser]]
== #1 TelAviv ==[[Category:CTF]][[Image:gits-scores.png]]
What is = Ghost in the password? ([[File:7139a4ea239dcac655f7c38ca6a77b61.bin|File]])<br>Hint: TeLaViv+ is a packet forensics challenge.Shellcode 2012 Teasers writeups =
== #2 AL's Revenge ==http://ghostintheshellcode.com/
* file 49dd327824d5afe9cdf931ea4b13719f.bin says xz compressed file -> xzcat > f* file f says LLVM bitcode -> llvm-dis > f.s (only works with LLVM 2.8, not with 3.0)* analyze disassembly, extract C representation:Thanks to the organizers for those pretty nice teasers!
<pre>intVerifySerial(uint64_t name, uint64_t serial){ uint64_t a = 0x8000000000000000LL; uint64_t b = 0xa348fccd93aea5a7LL; uint64_t result = 0;The following writeups have been made by members of the FIXME team during between January 6th and January 8th.
/* high order bit set? *Challenge [[CTF/ if (name & a) a ^= b;  if (serial & a) serial ^= b;  while (serial != 0) { if (serial & 1) result ^= name;  serial >>= 1; name <<= 1;  if (name & a) name ^= b; }H  return (result == 1);}<gits2012teaser/pre> * it looks like a multiplication over a galois field, with the irreducible polynomial 0x1a348fccd93aea5a7 (note leading bit not in C), but it actually isn't, because the high bit gets checked after the shift, not before.* lacking math knowledge and math package fu, decided to treat the problem as a linear equation system:* The shifting and xoring produces a set of integers, call them name_i. If the serial bit s_i is set, name_i gets added to the result. So you can roughly say r = N * s, with r being the result vector, s the serial vector and N the names matrix.* lacking math package fu, implement a gaussian elimination manually: <pre>class Numeric def bits64 sprintf("%064b", self).each_char.map{|c| c == "0" ? 0 : 1} endend def names(name) p = 0xa348fccd93aea5a7  if (name >> 63) & 1 == 1 name ^= p end  ([name] + 63.times.map do -TelAviv|i| name <<= #1 if (name >> 63) & 1 == 1 name ^= p end name end).map(&:bits64)end class Array def pivot res = [TelAviv] self[0].size.times.map do |i| self.size.times.map do |j| selfby [j][i] end end end  def bitary_to_int self.join.to_i(2) endend class Eq < Array attr_accessor User:res  def initialize(ary, res) self.replace(ary) @res = res end  def lead_zero self.take_while{Francois|e| e == 0} end  def first_pos self.index(1) end  def subtract(o) Eq.new(self.zip(o).map{|aa, bb| aa ^ bb}, @res ^ o.res) endend class EqSys < Array def initialize(ary, res=nil) if !(Eq === ary[0Francois]) && !ary.empty? ary = ary.zip(res).map{|a, r| Eq.new(a, r)} end self.replace(ary) end  def sort_by_zeros self.sort do |a, b| a.lead_zero <=> b.lead_zero end end  def subtract_eq(eq) pos = eq.first_pos return self if not pos EqSys.new(self.map{|e| e[pos] == 1 ? e.subtract(eq) : e}) end  def elim front = EqSys.new(* Challenge []) cur = nil rest = self.sort_by_zeros while not rest.empty? front << cur if cur cur = rest.shift  front = front.subtract_eq(cur) rest = rest.subtract_eq(cur) rest = rest.sort_by_zeros end front << cur  front end  def to_s self.map{[CTF/gits2012teaser/2-ALsRevenge|e| e.map(&:to_s).join + " = #{e.res}"}.join("\n") endend require 2 AL'pp'if __FILE__ == $0 ns = names(0x6638623261336134)  pv = ns.pivot es = EqSys.new(pv, 1.bits64)  puts es.to_s puts  r = es.elim puts r.to_s  res = r.map{s Revenge]] by [[User:Corecode|e| e.res}.reverseCorecode]] puts res.bitary_to_int.to_s(16)  s0 = r.pivot.last.reverse puts s0.bitary_to_int.to_s(16) puts (res.bitary_to_int^s0.bitary_to_int).to_s(16)end<* Challenge [[CTF/gits2012teaser/pre> == 3-Hackquest|#3 Hackquest ==]] by [[User:Corecode|Corecode]]
ControlGroup, administrator
4,202
edits