security

Total 112
Today 0
profile_image
운영자
01-02-06 09:23 0개 2,585회
How to get a detailed in formation from the remote host --(3)
이번주도 지난주에 이어 원격지에 있는 호스트로부터 해당 호스트의 정보를 어떻게 얻는지에 대한 방법과 관련한 강의를 계속합니다.





4. Remote OS Detection



---4.1 Classical Techniques



Stack fingerprinting은 가장 독특한 방법으로 OS를 구분하는 방법이나, 현재 많은 다른 방법들이 존재하며, 개중에는 매우 효과적인 것도 있다.. 다음과 같다.



playground~> telnet hpux.u-aizu.ac.jp



Trying 163.143.103.12...



Connected to hpux.u-aizu.ac.jp.



Escape character is '^]'.



HP-UX hpux B.10.01 A 9000/715 (ttyp2)



login :



이렇게 자신의 OS를 널리 공표하는 경우 왜 굳이 finger printing 이란 것을 해가며, target의 host의 OS를 알아내려 하는 것일까? vendor에서 제공하는 많은 unix들이 이렇게 자기의 OS를 공표하고 있으며, admin들은 이러한 banner를 끄지 않는다. (banner는 /etc/issue 에 있습니다. )



최근 security에 대해 admin들의 관심이 늘어감에 따라, 이러한 banner를 끄는 admin들이 늘어가고 있으며, 당연히 이 banner에 거짓정보를 넣는 것을 고려하는 admin들도 있을 것이다. 그러나 문제가 되는 banner를 끈다고 문제가 해결되는 것은 아니다. 많은 daemon들 역시 이러한 정보를 쉽게 넘겨준다. 다음 경우를 보면..



payfonez> telnet ftp.netscape.com 21



Trying 207.200.74.26...



Connected to ftp.netscape.com.



Escape character is '^]'.



220 ftp29 FTP server (UNIX (r) System V release 4.0) ready.



SYST



215 UNIX Type : L8 Version : SUNOS



banner에는 system detail에 대한 내용이 들어있으며, SYST 명령어를 치면, 더 많은 정보를 물어다 준다. 즉 server에서 돌고 있는 여러 application들이 많은 정보를 스스럼 없이 잘 내어주고 있다.



이외에도 어떠한 프로그램들이 어떤 port에 깔려있는지.. 등.. package의 구성을 보고 OS를 추측할 수도 있다.



이와 같은 방법들은 모두 상용 OS checker에서 쓰이고 있는 방법이다.





---4.2 Finger Printing Methodology



finger print를 구현할 수 있는 엄청나게 많은 방법들이 존재하며, 여러 test들을 통해 대상이 되는 OS의 범위를 좁혀 나가는 것이 Fingerprinting 의 기본적인 idea이다. 이러한 방법을 통해서, Solaris 2.4 와 Solaris 2.5-2.51, Solaris 2.6 을 구분할 수 있으며 Linux의 경우 kernel 2.0.30, kernel 2.0.31-34, kernel 2.0.35-36 등을 구분할 수 있다.



------4.2.1 The FIN probe : 열려있는 port에 하나의 FIN packet ( 즉 SYN 이나 ACK flag가 없는 packet) 을 보내고 응답을 기다린다. RFC 793에 의해 옳은 반응은 응답을 하지 않는 것이나, MS Windows, BSDI, CISCO, HP/UX, MVS, IRIX등 약간 어긋나게 구현한 OS들은 이에 응답한다. 이방법은 대부분의 최근의 tool들이 사용한다.



------4.2.2 The BOGUS flag probe : SYN packet의 header에 정의되지 않은 64나 128 등의 TCP flag를 set한다. Linux 2.0.35 이전의 기계들은 이러한 flag set을 유지하면서 응답한다. 다른 OS중 이러한 반응을 보이는 것은 찾지 못했으나, SYN+BOGUS packet을 받은 경우 connection을 reset하는 OS들은 몇 개 있으며, 이 정보는 OS를 구분하는데 유용하게 쓰일 수 있다.



------4.2.3 TCP ISN Sampling : connection request의 응답내의 ISN(initial Sequencing Number)중의 pattern을 찾는다. 이 test에 따라 다음과 같은 group으로 나누어질 수 있는데, 64K rule (many old UNIX boxes), Random increments (newer versions of Solaris, IRIX, FreeBSD, Digital UNIX, Cray, and many others), True 'Random' (Linux 2.0.*, OpenVMS, newer AIX, etc..) 이렇게 구분되며 windows 같은 경우 ISN이 작은 시간 간격이 지나면 증가하는 time dependent한 model을 쓰고 있다. 이는 물론 64K rule과 마찬가지로, 쉽게 도용당할 수 있다. 또 ISN 이 항상 상수인 것도 있는데, 3Com hubs나 Apple LaserWriter등이 이러한 방식을 쓰고 있다. 또 Random increments는 다음의 group으로 나누어질 수 있는데, 이 increment가 computing variance, 최대공약수인가, 아니면 외부의 함수인가.. 등등으로 나누어질 수 있다. 이 ISN generation 은 Security에 있어서도 매우 중요하다. ... Spoofing



------4.2.4 Don't Fragment bit : 많은 OS들이 packet중 일부에 IP "Don't Fragment" bit을 set하기 시작했다. 이는 performance의 향상을 가져온다. (nmap의 fragmentation scan이 solaris에서 안되는 이유!) 어쨋든 모든 OS들이 이렇지는 않으므로 이것도 OS를 분류하는 하나의 수단이 될 수 있다.



------4.2.5 TCP Initial Window : 돌아온 packet의 window size를 check하는 방법이다. window size는 OS에 따라 다르며 거의 상수이다. 이 test는 상당히 많은 양의 정보를 제공해 준다. (일부의 OS는 단지 이 test만으로 구별할 수 있으므로)



------4.2.6 ACK Value : 이는 상당히 standard하게 보일지 몰라도, 실제로 구현된 것을 보면 OS에 따라 약간씩 다르다는 것을 알 수 있다. 예를 들어 닫힌 TCP port에 FIN|PSH|URG packet을 보낼 경우, 대부분의 경우, 보낸 것과 같은 ISN을 가진 ACK가 돌아올 것이다. 그러나, windows나 일부 printer들은 ISN+1 을 보내준다. 또 열린 port에 SYN|FIN|URG|PSH packet을 보낼 경우, windows는 매우 불안하게 반응한다. 보냈던 seq.num을 그대로 보내주거나, seq_num+1, 혹은 거의 random하게 보내준다.



------4.2.7 ICMP Error Message Quenching : 일부 똑똑한 OS들은 RFC 1812에 따라 여러 error message의 시간당 발생량에 제한을 둔다. 예를 들어 Linux같은 경우는 4초 내에 80개까지 정상적으로 보낼 수 있으며, 그 이후부터는 1/4초의 penalty가 적용된다. 이러한 반응을 test하는 방법으로는 많은 수의 packet을 저 위쪽의 UDP port로 보낸 후에 unreachable이 돌아온 갯수를 세는 것이 있다. 이 방법은 OS detection 과정을 지루하게 만들어 주며, 또 network상황이 안좋아 누락된 packet들까지 생각을 해 주어야 하므로 구현하는데 좀 어려움이 있다.



------4.2.8 ICMP Message Quoting : RFC문서들은 ICMP error message들이 error를 일으킨 ICMP message중의 일부를 인용하도록 규정하고 있다. 거의 모든 OS들은 딱 IP header + 8 bytes만을 보내는데 반해 Solaris는 좀 더 보내고 Linux는 Solaris보다 더 많이 보낸다. 이 사실이 매우 유용한 까닭은 Linux와 Solaris는 열린 port가 없어도, OS를 구분할 수 있기 때문이다.



------4.2.9 ICMP Error message echoing integrity : 위에서 말했듯이 기계는 port unreachable message와 함께 원래의 message를 같이 보내게 되어 있다. 그러나 어떠한 기종들은 이 header들을 "낙서장" 으로 사용하기 때문에, 이 original message는 좀 변형되어서 돌아오게 된다. 예를 들어, AIX, BSDI기종들은 IP total length field를 보내게 되며 이는 data보다 20bytes 정도 틀려있다. 그리고 약간의 BSDI, FreeBSD, ULTRIX, VAXen IP ID를 날려 버린다. checksum은 TTL이 달라질므로 약간 달라지기는 하지만, AIX나 FreeBSD등은 0이나 엉뚱한 checksum을 보내온다. UDP의 경우도 마찬가지이다. 전부 합쳐서 nmap은 9개의 test를 수행한다.



------4.2.10 Type of Service : ICMP port unreachable packet의 TOS value가 어떻게 set되어 있는가를 보는 것은 미래를 위한 test이다. 거의 모든 기종들이 ICMP error에 0을 사용하고 LINUX는 0xC0 을 사용한다. 물론 이는 standard한 TOS는 아니지만, 쓰이지 않은 AFAIK precedence field이다. 왜 이런 이렇게 set되어있는지는 모르겠지만, 만약 이것을 0으로 고친다면 나중에 구 version과 신 version을 구별할 수 있을 것이다.



------4.2.11 TCP options : TCP option은 정보의 바다이다. 이를 통해 정말 많은 정보를 얻을 수 있다. 이 option의 좋은 점은



- TCP option은 단순히 option이며 따라서 모든 host들이 이를 구현하고 있지는 않다.



- target host가 option을 구현하는지의 여부는 option set과 함께 query를 보내면, 이 target은 option 지원 여부를 reponse에 option을 set해서 보낸다. .. option을 지원하는지 쉽게 알 수 있다.



- 한 packet에 option들을 모두 넣어 보내서 한번에 모든 것을 test할 수 있다.



Nmap은 다음과 같은 option을 거의 모든 패켓에 넣어 보낸다.



Windows Scale=10; NOP; Max Segment Size = 256; Timestamp; End of Ops;



reponse가 오면 target기종이 어떤 option을 지원하는가 쉽게 알 수 있다. 그 뿐만이 아니라, 만약 여러 OS가 같은 option들을 지원한다고 해도 option의 값들을 가지고 OS들을 구분할 수 있다. 예를 들어 Linux에 MSS값을 보내면 같은 MSS값이 echo되서 돌아오지만, 다른 OS의 경우 다른 값을 주게 된다. 또 같은 option을 지원하고 같은 값들을 가져도 이 option들이 배치된 순서에 따라서 OS들을 구별할 수 있다. 예를 들어 Solaris는 'NNTNWME'와 같이 return하는데.. 이를 보면,







의 순서로 return되었음을 안다. 그러나 LInux 2.1.122같은 경우 같은 option은 지원하고, 값들도 다 똑같기는 한데, 다른 순서 즉, 'MENNTNW'를 return한다.



이 방법은 상당히 유용하며 Nmap에서만 구현된 기능이다.



------4.2.12 Windows? : 신기하게 위의 과정을 모두 거쳐도 windows 95/98, nt는 구별할 수 없다. 이는 매우 놀라운 사실이다. win98은 95보다 4년후에 나왔다.. (다른 OS와 비교해보라.) NT도 마찬가지 이다. NT의 tcp/ip stack은 win95의 겻이랑 똑같다.. -_- 그러나 희망을 버리지 말자.. 이들을 구별할 수 있는 방법이 있다. 초기의 windows attack부터 시작하는 것이다. (Ping of Death.. Winnuke, etc) attack후에 host를 ping해보고 안죽어 있으면 더 최근의 공격을 해보고.. 그리고 나서 어떤 특정 공격에 죽었다면 그로부터 windows의 version과 service pack 번호까지 알 수 있게 된다.





---4.3 OS Fingerprint Example



그렇다면 실제로 어떤 정보를 기반으로 OS를 판별하는지 알아보자.



Nmap의 경우 각종 OS들의 fingerprint들을 프로그램 바깥에 위치시켜서 새로운 정보의 추가, 수정등이 간편하게 되었다. 다음은 Irix 6.2 - 6.4의 fingerprint이다.



FingerPrint IRIX 6.2 - 6.4 # Thanks to Lamont Granquist



TSeq(Class=i800)



T1(DF=N%W=C000|EF2A%ACK=S++%Flags=AS%Ops=MNWNNT)



T2(Resp=Y%DF=N%W=0%ACK=S%Flags=AR%Ops=)



T3(Resp=Y%DF=N%W=C000|EF2A%ACK=O%Flags=A%Ops=NNT)



T4(DF=N%W=0%ACK=O%Flags=R%Ops=)



T5(DF=N%W=0%ACK=S++%Flags=AR%Ops=)



T6(DF=N%W=0%ACK=O%Flags=R%Ops=)



T7(DF=N%W=0%ACK=S%Flags=AR%Ops=)



PU(DF=N%TOS=0%IPLEN=38%RIPTL=148%RID=E%RIPCK=E%UCK=E%ULEN=134%DAT=E)



그럼 한줄한줄 살펴보자. ( > 는 이용된 구절.)



FingerPrint IRIX 6.2 - 6.4 # Thanks to Lamont Granquist



이 구절은 이 아래 9줄은 IRIX 6.2-6.4의 fingerprint이며, Lamont Granquist가 친절하게 이 OS를 운영하는 host의 IP를 알려주었거나 직접 fingerprint를 보내주었음을 뜻한다.



TSeq(Class=i800)



이 기종은 ISN sampling 결과 i800 class 임을 뜻한다. 이 class는 각각의 새로운 seq. num이 직전의 seq. num보다 800의 배수만큼 큼을 뜻한다.



T1(DF=N%W=C000|EF2A%ACK=S++%Flags=AS%Ops=MNWNNT)



이는 test 1을 따서 T1로 명명되었다. 이 test에서는 많은 TCP option을 setting한 SYN packet을 열린 port에 보낸다. 괄호 안의 DF=N은 response의 'don't fragment' bit이 set되면 안됨을 뜻한다. W=C000|EF2A는 reponse의 window advertisement값이 0xC000이나 EF2A이어야 함을 뜻한다. ACK=S++는 response의 ACK값이 우리가 보낸 ISN값에 1을 더한 수가 되어야 함을 뜻한다. Flags=AS는 response에 ACK나 SYN flag가 set되어 있어야 함을 뜻하고, Ops=MNWNNT는 response의 option이 다음과 같이 배열되어 있음을 뜻한다.







T2(Resp=Y%DF=N%W=0%ACK=S%Flags=AR%Ops=)



test 2는 open port에 NULL packet을 위와 같은 option을 주고 보낸 경우를 뜻한다. Resp=Y는 response가 있음을 뜻한다. Ops=는 response에 어떠한 option도 set되어 있으면 안됨을 뜻한다. 만약 '%Ops=' 를 없앤다면, response에 어떠한 option이 set되어있어도 상관없음을 뜻한다.



T3(Resp=Y%DF=N%W=C000|EF2A%ACK=O%Flags=A%Ops=NNT)



test 3은 open port에 SYN|FIN|URG|PSH w/options packet을 보낸 경우의 response를 나타낸다.



T4(DF=N%W=0%ACK=O%Flags=R%Ops=)



test 4는 open port에 ACK packet을 보낸 경우를 뜻한다. 여기에 'Resp=' 가 없음에 주목하자.. 즉 response가 누락되어서 T3이 false로 나타나도 다른 결과가 true일 경우 이 기종임을 인정한다는 뜻이다. 이는 물론 network의 상황을 고려한 것이지만, T2, T3에 Resp=Y가 있는 이유는 일부의 OS는 위 packet에 대해 response를 하지 않기 때문에 이들을 걸러내야 하는 것이다.



T5(DF=N%W=0%ACK=S++%Flags=AR%Ops=)



T6(DF=N%W=0%ACK=O%Flags=R%Ops=)



T7(DF=N%W=0%ACK=S%Flags=AR%Ops=)



위의 test는 closed port에 SYN, ACK, FIN|PSH|URG packet을 보냈을 때의 결과이다. 모든 option은 set된 상태이다.



PU(DF=N%TOS=0%IPLEN=38%RIPTL=148%RID=E%RIPCK=E%UCK=E%ULEN=134%DAT=E)



이 무식하게 덩치 큰 놈은 'port unreachable' message test이다. TOS=0은 type of service field가 0임을 뜻한다. 다음 두 field는 message IP header의 IP total length와 IP header의 total length를 echo해주는 값을 16진수로 나타낸 것이다. RID = E는 우리가 보냈던 message의 RID 값이 돌아온 message의 값과 같음을 나타낸다. RIPCK=E 는 돌아온 message의 checksum이 정상임을 뜻하고 만약 아니라면, RIPCK=F 라 나타낸다. UCK=E는 UDP의 checksum가 정확할 경우는 나타낸다. ULEN은 UDP의 크기가 0x134였음을, 또 DAT = E는 target의 기종이 우리가 보낸 UDP packet을 틀리지 않고 보냈음을 뜻한다.

댓글목록

등록된 댓글이 없습니다.