こんにちわ 初音(はつね)ミクだよ

音域(おんいき)テストを始(はじ)めるよ

高音厨(こうおんちゅう)のお前(まえ)らならば

余裕(よゆう)で歌(うた)えるね


hiA hiB hiC hiD hiC


こんなの重低音(じゅうていおん)だね


すこしだけ音(おと)を上(あ)げるよ

普通(ふつう)の人(ひと)なら出(で)ないけど

高音厨(こうおんちゅう)のお前(まえ)らならば

風邪(かぜ)でも歌(うた)えるね


hiD hiE hiF hiG hiF


まだまだ中音域(じゅうていおん)だね


もうちょっと音(おと)を上(あ)げるよ

ファルセットだけじゃきついかな?ww

高音厨(こうおんちゅう)のお前(まえ)らならば

朝飯前(あさめしまえ)だよね


hiG hihiA hihiA# hihiC hihiD


ギブアップしてもいいのよ?


最後(さいご)は一気(いっき)に上(あ)げちゃうよ

もはや歌詞(かし)も聞(き)き取(と)れないね

高音厨(こうおんちゅう)の本気(ほんき)の力(ちから)

見(み)せておくれよ


hihiC hihiD hihiD# hihiF hihiG


終(お)わりだよ

いや嘘(うそ)だよ


hihihiA hihihiB hihihiC hihihiD hihihiE


ここまで出(で)たなら

合格(ごうかく)



--- 単語 ---

お前ら: 너희. ら가 뒤에 붙어서 복수가 된다는 걸 잊어버림...

ファルセット: (남성의) 가성. falsetto.

朝飯前: 누워서 떡 먹기.


'Diary' 카테고리의 다른 글

CVE 획득  (1) 2016.03.21
BoB 4기 최종합격!!!  (2) 2015.06.26
엿같은 Active X  (0) 2015.04.12
네팔 여행기 - Kailashnath Mahadev Statue in Sanga  (0) 2015.01.30
지식iN 폐인짓  (0) 2015.01.26

flag가 여러 번 암호화된 다음 파일이 주어집니다.

The file below is given saying that the flag is encrypted several times.

captured_827a1815859149337d928a8a2c88f89f


맨 윗줄에 {N : e : c}라는 설명이 있는데, RSA인 듯합니다.

At the top there is {N : e : c}, and we can assume that it is RSA.

특징을 살펴보면 N이 다 같은 것을 볼 수 있습니다. 이 때 사용할 수 있는 공격은 Common Modulus Attack입니다. (참고: http://diamond.boisestate.edu/~liljanab/ISAS/course_materials/AttacksRSA.pdf)

Looking into the file, we notice that all the N are the same. In this case, we can do Common Modulus Attack. (Reference: http://diamond.boisestate.edu/~liljanab/ISAS/course_materials/AttacksRSA.pdf)


먼저 N, e, C를 파싱하고, 서로소인 \(e_{1}\)과 \(e_{2}\)을 찾습니다.

First we parse N, e, C, then look for \(e_{1}\) and \(e_{2}\), which are relatively primes.

# parsing
s = open('captured_827a1815859149337d928a8a2c88f89f', 'rt').read()[12:] # excluding top {N : e : c}
N=[]
e=[]
C=[]
s=s.replace(' ','')
for i in s.split():
	t=map(eval,i.replace(' ','').lstrip('{').rstrip('}').split(':'))
	N.append(t[0])
	e.append(t[1])
	C.append(t[2])

# find relatively prime e1, e2
import itertools, fractions
for i,j in itertools.combinations(e, 2):
	if fractions.gcd(i, j)==1: print e.index(i),e.index(j)

결과: 8, 18

Result: 8, 18

따라서 서로소인 \(e_1=e[8]\)과 \(e_2=e[18]\)를 찾았습니다. 그럼 이제 다음 식을 만족하는 \(x, y\)를 찾아야합니다.

So we found \(e_1=e[8]\) and \(e_2=e[18]\). Now we have to find \(x, y\) such that

\[x\times e_1+y\times e_2=1\]

이는 Diophantine 방정식(참고: http://yum3.tistory.com/22)을 이용해서 찾을 수 있습니다. diophantine(e[8], e[18], 1)을 넣으면 \((x,y)=(-3898661337, 407775632)\)가 반환됩니다. 그러면 \(C_{1}^x\times C_{2}^y \mod n\)을 통해 P를 알아낼 수 있습니다. 하지만 \(x\)가 음수이므로 \(C_{1}^{-3898661337}=(C_{1}^{3898661337})^{-1}\)로 바꿔줘야하고, \(C_{1}^{3898661337}\)의 modular 연산의 역원(Multiplicative Inverse)을 구해야합니다.

This can be easily found using Diophantine Equation. Using the function specified here: http://yum3.tistory.com/22, diophantine(e[8], e[18], 1) would result in \((x,y)=(-3898661337, 407775632)\). Then we can easily find the plaintext by \(C_{1}^x\times C_{2}^y \mod n\). However, because \(x\) is negative, we have to consider \(C_{1}^{-3898661337}=(C_{1}^{3898661337})^{-1}\), which is the multiplicative inverse of \(C_{1}^{3898661337}\) in modular operation.

Multiplicative Inverse는 다음과 같은 코드로 구할 수 있습니다.

We can find Multiplicative Inverse using the following code:

def mul_inv(a, n):
	if n == 1: return 1
	
	r1, r2 = n, a
	t1, t2 = 0, 1
	
	while r2 != 0:
		q = r1/r2
		r1, r2 = r2, r1%r2
		t1, t2 = t2, t1-q*t2
	if t1 < 0: t1 += n
	return t1

최종 코드는 다음과 같습니다.

The final code is as follows:

def diophantine(a, b, c):
	'''returns (x, y) where ax+by=c'''
	r1, r2 = a, b
	s1, s2 = 1, 0
	t1, t2 = 0, 1
	
	while r2!=0:
		q = r1/r2
		r1, r2 = r2, r1%r2
		s1, s2 = s2, s1-q*s2
		t1, t2 = t2, t1-q*t2
	# gcd: r1
	return (c/r1*s1, c/r1*t1)

def mul_inv(a, n):
	if n == 1: return 1
	
	r1, r2 = n, a
	t1, t2 = 0, 1
	
	while r2 != 0:
		q = r1/r2
		r1, r2 = r2, r1%r2
		t1, t2 = t2, t1-q*t2
	if t1 < 0: t1 += n
	return t1

x, y = diophantine(e[8], e[18], 1)
print hex((mul_inv(pow(C[8],-x,N[0]),N[0])*pow(C[18],y,N[0]))%N[0])

결과는 '0x666c61675f537472656e6774685f4c6965735f496e5f446966666572656e636573L'이 나오는데, 이를 decode하면 Flag를 얻을 수 있습니다.

It prints '0x666c61675f537472656e6774685f4c6965735f496e5f446966666572656e636573L', and we decode it to get the flag.


Flag: flag_Strength_Lies_In_Differences

주어진 정수 \(a, b, c\)에 대하여 \[ax + by = c\]를 만족하는 정수 \(x, y\)를 찾는게 목적이다.

\(d\)는 \(a, b\)의 최대공약수라고 하자. 이 때, \(d\mid c\)인 경우 무한한 \(x, y\)가 존재하고, \(d\nmid c\)인 경우 해는 존재하지 않는다. (\(a\mid b\)의 의미는, \(a\)는 \(b\)를 나눌 수 있다는 의미이다.)

해가 존재할 경우, 특수해(Particular Solution)는 \(x_0=c/d\times s, y_0=c/d\times t\)로 구한다. 이 때 s와 t는 Extended Euclidean Algorithm으로 구한 값이다.

일반해(General Solution)는 \(x=x_0+k(b/d), y=y_0-k(a/d) \mbox{ where } k\in \mathbb Z\)로 구할 수 있다.


예를 들어 방정식 \(21x +14y =35\)를 풀어보자. 우선 \(d=\mbox{gcd}(21, 14)=7\mid 35\)이므로 무수히 많은 해가 존재한다. 그럼 양변을 7로 나누면 \(3x+2y=5\)로 간소화할 수 있다. 이제 \(s\)와 \(t\)를 구하기 위해 Extended Euclidean Algorithm을 사용하면

\(q\)

\(r_1\)

\(r_2\)

\(r\)

\(s_1\)

\(s_2\)

\(s\)

\(t_1\)

\(t_2\)

\(t\)

1

3

2

1

1

0

1

0

1

-1

2

2

1

0

0

1

-2

1

-1

3

1

0

1

-2

-1

3

따라서 \(s=1, t=-1\)이므로 특수해는 \(x_0=35/7\times 1=5, y_0=35/7\times -1=-5\)이고, 일반해는 \(x=5+2k, y=-5-3k\)가 된다.


디오판틴 방정식의 특수해(\(x_0, y_0\))를 구하는 파이썬 코드를 작성해보자.

def diophantine(a, b, c):
	'''returns (x, y) where ax+by=c'''
	r1, r2 = a, b
	s1, s2 = 1, 0
	t1, t2 = 0, 1
	
	while r2!=0:
		q = r1/r2
		r1, r2 = r2, r1%r2
		s1, s2 = s2, s1-q*s2
		t1, t2 = t2, t1-q*t2
	# gcd: r1
	return (c/r1*s1, c/r1*t1)

diophantine(21, 14, 35)를 하면 (5, -5)가 반환되는 것을 볼 수 있다.

+ Recent posts