rest - Dave's Blog


Search

Quadrilateral Cowboy gameplay video "Quadrilateral Cowboy is a...

16 days ago


Quadrilateral Cowboy gameplay video

"Quadrilateral Cowboy is a game we’ve been watching with great interest ever since Thirty Flights Of Loving creator Brendon Chung first debuted it last year. It’s about hacking, but not via irritating minigames or jargon-your-problems-away Hollywood magic. Instead, you learn basic (albeit fictional) code and take down everything from laser grids to gun emplacements with a twitch of your fingers and a wriggle of your brain. It’s already an extremely clever game, and it’s quite empowering despite the fact that you play as someone who probably couldn’t even heft an assault rifle - let alone fire one. Basically, it’s a wonderfully novel idea - more Neuromancer than Deus Ex - but words only do it so much justice. Thus, I’ve decided to play it for your enrichment, in hopes that you will understand why Quadrilateral should be driving your radar haywire."

PermalinkCommentsgame video-game hack computer

Detect login with CSP - When Security Generates Insecurity

Jul 8, 1:13

An interesting way to use the report-uri feature of CSP to detect if a user is logged into Google, Facebook etc.

PermalinkCommentstechnical security csp web

Houston, We Have A Public Domain Problem

Jun 24, 3:18

A bogus SoundCloud takedown anecdote and a brief history of and issues with US copyright law.

Another reminder that the rest of the Western world has a public domain day every year in which new IP enters the public domain

PermalinkCommentslaw copyright

ios - Capture image via captureStillImageAsynchronouslyFromConnection with no shutter sound - Stack Overflow

May 24, 2:42

The best hack I’ve seen in a while. With no way to disable the shutter sound from the capture photo API, the developer creates the inverse waveform of the shutter sound and plays it at the same time to cancel out the shutter sound.

PermalinkCommentstechnical humor ios photo sound

Debugging anecdote - the color transparent black breaks accessibility

May 22, 10:36

Some time back while I was working on getting the Javascript Windows Store app platform running on Windows Phone (now available on the last Windows Phone release!) I had an interesting bug that in retrospect is amusing.

I had just finished a work item to get accessibility working for JS WinPhone apps when I got a new bug: With some set of JS apps, accessibility appeared to be totally broken. At that time in development the only mechanism we had to test accessibility was a test tool that runs on the PC, connects to the phone, and dumps out the accessibility tree of whatever app is running on the phone. In this bug, the tool would spin for a while and then timeout with an error and no accessibility information.

My first thought was this was an issue in my new accessibility code. However, debugging with breakpoints on my code I could see none of my code was run nor the code that should call it. The code that called that code was a more generic messaging system that hit my breakpoints constantly.

Rather than trying to work backward from the failure point, I decided to try and narrow down the repro and work forwards from there. One thing all the apps with the bug had in common was their usage of WinJS, but not all WinJS apps demonstrated the issue. Using a binary search approach on one such app I removed unrelated app code until all that was left was the app's usage of the WinJS AppBar and the bug still occurred. I replaced the WinJS AppBar usage with direct usage of the underlying AppBar WinRT APIs and continued.

Only some calls to the AppBar WinRT object produced the issue:

        var appBar = Windows.UI.WebUI.Core.WebUICommandBar.getForCurrentView(); 
// appBar.opacity = 1;
// appBar.closeDisplayMode = Windows.UI.WebUI.Core.WebUICommandBarClosedDisplayMode.default;
appBar.backgroundColor = Windows.UI.Colors.white; // Bug!
Just setting the background color appeared to cause the issue and I didn't even have to display the AppBar. Through additional trial and error I was blown away to discover that some colors I would set caused the issue and other colors did not. Black wouldn't cause the issue but transparent black would. So would aqua but not white.

I eventually realized that predefined WinRT color values like Windows.UI.Colors.aqua would cause the issue while JS literal based colors didn't cause the issue (Windows.UI.Color is a WinRT struct which projects in JS as a JS literal object with the struct members as JS object properties so its easy to write something like {r: 0, g: 0, b: 0, a: 0} to make a color) and I had been mixing both in my tests without realizing there would be a difference. I debugged into the backgroundColor property setter that consumed the WinRT color struct to see what was different between Windows.UI.Colors.black and {a: 1, r: 0, g: 0, b: 0} and found the two structs to be byte wise exactly the same.

On a hunch I tried my test app with only a reference to the color and otherwise no interaction with the AppBar and not doing anything with the actual reference to the color: Windows.UI.Colors.black;. This too caused the issue. I knew that the implementation for these WinRT const values live in a DLL and guessed that something in the code to create these predefined colors was causing the issue. I debugged in and no luck. Now I also have experienced crusty code that would do exciting things in its DllMain, the function that's called when a DLL is loaded into the process so I tried modifying my C++ code to simply LoadLibrary the DLL containing the WinRT color definition, windows.ui.xaml.dll and found the bug still occurred! A short lived moment of relief as the world seemed to make sense again.

Debugging into DllMain nothing interesting happened. There were interesting calls in there to be sure, but all of them behind conditions that were false. I was again stumped. On another hunch I tried renaming the DLL and only LoadLibrary'ing it and the bug went away. I took a different DLL renamed it windows.ui.xaml.dll and tried LoadLibrary'ing that and the bug came back. Just the name of the DLL was causing the issue.

I searched for the DLL name in our source code index and found hits in the accessibility tool. Grinning I opened the source to find that the accessibility tool's phone side service was trying to determine if a process belonged to a XAML app or not because XAML apps had a different accessibility contract. It did this by checking to see if windows.ui.xaml.dll was loaded in the target process.

At this point I got to fix my main issue and open several new bugs for the variety of problems I had just run into. This is a how to on writing software that is difficult to debug.

PermalinkCommentsbug debug javascript JS technical windows winrt

The Doritos origin story: Repurposed garbage from Disneyland

May 6, 7:16

shortformblog:

A reminder that those Doritos you love are trash:

Shortly after Disneyland opened in 1955, the founder of Frito-Lay got permission from Walt Disney to open a restaurant in Frontierland with a Mexican-ish theme. “Casa de Fritos” was, unsurprisingly, all about the Fritos. Customers got free Fritos, and Fritos were incorporated into many of the dishes. Fritos were dispensed by an animatronic vending machine that featured the terrifying “Frito Kid”asking his assistant “Klondike” to bring the bag up from a mineshaft. I guess the conceit is that Fritos were mined by Forty-Niners?

Casa de Fritos contracted their tortilla production to a company called Alex Foods. One of the salesmen from Alex Foods, making a delivery to Casa de Fritos, noticed stale tortillas in the garbage and gave the cook a little tip: fry them and sell them as chips instead of throwing them away. Casa de Fritos began making these fried, seasoned chips to enormous success, but didn’t report this new menu item to the Frito-Lay company.

Eventually Frito-Lay found out what they were doing with the chips, packaged them, and sold them by the truckload. See, dumpster diving works out sometimes!

PermalinkComments

laughingsquid: F.A.A. Lifts Restrictions on Electronics During...

2013 Oct 31, 4:57


laughingsquid:

F.A.A. Lifts Restrictions on Electronics During All Phases of Flight

PermalinkCommentsflight plane electronics faa

Percent Clcok Windows Store App Development Notes

2013 Jul 11, 1:00

My third completed Windows Store app is Percent Clock which displays portions of a time span like the time of the day or time until your next birthday, as a percentage. This was a small project I had previously started as a webpage and converted and finished as an HTML JavaScript Windows Store app.

The only somewhat interesting aspect of this app is that its the first app for which I tried charging. I picked the minimum amount for price 1.49 USD as it is a simple app and unsurprisingly it has sold very poorly. I'm considering releasing new instances of the app for specific scenarios:

  • Death Clock: viewing your current age with respect to your life expectancy as a percentage.
  • New Year Countdown: percentage of the year until New Years.
PermalinkCommentsdevelopment javascript technical windows windows-store

Shout Text Windows 8 App Development Notes

2013 Jun 27, 1:00

My first app for Windows 8 was Shout Text. You type into Shout Text, and your text is scaled up as large as possible while still fitting on the screen, as you type. It is the closest thing to a Hello World app as you'll find on the Windows Store that doesn't contain that phrase (by default) and I approached it as the simplest app I could make to learn about Windows modern app development and Windows Store app submission.

I rely on WinJS's default layout to use CSS transforms to scale up the user's text as they type. And they are typing into a simple content editable div.

The app was too simple for me to even consider using ads or charging for it which I learned more about in future apps.

The first interesting issue I ran into was that copying from and then pasting into the content editable div resulted in duplicates of the containing div with copied CSS appearing recursively inside of the content editable div. To fix this I had to catch the paste operation and remove the HTML data from the clipboard to ensure only the plain text data is pasted:

        function onPaste() {
var text;

if (window.clipboardData) {
text = window.clipboardData.getData("Text").toString();
window.clipboardData.clearData("Html");
window.clipboardData.setData("Text", util.normalizeContentEditableText(text));
}
}
shoutText.addEventListener("beforepaste", function () { return false; }, false);
shoutText.addEventListener("paste", onPaste, false);

I additionally found an issue in IE in which applying a CSS transform to a content editable div that has focus doesn't move the screen position of the user input caret - the text is scaled up or down but the caret remains the same size and in the same place on the screen. To fix this I made the following hack to reapply the current cursor position and text selection which resets the screen position of the user input caret.

        function resetCaret() {
setTimeout(function () {
var cursorPos = document.selection.createRange().duplicate();
cursorPos.select();
}, 200);
}

shoutText.attachEvent("onresize", function () { resetCaret(); }, true);
PermalinkCommentsdevelopment html javascript shout-text technical windows windows-store

laughingsquid: Arrested Development Season 4 Trailer Brings...

2013 May 13, 2:47


laughingsquid:

Arrested Development Season 4 Trailer Brings Back the Dysfunctional Bluth Family

Come on!

PermalinkCommentshumor trailer arrested-development awesome

Will Arnett Explains the Origins of His Arrested Development Chicken Dance

2013 May 8, 11:26

thebluthcompany:

To decide what Gob’s bad impression of a chicken might be, Arnett consulted on set in 2003 with series executive producers Mitch Hurwitz and James Vallely. They all tried out different versions for each other. “Jimmy started doing a little bit, then Mitch got up and did some, and then I began trying things,” remembers Arnett. “Picture three grown men hopping around, working out what it would be … They were pitching this really taunting dance, but I wanted to give it this very sharp, almost roosterlike, chest-sticking-out mannerism, like a real macho bravado dance.” And how did clapping get introduced to the move? “Because I wanted it to be only sort of threatening.”

Read More | Vulture

PermalinkCommentshumor chicken chicken-dance arrested-development

Stripe CTF - Level 8

2012 Dec 7, 2:07
Level 8 of the Stripe CTF is a password server that returns success: true if and only if the password provided matches the password stored directly via a RESTful API and optionally indirectly via a callback URI. The solution is side channel attack like a timing attack but with ports instead of time.

(I found this in my drafts folder and had intended to post a while ago.)

Code

    def nextServerCallback(self, data):
parsed_data = json.loads(data)
# Chunk was wrong!
if not parsed_data['success']:
# Defend against timing attacks
remaining_time = self.expectedRemainingTime()
self.log_info('Going to wait %s seconds before responding' %
remaining_time)
reactor.callLater(remaining_time, self.sendResult, False)
return

self.checkNext()

Issue

The password server breaks the target password into four pieces and stores each on a different server. When a password request is sent to the main server it makes requests to the sub-servers for each part of the password request. It does this in series and if any part fails, then it stops midway through. Password requests may also be made with corresponding URI callbacks and after the server decides on the password makes an HTTP request on the provided URI callbacks saying if the password was success: true or false.
A timing attack looks at how long it took for a password to be rejected and longer times could mean a longer prefix of the password was correct allowing for a directed brute force attack. Timing attacks are prevented in this case by code on the password server that attempts to wait the same amount of time, even if the first sub-server responds with false. However, the server uses sequential outgoing port numbers shared between the requests to the sub-servers and the callback URIs. Accordingly, we can examine the port numbers on our callback URIs to direct a brute force attack.
If the password provided is totally incorrect then the password server will contact one sub-server and then your callback URI. So if you see the remote server's port number go up by two when requesting your callback URI, you know the password is totally incorrect. If by three then you know the first fourth of the password is correct and the rest is incorrect. If by four then two fourths of the password is correct. If by five then four sub-servers were contacted so you need to rely on the actual content of the callback URI request of 'success: true' or 'false' since you can't tell from the port change if the password was totally correct or not.
The trick in the real world is false positives. The port numbers are sequential over the system, so if the password server is the only thing making outgoing requests then its port numbers will also be sequential, however other things on the system can interrupt this. This means that the password server could contact three sub-servers and normally you'd see the port number increase by four, but really it could increase by four or more because of other things running on the system. To counteract this I ran in cycles: brute forcing the first fourth of the password and removing any entry that gets a two port increase and keeping all others. Eventually I could remove all but the correct first fourth of the password. And so on for the next parts of the password.
I wrote my app to brute force this in Python. This was my first time writing Python code so it is not pretty.
PermalinkCommentsbrute-force password python side-channel technical web

thebluthcompany: Hey, guys, remember this? Please don’t forget...

2012 Nov 7, 6:06




thebluthcompany:

Hey, guys, remember this?

Please don’t forget to go out and vote! Find you polling place here.


Voting complete. Now we get more Arrested Development.

PermalinkCommentshumor vote election obama arrested-development

Attention:!!!, Behold, you are reading a letter from your President Barack Obama.

2012 Sep 26, 2:43

Eric gets the most entertaining mail.

You have failed to comply with them after all the warning and instructions given to you, but since you are also among the terrorist we are facing in the country, I will personal make sure that I wipe away the crime in the state and I promise you that you will definitely pay with your life because I am here to protect the interest of my people and not to put them in shame, you suppose to support this government and not to spoil it.

PermalinkCommentshumor spam scam email eric-law

The Lucille Bluth/Mitt Romney Tumblr confirms that saying awful rich person things is all about context

2012 Sep 24, 7:33

Mitt Romney quotes on screen shots of Lucille from Arrested Development works surprisingly well.

PermalinkCommentshumor arrested-development mitt-Romney politics

theatlantic: How the 8.5” x 11” Piece of Paper Got Its...

2012 Sep 19, 6:37


theatlantic:

How the 8.5” x 11” Piece of Paper Got Its Size

Why do we use a paper size that is so unfriendly for the basic task of reading? According to a very interesting post by Paul Stanley, the rough dimensions of office paper evolved to accommodate handwriting and typewriters with monospaced fonts, both of which rendered many fewer characters per line. “Typewriters,” he explains, “produced 10 or 12 characters per inch: so on (say) 8.5 inch wide paper, with 1 inch margins, you had 6.5 inches of type, giving … around 65 to 78 characters.” This, he says, is “pretty close to ideal.”

Read more. [Image: Picsfive/Shutterstock]

PermalinkCommentstechnical paper history

Stripe CTF - Level 7

2012 Sep 13, 5:00

Level 7 of the Stripe CTF involved running a length extension attack on the level 7 server's custom crypto code.

Code

@app.route('/logs/')
@require_authentication
def logs(id):
rows = get_logs(id)
return render_template('logs.html', logs=rows)

...

def verify_signature(user_id, sig, raw_params):
# get secret token for user_id
try:
row = g.db.select_one('users', {'id': user_id})
except db.NotFound:
raise BadSignature('no such user_id')
secret = str(row['secret'])

h = hashlib.sha1()
h.update(secret + raw_params)
print 'computed signature', h.hexdigest(), 'for body', repr(raw_params)
if h.hexdigest() != sig:
raise BadSignature('signature does not match')
return True

Issue

The level 7 web app is a web API in which clients submit signed RESTful requests and some actions are restricted to particular clients. The goal is to view the response to one of the restricted actions. The first issue is that there is a logs path to display the previous requests for a user and although the logs path requires the client to be authenticatd, it doesn't restrict the logs you view to be for the user for which you are authenticated. So you can manually change the number in the '/logs/[#]' to '/logs/1' to view the logs for the user ID 1 who can make restricted requests. The level 7 web app can be exploited with replay attacks but you won't find in the logs any of the restricted requests we need to run for our goal. And we can't just modify the requests because they are signed.

However they are signed using their own custom signing code which can be exploited by a length extension attack. All Merkle–Damgård hash algorithms (which includes MD5, and SHA) have the property that if you hash data of the form (secret + data) where data is known and the length but not content of secret is known you can construct the hash for a new message (secret + data + padding + newdata) where newdata is whatever you like and padding is determined using newdata, data, and the length of secret. You can find a sha-padding.py script on VNSecurity blog that will tell you the new hash and padding per the above. With that I produced my new restricted request based on another user's previous request. The original request was the following.

count=10&lat=37.351&user_id=1&long=%2D119.827&waffle=eggo|sig:8dbd9dfa60ef3964b1ee0785a68760af8658048c
The new request with padding and my new content was the following.
count=10&lat=37.351&user_id=1&long=%2D119.827&waffle=eggo%80%02%28&waffle=liege|sig:8dbd9dfa60ef3964b1ee0785a68760af8658048c
My new data in the new request is able to overwrite the waffle parameter because their parser fills in a map without checking if the parameter existed previously.

Notes

Code review red flags included custom crypto looking code. However I am not a crypto expert and it was difficult for me to find the solution to this level.

PermalinkCommentshash internet length-extension security sha1 stripe-ctf technical web

Stripe CTF - Input validation (Levels 1 & 2)

2012 Sep 6, 5:00

Stripe's web security CTF's Level 1 and level 2 of the Stripe CTF had issues with missing input validation solutions described below.

Level 1

Code

          $filename = 'secret-combination.txt';
extract($_GET);
if (isset($attempt)) {
$combination = trim(file_get_contents($filename));
if ($attempt === $combination) {

Issue

The issue here is the usage of the extract php method which extracts name value pairs from the map input parameter and creates corresponding local variables. However this code uses $_GET which contains a map of name value pairs passed in the query of the URI. The expected behavior is to get an attempt variable out, but since no input validation is done I can provide a filename variable and overwrite the value of $filename. Providing an empty string gives an empty string $combination which I can match with an empty string $attempt. So without knowing the combination I can get past the combination check.

Notes

Code review red flag in this case was the direct use of $_GET with no validation. Instead of using extract the developer could try to extract specifically the attempt variable manually without using extract.

Level 2

Code

    $dest_dir = "uploads/";
$dest = $dest_dir . basename($_FILES["dispic"]["name"]);
$src = $_FILES["dispic"]["tmp_name"];
if (move_uploaded_file($src, $dest)) {
$_SESSION["dispic_url"] = $dest;
chmod($dest, 0644);
echo "

Successfully uploaded your display picture.

";
}

Issue

This code accepts POST uploads of images but with no validation to ensure it is not an arbitrary file. And even though it uses chmod to ensure the file is not executable, things like PHP don't require a file to be executable in order to run them. Accordingly, one can upload a PHP script, then navigate to that script to run it. My PHP script dumped out the contents of the file we're interested in for this level:


Notes

Code review red flags include manual file management, chmod, and use of file and filename inputs without any kind of validation. If this code controlled the filename and ensured that the extension was one of a set of image extensions, this would solve this issue. Due to browser mime sniffing its additionally a good idea to serve a content-type that starts with "image/" for these uploads to ensure browsers treat these as images and not sniff for script or HTML.

PermalinkCommentsinput-validation php security technical

Stripe CTF - SQL injections (Levels 0 & 3)

2012 Sep 5, 9:10

Stripe's web security CTF's level 0 and level 3 had SQL injection solutions described below.

Level 0

Code

app.get('/*', function(req, res) {
var namespace = req.param('namespace');

if (namespace) {
var query = 'SELECT * FROM secrets WHERE key LIKE ? || ".%"';
db.all(query, namespace, function(err, secrets) {

Issue

There's no input validation on the namespace parameter and it is injected into the SQL query with no encoding applied. This means you can use the '%' character as the namespace which is the wildcard character matching all secrets.

Notes

Code review red flag was using strings to query the database. Additional levels made this harder to exploit by using an API with objects to construct a query rather than strings and by running a query that only returned a single row, only ran a single command, and didn't just dump out the results of the query to the caller.

Level 3

Code

@app.route('/login', methods=['POST'])
def login():
username = flask.request.form.get('username')
password = flask.request.form.get('password')

if not username:
return "Must provide username\n"

if not password:
return "Must provide password\n"

conn = sqlite3.connect(os.path.join(data_dir, 'users.db'))
cursor = conn.cursor()

query = """SELECT id, password_hash, salt FROM users
WHERE username = '{0}' LIMIT 1""".format(username)
cursor.execute(query)

res = cursor.fetchone()
if not res:
return "There's no such user {0}!\n".format(username)
user_id, password_hash, salt = res

calculated_hash = hashlib.sha256(password + salt)
if calculated_hash.hexdigest() != password_hash:
return "That's not the password for {0}!\n".format(username)

Issue

There's little input validation on username before it is used to constrcut a SQL query. There's no encoding applied when constructing the SQL query string which is used to, given a username, produce the hashed password and the associated salt. Accordingly one can make username a part of a SQL query command which ensures the original select returns nothing and provide a new SELECT via a UNION that returns some literal values for the hash and salt. For instance the following in blue is the query template and the red is the username injected SQL code:

SELECT id, password_hash, salt FROM users WHERE username = 'doesntexist' UNION SELECT id, ('5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8') AS password_hash, ('word') AS salt FROM users WHERE username = 'bob' LIMIT 1
In the above I've supplied my own salt and hash such that my salt (word) plus my password (pass) hashed produce the hash I provided above. Accordingly, by providing the above long and interesting looking username and password as 'pass' I can login as any user.

Notes

Code review red flag is again using strings to query the database. Although this level was made more difficult by using an API that returns only a single row and by using the execute method which only runs one command. I was forced to (as a SQL noob) learn the syntax of SELECT in order to figure out UNION and how to return my own literal values.

PermalinkCommentssecurity sql sql-injection technical web-security

Say goodbye to these!

2012 Aug 24, 1:52




Say goodbye to these!

PermalinkCommentshumor politics arrested-development
Older Entries Creative Commons License Some rights reserved.