Skip to content

Instantly share code, notes, and snippets.

@Sanokei
Last active October 28, 2022 01:22
Show Gist options
  • Save Sanokei/8793e27260d2b55964b0d7287c76e12d to your computer and use it in GitHub Desktop.
Save Sanokei/8793e27260d2b55964b0d7287c76e12d to your computer and use it in GitHub Desktop.

The Bug trailer

By Sano 7/16/22
edited: 10/27/22
(special thanks to mark)


Bugs are everywhere – in games, in everyday software where they are played off as features, and in our own code.

So what do you do when you find a bug? Best practices would call for you to create a bug report and tell the party responsible (and maybe even get compensated – or at least thanked – for your efforts). When I found a security bug in Google Chrome I didn’t go the standard route. My first thought was "Man this would make a cool level in Hackpunk.”

So what’s the tl;dr of Hackpunk?

Thanks for asking – and yes it was a leading question. Hackpunk is a game I am developing where you can write, play and distribute levels of a 3D puzzle game. (The elevator pitch is Super Mario Maker meets Roblox. I am not in love with that description but it usually gets the point across.)

Tell me about the bug already

Some might say the bug isn’t that big a deal – especially since it requires access to a user’s unlocked computer to exploit. But IMHO it is a serious security flaw – as is anything that exposes stored passwords.

Here’s the issue. When you want to see your stored site passwords in Google you would normally go to your settings in Chrome chrome://settings/passwords. From there you would be asked to authenticate with the OS before seeing the actual password. This is a basic and reasonable security measure.

But in reality you don’t need to authenticate with the OS to see the stored password. Instead, just surf to the site in question – just don’t login. Instead, register for the site. Don’t worry about what username (or email) you’re using. But when it comes time to enter the password for the new account use the Autofill feature in Chrome to use the password associated with the account whose credentials you’re after. Now submit your faux registration. When you do so Chrome will politely ask you if you want to save the new faux credentials. In that dialog box there’s a convenient eye icon that when clicked reveals the password you are about to save. Congrats, you just exposed the stored password.

I call this the Autofill Leak. It has been confirmed to be an issue on MacOS and Windows.

Simple steps to see a stored password without credentials

  1. Get access to an unlocked computer.
  2. Go to the site from which you want the stored password
  3. Logout if the user is logged in.
  4. Register for the site using a new username or email
  5. When it comes time to set your password use the Chrome Autofill feature to set the password.
  6. Submit and Chrome will ask you if you want to save the password.
  7. In that dialog box click the eye icon next to the password
  8. You now have the password.

That's it??

Yeah, that is the whole security flaw. I know what you’re thinking – who cares? The user has access to the unlocked computer anyway and can do a ton of damage (including logging into sites using stored credentials). But there are cases where the illicit access is short-term (typically for a temporarily unattended computer). This gives a hacker an opportunity to quickly harvest passwords for later usage. In addition, while I have not tested this, the hack may give an evil doer the ability to harvest passwords from a drive removed from a computer – passwords that are otherwise encrypted at rest and inaccessible.

How is the bug used in Hackpunk

Hackpunk uses a custom networking system and a unique interface builder that allows the in-game target IOT devices to have their own GUIs. In this codeblock we create a control for entering codes to unlock a door:

door_gui.lua

local num_buttons[]
local code
local username
local current_code
local clear

local gui = new GUI() 

Start(){
    --input field
    username = gui.inputField("username")
    -- password code 
    for i=1,i<10,i++ do
        num_buttons[i] = gui.button(i * 1,i * 1,2,2,i.toString())
    end
    
    clear = gui.button(10,0,2,1,"clear")
}

Update(){
    if clear.isPressed() do
        current_code = ''
        code = ''
    end
    if username in security.usernames
    do 
        local window = gui.window.default('Autofill?')
        local yes = gui.button(10,1,1,1,'yes')
        if choice.isPressed() do
            -- auto fill password for that username
            current_code = security.hide(security.passwords.get(username))
        else do
            window.destroy()
        end
        
    end
    if code.length == 4
    do
        if code in security.passwords
            do
            code = ''
            -- show gui for 2 seconds
            gui.window.approval('door open',2)
            door.open
            if !(username in security.usernames)
            do
                local window = gui.window.default('Save password?',5)
                local eye = gui.button(10,1,1,1,'View password')
                local shown = false

                window.add(eye)

                if eye.isPressed()
                do
                    if(shown) do
                        currrent_code = security.show(current_code)
                    else do 
                        current_code = security.hide(current_code)
                    end
                end
            end
        else do
            code = ''
            gui.window.warning('wrong',2)
        end
    end

    if gui.buttonPressedEvent.eventData in num_buttons
    do
        -- when the button is pressed to add to the code
        code += gui.buttonPressedEvent.eventData.name
        current_code = security.hide(code)
    end
}

This code has deliberately recreated the bug I found in Chrome. If you use the same technique that I used to exploit the weakness in Chrome, you can open an in-game door that you would not otherwise be able to open.

GUI system...?

Yeah! I have in the works a Lua-powered fully injectable GUI system. The way it works is pretty simple, it just leverages the Unity UI system but uses Lua commands to instantiate interface items.

How in the hell is the player gonna know all of this?

So this is definitely something I have thought about a lot! My goal is to create a game that a relatively sophisticated player can wade right into – without having to study as if they were cramming for a big exam beforehand. Having said that, we also want to make resources available for the player who shows initiative. We plan to make available multiple booklets, handbooks and manuals. The idea of breaking up the manuals and having the player decide how to use them reflects the spirit of a hacking game. Nobody will be spoon fed solutions – but I also do not want them to feel like a failure. So there will be resources available to help them. And, just like in real life, the resources will range in quality. Expect to find some deliberately poor/obtuse writing – which will accurately reflect the actual state of the majority of real world documentation.

I hope savvy users print out the documentation and use them as guidebooks. But how to exactly play will be up to the user.

Does using this bug reflect your design philosophy?

Man, I wish I was well thought out enough as a creative to say I have a well articulated design philosophy. In reality I just thought it was a cool thing to do: put a real world security flaw in my own game. And then I took it further and made security exploits the whole point of the game

I want players of the game to feel like they have found something out for themselves – to get that same great feeling I got when I found that Chrome bug. By looking at the in-game code they will be able to find and exploit mistakes made by other people and use them for their own goals. If the game player feels like a real hacker, I will have achieved my goal.

I guess if I had to state a design philosophy it would be that I want the player to experience what I have experienced.

The player/creator/hacker has many tools at their disposal including the aforementioned GUI system, Premade IOT devices (that they can customize) and a level designer.

Tangent: Level design for a puzzle game

The level design of Hackpunk is very clear. The idea is if you were stuck in a room with nothing but a computer would you be able to get out of your imprisonment.

By the way, though the level builder is still in the works, it was pretty much stolen beat for beat from the good people at Valve. I love their portal level editor.

Level design for a puzzle game is key because you need the level design to guide players. You need to engineer serendipity, which will mean players will stumble upon hints to the solution of the problem. The way I like to look at it is this: player interacts with world -> world reveals itself to player -> player finds new ways to interact with world and so on. Level design is definitely a great way to telegraph things to the players and can be discussed further in another dev log.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment