본문 바로가기

CTF/Write-up

pragyan ctf MI6

정해진 대로 푼 문제는 아니다 그냥 수많은 게싱을 반복해서 푼 문젠데 나중에 꼭 풀이를 보고싶다.

ruby라는 언어는 안써봐서 어떻게 소스를 해석해야할지 몰라서 그냥 게싱했다


이 대회가 좀 이상한게 그냥 주는 파일마다 확장자를 exe를 붙여놨다. 아무튼 저 만큼 까지가 bash 소스이고

그 밑에 payload.tar tar 압축 파일명이 보인다. 그래서 헤더를 검색해보면

바로 옆에 있던 1f 8b 08이 tar 헤더이다.

고대로 tar파일을 빼서 tar.gz파일로 만든다음 압축을 풀면


reverse_1.rb가 주어진다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class Fixnum
  def random_split(set = nil, repeats = false)
    set ||= 1..self
    set = [*set]
    return if set.empty? || set.min > self || set.inject(0, :+< self
    tried_numbers = []
    while (not_tried = (set - tried_numbers).select {|n| n <= self }).any?
      tried_numbers << number = not_tried.sample
      return [number] if number == self
      new_set = set.dup
      new_set.delete_at(new_set.index(number)) unless repeats
      randomized_rest = (self-number).random_split(new_set, repeats)
      return [number] + randomized_rest if randomized_rest
    end
  end
end
 
class String
  def ^( other )
    b1 = self.unpack("U*")
    b2 = other.unpack("U*")
    longest = [b1.length,b2.length].max
    b1 = [0]*(longest-b1.length) + b1
    b2 = [0]*(longest-b2.length) + b2
    b1.zip(b2).map{ |a,b| a^b }.pack("U*")
  end
end
 
a2= Array.new
a= Array.new
string = gets
a=string.upcase.chars
sum = 0
length1 = a.length
 
for i in 0..a.length-1  ## /n is worth 10 characters change to length-1 at the end
  a[i] = (a[i].ord)^61
  sum = sum + a[i].ord
end
for i in 0..length1-1
  a2[i] = a[i].to_i.random_split(20..30)
end
# Print the final output array which will be used for reversing
for i in 0..a2.length-1
  print a2[i].join(" "+ " "
end
 
cs

나는 루비를 할 줄 모른다.

일단 실행해보면


a를 입력했을 때 숫자가 나온다.

이걸 보니 문제에 있었던 숫자를 만족해야하는거 같다.


하지만 실행할 때마다 다른데


소스보면서 몇번 하다 보니깐 다 더하면 172가 나온다. 172는 55를 더한 값이라서

55를 빼주고 61로 XOR하면 A라는 값을 얻을 수 있다.


많이 실행해보면 한글자는 7개의 숫자가 나오고 2자리부터 5자리 추가된다.

근데 이런식으로 해보면 대충 문자열이 22자리라는것을 알 수 있는데

flag가 22자리일리가 없다

그래서 생각난게 pragyanctf{HelloWorld} 이 형식이였고

대충 보면 21자리로 비슷하다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
result = ""
result += chr((26+25+30+28) ^ 61)
result += chr((22+25+20+23+21) ^ 61)
result += chr((29+22+24+26+23) ^ 61)
result += chr((21+26+27+20+28) ^ 61)
result += chr((22+25+23+30) ^ 61)
result += chr((29+23+28+24+20) ^ 61)
result += chr((21+26+25+20+23) ^ 61)
result += chr((27+23+29+25+22) ^ 61)
result += chr((23+26+27+29) ^ 61)
result += chr((24+23+30+21+25) ^ 61)
result += chr((24+26+20) ^ 61)
result += chr((24+22+21+30+26) ^ 61)
result += chr((20+25+24+21+23) ^ 61)
result += chr((27+29+26+22+20) ^ 61)
result += chr((21+23+22+30+26) ^ 61)
result += chr((29+26+28+27) ^ 61)
result += chr((22+20+27+29+26) ^ 61)
result += chr((30+28+27+26) ^ 61)
result += chr((23+29+21+22+25) ^ 61)
result += chr((27+24+21+29+25) ^ 61)
result += chr((24+20+25+23+22) ^ 61)
result += chr((30+28+27+29) ^ 61)
result += chr((25+20+24+21+23) ^ 61)
result += chr((20+23+21+29+26)-55 ^ 61)
print result.lower()
 
cs

노가다를 통해 pragyanctf{} 이부분은 쉽게 구할 수 있었지만

안에 부분은 조금 힘들었다.

pragyanctf{flagsarecool}

'CTF > Write-up' 카테고리의 다른 글

Reto Android Crackme #2  (0) 2017.03.05
Reto Android Crackme #1  (0) 2017.03.05
Hashdays 2012 Android Challenge  (0) 2017.02.26
Insomni’hack 2012 InsomniDroid CrackMe  (0) 2017.02.24
BSidesSF-pinlock  (0) 2017.02.20