컴퓨터 공학/작업일지

HTTP Digest 인증 문제

혼새미로 2020. 1. 26. 17:46
반응형


최근에 회사에서 카메라 서버에 PTZ (Pan Tilt Zoom) 명령을 전달하는 과정에서 사용하는 HTTP Digest 인증에서 문제에 직면했다. 그 전까지 HTTP를 통신하는 과정에서 인증이 있다는 것도 몰랐던 나는 이 기회에 HTTP 인증 방식에 대한 공부를 해보기로 하였다. 다음은 @ssup2로부터 참조한 것이다.


일반적으로 HTTP를 통해 서버와 통신할 때 클라이언트의 신분을 확인하기 위해 인증작업을 진행하는데, 대표적으로 다음과 같은 인증방식이 있다.

  • 익명: 인증정보를 포함하지 않는 요청을 말한다.
  • Basic: 기본 인증은 클라이언트에 대한 사용자 이름과 암호를 Base64로 인코딩 된 문자열을 보낸다.
  • Digest: 사용자 이름, 암호 등을 조합하여 MD5 값으로 인증한다. 인증과정은 다음과 같다.
    1. 클라이언트가 서버에게 페이지를 요청한다.
    2. 서버는 클라이언트에게 Digest 인증이 필요하다고 통보한다.
    3. 클라이언트는 서버정보와 클라이언트 아이디와 암호 등을 병합하여 MD5로 만들어 전송한다.


이 중에서 우리회사에서는 Digest 방식을 통해 HTTP 인증을 진행하고 있었다. 따라서, Digest 방식에서 서버가 클라이언트에게 요청한 정보에 대해 조금 더 자세히 알아볼 필요가 있다.


  • realm: 요청한 Resource의 Protection Space를 나타내는 속성이다. Resource가 속해있는 Protection Space마다 Client는 각기 다른 ID, Password를 이용할 수 있다.
  • nonce: 클라이언트가 서버에게 Resource를 요청할 때 마다 Server에서 생성하는 임의의 값이다. 클라이언트는 서버로부터 받은 nonce를 그대로 서버에게 전달해야 한다. 서버에서는 nonce가 다르면 Resource 요청을 거부한다. 따라서 nonce를 통해 Server Reply Attack을 방지할 수 있다.
  • qop: Quality of Protection의 약자로 의미 그대로 Protection 등급을 나타낸다.

인증요청을 받은 클라이언트는 서버로부터 받은 nonce, qop, realm 속성값을 Authorization 헤더에 그대로 추가하고 그 외의 필요한 속성값들을 추가한다.

  • nc: nonce count의 약자로 클라이언트가 서버로부터 받은 nonce를 이용하여 서버에게 몇 번 요청했는지 나타낸다.
  • cnonce: 클라이언트에서 생성하는 임의의 값이다. nonce와 유사하게 Client Reply Attack을 방지한다.
  • response는 인증에 필요한 정보가 포함된 Digest이다.

response 는 다음의 공식으로 구할 수 있다.

  • HA1 = MD5(username:realm:password)
  • HA2 = MD5(method:uri)
  • response = MD5(HA1:nonce:nc:cnonce:qop:HA2)

서버는 nonce와 response의 일치를 확인하면 Client가 요청한 Resource와 함께 Authorization-Info Header를 통해 인증정보도 같이 전송한다.

  • qop: 서버에서 이용한 Protection 등급을 나타낸다.
  • nc와 cnonce는 클라이언트에서 보낸 값과 일치해야 한다.
  • rspauth는 response auth를 의미하며 서버와 클라이언트 사이의 상호인증 시 이용된다.
  • nextnonce는 클라이언트가 서버에게 다음 요청시 사용되길 원하는 nocne 값을 나타낸다.


이 중에서 HA2를 생성할 때 사용되는 URI 부분에서 문제가 발생하였다. 우리회사는 특정 URI에 대해 요청할 때 그 URI에서 파라미터를 제거하고 전송했었다. 그래서 나는 이 방법이 정말 맞는지, 그리고 URL과 URI의 차이가 무엇인지 궁금해졌다. 다음 정보는 @pa324로부터 참조한 것이다.


URL (Uniform Resource Locator)
  • 자원
  • 예전에는 URL이 가리키는게 파일 소스였음
  • 웹 상에 서비스를 제공하는 각 서버들에 있는 파일의 위치를 표시하기 위한 것

URI (Uniform Resource Identifier)


다시 HTTP Digest로 돌아와서, 우리회사에서는 카메라의 HTTP 서버에 인증정보를 전송할 때 마다 서버로부터 <400 Bad Request>가 반환되었다. 그래서 이에 대한 원인을 찾기 위해 인터넷을 검색하던 중 @iloveulhj로부터 다음의 정보를 발견했다.



  • Digest 인증에서 지시자나 그 값이 적절하지 않거나 요구된 지시자가 빠진 경우 <400 Bad Request>를 반환해야 적절한 응답이다.
  • 인증서버는 반드시 URI 지시자가 가리키는 리소스가 요청 줄에 명시된 리소스와 같음을 확인해야 한다. 다를 경우, 이는 공격의 징후일 수 있으므로 로그를 남기는 것이 좋다.


즉, http://test.com/stw-cgi/attribute.cgi?auth=1311 이라는 URI을 서버에 요청할 때, HTTP Digest에서 auth 라는 파라미터를 제거하고 authorization에 전달할 경우, 공격의 징후로 볼 수 있기 때문에 반드시 요청 URI와 인증 URI는 동일하게 전달해야 한다. 그런데, 우리회사에서는 요청 URI와 인증 URI가 다르게 입려되어 서버에 전달하였고, 이로 인해 카메라 서버에서 <400 Bad Request> 메시지를 전달한 것이다. 이에 따라, 소스코드에서 요청 URI와 인증 URI를 동일하게 수정하고 테스트를 해 보았더니 <400 Bad Request>를 받지 않고 정상처리가 되었다.





반응형