Tuesday, January 5, 2016

SANS Holiday Hack 2015-Part 3

Super Gnome 2
JoshW and Tim gave the hints about how to solve this part of the challenge. I found the vulnerable scripts in the gnome/www/routes/index.js file. The particular vulnerability in this gnome was in the camera viewer. It allowed for a local file inclusion. There were two problems: One) The attacker had to bypass the extension check. Two) The attacker had to target a directory that they had permission to access.

Cam Viewer Code:
router.get('/cam', function(req, res, next) {
var camera = unescape(req.query.camera);
// check for .png
//if (camera.indexOf('.png') == -1) // STUART: Removing this...I think this is a better solution... right?
camera = camera + '.png'; // add .png if its not found
console.log("Cam:" + camera);
fs.access('./public/images/' + camera, fs.F_OK | fs.R_OK, function(e) {

if (e) {
res.end('File ./public/images/' + camera + ' does not exist or access denied!');

} });
fs.readFile('./public/images/' + camera, function (e, data) { res.end(data);
}); });

Tim gave the hint that LFI's are useful with file upload features. I looked at the settings upload code. The settings upload code allows me to make a directory. It is also supposed to accept a file, but this code is broken. The directory is made, however, the file is not really uploaded. In this case, the attacker has to get out of the /gnome/www/public/upload/<new random directory> directories.

Settings Upload Code:
router.post('/settings', function(req, res, next) {
if (sessions[sessionid].logged_in === true && sessions[sessionid].user_level > 99) { // AUGGIE:

settings upload allowed for admins (admins are 100, currently)
var filen = req.body.filen;
var dirname = '/gnome/www/public/upload/' + newdir() + '/' + filen; var msgs = [];
var free = 0;
disk.check('/', function(e, info) {

free = info.free; });
try {
fs.mknewdir(dirname.substr(0,dirname.lastIndexOf('/')));
msgs.push('Dir ' + dirname.substr(0,dirname.lastIndexOf('/')) + '/ created successfully!');
} catch(e) {
if (e.code != 'EEXIST')

throw e; }
if (free < 99999999999) { // AUGGIE: I think this is breaking uploads? Stuart why did you set this so high?
msgs.push('Insufficient space! File creation error!'); }
res.msgs = msgs;
next(); } else
res.render('index', { title: 'GIYH::ADMIN PORT V.01', session: sessions[sessionid], res: res }); });
In order to exploit the LFI, the attacker had to make a directory named .png. It can be done because hidden directories/files in Linux are started with a “.”. The file upload adds a random directory. All the attacker had to do was to make note of the directory structure and use “../”'s to move out of the unnecessary directories. The attacker could use trial and error until they got the file that they wanted. The directory that worked for me was:

http://52.34.3.80/cam?camera=../../../../../../../gnome/www/public/upload/LUbQRcPB/abcde/bob.png/../../../../../../../gnome/www/files/gnome.conf

This on also worked for me. (I lost the config file and had to re-exploit it.)

http://52.34.3.80/cam? camera=../../../../../../../gnome/www/public/upload/sCzEsNoM//.png/../../../../../../../gnome/www/files/gnome.conf

E-Mail 2
Maratha,
As a follow-up to our phone conversation, we'd like to proceed with an order of parts for our upcoming product line. We'll need two million of each of the following components:
+ Ambarella S2Lm IP Camera Processor System-on-Chip (with an ARM Cortex A9 CPU and Linux SDK)
+ ON Semiconductor AR0330: 3 MP 1/3" CMOS Digital Image Sensor + Atheros AR6233X Wi-Fi adapter
+ Texas Instruments TPS65053 switching power supply


+ Samsung K4B2G16460 2GB SSDR3 SDRAM + Samsung K9F1G08U0D 1GB NAND Flash
Given the volume of this purchase, we fully expect the 35% discount you mentioned during our phone discussion. If you cannot agree to this pricing, we'll place our order elsewhere.
We need delivery of components to begin no later than April 1, 2015, with 250,000 units coming each week, with all of them arriving no later than June 1, 2015.

Finally, as you know, this project requires the utmost secrecy. Tell NO ONE about our order, especially any nosy law enforcement authorities.
Regards, -CW

Super Gnome 3

The vulnerable code for Super Gnome 3 is in the login code.

router.post('/', function(req, res, next) { var db = req.db;
var msgs = [];

{db.get('users').findOne({username: req.body.username, password: req.body.password}, function (err,
user)});
 // STUART: Removed this in favor of below. Really guys? //db.get('users').findOne({username: (req.body.username || "").toString(10), password:
(req.body.password || "").toString(10)}, function (err, user) { // LOUISE: allow passwords longer than 10 chars
if (err || !user) {
console.log('Invalid username and password: ' + req.body.username + '/' + req.body.password); msgs.push('Invalid username or password!');
res.msgs = msgs;
res.render('index', { title: 'GIYH::ADMIN PORT V.01', session: sessions[req.cookies.sessionid],

res: res }); } else {
sessionid = gen_session();
sessions[sessionid] = { username: user.username, logged_in: true, user_level: user.user_level }; console.log("User level:" + user.user_level);
res.cookie('sessionid', sessionid);
res.writeHead(301,{ Location: '/' });
res.end();

} });

The hint given to exploit this vulnerability was given by Dan. The answer to this challenge was found in Petko D. Petkov’s article on MongoDB injection. The difference between his example and this problem was that he used the “find” parameter in the database query, and not the “findOne” parameter. The difference between “find” and “findOne” is that “find” returns more than one record. “findOne” only returns one record. The problem with this query is that it allows not only strings to be sent to the database, but objects as well. I can change the nature of the query so that either the username or the password evaluates to true, meaning that I don't need a password. However, just because I'm logged in does not mean that I have admin privileges. I could also specify a particular username. So, If I for instance, specify “admin” and have the password return “true”, then I can log in as an admin without a password. The problem is finding the administrator user name. It is not always, “Administrator” or “Admin”. In this case, the username was “admin”. I typed the Content-Type:application/json in the POST query headers. I typed the following query into the body of the POST query. I actually kept getting error messages using Burp suite. I had the right idea, but I had to try the exploit more than once.
{"username": "admin","password": {"$gt": ""}}

E-Mail 3

From: "c" <c@atnascorp.com>
To: <burglerlackeys@atnascorp.com>
Subject: All Systems Go for Dec 24, 2015
Date: Tue, 1 Dec 2015 11:33:56 -0500
Message-ID: <005501d12c56$12bf6dc0$383e4940$@atnascorp.com> MIME-Version: 1.0
Content-Type: multipart/alternative; .boundary="----=_NextPart_000_0056_01D12C2C.29E9B3E0" X-Mailer: Microsoft Outlook 15.0
Thread-Index: AdEsVeghqBzCbZs7SUyM8aoCkrx6Ow== Content-Language: en-us

This is a multipart message in MIME format.
------=_NextPart_000_0056_01D12C2C.29E9B3E0 Content-Type: text/plain;
.charset="us-ascii"
Content-Transfer-Encoding: 7bit

My Burgling Friends,
Our long-running plan is nearly complete, and I'm writing to share the date
when your thieving will commence! On the morning of December 24, 2015, each individual burglar on this email list will receive a detailed itinerary of
specific houses and an inventory of items to steal from each house, along


with still photos of where to locate each item. The message will also include a specific path optimized for you to hit your assigned houses quickly and efficiently the night of December 24, 2015 after dark.
Further, we've selected the items to steal based on a detailed analysis of
what commands the highest prices on the hot-items open market. I caution you - steal only the items included on the list. DO NOT waste time grabbing anything else from a house. There's no sense whatsoever grabbing crumbs too small for a mouse!

As to the details of the plan, remember to wear the Santa suit we provided you, and bring the extra large bag for all your stolen goods.
If any children observe you in their houses that night, remember to tell them that you are actually "Santy Claus", and that you need to send the specific items you are taking to your workshop for repair. Describe it in a very friendly manner, get the child a drink of water, pat him or her on the head, and send the little moppet back to bed. Then, finish the deed, and get out of there. It's all quite simple - go to each house, grab the loot,
and return it to the designated drop-off area so we can resell it. And, above all, avoid Mount Crumpit!
As we agreed, we'll split the proceeds from our sale 50-50 with each burglar.
Oh, and I've heard that many of you are asking where the name ATNAS comes from. Why, it's reverse SANTA, of course. Instead of bringing presents on Christmas, we'll be stealing them!
Thank you for your partnership in this endeavor. Signed:
-CLW
President and CEO of ATNAS Corporation 

No comments:

Post a Comment