flag - Dave's Blog

Search
My timeline on Mastodon

Cdb/Windbg Commands for Runtime Patching

2016 Feb 8, 1:47

You can use conditional breakpoints and debugging commands in windbg and cdb that together can amount to effectively patching a binary at runtime. This can be useful if you have symbols but you can't easily rebuild the binary. Or if the patch is small and the binary requires a great deal of time to rebuild.

Skipping code

If you want to skip a chunk of code you can set a breakpoint at the start address of the code to skip and set the breakpoint's command to change the instruction pointer register to point to the address at the end of the code to skip and go. Voila you're skipping over that code now. For example:

bp 0x6dd6879b "r @eip=0x6dd687c3 ; g"

Changing parameters

You may want to modify parameters or variables and this is simple of course. In the following example a conditional breakpoint ANDs out a bit from dwFlags. Now when we run its as if no one is passing in that flag.

bp wiwi!RelativeCrack "?? dwFlags &= 0xFDFFFFFF;g"

Slightly more difficult is to modify string values. If the new string length is the same size or smaller than the previous, you may be able to modify the string value in place. But if the string is longer or the string memory isn't writable, you'll need a new chunk of memory into which to write your new string. You can use .dvalloc to allocate some memory and ezu to write a string into the newly allocated memory. In the following example I then overwrite the register containing the parameter I want to modify:

.dvalloc 100
ezu 000002a9`d4eb0000 "mfcore.dll"
r rcx = 000002a9`d4eb0000

Calling functions

You can also use .call to actually make new calls to methods or functions. Read more about that on the Old New Thing: Stupid debugger tricks: Calling functions and methods. Again, all of this can be used in a breakpoint command to effectively patch a binary.

PermalinkCommentscdb debug technical windbg

Retweet of brucel

2015 Sep 16, 8:24
There aren't many reasons I'd want to move to Switzerland, but the flag's a big plus. pic.twitter.com/oqo2SxANaC
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 - Level 5

2012 Sep 11, 5:00

Level 5 of the Stripe CTF revolved around a design issue in an OpenID like protocol.

Code

    def authenticated?(body)
body =~ /[^\w]AUTHENTICATED[^\w]*$/
end

...

if authenticated?(body)
session[:auth_user] = username
session[:auth_host] = host
return "Remote server responded with: #{body}." \
" Authenticated as #{username}@#{host}!"

Issue

This level is an implementation of a federated identity protocol. You give it an endpoint URI and a username and password, it posts the username and password to the endpoint URI, and if the response is 'AUTHENTICATED' then access is allowed. It is easy to be authenticated on a server you control, but this level requires you to authenticate from the server running the level. This level only talks to stripe CTF servers so the first step is to upload a document to the level 2 server containing the text 'AUTHENTICATED' and we can now authenticate on a level 2 server. Notice that the level 5 server will dump out the content of the endpoint URI and that the regexp it uses to detect the text 'AUTHENTICATED' can match on that dump. Accordingly I uploaded an authenticated file to

https://level02-2.stripe-ctf.com/user-ajvivlehdt/uploads/authenticated
Using that as my endpoint URI means authenticating as level 2. I can then choose the following endpoint URI to authenticate as level 5.
https://level05-1.stripe-ctf.com/user-qtoyekwrod/?pingback=https%3A%2F%2Flevel02-2.stripe-ctf.com%2Fuser-ajvivlehdt%2Fuploads%2Fauthenticated&username=a&password=a
Navigating to that URI results in the level 5 server telling me I'm authenticated as level 2 and lists the text of the level 2 file 'AUTHENTICATED'. Feeding this back into the level 5 server as my endpoint URI means level 5 seeing 'AUTHENTICATED' coming back from a level 5 URI.

Notes

I didn't see any particular code review red flags, really the issue here is that the regular expression testing for 'AUTHENTICATED' is too permisive and the protocol itself doesn't do enough. The protocol requires only a set piece of common literal text to be returned which makes it easy for a server to accidentally fall into authenticating. Having the endpoint URI have to return variable text based on the input would make it much harder for a server to accidentally authenticate.

PermalinkCommentsinternet openid security stripe-ctf technical web

Stripe CTF - XSS, CSRF (Levels 4 & 6)

2012 Sep 10, 4:43

Level 4 and level 6 of the Stripe CTF had solutions around XSS.

Level 4

Code

> Registered Users 

    <%@registered_users.each do |user| %>
    <%last_active = user[:last_active].strftime('%H:%M:%S UTC') %>
    <%if @trusts_me.include?(user[:username]) %>

  • <%= user[:username] %>
    (password: <%= user[:password] %>, last active <%= last_active %>)
  • Issue

    The level 4 web application lets you transfer karma to another user and in doing so you are also forced to expose your password to that user. The main user page displays a list of users who have transfered karma to you along with their password. The password is not HTML encoded so we can inject HTML into that user's browser. For instance, we could create an account with the following HTML as the password which will result in XSS with that HTML:

    
    
    This HTML runs script that uses jQuery to post to the transfer URI resulting in a transfer of karma from the attacked user to the attacker user, and also the attacked user's password.

    Notes

    Code review red flags in this case included lack of encoding when using user controlled content to create HTML content, storing passwords in plain text in the database, and displaying passwords generally. By design the web app shows users passwords which is a very bad idea.

    Level 6

    Code

    
    

    ...

    def self.safe_insert(table, key_values)
    key_values.each do |key, value|
    # Just in case people try to exfiltrate
    # level07-password-holder's password
    if value.kind_of?(String) &&
    (value.include?('"') || value.include?("'"))
    raise "Value has unsafe characters"
    end
    end

    conn[table].insert(key_values)
    end

    Issue

    This web app does a much better job than the level 4 app with HTML injection. They use encoding whenever creating HTML using user controlled data, however they don't use encoding when injecting JSON data into script (see post_data initialization above). This JSON data is the last five most recent messages sent on the app so we get to inject script directly. However, the system also ensures that no strings we write contains single or double quotes so we can't get out of the string in the JSON data directly. As it turns out, HTML lets you jump out of a script block using no matter where you are in script. For instance, in the middle of a value in some JSON data we can jump out of script. But we still want to run script, so we can jump right back in. So the frame so far for the message we're going to post is the following:

    
    
    
    
PermalinkCommentscsrf encoding html internet javascript percent-encoding script security stripe-ctf technical web xss

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

Stripe Web Security CTF Summary

2012 Aug 30, 5:00

I was the 546th person to complete Stripe's web security CTF and again had a ton of fun applying my theoretical knowledge of web security issues to the (semi-)real world. As I went through the levels I thought about what red flags jumped out at me (or should have) that I could apply to future code reviews:

Level Issue Code Review Red Flags
0 Simple SQL injection No encoding when constructing SQL command strings. Constructing SQL command strings instead of SQL API
1 extract($_GET); No input validation.
2 Arbitrary PHP execution No input validation. Allow file uploads. File permissions modification.
3 Advanced SQL injection Constructing SQL command strings instead of SQL API.
4 HTML injection, XSS and CSRF No encoding when constructing HTML. No CSRF counter measures. Passwords stored in plain text. Password displayed on site.
5 Pingback server doesn't need to opt-in n/a - By design protocol issue.
6 Script injection and XSS No encoding while constructing script. Deny list (of dangerous characters). Passwords stored in plain text. Password displayed on site.
7 Length extension attack Custom crypto code. Constructing SQL command string instead of SQL API.
8 Side channel attack Password handling code. Timing attack mitigation too clever.

More about each level in the future.

PermalinkCommentscode-review coding csrf html internet programming script security sql stripe technical web xss

Web Security Contest - Stripe CTF

2012 Aug 27, 4:18

Stripe is running a web security capture the flag - a series of increasingly difficult web security exploit challenges. I've finished it and had a lot of fun. Working on a web browser I knew the theory of these various web based attacks, but this was my first chance to put theory into practice with:

  • No adverse consequences
  • Knowledge that there is a fun security exploit to find
  • Access to the server side source code

Here's a blog post on the CTF behind the scenes setup which has many impressive features including phantom users that can be XSS/CSRF'ed.

I'll have another post on my difficulties and answers for the CTF levels after the contest is over on Wed, but if you're looking for hints, try out the CTF chatroom or the level specific CTF chatroom.

PermalinkCommentscontest security technical

Capturing HTTPS with FiddlerCore

2011 Apr 6, 10:00

I used FiddlerCore in GeolocMock to edit HTTPS responses and ran into two stumbling blocks that I'll document here. The first is that I didn't check if the Fiddler root cert existed or was installed, which of course is necessary to edit HTTPS traffic. The following is my code where I check for the certs.

    if (!Fiddler.CertMaker.rootCertExists())
{
if (!Fiddler.CertMaker.createRootCert())
{
throw new Exception("Unable to create cert for FiddlerCore.");
}
}

if (!Fiddler.CertMaker.rootCertIsTrusted())
{
if (!Fiddler.CertMaker.trustRootCert())
{
throw new Exception("Unable to install FiddlerCore's cert.");
}
}

The second problem I had (which would have been solved had I read all the sample code first) was that my changes weren't being applied. In my app I only need the BeforeResponse but in order to modify the response I must also sign up for the BeforeRequest event and mark the bBufferResponse flag on the session before the response comes back. For example:

    Fiddler.FiddlerApplication.BeforeRequest += new SessionStateHandler(FiddlerApplication_BeforeRequest);
Fiddler.FiddlerApplication.BeforeResponse += new SessionStateHandler(FiddlerApplication_BeforeResponse);
...
private void FiddlerApplication_BeforeRequest(Session oSession)
{
if (IsInterestingSession(oSession))
{
oSession.bBufferResponse = true;
}
}
PermalinkCommentshttp fiddler technical https geolocmock programming fiddlercore

Cheap Multiplayer Tricks for New Super Mario Bros. Wii

2010 Jan 5, 1:47

The New Super Mario Bros. Wii is a great game. Its the fun of old school Mario with the addition of great graphics and the kind of multiplayer I've wanted for Mario since playing the original as a child: its got up to four player simultaneous cooperative multiplayer. I recommend it to anyone who has enjoyed Mario in the past. Watch this amazing video of level 1-3 you can unlock in the game.

As noted elsewhere, multiple players attempting to navigate platforms, grab power ups, and throw turtle shells creates new challenges but along with that there's new ways to be incredibly cheap.

Jumping Higher
A second player means a head one can jump on to reach higher locations. Jump on your friend's head at the apex of their jump while holding down the jump button yourself for maximum jumping. In the game you can also grab other players and hold them over your head. This is useful for reaching the top of the flagpole at the end of levels. On that same line, if the player you grab has a flying cap you can now use them to fly in the same manner you would use a flying block which makes it easy to get two players to the top of the finish flagpole if only one of you has a flying cap.
Power-Ups
Normal power-up blocks now spawn enough power-ups for everyone. A mushroom is spawned for each small player and full power-ups for the rest, except in the case everyone is small: then one of the power-ups is a full power-up. If there's two players and you're both small, the full power-up always jumps out of the block to the right. Some hidden power-up blocks only give out one power-up and in that case its a mushroom or not based on the player who hits the block - so be sure that a big player hits that if you have one.
Death & Bubbles
When a player dies but at least one other player lives the dead player comes back in a limbo bubble from which they must be released before they may play again. Because of this, in a tough spot you can send one player in and leave a second behind. If the first dies you don't lose your place in the level and the first comes back in a bubble ready to try again. For instance, if you're trying to get the last star coin in 2-1 which sits just above the abyss, one player can just jump to their death for it and as long as another player lives you've collected the coin. However you need not sacrifice your life to do this: you can press down and 'a' to force yourself into a bubble saving yourself from death. This is true in general as long as you have enough time to see your death coming. This is also useful if one player runs ahead to the right. The screen will expand a bit but then it will just move to the right following the player in the lead. Players left behind walls or now forced into lava pits will die unless they use the bubble.
Misc.
  • If all players hit the ground at the same time from a ground pound it acts like hitting a pow block, killing the enemies on the screen.
  • If you hold a player who has a projectile power over your head they can still use their power.
  • Bubbles can be popped by hitting them with your fire or ice projectiles as well as thrown shells or blocks.
  • All players get the extra lives from anyone collecting 100 coins or finishing a level with more than 7 enemies on the screen.
PermalinkCommentsmultiplayer mario wii

Bear Flag Wine Bottle

2009 Sep 12, 3:55

sequelguy posted a photo:

Bear Flag Wine Bottle

Bear Flag wine has a cool label and has the barcode wrapped around the neck of the bottle.

PermalinkCommentsbottle wine bearflag

tweenbots | kacie kinzer

2009 Apr 13, 10:17If the face drawn onto the robot hadn't been as cute I doubt as many people would have helped =). "Tweenbots are human-dependent robots that navigate the city with the help of pedestrians they encounter. Rolling at a constant speed, in a straight line, Tweenbots have a destination displayed on a flag, and rely on people they meet to read this flag and to aim them in the right direction to reach their goal."PermalinkCommentstweenbot video social map robot cute nyc society humor

Business & Technology | Jobs with real authority: working on Microsoft's spell-checker | Seattle Times Newspaper

2008 Sep 30, 11:05Article on the team that owns the Office spell-checker: 'But, the team asked itself, should "calender" be flagged, or squiggled - have the red squiggly underline that indicates a misspelling? Yes, because letting it go through as correct "more often masks the really common spelling error that people make for calendar."' I didn't even realize they had written calender rather than calendar in the articlePermalinkCommentsmicrosoft office spell-check language

Flickr: GAMA-GO Photo Royale

2008 Aug 26, 3:34Some enjoyable and surreal photos in here featuring Gama-Go gear. "Gama-Go fans gather round, for this is the place to post your Gama-Go fan photos and sightings! ". I like all the pirate kitty flags in "Greetings from Terschelling".PermalinkCommentsphoto gama-go flickr

Bumper Sticker: Re-elect *SENATOR* John McCain 2008 [Arizona Flag]

2008 Jul 3, 12:17Humorous Obama bumper sticker that says: "Re-elect *SENATOR* John McCain 2008 [Arizona Flag]"PermalinkCommentspolitics humor bumper-sticker via:boingboing

RFC 3514 - The Security Flag in the IPv4 Header

2008 Jun 30, 3:57"Firewalls, packet filters, intrusion detection systems, and the like often have difficulty distinguishing between packets that have malicious intent and those that are merely unusual. We define a security flag in the IPv4 header as a means of distinguisPermalinkCommentshumor rfc security ipv4 ip

RFC 3675 - .sex Considered Dangerous

2008 Jun 30, 3:55FCC wants nationwide free wifi that's free of porn. They should read this. "Periodically there are proposals to mandate the use of a special top level name or an IP address bit to flag "adult" "unsafe" material or the like. This document explains why thiPermalinkCommentsdomain dns rfc ietf internet porn government politics censorship

How to stop an ActiveX control from running in Internet Explorer

2008 May 30, 1:36Killbits: "This article describes how to stop an ActiveX control from running in Microsoft Internet Explorer and in Windows Internet Explorer. You can do this by modifying the data value of the Compatibility Flags DWORD value for the Class identifier (CLSPermalinkCommentssecurity ie killbit msdn microsoft windows browser reference

Update: Why is NBC Flagging Digital TV Programs - and Why is Microsoft Obeying It? | Electronic Frontier Foundation

2008 May 18, 12:15'...he was recording Raleigh's HDTV channel WNCN-DT1 on his Vista machine when a popup stating that "restrictions set by the broadcaster...prohibit recording of this program" appeared.'PermalinkCommentstv vista mce microsoft television video windows nbc via:boingboing
Older Entries Creative Commons License Some rights reserved.