단순 xor 역연산이다. 알고 있는 값들을 토대로 하나씩 xor 역연산 해가면서 찾아나아가면 된다. 참고로 S[0] = "LINECTF{" 임을 알고 있으면 된다.
X Factor
rsa blind signature attack 같은 느낌인데 sign을 해주는 기능을 제공해주지는 않는다. 대신 plain -> signature pair들을 제공해주기 때문에 이 값들을 sign함수 대신 사용하는 느낌으로 가야된다. 0x686178656c696f6e 값의 signature를 구하는 문제이다.
문제 제목이 힌트라고 볼 수 있는데, 각 plain 값들을 소인수분해한다. 이는 factordb 사이트를 이용하면 된다. a ~ g의 값들을 사용하여 Z를 만들어내려면 ( f * b * g * d * g * d ) / ( c * e * a ) 가 된다.
plain a ~ g, Z의 signature 값을 Sa ~ Sg, SZ 라고 하면, 위 사진의 식에서 M=Z = ( f * b * g * d * g * d ) / ( c * e * a ) , r= Sc * Se * Sa r^e mod N = c * e * a 이므로 M' = ( f * b * g * d * g * d ) / ( c * e * a ) * (c * e * a) mod N = ( f * b * g * d * g * d )
S' = M'^d mod N = ( f * b * g * d * g * d )^d mod N = ( Sf * Sb * Sg * Sd * Sg * Sd ) mod N
우리가 원하는 S = S'/r mod N = ( ( Sf * Sb * Sg * Sd * Sg * Sd ) / ( Sc * Se * Sa ) ) mod N 이다.
( Sc * Se * Sa ) 의 역원을 구해야 한다.
( Sc * Se * Sa ) 와 N 은 서로소이므로 확장된 유클리드 호제법을 사용하여 역원 x를 구한다.
처음에 크립토 잡고 풀다가 하루 다 보내버리고 뒤늦게 웹에 합류하여 문제를 풀었다. 좀 더 빨리 웹을 잡고 풀었으면 좀 더 점수를 낼 수 있었을 텐데 아쉬웠다. 그리고 예선전은 인원 제한이 없는걸 몰랐어서 처음엔 4명 모아서 할려고 했다가 대회 시작 직전에 뒤늦게 사람 2명밖에 못 데려온 것도 좀 아쉬었다. 내년에는 소학회원들 많이 데리고 하면 좋을 거 같다.
코게에도 포렌식이나 네트워크 문제 나왔으면 좋겠다. 예전엔 그래도 한 두개씩 나왔던거 같은데..
WEB - superbee
golang으로 작성되어 있고
beego 라는 프레임워크를 사용하고 있다.
플래그는 app.conf에 정의되어 있고 (물론 주어진 파일에서는 REDEACTED)
http://[IP]/main/index 경로로 접속하면 flag를 확인할 수 있도록 되어 있지만
쿠키값을 비교하여 admin이 아니면 플래그를 확인할 수 없고, login 페이지로 redirect된다.
먼저 어드민 패스워드를 획득하여 어드민계정으로 로그인 하는 방법은
패스워드를 알아낼 방법이 없으므로 불가능하고
SSTI일까 생각해봤지만,
사용자가 입력한 값으로 render하는 곳이 없고, 애초에 beego에서는 값을 직접 때려주기 때문에 불가능하다.
어떻게 풀어야 될까 생각을 해보다가
/admin/authkey 페이지로 접근해서 encrypted_auth_key를 얻고
aes 복호화를 해서 평문 auth_key를 얻어서 sess 쿠키 값을 설정해서 main/index로 접근하여 flag를 얻는 루트같았다.
그러지 않고서야 aesencrypt함수를 넣어두고 admin페이지를 만들어둘 이유가 없다고 생각했다.
그런데 admin/authkey에 접근할려면 domain이 localhost가 되어야 한다.
아니 ssrf때릴 곳도 없는거 같은데 어떻게 domain명을 localhost로 만들지 고민을 하다가
Ctx.Input.Domain()이 사실 처음 보는 함수였기 때문에 정확히 어떻게 동작하는 지 알 필요가 있었다.
코드를 살펴보니 request의 host가 공백이면 localhost를 return해주고 있었다. (.....이게 맞나?)