보안 공부/소스코드 보안약점 진단

소스코드 보안약점 진단 - DNS lookup에 의존한 보안결정

H.J.World 2022. 2. 15. 10:10
728x90
반응형

소스코드 보안약점 진단 // 소프트웨어 보안약점 진단 // SW 보안약점 진단과 같이 다양한 이름으로 불리는 진단 과업 중 하나이다.

SW개발보안은 해킹 등 사이버공격의 원인인 보안약점을 SW개발단계에서 사전에 제거하고 SW 개발 생명주기의 각 단계별로 수행하는 일련의 보안활동을 통하여 안전한 SW를 개발·운영하기 위한 목적으로 적용하는 개발체계이다.

해당 내용은 KISA에서 발간하는 취약점 진단 가이드 항목을 기준으로 작성한다.

 

제 7절 API 오용

의도된 사용에 반하는 방법으로 API를 사용하거나, 보안에 취약한 API를 사용하여 발생할 수 있는 보안약점이다.


1. DNS lookup에 의존한 보안결정

가. 개요

공격자가 DNS 엔트리를 속일 수 있으므로 도메인명에 의존에서 보안결정(인증 및 접근통제 등)을 하지 않아야 한다. 만약, 로컬 DNS 서버의 캐시가 공격자에 의해 오염된 상황이라면, 사용자와 특정 서버간의 네트워크 트래픽이 공격자를 경유하도록 할 수도 있다. 또한, 공격자가 마치 동일 도메인에 속한 서버인 것처럼 위장할 수도 있다.

나. 보안대책

보안결정에서 도메인명을 이용한 DNS lookup을 하지 않도록 한다.

다. 코드예제

다음의 예제는 도메인명을 통해 해당 요청을 신뢰할 수 있는지를 검사한다. 그러나 공격자는 DNS 캐쉬 등을 조작해서 쉽게 이러한 보안 설정을 우회할 수 있다.

- 안전하지 않은 코드의 예 JAVA -

1: public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
2: boolean trusted = false;
3: String ip = req.getRemoteAddr();
4: InetAddress addr = InetAddress.getByName(ip);
5: //도메인은 공격자에 의해 실행되는 서버의 DNS가 변경될 수 있으므로 안전하지 않다.
6: if (addr.getCanonicalHostName().endsWith("trustme.com")) {
7: do_something_for_Trust_System();
8: }

 

- 안전한 코드의 예 JAVA -

그러므로, 다음의 예제와 같이 DNS lookup에 의한 호스트 이름 비교를 하지 않고, IP 주소를 직접 비교 하도록 수정한다.

1: public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
2: String ip = req.getRemoteAddr();
3: if (ip == null || "".equals(ip)) return ;
4: //이용하려는 실제 서버의 IP 주소를 사용하여 DNS변조에 방어한다.
5: String trustedAddr = "127.0.0.1";
6: if (ip.equals(trustedAddr)) {
7: do_something_for_Trust_System();
8: }

 

라. 진단방법

DNS lookup을 하는 모듈이 존재하는지 확인하고(①), 보안결정을 하는 부분이 존재하는지 확인 한다(②). DNS 이름을 통해 해당 요청이 신뢰할 수 있는지를 검사한다. 그러나 공격자가 DNS 캐쉬 등 을 조작하면 잘못된 신뢰 상태 정보를 얻을 수 있다.

1: public class U247 extends HttpServlet {
2: public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
3: boolean trusted = false;
4: String ip = req.getRemoteAddr();
5: // 호스트의 IP 주소를 얻어온다.
6: InetAddress addr = InetAddress.getByName(ip);--------------①
7: // 호스트의 DNS이름이 신뢰할 수 있는 도메인(trustme.com)에 속하는지 검사한다.
8: if (addr.getCanonicalHostName().endsWith(“trustme.com”) ) {----②
9: trusted = true;
10: }
11: if (trusted) {
12: …
13: } else {
14: …
15: }
16: }
17: }
728x90
반응형