티스토리 뷰
문제개요
AES Decrypt with known key
코드분석
우선 Flag의 위치를 탐색해보았습니다. 아래는 app.conf 파일의 내용인데요. flag는 해당 설정파일의 속성에 존재하고 있었습니다.
app_name = superbee
auth_key = [----------REDEACTED------------]
id = admin
password = [----------REDEACTED------------]
flag = [----------REDEACTED------------]
그리고 해당 flag의 내용은 다시 index.html 에서 확인할 수 있었습니다.
<html>
<head>
<title>{{.app_name}}</title>
</head>
<body>
<h3>Index</h3>
{{.flag}}
</body>
</html>
그리고 아래 내용에서 보면 알 수 있듯이 admin 계정으로 로그인에 성공하면 index.html 로 이동하고 flag 내용을 확인할 수 있다고 합니다.
func (this *LoginController) Auth() {
id := this.GetString("id")
password := this.GetString("password")
if id == admin_id && password == admin_pw {
this.Ctx.SetCookie(Md5("sess"), Md5(admin_id + auth_key), 300)
this.Ctx.WriteString("<script>alert('Login Success');location.href='/main/index';</script>")
return
}
this.Ctx.WriteString("<script>alert('Login Fail');location.href='/login/login';</script>")
}
근데 여기서 id 와 password 를 모르더라도 session 값이 관리자와 일치할 경우에도 관리자로 인식될 수 있겠다 싶었습니다.
문제에서 주어진 정보 중에 우리가 아는 내용은 admin_id 입니다. 그리고 auth_key 는 app.conf 에서도 확인했다시피 알 수 없었습니다. 그래서 auth_key부터 알아낼 방법을 찾아보았습니다.
그러다가 auth_key 를 암호화한 값을 출력해주는 타겟을 찾을 수 있었는데,
func (this *AdminController) AuthKey() {
encrypted_auth_key, _ := AesEncrypt([]byte(auth_key), []byte(auth_crypt_key))
this.Ctx.WriteString(hex.EncodeToString(encrypted_auth_key))
}
바로 관리자페이지의 AuthKey Controller였습니다. 그렇기 때문에 AutoRouter 에 따르면 /admin/authkey 경로일 것으로 예상되어 해당 경로로 요청을 보내보았지만,
localhost가 아니라고 나옵니다. 그리고 다시 BaseController의 Prepare 함수 부분에서 localhost 임을 확인하는 코드에서 Domain 값을 사용자입력을 받는듯 해보였습니다.
else if controllerName == "AdminController" {
domain := this.Ctx.Input.Domain()
if domain != "localhost" {
this.Abort("Not Local")
return
}
}
그래서 경로로 요청을 보낼 때 HTTP Header에서 Host를 localhost 로 수정하여 보내보았더니 아래와 같이 encrypted_auth_key를 획득할 수 있었습니다.
encrypted_auth_key 값은 다시 AesEncrpyt 함수로 만들어지는데, app.conf 에서도 확인했지만 auth_crypt_key는 존재하지 않는 변수이기 때문에 null 값이 되게 됩니다.
func (this *AdminController) AuthKey() {
encrypted_auth_key, _ := AesEncrypt([]byte(auth_key), []byte(auth_crypt_key))
this.Ctx.WriteString(hex.EncodeToString(encrypted_auth_key))
}
그래서 AesEncrypt 함수 로직을 보면 알다시피,
func AesEncrypt(origData, key []byte) ([]byte, error) {
padded_key := Padding(key, 16)
block, err := aes.NewCipher(padded_key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
origData = Padding(origData, blockSize)
blockMode := cipher.NewCBCEncrypter(block, padded_key[:blockSize])
crypted := make([]byte, len(origData))
blockMode.CryptBlocks(crypted, origData)
return crypted, nil
}
null 값인 key값은 전부 padding 값으로 채워지게 되고 그 상태로 CBC 모드로 AES 암호화가 되어 버립니다. key값을 알고 있는 상태로라면 위 encrypt 과정을 반대로 수행해서 그대로 복호화가 가능하다는 말과 동일하기 때문에 encrypted_auth_key를 그대로 복호화를 할 수 있습니다.
이제 auth_key도 구했고, admin_id도 이미 알고 있기 때문에 아까 보았던 세션 값을 조작할 수 있게 됩니다.
문제풀이
우선 AesDecrpyt 함수를 작성합니다.
func AesDecrypt(cipherText string, key []byte) ([]byte, error) {
padded_key := Padding(key, 16)
block, err := aes.NewCipher(padded_key)
if err != nil {
return nil, err
}
ct, _ := hex.DecodeString(cipherText)
blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, padded_key[:blockSize])
plainText := make([]byte, len(ct))
blockMode.CryptBlocks(plainText, ct)
return plainText, nil
}
그리고 AesDecrypt 함수에 localhost bypass 해서 구했던 encrypted_auth_key 값을 파라미터로 넣어주고 결과값을 확인합니다.
decrypted_auth_key, _ := AesDecrypt("00fb3dcf5ecaad607aeb0c91e9b194d9f9f9e263cebd55cdf1ec2a327d033be657c2582de2ef1ba6d77fd22784011607", []byte(auth_crypt_key))
fmt.Println(string(decrypted_auth_key))
결과값으로는 아래와 같이 나옵니다.
Th15_sup3r_s3cr3t_K3y_N3v3r_B3_L34k3d
정확히는 아래와 같이 패딩값이 같이 추가되어져서 보입니다.
그리고 문제의 요구사항대로 아래 코드에서 나타난 형태로 맞춰줍니다.
this.Ctx.SetCookie(Md5("sess"), Md5(admin_id + auth_key), 300)
그러면 아래와 같이 됩니다.
f5b338d6bca36d47ee04d93d08c57861 e52f118374179d24fa20ebcceb95c2af
그리고 이 둘을 각각 쿠키값으로 해주기 위해서 브라우저에서 아래 명령을 수행해줍니다.
document.cookie="f5b338d6bca36d47ee04d93d08c57861=e52f118374179d24fa20ebcceb95c2af";
그리고 새로고침하면 아래와 같이 Flag값을 획득할 수 있게 됩니다.
- 끝 -
'보안 > CTF' 카테고리의 다른 글
[Codegate2022예선] (WEB) MYBLOG 문제풀이 (0) | 2022.03.01 |
---|---|
[Codegate2022예선] (WEB) BABYFIRST 문제풀이 (0) | 2022.02.28 |
[Codegate2022예선] (WEB) CAFE 문제풀이 (0) | 2022.02.28 |
Flag Generator/플래그 생성기 (0) | 2021.10.18 |
[Web] Become Admin 2021 Tamil CTF Writeup (0) | 2021.09.30 |