네이버클라우드

[Ncloud] Hash Filter API로 내 파일 간단 검사해보기 in File Safer

graph-dev 2023. 8. 20. 18:11
728x90

Ncloud logo

 

 

지난 글에 이어서, 이번에는 API를 사용해서 File Safer 중 Hash Filter를 수행해보겠습니다. API를 사용하려면, 당연하게도 api 가이드를 참고해야 합니다.

 

가이드를 살펴보겠습니다. 제가 살펴볼 부분은 checkHash API 하나입니다.

https://api.ncloud-docs.com/docs/security-filesafer-checkhash

 

checkHash (Hash Filter)

 

api.ncloud-docs.com

 

개요 발췌

 File Safer의 Hash Filter에서 제공하는 기능이라고 설명하고, Hash 값으로 악성여부 확인하는 API라고 합니다. 오타 chechHash가 있네요. 차후 개선하겠죠?

 

 이 API에는 호출을 위해서 5가지 헤더와, 2가지 파라미터가 필요합니다. POST 메서드를 사용한다면 바디를 넣어줘야 합니다. 그러나 현재는 GET 메서드만을 사용해서 악성코드 탐지를 수행하겠습니다. 가이드를 보면서 느낀 점은 주어진 가이드 문서를 꼼꼼히 읽고, 특히 “예시”를 잘 따라하는 것이 중요합니다. 예시로 제공된 curl 메서드는 아래와 같습니다.

 

curl -X GET "https://filesafer.apigw.ntruss.com/hashfilter/v1/checkHash?hashCode=f093e7767bb63ac973b697d3fd1d40a78b87b8bf&hashType=sha1"
   -H "accept: application/json"
   -H "x-ncp-apigw-api-key: {x-ncp-apigw-api-key}"
   -H "x-ncp-iam-access-key: {x-ncp-iam-access-key}"
   -H "x-ncp-apigw-timestamp: {x-ncp-apigw-timestamp}"
   -H "x-ncp-apigw-signature-v2: {x-ncp-apigw-signature-v2}"

여기서 {} 중괄호 처리된 부분을 채울 것입니다. 그 중에서 제일 어려웠던 것은 signature라는 값이었습니다. 나머지는 문서에 나온 그대로 입력만 하면 되지만, 이 값은 별도 암호화 코드를 수행해서 출력해서 가져다 쓸 수 있습니다.

 

하나씩 알아보겠습니다. 다음은 API 가이드의 일부를 캡처한 것입니다.

 

API 가이드 헤더 부분

 

timestamp

timestamp는 주어진 것 처럼 경과시간을 밀리초 단위로 나타낸 것입니다. Java에 좋은 함수가 있어 가져왔습니다.

long timestamp = System.currentTimeMillis();

 

그러나 이건 long 타입으로 나타나있는데, 제 메서드는 String 타입을 사용하므로, 약간의 변환 처리를 했습니다.

String timestamp = String.valueof(System.currentTimeMillis());

 

API Gateway Key

다음으로, API-GW Key를 가져와보겠습니다. 가이드 내용을 바탕으로 작성했습니다 먼저 네이버 클라우드 플랫폼 콘솔에서, API Gateway로 가서 상품 이용 신청을 합니다.

 

API GW 이용신청 화면

 

 

이용 신청 후, 다른 거 보지 마시고 “API Gateway > API Keys”로 이동합니다. 이동 후 API Key 생성을 누르면, 이름을 입력하고 저장을 누르면 키 값을 생성할 수 있습니다.

 

API Key 생성

 

해당 API key를 찾아서, API Keys의 보기를 누르면 아래와 같이 두 가지 키(Primary & Secondary Key) 값이 나오는데, 그 중에 하나만 있으면 되므로, Primary key 하나를 사용할 것입니다.

 

API Keys 보기

 

IAM Access Key

설명서를 읽어보면 네이버클라우드 인증키 혹은 IAM 키값이 가능하다고 합니다. IAM 키는 AWS 리소스에 접근하기 위한 인증키를 말하는 것이므로 생략하고, 저는 네이버클라우드에서 제공하는 인증키를 가져오겠습니다.

 

먼저 네이버클라우드 홈페이지에서 로그인 > 마이페이지 > 계정관리 > 인증키관리로 들어갑니다. 

 

API 인증키 관리

위에서 Access Key ID를 복사해두면 준비가 끝난 것입니다.

 

 

Signature*

마지막으로, apigw-signature가 남았습니다. 아래 Ncloud API 문서에서 시그니처 생성 부분을 참고했습니다.

 

https://api.ncloud-docs.com/docs/common-ncpapi

 

Ncloud API

 

api.ncloud-docs.com

 

이 값을 구하기 위해서는 앞서 사용한 Access key ID와 우측에 있는 Secret Key, Timestamp, URL 값이 다시 필요합니다. 이 값은 각각 위에서 구한 방법대로 구하면 되고, URL은 값을 입력할 때, 조금 주의가 필요합니다.

 

 

URL은 우리가 사용하는 주소값 전체가 필요합니다. 이게 무슨말 일까요?

 

먼저 가이드에 나온 주소는 아래와 같습니다.

https://filesafer.apigw.ntruss.com/hashfilter/v1/checkHash

 

가이드 문서에 따르면, 위 주소에서 도메인주소(.com) 이후의 값이 필요하다고 합니다. 그러면 이 경우 “/hashfilter/v1/checkHash” 값이 필요하다는 것입니다. 그런데, 이것만 있으면 될까요? 아닙니다.

 

API 가이드에 나온 예시를 살펴볼께요. 예시가 중요합니다!

 

https://example.apigw.ntruss.com/photos/puppy.jpg?query1=&query2' 이러한 주소값이 있을 때, 도메인 이후에 해당하는 것은 /photos/puppy.jpg 입니다. 그런데 이것만 필요한 게 아니라 “.jpg?” 이후로 나타나는 쿼리 스트링 값도 모두 필요하다고 설명하고 있습니다.

String url = "/photos/puppy.jpg?query1=&query2";	// url (include query string)

 

본 예시에서 제공한 주소를 이러한 조건에 적용해보기 위해, 가이드에 나온 예시를 그대로 입력해보겠습니다.

https://filesafer.apigw.ntruss.com/hashfilter/v1/checkHash?hashCode=f093e7767bb63ac973b697d3fd1d40a78b87b8bf&hashType=sha1

 

이 주소에서, 도메인(.com)값이후에 나온 모든 값은 “/hashfilter/v1/checkHash?hashCode=f093e7767bb63ac973b697d3fd1d40a78b87b8bf&hashType=sha1” 이렇게 됩니다. 이것을 url 이름의 변수에 담습니다.

 

String url = “/hashfilter/v1/checkHash?hashCode=f093e7767bb63ac973b697d3fd1d40a78b87b8bf&hashType=sha1”

 

 

이제 이 모든 값을 가이드에 나온 Java 메서드에 입력해서 출력하면 됩니다. 가이드에서 일부 변형한 Signature를 구하는 메서드는 다음과 같습니다.

 

public static String makeSignature(String timestamp, String method, String signUrl) {
            try {
                String space = " ";
                String newLine = "\n";
                String accessKey = "이것은 API 인증키 관리 Access Key ID이다.";
                String secretKey = "이것은 API 인증키 관리 Secret Key이다.";

                String message = new StringBuilder()
                        .append(method)
                        .append(space)
                        .append(signUrl)
                        .append(newLine)
                        .append(timestamp)
                        .append(newLine)
                        .append(accessKey)
                        .toString();

                SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256");
                Mac mac = Mac.getInstance("HmacSHA256");
                mac.init(signingKey);

                byte[] rawHmac = mac.doFinal(message.getBytes("UTF-8"));
                String encodeBase64String = Base64.encodeBase64String(rawHmac);

                return encodeBase64String;
            } catch (Exception e) {
                return e.getMessage();
            }

        }

 

근데, 이렇게만 해주면 출력이 안됩니다. 좀 더 직관적으로 값을 하나하나 잘 보기 위해 Java에서 메인함수를 통해 출력까지 해주겠습니다. 참고로 url은 가이드에 나온 url을 그대로 사용했습니다.

 

public static void main(String[] args) {
            String timestamp = String.valueOf(System.currentTimeMillis());
            String method = "GET";
            String hashCheckFullUrl = "https://filesafer.apigw.ntruss.com/hashfilter/v1/checkHash?hashCode=f093e7767bb63ac973b697d3fd1d40a78b87b8bf&hashType=sha1";
            StringBuilder urlBuilder = new StringBuilder();
            urlBuilder.append(hashCheckFullUrl);
            String url = urlBuilder.toString();
            String signUrl = url.substring(url.indexOf(".com") + 4);

            //예쁘게 출력해봅니다.
            System.out.println("METHOD: " + method);
            System.out.println("TIMESTAMP: " + timestamp);
            System.out.println("URL: " + signUrl);
            System.out.println("SIGNATURE: " + makeSignature(timestamp, method, signUrl));
        }

 

이렇게 하면 아래와 같이 출력이 됩니다. (시그니처 값만 가렸습니다.)

METHOD: GET
TIMESTAMP: 1692518000910
URL: /hashfilter/v1/checkHash?hashCode=f093e7767bb63ac973b697d3fd1d40a78b87b8bf&hashType=sha1
SIGNATURE: 이것은 시그니처 값

 

Hash Filter API 적용하기

이걸 가지고, “5분 이내”에 빠르게 예시에 나온 curl 메서드 내용을 채워서 실행합니다. 아래와 같이 작성할 수 있습니다. 왜 5분 이내인지 궁금하신가요? 아래 가이드에서는 그렇게 해야 유효한 값으로 인정한다네요.

timestamp 5분 이내

 

참고로, 시그니처 값도 timestamp 값을 사용하는데, 이 값이 유효해야 하므로 동일하게 API Gateway 서버와 시간 차가 5분 이내로 나타나야 겠죠? 정리하면 아래와 같습니다.

curl -X GET "https://filesafer.apigw.ntruss.com/hashfilter/v1/checkHash?hashCode=f093e7767bb63ac973b697d3fd1d40a78b87b8bf&hashType=sha1"
   -H "accept: application/json"
   -H "x-ncp-apigw-api-key:  이것은 API Gateway의 Primary Key이다"
   -H "x-ncp-iam-access-key: 이것은 API 인증키 관리 Access Key ID이다"
   -H "x-ncp-apigw-timestamp: 이것은 5분 내에 사용할 시간 값이다"
   -H "x-ncp-apigw-signature-v2: 이것도 5분 내에 사용할 시그니처 값이다"

 

이 문장을 터미널(윈도우면 명령 프롬프트)에서 수행해보겠습니다.

실행한 결과

 

위와 같이 결과가 나타나고, 이 결과 부분만 살펴보면 다음과 같습니다. “success”는 요청을 잘 받아들여 탐지를 완료했다는 의미이고, 입력한 hashCode 값 등이 나타납니다. 그리고 result가 1이라는 것은 악성 코드로 분류했다는 의미입니다.

{
    "returnCode": "0",
    "returnMessage": "success",
    "totalRows": 1,
    "hashCheckResultList": [
        {
            "hashType": "sha1",
            "hashCode": "f093e7767bb63ac973b697d3fd1d40a78b87b8bf",
            "group": "file",
            "result": "1",
            "regDatetime": 1497409737000
        }
    ]
}

 

Notification 확인

이전 글에서 제가 notification 세팅을 했으니 메일을 확인해보겠습니다.

https://graph-dev.tistory.com/72

 

[Ncloud] File Safer로 내 파일 악성코드 잡아내기

악성코드 탐지의 필요성 보안(Security)에 대한 관심이 높아지는 추세입니다. 많은 콘텐츠들이 디지털화되고, 해킹에 대한 위험도 함께 높아지고 있습니다. 2020년도 경험한 침해사고 유형을 살펴

graph-dev.tistory.com

 

이번 예시에는 악성코드가 포함된 Hash 값을 사용했으니, 탐지했다고 나타날 것 입니다.

탐지 조회 메일

 

 

또한, 고급 설정에서 5분 이내에 1번 이상 악성 코드를 찾으면 알림을 주도록 했죠? 관련 메일이 왔습니다.

 

임계치 초과 메일

 

 

이렇게 임계치를 초과했다는 알림도 이중으로 잘 도착한 점을 확인했습니다.

 

 

Postman으로도 API 실행해보기

지난 글에서 사용한 예시 파일을 사용해서 Postman으로도 Hash filter를 수행해보겠습니다.

 

먼저 Hash값을 MD5로 다시 뽑아냅니다.

 

URL도 다시 작성합니다. 해시코드 넣고, 해시타입도 md5로 입력했습니다.

https://filesafer.apigw.ntruss.com/hashfilter/v1/checkHash?hashCode=해시코드&hashType=md5

 

그대로 Postman에 입력합니다. Send를 누르면 아래와 같은 결과가 나타납니다.

 

postman 장면

 

결과를 다시 보겠습니다. 요청이 성공적으로 이루어지고, 별다른 결과값이 없습니다. 이는 악성 코드가 탐지되지 않았다는 것입니다.

{
    "returnCode": "0",
    "returnMessage": "success",
    "totalRows": 0,
    "hashCheckResultList": []
}

 

자 메일도 한번 보시죠! 

 

file safer 결과

 

Malware not detected, 즉, 악성코드가 탐지되지 않았다고 나옵니다.

 

이렇게 API를 통해 간단히 Hash 값을 이용한 악성 코드 감지 작업을 수행해보았습니다. 차후 기회가 된다면 File Filter도 수행해볼 예정입니다.

 

이렇게 두 방법으로 모두 사용해보니 웹 콘솔에서 작업하는게 정말 편하다는 걸 깨닫습니다. 그러나 한편으로는 내가 만드는 웹 사이트에 이 기능을 집어 넣고 싶다면, 본 API 가이드를 꼼꼼히 읽으며 적용해봐야겠습니다.