네이버클라우드

[Ncloud] File filter API로 악성코드 정밀 검사해보기 in File Safer

graph-dev 2023. 8. 20. 22:02
728x90

ncloud logo

 

 

File filter라는 것이 있습니다. 파일을 첨부하면, 해당 파일을 검사해서 악성코드 포함 여부를 확인해서 알려주는 기능입니다. Hash Filter보다 좀 더 정밀하게 파일을 통째로 검사하는 기능으로 생각하면 되겠습니다.

 

지난 글에서는 웹 콘솔로 검사를 했는데, API로도 같은 기능을 제공합니다.

 

참고로 개발 가이드에는 File filter에 대한 시나리오도 있습니다.

https://guide.ncloud-docs.com/docs/filesafer-programming-file

 

File Filter 개발

 

guide.ncloud-docs.com

 

시나리오를 간단히 살펴보겠습니다. 두 가지 API를 통해 파일을 검사를 요청(POST)하고, 그 검사 결과를 받아서 확인할 수 있습니다. 그 결과에 따라 사용자는 응답 값을 확인하고, 파일을 차단할 지 여부를 스스로 선택합니다.

 

두 가지 API로는 inputFile API와 getInputFileLog API가 있습니다. inputFile API부터 살펴보겠습니다.

 

inputFile API

가이드에서는 분석을 위해 파일을 전송하는 API라고 합니다. 이름처럼 파일을 입력 요청하는 API라고 볼 수 있습니다.

 

요청시 POST 메서드로 https://filesafer.apigw.ntruss.com/filefilter/v1/inputFile 주소를 사용하면 됩니다. format은 multipart이므로 다양한 종류의 파일(이미지, 텍스트, 영상 등)을 보낼 수 있겠죠?

 

예시 코드를 살펴보겠습니다. curl 메소드를 사용합니다.

curl -X POST "https://filesafer.apigw.ntruss.com/filefilter/v1/inputFile"
   -H "accept: application/json"
   -H "Content-Type: multipart/form-data"
   -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}"
   -d {"archivePassword":{password},"file":{binary}}

 

헤더 값이 6개이고 요청 파라미터가 있습니다. 이전 글을 보시면, api-gw-key, iam-access-key, timestamp, signature 값을 쉽게 구해서 넣을 수 있습니다.

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

 

[Ncloud] API를 통해 File Safer 사용해보기 - Hash Filter

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

graph-dev.tistory.com

 

예시에 나온 url을 모두 사용하고 나머지는 메서드를 통해 출력한 다음, curl 메소드에 있는 중괄호 값을 채우시면 됩니다. 남은 것은 file과 password입니다. password는 압축 파일 등에서 암호로 보호된 경우 해당 값을 입력하는 것입니다. 따로 없다면, 빼고 file 경로만 입력하면 되겠습니다.

 

이제 file 하나만 넣어보고 그 결과 값을 확인해보겠습니다. file은 binary로 표기된 부분에 입력합니다. 저는 지난 글에서도 사용한 텍스트 파일을 넣어보았습니다.

curl -X POST "https://filesafer.apigw.ntruss.com/filefilter/v1/inputFile" \
   -H "accept: application/json" \
   -H "Content-Type: multipart/form-data" \
   -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분 내에 사용할 시그니처 값이다" \
   -d {"file":"/사용자경로/이것은예제파일이다.rtf"}

 

 

그런데 계속 에러가 발생합니다. 파일의 용량이 제한 수치를 넘는다는 것입니다. 제한 용량이 10MB일텐데, 제 파일은 511바이트 밖에 안되서 더욱 이상합니다.

{"returnCode":"140007","returnMessage":"file size exceeds the limit."}

 

 

그래서 요즘 유행하는 chat GPT를 사용해보았습니다. 답변은 아래와 같습니다.

 

-d 옵션을 사용하면 데이터를 application/x-www-form-urlencoded 포맷으로 보내게 됩니다. 하지만 바이너리 파일을 첨부하려면 multipart/form-data 포맷이 더 적절합니다.
그럼에도 불구하고 -d 옵션을 사용하여 파일을 첨부하려고 한다면, 바이너리 파일의 내용을 인코딩하여 문자열 형태로 포함시켜야 합니다. 하지만 실제로 이러한 방식은 매우 비효율적이며, 대부분의 API에서는 이러한 방식을 지원하지 않습니다. 만약 단순한 텍스트 데이터나 JSON과 같은 문자열 기반의 데이터를 전송한다면 -d 옵션을 사용할 수 있습니다.

 

굳이 -d 옵션을 사용하려면 base64로 전환해야한다는 의견도 있지만, 잘못된 방법이라고 생각합니다.

 

이 가이드도 업데이트가 필요해보입니다. 비밀번호가 함께 넣어야 한다면 GPT 의견처럼 별도로 두어도 됩니다. 이와 관련해서, GPT가 제공한 코드는 다음과 같습니다. 여기서 중괄호 부분을 채워서 사용하면 되겠습니다.

curl -X POST "https://filesafer.apigw.ntruss.com/filefilter/v1/inputFile" \
   -H "accept: application/json" \
   -H "Content-Type: multipart/form-data" \
   -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}" \
   -F "archivePassword={password}" \
   -F "file=@/path/to/your/file.ext"

 

 

결국 저는 -d 옵션은 쓰지 않고, -F 라는 옵션을 사용해서 수행하겠습니다. 아래와 같이 코드를 작성했습니다.

curl -X POST "https://filesafer.apigw.ntruss.com/filefilter/v1/inputFile" \
   -H "accept: application/json" \
   -H "Content-Type: multipart/form-data" \
   -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분 내에 사용할 시그니처 값이다" \
   -F "file=@/사용자경로/이것은예제파일이다.rtf"

inputFile API 결과

결과는 아주 간단하게 성공했다는 것 뿐입니다.

{"returnCode":"0","returnMessage":"success"}

 

입력 요청을 성공적으로 전달했습니다. 이제 검사 결과를 확인해볼까요?

 

getInputFileLog API

파일 검사 결과를 확인하는 API를 사용합니다.

 

사실 이해가 안가는게 “왜 file filter 기록을 위해 hash를 사용하는가?”라는 점입니다. 그냥 결과적으로 file filter 검사 기록은 hash값으로 조회를 해야한다고만 생각하기로 했습니다.

 

요청 url은 https://filesafer.apigw.ntruss.com/filefilter/v1/getInputFileLog 이며, GET 메서드로 사용합니다.

 

가이드 예시 파일 따라해보기

이번에도 가이드 예시를 잘 활용해보겠습니다. 지난 글에서 이 hash값은 악성 코드가 이미 탐지된 적이 있었죠?

파일 검사 기록도 궁금해서 한번 확인해보겠습니다.

 

curl -X GET "https://filesafer.apigw.ntruss.com/filefilter/v1/getInputFileLog?hash=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}"

 

결과는 아무것도 안나옵니다. 제가 이 파일로 검사하지는 않았기 때문입니다.

 

{"returnCode":"0","returnMessage":"success","inputFileLogList":[]}

 

내 파일로 검사기록 조회하기

 

이제는 위에서 검사한 파일의 md5 hash 값을 넣어서 다시 확인하겠습니다. 아래와 같이 실행한 결과는 다음과 같습니다. 여러번 file filter로 검사한 기록이 모두 나오고 다 동일한 내용이므로 잘라서 하나만 살펴보겠습니다.

내 파일 검사 기록 조회

간단히 결과를 보면 inputfile의 파일 타입과, 파일 크기, 암호화된 hash값들이 있습니다. 중요하게 볼 부분은 analysisStatusCode와 ResultCode가 "N"이라는 점입니다. 아래에서 좀 더 살펴보겠습니다.

 

그 외에 결과에 대한 자세한 내용은 아래 가이드에서 응답 바디 부분을 참고해주세요.

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

 

getInputFileLog (File Filter)

 

api.ncloud-docs.com

 

 

특히, 제가 가장 중요하게 생각하는 부분은 개발 가이드에서 발췌했습니다.

 

가이드 발췌 결과값 발췌

 

결과에 보면 N만 있죠? 정상 파일이며 악성 코드는 감지되지 않은 것입니다. 또한, analysisStatusCode가 CMPL이면 분석이 완료되었다는 의미입니다. 처음 제시한 개발 가이드를 꼼꼼히 읽어봅시다. 감지되면 차단 혹은 삭제하도록 권유하고 있습니다.

 

 

File filter 통보 설정

이 모든 결과를 메일이나 SMS로 받으려면 통보 설정(Notification setting)을 해야 합니다. File Safer > File Filter > 결과 통보 설정을 누릅시다.

 

File filter 결과 통보 설정 화면

 

일반 설정과 고급 설정을 각각 아래와 같이 설정합니다. 일반에서는 모두 통보하고, 고급 설정에서는 5분간 악성코드 1회 탐지시 통보하도록 설정했습니다.

 

결과 통보 일반 및 고급 설정 화면

 

그리고 File filter를 수행하면 아래 사진과 같은 메일이 오게됩니다.

 

File filter 결과 통보 메일

 

 

Postman으로 FileFilter 검사하기

마지막으로, postman으로 동일하게 수행해보겠습니다. 위에서 사용한 url, 각종 인증키와 timestamp를 그대로 헤더에 넣어주면 됩니다.

 

파일 검사 요청하기(InputFile API)

이거는 POST로 요청을 해야하며, 헤더와 더불어 Body에도 값을 넣어야 합니다.

 

Body를 작성할 때, binary로 선택하면, 계속해서 아래와 같이 file size 초과 오류가 발생하니 유의해주세요.

{
    "returnCode": "140007",
    "returnMessage": "file size exceeds the limit."
}

 

이번에도 Body 작성은 form-data 옵션으로 수행했습니다. Key에는 file을 입력하고, Value는 Text가 아니라 file을 선택해서 업로드해주셔야 합니다!

form-data 유의할 점 file

 

그 외에는 아래처럼 Body를 추가로 작성해서 Send를 누르면 됩니다.

body 입력창

 

그 결과 아래처럼 성공을 합니다.

{
    "returnCode": "0",
    "returnMessage": "success"
}

 

 

검사결과 확인하기(getInputFileLog API)

이제 바로 GET 요청을 수행하고자 getInputFileLog API를 사용해보겠습니다. Postman에서 GET 요청으로 설정하고 가이드에 나온 url을 입력합니다. 헤더값만 잘 작성해서, Send를 누르면 아래 결과가 나타납니다.

 

 

결과만 다시 살펴보겠습니다. 중복되는 것은 다 제외하고 해시값도 가렸습니다.

{
    "returnCode": "0",
    "returnMessage": "success",
    "inputFileLogList": [
        {
            "fileType": "Microsoft Rich Text Format",
            "fileSize": 511,
            "parentSha1": null,
            "md5": "이것은 md5 해시값이다",
            "sha1": "이것은 sha1 해시값이다",
            "sha256": "이것은 sha256 해시값이다",
            "analysisStatusCode": "CMPL",
            "analysisResultCode": "N",
            "notifyYmdt": null,
            "registrationYmdt": 1692531116000,
            "serviceCode": null,
            "applicationCode": null
        }
    ]
}

 

중요한 부분은 위에서 설명했지만 analysisStatusCode가 CMPL로 분석이 완료되었고, analysisResultCode가 N으로 악성 코드가 탐지되지 않았다는 부분입니다.

 

만약에 analysisResultCode가 N이 아니라 M이라면 악성코드가 탐지된 것이므로 가이드의 권고에 따라 파일을 삭제하거나 안전하게 격리하도록 합시다.

 

이렇게 file Safer 서비스를 API로 호출해서 사용해봤습니다. 비용이 저렴한 편은 아니지만 해킹 등으로 인한 보안 피해가 발생한다면 그보다 훨씬 클 것입니다.

 

항상 안전한 웹 문화를 정착하기 위해, 개발자로서 보안에 신경을 쓰고, 좀 더 노력해야겠습니다.