hash page 3 - Dave's Blog

Search
My timeline on Mastodon

Retweet of davidhoang

2015 Jul 13, 11:34
Basically this. #EdgeCases pic.twitter.com/0ZPDUdJ5Fs
PermalinkComments

Retweet of wilshipley

2015 Jun 26, 5:47
Summary of Scalia’s dissent. #stolenjokes pic.twitter.com/Qp27BeWELc
PermalinkComments

Retweet of NSA_PR

2015 Apr 1, 2:23
#FreeSnowden #WithThePurchaseOfAMediumOrLargeDataCenter
PermalinkComments

Retweet of indiecom

2015 Mar 26, 1:33
"The best cyber film of the year!" -- Which year? Every year. #HackThePlanet #BeKindRewind pic.twitter.com/ZNCigxXgds
PermalinkComments

Retweet of RottenTomatoes

2015 Mar 24, 8:35
#iZombie is Certified Fresh at 91% ---> http://tmto.es/KsHyX  @iZombieWriters @RobThomas 🍅 #Tomatometer
PermalinkComments

Retweet of JustRogDigiTec

2015 Mar 18, 10:48
Xpath in #EdgeHTML using CSS selectors and WGX (Wicked Good XPath) http://blogs.msdn.com/b/ie/archive/2015/03/19/improving-interoperability-with-dom-l3-xpath.aspx … The tech here is amazing. #ICodeReviewedThat
PermalinkComments

Retweet of MrPooni

2015 Mar 7, 5:42
People only care about International Men's Day on International Women's Day (continued) #HappyWomensDay pic.twitter.com/vbipruBswJ
PermalinkComments

Retweet of industrial_book

2015 Mar 6, 6:11
Old war. New battlefield. #mathjoke pic.twitter.com/TvWxI0h8Xw
PermalinkComments

Retweet of pacohope

2015 Feb 25, 2:28
Stopped at the roadside for a #software update. Sigh. pic.twitter.com/wYWXkcnA91
PermalinkComments

Retweet of getify

2015 Feb 24, 6:25
Lots of questions about my #ES6 arrow functions assertions. Here's full context (and some cleanup/clarifications): https://github.com/getify/You-Dont-Know-JS/blob/master/es6%20%26%20beyond/ch2.md#arrow-functions …
PermalinkComments

Retweet of ThatJessePorter

2015 Feb 19, 8:27
Harris' Phone/Foam Corner is one of the best part of #ComedyBangBang. http://youtu.be/AweVgPJhVFQ  #RIPHarrisWittels
PermalinkComments

Retweet of shadowspar

2015 Feb 18, 3:33
"hey, is that a new Lenovo laptop you've got there?" "well, sort of. it's pre-owned." #superfish
PermalinkComments

Retweet of JustRogDigiTec

2015 Feb 12, 6:29
Historical note for #mshtml is that cells did Excel style col/row indexing. Either single A7, or range A7:C12, Try it http://jsfiddle.net/16xcvwag/1/ 
PermalinkComments

Retweet of ClickHole

2015 Jan 27, 7:47
This Will Change The Way You Watch ‘Fight Club’ http://www.clickhole.com/r/1803tsd  #NSFW pic.twitter.com/cnBwtF1QqC
PermalinkComments

location.hash and location.search are bad and they should feel bad

2014 May 22, 9:25
The DOM location interface exposes the HTML document's URI parsed into its properties. However, it is ancient and has problems that bug me but otherwise rarely show up in the real world. Complaining about mostly theoretical issues is why blogging exists, so here goes:
  • The location object's search, hash, and protocol properties are all misnomers that lead to confusion about the correct terms:
    • The 'search' property returns the URI's query property. The query property isn't limited to containing search terms.
    • The 'hash' property returns the URI's fragment property. This one is just named after its delimiter. It should be called the fragment.
    • The 'protocol' property returns the URI's scheme property. A URI's scheme isn't necessarily a protocol. The http URI scheme of course uses the HTTP protocol, but the https URI scheme is the HTTP protocol over SSL/TLS - there is no HTTPS protocol. Similarly for something like mailto - there is no mailto wire protocol.
  • The 'hash' and 'search' location properties both return null in the case that their corresponding URI property doesn't exist or if its the empty string. A URI with no query property and a URI with an empty string query property that are otherwise the same, are not equal URIs and are allowed by HTTP to return different content. Similarly for the fragment. Unless the specific URI scheme defines otherwise, an empty query or hash isn't the same as no query or hash.
But like complaining about the number of minutes in an hour none of this can ever change without huge compat issues on the web. Accordingly I can only give my thanks to Anne van Kesteren and the awesome work on the URL standard moving towards a more sane (but still working practically within the constraints of compat) location object and URI parsing in the browser.
PermalinkComments

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 - 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

Lifetimes of cryptographic hash functions

2011 Jun 20, 11:25A cautionary tale in chart form: lesson is make sure you can always upgrade your hashing algorithm or don't have security dependencies on hashing algorithms.PermalinkCommentsreference hash encryption security table technical humor

RFC 3797 - Publicly Verifiable Nominations Committee (NomCom) Random Selection

2010 Dec 13, 11:12Used to generate publicly verifiable random numbers. For instance to pick 'xn--' for the IDN prefix from a set of prefixes, they decided on a hash, a set of stocks and a time in the future to generate the hash from the stock values. The resulting value is random and anyone can check the work to verify that it was chosen randomly.


Although, now looking back from the future I can't verify that they didn't generate this data after the stock quotes came out. And they're using MD5...PermalinkCommentsrfc algorithm random election ietf technical

RFC 5854 - The Metalink Download Description Format

2010 Jun 1, 6:46"Metalink describes download locations (mirrors), cryptographic hashes, and other information. Clients can transparently use this information to reliably transfer files."PermalinkCommentstechnical internet download web url xml metalink
Older EntriesNewer Entries Creative Commons License Some rights reserved.