티스토리 뷰

reversing

디미ctf 2018 mm

slyfizz 2018. 11. 11. 00:25

어제 풀었던 랜덤 값 문제와 비슷한 문제를 찾던 중 디미 ctf 2018 mm 문제를 발견했다.

디미 ctf 당시에 못 풀고 저장해뒀던 문제라 꼭 다시 풀어보고 싶었다. 


mm.zip



srand에 seed값으로 0x17A3을 넣고



rand값과 입력값을 연산한 후 

memcmp로 unk_201020의 배열들과 비교한다.






이때 이 값들은 0xa8,0x73 -> 0x73a8 로 배열에 들어가게 된다는 사실을 동적 디버깅중 알아냈다.


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
from ctypes import *
import string
 
libc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
 
table=[0x73a8,0x39cc,0x4e0a,0x8d85,0xd1f2,0x7776,0x272e,0xab31,0x8f34,
0x4659,0xe7ac,0xa308,0x154d,0x7d9f,0x7123,0xf8db,0x49c4,0x5bb8,
0x2274,0xdd76,0xc29d,0x7048,0x52ae,0x1361,0xc98c,0x73a6,0x870a,
0x8870,0x748d,0x669,0x8c8f,0xe8a9,0x40b1,0xdabf,0x76c7,0x133d,
0x52b2,0x9e59,0xbe76,0xe248,0xe4dd,0xa6c5,0x856e,0xfab7,0x2465,
0xf6f7,0xf41c,0x6e93,0x535a,0x16da,0x4c54,0x166d,0x87a4,0x9f0f,
0x29dd,0x51a3,0x1327,0xb13a]
flag = ""
 
seed = 0x17A3
 
libc.srand(seed)
 
for i in range(len(table)):
    v1 = libc.rand()
    for j in string.printable:
        k=ord(j)
        m = (v1 * k)% (v1 + 1)
        if m==table[i]:
            flag+=j
print "flag:"+flag
 
 
 
 
 
cs



음?? 플래그가 출력되지않는다!!


1
2
3
input=ord("d")
random=0x448f740b
print("table:"+hex(random*input%(random+1)))
cs


플래그를 출력하기 위해서 계속 삽질하던 중 플래그형식인 dimi{}의 d와 랜덤값 0x448f740b를 문제대로 연산해보았다.



?? unk2010의배열인 73a8이 있다.


즉 테이블은 랜덤값을 hex로 바꾼 앞4자리 + unk 2010의 배열이 되는것이다.

예외적으로 랜덤값이 0x827db38 처럼 0x뒤가 7자리인 경우는 랜덤값의4번째자리와 unk table의 1번째 자리가 같으면 한번만 쓴다.


랜덤값4자리: 0x827d

unk table: dabf

최종배열:0x827dabf


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
from ctypes import *
import string
 
libc = CDLL("/lib/x86_64-linux-gnu/libc.so.6")
 
table=[0x448f73a8,0x7fef39cc,0x26294e0a,0x39a58d85,0x242fd1f2,0x17257776,0x411c272e,0x14c1ab31,0x3048f34,
0x2a444659,0x61cde7ac,0x5550a308,0x29f7154d,0x24b17d9f,0x21a17123,0x6621f8db,0x7d5249c4,0x17275bb8,
0x3fdf2274,0x3e88dd76,0x3f2ac29d,0x3fbc7048,0x84a52ae,0x28801361,0x510ac98c,0x623173a6,0x3dd4870a,
0x38e8870,0x10a748d,0x5e9b0669,0x61fe8c8f,0x4599e8a9,0x5e8a40b1,0x827dabf,0x7f3f76c7,0x2ba133d,
0x1f4d52b2,0x405b9e59,0x177bbe76,0x2251e248,0x6a9fe4dd,0x7949a6c5,0x77a2856e,0x1496fab7,0x1dfb2465,
0x1943f6f7,0x7ab8f41c,0x1b4d6e93,0x306b535a,0x3a9816da,0x59d64c54,0x6f96166d,0x7a5487a4,0x62209f0f,
0x181629dd,0x4b5f51a3,0x44521327,0x55eab13a]
flag = ""
 
seed = 0x17A3
 
libc.srand(seed)
 
for i in range(len(table)):
    v1 = libc.rand()
    for j in string.printable:
        k=ord(j)
        m = (v1 * k)% (v1 + 1)
        if m==table[i]:
            flag+=j
print(flag)
 
 
 
 
cs


flag: dimi{ca1cul4t3d_inv3rs3?_0r_us3d_z3?_0h_y0u_ar3_4_F0Ol_;)}


정답이다!



제가 분석하고 이해한 대로 써서 잘 이해가 가지 않을 수도 있고 출제의도랑 다를 수 도 있습니다. 
잘못된 정보가 있다면 댓글로 달아주시기 바랍니다 ㅠㅠ

------------------------------------------------------------------------------------------------------



unk2010의 배열을 이용해서 푸는 방법도 찾아냈다.

1
2
3
input=ord("d")
random=0x448f740b
print("table:"+hex(random*input%(random+1)&0xff))
cs


연산결과에 0xff(255)를 &연산한 결과는  unk2010테이블의 첫번째 인덱스인 0xa8이고 위 연산결과는 

1,3,5,7......번째 인덱스에만 적용되므로

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
from ctypes import *
import string
 
libc = CDLL("/lib/x86_64-linux-gnu/libc.so.6")
 
table=[
 0xa8,   0x73   ,0xcc   ,0x39   ,0x0a   ,0x4e    ,0x85    ,0x8d
,0xf2    ,0xd1    ,0x76    ,0x77    ,0x2e    ,0x27    ,0x31    ,0xab
,0x34    ,0x8f    ,0x59    ,0x46    ,0xac    ,0xe7    ,0x08    ,0xa3
,0x4d    ,0x15    ,0x9f    ,0x7d    ,0x23    ,0x71    ,0xdb    ,0xf8
,0xc4    ,0x49    ,0xb8    ,0x5b    ,0x74    ,0x22    ,0x76    ,0xdd
,0x9d    ,0xc2    ,0x48    ,0x70    ,0xae    ,0x52    ,0x61    ,0x13
,0x8c    ,0xc9    ,0xa6    ,0x73    ,0x0a    ,0x87    ,0x70    ,0x88
,0x8d    ,0x74    ,0x69    ,0x06    ,0x8f    ,0x8c    ,0xa9    ,0xe8
,0xb1    ,0x40    ,0xbf    ,0xda    ,0xc7    ,0x76    ,0x3d    ,0x13
,0xb2    ,0x52    ,0x59    ,0x9e    ,0x76    ,0xbe    ,0x48    ,0xe2
,0xdd    ,0xe4    ,0xc5    ,0xa6    ,0x6e    ,0x85    ,0xb7    ,0xfa
,0x65    ,0x24    ,0xf7    ,0xf6    ,0x1c    ,0xf4    ,0x93    ,0x6e
,0x5a    ,0x53    ,0xda    ,0x16    ,0x54    ,0x4c    ,0x6d    ,0x16
,0xa4    ,0x87    ,0x0f    ,0x9f    ,0xdd    ,0x29    ,0xa3    ,0x51
,0x27    ,0x13    ,0x3a    ,0xb1]
flag = ""
 
seed = 0x17A3
 
libc.srand(seed)
 
for i in range(0,len(table),2):
    v1 = libc.rand()
    for j in string.printable:
        k=ord(j)
        m = v1 * k%(v1 + 1)&0xff
        if m==table[i]:
            flag+=j
print "flag:"+flag
 
 
 
 
cs


이렇게 하면 플래그가 나온다.


'reversing' 카테고리의 다른 글

나보려고 만든 rev,misc 꿀팁 소스  (0) 2019.03.13
디미ctf 2017 rev 본선 50  (0) 2018.11.09
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2025/04   »
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
글 보관함