A little bit story of CTF

Idsecconf2011 baru saja berakhir. Kudos untuk para panitia, speaker, dan khususnya para anggota komite yang sudah meluangkan waktunya untuk acara tersebut. Saya sendiri tidak dapat menghadiri, namun dari beberapa dokumentasi tampaknya acara tersebut berjalan dengan baik dan antusiasme komunitas security khususnya dari kota palembang disebutkan cukup besar.

Pada kesempatan kali ini saya ingin membahas mengenai salah satu challenge yang diberikan pada CTF online untuk idsecconf2011. Challenge untuk idsecconf dibuat oleh beberapa anggota komite sehingga terdapat beragam jenis challenge (setiap orang memiliki hobby pada bidang yang beda-beda), dan tidak dilakukan share solution dengan tujuan agar jika salah satu dari anggota komite di-compromise (we’re living in hacking world, remember?) maka tidak semua challenge dari idsecconf akan jatuh begitu saja. Challenge dari saya sebelumnya (bl00dyh0l1d4y) berada pada ranah reverse engineering, untuk tahun ini juga masih sama namun lebih di fokuskan pada topic yang sedang hangat atau menjadi trend dalam dunia security, yaitu PDF analysis.

Untuk sebagian orang di bidang security tentunya sudah menyadari bahwa PDF menjadi topik favorit beberapa tahun tearkhir, hal ini disebabkan karena hampir setiap komputer memiliki program pembaca PDF seperti adobe acrobat reader. Dan dalam beberapa tahun terakhir, riset terhadap eksploitasi ataupun penyebaran malware melalui file-file PDF berkembang dengan pesat. Untuk itulah saya ingin mengenalkan kepada komunitas IT security Indonesia (khususnya non-profesional) mengenai reverse engineering pada format PDF. Hal ini sangat bermanfaat baik untuk proses analisis suatu malware ataupun PDF exploit. Komite idsecconf juga mengutamakan hal lain untuk CTF selain hal-hal berbau teknikal, diantara beberapa poin yang sempat kami diskusikan secara internal adalah “FUN”. Kami menyadari bahwa komunitas non-profesional umumnya pendatang baru ataupun generasi muda yang sedang dalam proses pembelajaran, untuk itu harus dipertimbangkan juga mengenai tingkat kesulitan dari challenge yang diberikan. Untuk reverse engineering ini saya mengkategorikan level “basic”, dimana untuk penyelesaian-nya diperkirakan dapat dilakukan dengan googling + membaca beberapa referensi publik + menggunakan tools public.

Berikut ini adalah code yang digunakan untuk meng-generate file ber-ekstensi .exe yang akan dikirimkan kepada peserta CTF untuk dipecahkan dan dicari flag-nya,


#!/usr/bin/env ruby

require 'zlib'

#########################################
# Basic Reverse Engineering for CTF     #
# idsecconf2011 palembang - online ctf  #
#                                       #
# ruby pdf.rb <nickname>                #
#                                       #
#                           - Cyberheb  #
#########################################

# borrowed from metasploit, pdf fileformat exploit
class Pdf
  	def RandomNonASCIIString(count)
  		result = ""
  		count.times do
  			result << (rand(128) + 128).chr
  		end
  		result
  	end

  	def ioDef(id)
  		"%d 0 obj" % id
  	end

  	def ioRef(id)
  		"%d 0 R" % id
  	end

  	# http://blog.didierstevens.com/2008/04/29/pdf-let-me-count-the-ways/
  	def nObfu(str)
  		result = ""
  		str.scan(/./u) do |c|
  			if rand(2) == 0 and c.upcase >= 'A' and c.upcase <= 'Z'
  				result << "#%x" % c.unpack("C*")[0]
  			else
  				result << c
  			end
  		end
  		result
  	end

  	def ASCIIHexWhitespaceEncode(str)
  		result = ""
  		whitespace = ""
  		str.each_byte do |b|
  			result << whitespace << "%02x" % b
  			whitespace = " " * (rand(3) + 1)
  		end
  		result << ">"
  	end

  	def make_pdf(js)

  		xref = []
  		eol = "\x0d\x0a"
  		endobj = "endobj" << eol

  		# Randomize PDF version?
  		pdf = "%PDF-1.5" << eol
  		pdf << "%" << RandomNonASCIIString(4) << eol
  		xref << pdf.length
  		pdf << ioDef(1) << nObfu("<</Type/Catalog/Outlines ") << ioRef(2) << nObfu("/Pages ") << ioRef(3) << nObfu("/OpenAction ") << ioRef(5) << ">>" << endobj
  		xref << pdf.length
  		pdf << ioDef(2) << nObfu("<</Type/Outlines/Count 0>>") << endobj
  		xref << pdf.length
  		pdf << ioDef(3) << nObfu("<</Type/Pages/Kids[") << ioRef(4) << nObfu("]/Count 1>>") << endobj
  		xref << pdf.length
  		pdf << ioDef(4) << nObfu("<</Type/Page/Parent ") << ioRef(3) << nObfu("/MediaBox[0 0 612 792]>>") << endobj
  		xref << pdf.length
  		pdf << ioDef(5) << nObfu("<</Type/Action/S/JavaScript/JS ") + ioRef(6) + ">>" << endobj
  		xref << pdf.length
  		compressed = Zlib::Deflate.deflate(ASCIIHexWhitespaceEncode(js))
  		pdf << ioDef(6) << nObfu("<</Length %s/Filter[/FlateDecode/ASCIIHexDecode]>>" % compressed.length) << eol
  		pdf << "stream" << eol
  		pdf << compressed << eol
  		pdf << "endstream" << eol
  		pdf << endobj
  		xrefPosition = pdf.length
  		pdf << "xref" << eol
  		pdf << "0 %d" % (xref.length + 1) << eol
  		pdf << "0000000000 65535 f" << eol
  		xref.each do |index|
  			pdf << "%010d 00000 n" % index << eol
  		end
  		pdf << "trailer" << nObfu("<</Size %d/Root " % (xref.length + 1)) << ioRef(1) << ">>" << eol
  		pdf << "startxref" << eol
  		pdf << xrefPosition.to_s() << eol
  		pdf << "%%EOF" << eol

  	end

end

class Flag
    def generate(nick)
      fuzz = [('a'..'z'), ('A'..'Z'), ('0'..'9')].map{|i| i.to_a}.flatten
      str = (0..50).map{ fuzz[rand(fuzz.length)]}.join
      
      nick + "-" + str
    end
end

# Generate random flag based on username
rand_flag = Flag.new
ctf_flag = rand_flag.generate(ARGV[0])

ctf = Pdf.new
js = %Q|
  var submit_this_flag = #{ctf_flag}
  |

pdf = ctf.make_pdf(js)

# Create filename using .exe extension, it will camouflage .pdf and force them to learn basic reverse engineering by 
# looking at binary header information
file = File.new("findthesecretflaginsidemebabe.exe", "w")
file.write(pdf)
file.close

Code diatas diambil dari salah satu pdf exploit pada metasploit framework. Hasilnya adalah suatu file pdf menyimpan suatu flag. Bagi yang sudah terbiasa dengan analisis PDF tentu tahu apa yang harus dilakukan. Namun untuk pemula dapat membaca Free Malicious PDF Analysis oleh Didier Stevens.

File yang dikirimkan kepada peserta akan ber-ekstensi .exe, ini adalah basic dari RE dimana kita harus memastikan jenis file tersebut untuk maju ke proses berikutnya.

$ file findthesecretflaginsidemebabe.exe
findthesecretflaginsidemebabe.exe: PDF document, version 1.5

Tools seperti “file” dapat digunakan untuk menentukan jenis file secara instant. Dengan mengetahui bahwa file tersebut adalah PDF, selanjutnya dapat menggunakan pdf-parser milik stevens (dengan harapan sudah membaca terlebih dahulu dan memahami konsep PDF đŸ™‚ ). Selain pdf-parser.py ada beberapa tools lain, silahkan cari sendiri.


$ python pdf-parser.py findthesecretflaginsidemebabe.exe 
PDF Comment '%PDF-1.5\r\n'

PDF Comment '%\xaa\xc0\x9b\xf8\r\n'

obj 1 0
 Type: /Catalog
 Referencing: 2 0 R, 3 0 R, 5 0 R
 [(2, '<<'), (2, '/T#79#70#65'), (2, '/Ca#74a#6co#67'), (2, '/Outli#6e#65#73'), (1, ' '), (3, '2'), (1, ' '), (3, '0'), (1, ' '), (3, 'R'), (2, '/P#61#67es'), (1, ' '), (3, '3'), (1, ' '), (3, '0'), (1, ' '), (3, 'R'), (2, '/#4fp#65n#41ct#69#6f#6e'), (1, ' '), (3, '5'), (1, ' '), (3, '0'), (1, ' '), (3, 'R'), (2, '>>')]

 <<
   /Type /Catalog
   /Outlines 2 0 R
   /Pages 3 0 R
   /OpenAction 5 0 R
 >>


obj 2 0
 Type: /Outlines
 Referencing: 
 [(2, '<<'), (2, '/#54yp#65'), (2, '/Out#6c#69#6e#65s'), (2, '/#43#6f#75nt'), (1, ' '), (3, '0'), (2, '>>')]

 <<
   /Type /Outlines
   /Count 0
 >>


obj 3 0
 Type: /Pages
 Referencing: 4 0 R
 [(2, '<<'), (2, '/Type'), (2, '/#50#61ges'), (2, '/#4b#69#64s'), (2, '['), (3, '4'), (1, ' '), (3, '0'), (1, ' '), (3, 'R'), (2, ']'), (2, '/C#6fun#74'), (1, ' '), (3, '1'), (2, '>>')]

 <<
   /Type /Pages
   /Kids [4 0 R]
   /Count 1
 >>


obj 4 0
 Type: /Page
 Referencing: 3 0 R
 [(2, '<<'), (2, '/#54#79pe'), (2, '/P#61#67#65'), (2, '/#50a#72#65#6e#74'), (1, ' '), (3, '3'), (1, ' '), (3, '0'), (1, ' '), (3, 'R'), (2, '/#4d#65#64#69#61#42o#78'), (2, '['), (3, '0'), (1, ' '), (3, '0'), (1, ' '), (3, '612'), (1, ' '), (3, '792'), (2, ']'), (2, '>>')]

 <<
   /Type /Page
   /Parent 3 0 R
   /MediaBox [0 0 612 792]
 >>


obj 5 0
 Type: /Action
 Referencing: 6 0 R
 [(2, '<<'), (2, '/#54ype'), (2, '/A#63#74i#6f#6e'), (2, '/S'), (2, '/#4aava#53cr#69#70t'), (2, '/J#53'), (1, ' '), (3, '6'), (1, ' '), (3, '0'), (1, ' '), (3, 'R'), (2, '>>')]

 <<
   /Type /Action
   /S /JavaScript
   /JS 6 0 R
 >>


obj 6 0
 Type: 
 Referencing: 
 Contains stream
 [(2, '<<'), (2, '/#4c#65#6eg#74#68'), (1, ' '), (3, '172'), (2, '/Fi#6c#74e#72'), (2, '['), (2, '/#46#6ca#74#65D#65#63#6f#64#65'), (2, '/#41S#43#49IH#65xDe#63#6f#64#65'), (2, ']'), (2, '>>'), (1, '\r\n')]

 <<
   /Length 172
   /Filter [
   /FlateDecode /ASCIIHexDecode]
 >>


xref [(3, 'xref'), (3, '0'), (3, '7'), (3, '0000000000'), (3, '65535'), (3, 'f'), (3, '0000000017'), (3, '00000'), (3, 'n'), (3, '0000000127'), (3, '00000'), (3, 'n'), (3, '0000000186'), (3, '00000'), (3, 'n'), (3, '0000000250'), (3, '00000'), (3, 'n'), (3, '0000000348'), (3, '00000'), (3, 'n'), (3, '0000000421'), (3, '00000'), (3, 'n')]

trailer
 <<
   /Size 7
   /Root 10R
 >>

startxref 732

PDF Comment '%%EOF\r\n'

Setiap object di-encode secara sederhana menggunakan hex encoding. Dan jika melihat object ke-6 (javascript),


$ python pdf-parser.py --object=6 --filter findthesecretflaginsidemebabe.exe
obj 6 0
 Type: 
 Referencing: 
 Contains stream
 [(2, '<<'), (2, '/#4c#65#6eg#74#68'), (1, ' '), (3, '172'), (2, '/Fi#6c#74e#72'), (2, '['), (2, '/#46#6ca#74#65D#65#63#6f#64#65'), (2, '/#41S#43#49IH#65xDe#63#6f#64#65'), (2, ']'), (2, '>>'), (1, '\r\n')]

 <<
   /Length 172
   /Filter [
   /FlateDecode /ASCIIHexDecode]
 >>

 '\n  var submit_this_flag = Cyberheb-ndI1MYAQ5jNvRfsiVwSrndugZPPkUf3TnvQTdevZaNRcGWLFHhR\n  '

Ada stream yang di compress dan stream object tersebut dapat di-decode dengan menggunakan FlateDecode dari zlib (salah satu standar compression untuk stream object pada adobe acrobat). Dengan pdf-parser yang telah memiliki built-in feature untuk FlateDecode, maka stream object tersebut dapat dibaca.


$ python pdf-parser.py --object=6 --filter findthesecretflaginsidemebabe.exe
obj 6 0
 Type: 
 Referencing: 
 Contains stream
 [(2, '<<'), (2, '/#4c#65#6eg#74#68'), (1, ' '), (3, '172'), (2, '/Fi#6c#74e#72'), (2, '['), (2, '/#46#6ca#74#65D#65#63#6f#64#65'), (2, '/#41S#43#49IH#65xDe#63#6f#64#65'), (2, ']'), (2, '>>'), (1, '\r\n')]

 <<
   /Length 172
   /Filter [
   /FlateDecode /ASCIIHexDecode]
 >>

 '\n  var submit_this_flag = Cyberheb-ndI1MYAQ5jNvRfsiVwSrndugZPPkUf3TnvQTdevZaNRcGWLFHhR\n  '

Tentu saja PDF exploit ataupun malware memiliki konstruksi PDF yang lebih kompleks, namun ini adalah basic-nya. Dan diharapkan dengan basic ini akan lebih banyak lagi komunitas IT security Indonesia yang mengenal PDF dan memahami proses analisisnya.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s