Race condition
멀티 프로그래밍을 구현한 컴퓨터는 분명히 유한한 자원을 여러 프로세스에
나누어 주는 역할을 하여야 한다. 이 때 그 여러 프로세스는 서로 자원을 가지기
위해서 경쟁을 하는데 이러한 상태를 race condition이라 한다. 즉 race condition이라는
말 자체가 해킹을 의미하는 것은 아니었다. 그러나 영국의 해킹단체 8lgm이 이
race condition을 이용하여 부당하게 root 권한을 얻어내는 방법을 발견, 발표한
이후에 race condition이란 단어가 하나의 해킹 기법을 의미하게 되었다.
실제로 이런 race condition 상태에서 시스템은 동일한 두 프로세스에게 규칙성
있게 할당하지 못한다. 이를 이용하여 버그를 가지고 있는 system program(SUID가
root나 Bin 등으로 설정되어 있는 program) 과 hacker가 만든 Exploit program
이 이런 경쟁상태를 만들고 이를 이용해서 root 권한으로 file에 대한 접근을
가능하게 한다.
race condition에서 또 다른 중요한 개념은 Symbolic link이다. 유닉스에서는
이 심볼릭 링크를 제공하므로써 대단히 편리한 기능을 주는데, 이를 악용하는
것이다. 심볼릭 링크를 사용하여 다음과 같이 만들었다고 치자.
[****]:/u4/cybertec% ln -s ~root/.rhosts this
이렇게 하면 this는 ~root/.rhosts를 가리키는 파일이 된다. 만일 여기서
this에 어떤 내용을 써 넣는다면 이것은 this에 써지는 것이 아니라, ~root/.rhosts에
써지는 것이 될 것이다. 만일 시스템이 이것을 체크하지 않는다면 커다란 문제를
일으킬 수가 있다.
물론 위에 쓴 것처럼 간단하게는 되지 않지만, SunOs 4.x버젼의 메일 프로그램의
불완전성을 이용하여 위와 같은 원리를 이용할 수 있다.
[****]:/u4/cybertec% cd /var/spool/mail; ln -s
~root/.rhosts
daemon [****]:/var/spool/mail% echo "+ +" | mail daemon
[****]:/var/spool/mail%
rlogin localhost -l root
여기서 /bin/mail 프로그램은 daemon 이 심볼릭 링크인지를 확인하지 않기
때문에, root 권한으로 USER_ID 에 해당하는 파일에 수신된 내용을 덮어쓰게
된다.
이것 때문에 이제 Sun 사에서 USER_ID 에 해당하는 내용이 실제로 존재하는지,
또는 심볼릭 링크인지를 확인하는 패치를 개발하였다. 하지만 곧 이 패치버젼에
걸맞는 hacking skill이 등장했는데 이것이야 말로 race condition이라 할 수
있는 기법인 것이다.
실제로 패치된 버전의 mail 프로그램에서 USER_ID 에 해당하는 내용이 심볼릭
링크가 아닐 때에만 이 파일을 연다. 이것의 비교는 lstat()에서 하며, 심볼릭
링크가 아님을 판단한 후 open()으로 연다. 그러나 이 비교과 열기의 사이에는
일정 시간의 갭이 있으며, 이를 만일 파고든다면, 정상적인 파일을 이 사이에
심볼릭 링크로 바꾸어 낼 수도 있을 것이다. 즉 이 과정이 race condition 이
일어나는 순간이다.
위와 같은 기법은 메일 프로그램 이외에도 임시 파일을 만드는 SUID 프로그램에서도
성립한다. 이것도 메일 버그와 비슷한 이유로 root 권한을 내어주게(?) 되는데.
만일 임시파일과 같은 이름의 심볼릭 링크를 걸어주고, 그 대상이 파일이 실제로
없다면, Default umask에 의해서 rwxrwxrwx의 퍼미션을 가진 파일이 생성되어
진다. 이를 이용하여 root권한을 가지거나 남의 메일을 열어보거나 할 수 있는
것이다. 마찬가지로 이에 대한 패치도, 결국 race condition에 의해서 뚫릴 수
있다.
race condition을 막으려면 첫째로 root권한의 SUID 실행시 될 수 있으면
임시파일을 만들지 않는 것이다. 임시파일은 심볼릭 링크로 악용될 빌미를 제공한다.
또한 unlink()를 불가능 하게 하는 것도 좋은 방법이다. 링크 점검시에 lstat()이용하여
심볼릭 링크 race를 피하도록 하고, open()후에는 fstat()으로 확인하는 것이
좋다.
Buffer overflow
이 방법은 비교적 최근에 발견된 방법으로, Aleph One 이라는 사람이 96년도에
Phrack이라는 보안관련 문서에 발표하면서 알려진 것이다. buffer overflow 란
말 그대로 버퍼를 오버플로우 시켜, 실제 그 명령이 아닌 다른 명령을 그 명령의
권한으로 실행되도록 하는 방법을 말한다.
하나의 프로세스는 스택 형태로 저장되는데, 스택 영역의 SP 포인터 부분에
함수의 연결관계, 그리고 사용하는 변수들이 지정된다. 이 부분을 조작하면,
SP 포인터가 가리키는 부분이 달라져서 전혀 다른 명령을 실행 시킬수 있는 것이다.
Buffer overflow의 타겟이 되는 프로그램은 주로 SUID 로 root 권한을 가지게
되는 프로그램이며, 실행되게 하는 프로그램은 주로 /bin/sh 같은 쉘 프로그램이기
때문에, 이것이 성공하면 바로 root를 쥘 수 있는 것이다.
overflow 시키는 것은, 무작정 에러를 내는 것만으로는 안된다. overflow
되어서 넘어가는 부분을 잘 조절하여 그것이 동작하도록 해야 하는데, 주로 쉘을
띄우는 것이 목적이므로 시스템 내에서의 /bin/sh의 위치, 동작하는 과정등을
알아야 할 것이다. 간단한 쉘을 띠우는 c프로그램을 컴파일 시켜, 어셈블리로
변환한 후에 ,그를 분석하면 꽤 많은 정보를 얻을 수 있다. 그를 바탕으로 seed를
정확히 작성하면, 원하는 프로그램을 띄울 수 있다.
overflow를 바탕으로 한 해킹 기술은 여러 가지가 있는데, 이를 방어하기
위해서는 주로 Overflow wrapper가 사용된다. 이 프로그램은 오스트레일리아의
AUSCERT 라는 보안 팀에서 만들어 배포한 것인데. 프로그램의 동작 원리는, 프로그램이
실행될 때 넘겨받는 인자의 길이를 먼저 검사하여, overflow일 경우에는 더 이상
접근할 수 없도록 하고, 그렇지 않을 때만 허용하도록 만들어져 있다. 하지만
wrapper도 방어할 수 있는 범위가 한정되므로 기타 여러 가지 최신 패치들을
구하여 사용하여야 할 것이다.
DoS, DDoS attack
- DoS attack
cracking의 또 다른 형태로서 Dos attack을 들 수 있다. Dos는 Denial
of Survice의 약어로서 즉, 서비스 거부를 하게 만드는 것이다. 물론 root권한은
불법 획득하여, 내부 파일 구조를 망가뜨림으로도 큰 피해를 줄 수 있지만,
그러기 어려울 경우에, 단순히 시스템이 서비스하는 것을 방해하는 것만으로도
시스템 운영자에게는 큰 타격이 될 것이다. 이것이야 말로 정말 사악한 attack이
아닐 수 없다.
주로 서비스를 제공하는 시스템의 리소스를 모두 먹어버리거나, 파괴하는
형태를 쓴다. 그런데 이런 것들은 감지하고 방어하는 것이 무척 어려워서
관리자의 세심한 주의가 요구된다.
DoS 공격의 유형은 크게 내부적인 공격과 외부적인 공격으로 나뉠 수
있다.
- 내부적인 공격
- 시스템의 디스크 고갈: 고의적으로 용량이 큰 파일을 생성하여,
파일 시스템을 꽉 차게 하고, 서비스를 더 이상 제공하지 못하도록
하는 방법. unlink 후에 파일의 크기를 무한정 증가시킨다.
- 시스템의 메모리 고갈: 고의적으로 load 가 큰 process를 걸어,
메모리를 고갈시키는 방법
- 시스템 내의 프로세스 killing : root 권한을 가진 후, 그 시스템에서
돌고 있는 모든 process들을 kill 시키는 방법.
- 프로세스 Overflow : Kernel에 한정되어 있는 수 이상의 process를
만들어 내어 모든 process가 돌지 못하도록 하는 방법.
- 외부적인 공격
- Mailstrom : 메일을 계속해서 보내어 mail system을 마비시킴.
- Client attack : Java 의 applet을 이용한다. applet은 서비스가
client로 전송되어, client의 시스템에서 돌아가는 형태이므로,
이런 applet를 준비하였다가 client가 접속하면 client의 리소스를
고갈시킨다.
- inetd attack
- TCP/IP, ethernet 에서의 packet 조작 : packet을 조작하여
네트워크를 마비시킨다.
- Network traffic overflow : network 기능을 마비시킴
최근에 유행했던 DoS attack들에 대하여 잠시 알아보면.
- echo/chargen
보통 UDP storm attack 이라 불리는데, UDP 서비스 중에 echo/chargen을
이용하여, 시스템을 다운시키는 공격이다. 이것들을 이용하여 공격을
받는 경우가 많고, 또한 실제로 echo/chargen service는 별로 이용되는
일이 없기 때문에 시스템에서 제거하는 편이 좋다. 제거하는 방법은
/etc/services 와 /etc/inetd.conf 파일에서 echo, chargen을 제거한
후에 inetd 수퍼서버를 다시 띄우는 것이다.
- flooding
Spoofing에서 trust 호스트를 마비시키기 위하여 사용된 방법. TCP
SYN flooding이라는 방법.
- mail bomb, Spam mail
mail bomb, 즉 메일 폭탄이라고 하는 것은 엄청난 용량의 mail을
익명으로 보내어 그 메일을 관장하는 서버의 파티션을 마비시키고 그럼으로서
mail service를 중지시키는 방법이다. 보통 받은 메일은 /var/spool/mail에
저장이 되는데, 이 파티션이 꽉 찬다면 그 이후의 mail을 저장하지 못하게
될 것이다. 이것이 메일 폭탄, mail bomb 이다.
spam mail이란 많은 사람들이 이미 겪어 본 것일 것이다. 원하지
않는 메일이 자신에게 오는 것을 뜻하는데, 이렇게 받는 사람의 의사에
상관없이 집단, 무설정 메일을 보내는 것이다. spam mail도 anonymous로
보내는 것이 가능해져 많은 사용자들이 불편을 받고 있다. spam mail을
지속적으로 뿌리는 자들을 list로 만들어 그들에게서 오는 메일을 거부하거나,
메일 자체에 어떤 식의 필터를 두어 원하는 내용의 메일만 받도록 하는
것이 간접적인 해결책이 될 것이다.
- DDoS (Distributed Denial of Service)
이름에서도 볼 수 있듯이 distributed system 즉 분산환경 하에서의 Dos
attack이라고 보면 될 것이다. 대규모 네트워크에서 많은 수의 host에 설치된
후에 공격자의 명령에 따라 한 시스템을 마비시킬 수 있다.
이런 분산 시스템 공격을 하는 도구로는 trinoo과 TFN이 있다.
- Trinoo : 많은 소스로부터, 통합된 UDP flood DoS attack을 만들어내는
도구이다. trinoo공격은 몇 개의 서버와, 그에 연결된 많은 수의 클라이언트로
이루어지는데. 서버를 통제하여 그 밑의 클라이언트에 거부공격 수행을
명령하는 것이다.
- TFN(Tribe Flood Network) : Trinoo와 그 목적은 거의 유사하나,
여러개의 소스에서 여러개의 시스템에 DoS attack을 할 수 있다. TFN은
UDP flood attack 이외에도 TCP SYN flood 공격, ICMP echo 공격, ICMP
broadcast 공격등도 할 수 있다.