Apache Web Server 1.2 beck exploit 버그의 교훈

Apache web server 1.2 beck exploit 는 Apache Web Server 1.2에 있던 버그라고 합니다.
(http://www.iss.net/security_center/reference/vuln/HTTP_Apache_DOS.htm 참조.)
Apache web server에는 / (slash) 가 동시에 여러 개 입력되는 URL이 있는 경우에 이를  이를 1개로 만드는 기능이 있습니다. 예를 들어, /d1///d2////d3/test.html 의 값으로 입력되면, 이를 /d1/d2/d3/test.html로 변환하는 기능입니다. 그런데 프로그램 모듈(no2slash)의 버그 때문에 시스템의 성능을 저하시키는 영향을 미치게 되어, DOS (denial of service) 공격이 용이하게 하는 문제를 안고 있었습니다. 이 프로그램의 원문은 다음과 같습니다.

void no2slash(char *name) {
  int x, y;
  for (x = 0; name[x]; ) {
    if (x && (name[x-1] == '/') && (name[x] == '/')) {
      for (y = x + 1; name[y-1]; y++)
        name[y-1] = name[y];
    }
    else {
      x++;
    }
  }
}

이 프로그램의 시간 복잡도는 2차(quadratic) 식입니다. 즉, ‘/’ 의 개수의 제곱에 비례하는 수행 시간이 증가하는 특성이 나타납니다. 이 특성 때문에, 많은 개수의 ‘/’가 포함된 URL이 주어지면, 이를 처리하느라 CPU의 시간을 다 소모하게 됩니다. 이를 개선한 프로그램은 다음과 같습니다.

public void no2slash2(char[] name) {
  int n = name.length;
  int offset = 0;
  for (int i = 1; i < n; i++) {
    if ((name[i-1] == '/') && (name[i] == '/')) {
      offset++;
    }
    else {
      name[i-offset] = name[i];
    }
  }
}

이 알고리즘의 시간 복잡도는 선형적(linear)입니다. 즉, ‘/’ 의 개수에 비례하여 수행시간이 증가하게 됩니다.

이 사례는 몇 가지 교훈을 남기고 있습니다.

1. 프로그램의 알고리즘은 매우 중요하다.

이 두 개의 프로그램의 정확성에는 문제가 없습니다. 둘 다 정확하게 원하는 결과를 얻을 수 있습니다. 하지만, quadratic 알고리즘과 linear 알고리즘은 그 수행 속도에서 매우 큰 차이를 보입니다. ‘/’ 가 500개가 연속되어 나타나는 URL로 테스트를 해 보면, 처음의 프로그램은 for 루프 안에서 130,000번을 헤매게 됩니다. 반면에, 개선된 프로그램은 510번만을 수행합니다. 단순하게 비교하면, 처음의 프로그램이 250배이나 많은 연산을 수행하고 있습니다. 뒤집어서 말하면, 개선된 프로그램이 250건의 request를 처리하는 동안, 최초의 프로그램은 단 1건만 처리할 수 있다는 것입니다. 따라서, 좋은 알고리즘을 찾기 위한 노력은 매우 중요합니다.

2. 알고리즘은 매우 고차원적인 프로그램에서만 사용되는 것은 아니다.

알고리즘의 개선은 프로그램에 작성할 때 고민하는 것은 매우 복잡하고, 어렵고, 고차원적인 수준의 프로그램에만 국한되는 것은 아닙니다. 이 경우처럼 중복되는 ‘/’ 를 제거하는, 어찌 보면 매우 단순한 로직에서도 사용됩니다.

3. 프로그램이 논리적으로 동작한다고 해서 완성된 것은 아니다.

정확하게 동작하는 것은 프로그램의 기본이지만 그것만으로 개발자의 역할이 끝난 것은 아닙니다.


문제 1:  '/' 가 500개 일 때, 프로그램 2는 0.0001 초의 시간이 걸리고, 프로그램 1은 0.0250 초가 걸린다고 할 때,
'/'가 10배인 5000개일 때는 각각의 프로그램은 얼마의 시간에 수행될까요?


문제 2:  '/' 가 500개 일 때, 수행 연산의 수에서 250배의 차이를 보였다면, 10배인 5000개일 때는 얼마의 차이를 보일까요?
(1) 250배    (2) 2,500배

문제1의 답: 프로그램 2는 0.001 초, 프로그램 1은 2.5 초가 소요된다.

문제2의 답: (2)
이유는, N^2 : N = 250 : 1 이므로,
(10N)^2 : 10N = 100N^2 : 10N = 10N^2 : N = 2500 : 1

댓글

이 블로그의 인기 게시물

Java의 String 객체의 메모리 사용량

리틀의 법칙 – Little’s law

true, false, positive, negative – TP/TN/FN/FP