Rating:

<html lang="en">
<head>
<meta charset="utf-8">
<link rel="dns-prefetch" href="https://github.githubassets.com">
<link rel="dns-prefetch" href="https://avatars0.githubusercontent.com">
<link rel="dns-prefetch" href="https://avatars1.githubusercontent.com">
<link rel="dns-prefetch" href="https://avatars2.githubusercontent.com">
<link rel="dns-prefetch" href="https://avatars3.githubusercontent.com">
<link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
<link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">

<link crossorigin="anonymous" media="all" integrity="sha512-FG+rXqMOivrAjdEQE7tO4BwM1poGmg70hJFTlNSxjX87grtrZ6UnPR8NkzwUHlQEGviu9XuRYeO8zH9YwvZhdg==" rel="stylesheet" href="https://github.githubassets.com/assets/frameworks-146fab5ea30e8afac08dd11013bb4ee0.css" />
<link crossorigin="anonymous" media="all" integrity="sha512-iXrV/b4ypc1nr10b3Giikqff+qAx5osQ0yJRxHRDd8mKFefdMtEZ0Sxs1QysJxuJBayOKThjsuMjynwBJQq0aw==" rel="stylesheet" href="https://github.githubassets.com/assets/site-897ad5fdbe32a5cd67af5d1bdc68a292.css" />
<link crossorigin="anonymous" media="all" integrity="sha512-whtr9xYX7utnpWsNSLW7XLm7eJONfryMwfwxIH2SpIRKCZbx4aryDfn/HGMFI5Fee7dogmqmtqvPPh13+2HW2Q==" rel="stylesheet" href="https://github.githubassets.com/assets/github-c21b6bf71617eeeb67a56b0d48b5bb5c.css" />



<meta name="viewport" content="width=device-width">

<title>write-ups-2016/README.md at pwn2win-ctf-2016 · epicleet/write-ups-2016 · GitHub</title>
<meta name="description" content="Wiki-like CTF write-ups repository, maintained by the community. 2016 - epicleet/write-ups-2016">
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">
<link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
<meta property="fb:app_id" content="1401488693436528">

<meta name="twitter:image:src" content="https://avatars2.githubusercontent.com/u/18104388?s=400&v=4" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary" /><meta name="twitter:title" content="epicleet/write-ups-2016" /><meta name="twitter:description" content="Wiki-like CTF write-ups repository, maintained by the community. 2016 - epicleet/write-ups-2016" />
<meta property="og:image" content="https://avatars2.githubusercontent.com/u/18104388?s=400&v=4" /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="epicleet/write-ups-2016" /><meta property="og:url" content="https://github.com/epicleet/write-ups-2016" /><meta property="og:description" content="Wiki-like CTF write-ups repository, maintained by the community. 2016 - epicleet/write-ups-2016" />

<link rel="assets" href="https://github.githubassets.com/">

<meta name="request-id" content="86B6:B5B2:B2AD37:103655F:5E8A05B9" data-pjax-transient="true"/><meta name="html-safe-nonce" content="a1de2c84ce9c6d7c5eb5d65a3b05f447ea7ca395" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4NkI2OkI1QjI6QjJBRDM3OjEwMzY1NUY6NUU4QTA1QjkiLCJ2aXNpdG9yX2lkIjoiNDY4MDE2MjA0MDgyMzI4NTE3NyIsInJlZ2lvbl9lZGdlIjoiYW1zIiwicmVnaW9uX3JlbmRlciI6ImFtcyJ9" data-pjax-transient="true"/><meta name="visitor-hmac" content="f156b1b8d7d11cfe2d5a65abbb3ffec5ed5d9ba1b910e92ca4c4db4e19ebf0e5" data-pjax-transient="true"/>

<meta name="github-keyboard-shortcuts" content="repository,source-code" data-pjax-transient="true" />

<meta name="selected-link" value="repo_source" data-pjax-transient>

<meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU">
<meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA">
<meta name="google-site-verification" content="GXs5KoUUkNCoaAZn7wPN-t01Pywp9M3sEjnt_3_ZWPc">

<meta name="octolytics-host" content="collector.githubapp.com" /><meta name="octolytics-app-id" content="github" /><meta name="octolytics-event-url" content="https://collector.githubapp.com/github-external/browser_event" /><meta name="octolytics-dimension-ga_id" content="" class="js-octo-ga-id" />
<meta name="analytics-location" content="/<user-name>/<repo-name>/blob/show" data-pjax-transient="true" />

<meta name="google-analytics" content="UA-3769691-2">

<meta class="js-ga-set" name="dimension1" content="Logged Out">

<meta name="hostname" content="github.com">
<meta name="user-login" content="">

<meta name="expected-hostname" content="github.com">

<meta name="enabled-features" content="MARKETPLACE_FEATURED_BLOG_POSTS,MARKETPLACE_INVOICED_BILLING,MARKETPLACE_SOCIAL_PROOF_CUSTOMERS,MARKETPLACE_TRENDING_SOCIAL_PROOF,MARKETPLACE_RECOMMENDATIONS,MARKETPLACE_PENDING_INSTALLATIONS,RELATED_ISSUES">

<meta http-equiv="x-pjax-version" content="80ebc3286fe9d88acaddc1320106dfc2">

<link href="https://github.com/epicleet/write-ups-2016/commits/pwn2win-ctf-2016.atom" rel="alternate" title="Recent Commits to write-ups-2016:pwn2win-ctf-2016" type="application/atom+xml">

<meta name="go-import" content="github.com/epicleet/write-ups-2016 git https://github.com/epicleet/write-ups-2016.git">

<meta name="octolytics-dimension-user_id" content="18104388" /><meta name="octolytics-dimension-user_login" content="epicleet" /><meta name="octolytics-dimension-repository_id" content="54845624" /><meta name="octolytics-dimension-repository_nwo" content="epicleet/write-ups-2016" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="true" /><meta name="octolytics-dimension-repository_parent_id" content="48103176" /><meta name="octolytics-dimension-repository_parent_nwo" content="ctfs/write-ups-2016" /><meta name="octolytics-dimension-repository_network_root_id" content="48103176" /><meta name="octolytics-dimension-repository_network_root_nwo" content="ctfs/write-ups-2016" /><meta name="octolytics-dimension-repository_explore_github_marketplace_ci_cta_shown" content="false" />

<link rel="canonical" href="https://github.com/epicleet/write-ups-2016/blob/pwn2win-ctf-2016/pwn2win-ctf-2016/reverse/timekeeperslock-600/README.md" data-pjax-transient>

<meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">

<meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">

<link rel="mask-icon" href="https://github.githubassets.com/pinned-octocat.svg" color="#000000">
<link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png">
<link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg">

<meta name="theme-color" content="#1e2327">

<link rel="manifest" href="/manifest.json" crossOrigin="use-credentials">

</head>

<body class="logged-out env-production page-responsive page-blob">

<div class="position-relative js-header-wrapper ">
Skip to content
<span>
<span></span>
</span>


<header class="Header-old header-logged-out js-details-container Details position-relative f4 py-2" role="banner">
<div class="container-lg d-lg-flex flex-items-center p-responsive">
<div class="d-flex flex-justify-between flex-items-center">

<svg height="32" class="octicon octicon-mark-github text-white" viewBox="0 0 16 16" version="1.1" width="32" aria-hidden="true"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg>

<div class="d-lg-none css-truncate css-truncate-target width-fit p-2">

<svg class="octicon octicon-repo-forked" viewBox="0 0 10 16" version="1.1" width="10" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8 1a1.993 1.993 0 00-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 002 1a1.993 1.993 0 00-1 3.72V6.5l3 3v1.78A1.993 1.993 0 005 15a1.993 1.993 0 001-3.72V9.5l3-3V4.72A1.993 1.993 0 008 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
epicleet
/
write-ups-2016

</div>

<div class="d-flex flex-items-center">

Sign up

<button class="btn-link d-lg-none mt-1 js-details-target" type="button" aria-label="Toggle navigation" aria-expanded="false">
<svg height="24" class="octicon octicon-three-bars text-white" viewBox="0 0 12 16" version="1.1" width="18" aria-hidden="true"><path fill-rule="evenodd" d="M11.41 9H.59C0 9 0 8.59 0 8c0-.59 0-1 .59-1H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zm0-4H.59C0 5 0 4.59 0 4c0-.59 0-1 .59-1H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zM.59 11H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1H.59C0 13 0 12.59 0 12c0-.59 0-1 .59-1z"></path></svg>
</button>
</div>
</div>

<div class="HeaderMenu HeaderMenu--logged-out position-fixed top-0 right-0 bottom-0 height-fit position-lg-relative d-lg-flex flex-justify-between flex-items-center flex-auto">
<div class="d-flex d-lg-none flex-justify-end border-bottom bg-gray-light p-3">
<button class="btn-link js-details-target" type="button" aria-label="Toggle navigation" aria-expanded="false">
<svg height="24" class="octicon octicon-x text-gray" viewBox="0 0 12 16" version="1.1" width="18" aria-hidden="true"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z"></path></svg>
</button>
</div>

<nav class="mt-0 px-3 px-lg-0 mb-5 mb-lg-0" aria-label="Global">



  • <details class="HeaderMenu-details details-overlay details-reset width-full">
    <summary class="HeaderMenu-summary HeaderMenu-link px-0 py-3 border-0 no-wrap d-block d-lg-inline-block">
    Why GitHub?
    <svg x="0px" y="0px" viewBox="0 0 14 8" xml:space="preserve" fill="none" class="icon-chevon-down-mktg position-absolute position-lg-relative">
    <path d="M1,1l6.2,6L13,1"></path>
    </svg>
    </summary>
    <div class="dropdown-menu flex-auto rounded-1 bg-white px-0 mt-0 pb-4 p-lg-4 position-relative position-lg-absolute left-0 left-lg-n4">
    Features <span>→</span>


    </div>
    </details>


  • Enterprise

  • <details class="HeaderMenu-details details-overlay details-reset width-full">
    <summary class="HeaderMenu-summary HeaderMenu-link px-0 py-3 border-0 no-wrap d-block d-lg-inline-block">
    Explore
    <svg x="0px" y="0px" viewBox="0 0 14 8" xml:space="preserve" fill="none" class="icon-chevon-down-mktg position-absolute position-lg-relative">
    <path d="M1,1l6.2,6L13,1"></path>
    </svg>
    </summary>

    <div class="dropdown-menu flex-auto rounded-1 bg-white px-0 pt-2 pb-0 mt-0 pb-4 p-lg-4 position-relative position-lg-absolute left-0 left-lg-n4">

    <h4 class="text-gray-light text-normal text-mono f5 mb-2 border-lg-top pt-lg-3">Learn & contribute</h4>

    <h4 class="text-gray-light text-normal text-mono f5 mb-2 border-lg-top pt-lg-3">Connect with others</h4>


    </div>
    </details>

  • Marketplace

  • <details class="HeaderMenu-details details-overlay details-reset width-full">
    <summary class="HeaderMenu-summary HeaderMenu-link px-0 py-3 border-0 no-wrap d-block d-lg-inline-block">
    Pricing
    <svg x="0px" y="0px" viewBox="0 0 14 8" xml:space="preserve" fill="none" class="icon-chevon-down-mktg position-absolute position-lg-relative">
    <path d="M1,1l6.2,6L13,1"></path>
    </svg>
    </summary>

    <div class="dropdown-menu flex-auto rounded-1 bg-white px-0 pt-2 pb-4 mt-0 p-lg-4 position-relative position-lg-absolute left-0 left-lg-n4">
    Plans <span>→</span>


    </div>
    </details>


</nav>

<div class="d-lg-flex flex-items-center px-3 px-lg-0 text-center text-lg-left">
<div class="d-lg-flex mb-3 mb-lg-0">
<div class="header-search flex-self-stretch flex-lg-self-auto mr-0 mr-lg-3 mb-3 mb-lg-0 scoped-search site-scoped-search js-site-search position-relative js-jump-to"
role="combobox"
aria-owns="jump-to-results"
aria-label="Search or jump to"
aria-haspopup="listbox"
aria-expanded="false"
>
<div class="position-relative">
</option></form><form class="js-site-search-form" role="search" aria-label="Site" data-scope-type="Repository" data-scope-id="54845624" data-scoped-search-url="/epicleet/write-ups-2016/search" data-unscoped-search-url="/search" action="/epicleet/write-ups-2016/search" accept-charset="UTF-8" method="get">
<label class="form-control input-sm header-search-wrapper p-0 header-search-wrapper-jump-to position-relative d-flex flex-justify-between flex-items-center js-chromeless-input-container">
<input type="text"
class="form-control input-sm header-search-input jump-to-field js-jump-to-field js-site-search-focus js-site-search-field is-clearable"
data-hotkey="s,/"
name="q"
value=""
placeholder="Search"
data-unscoped-placeholder="Search GitHub"
data-scoped-placeholder="Search"
autocapitalize="off"
aria-autocomplete="list"
aria-controls="jump-to-results"
aria-label="Search"
data-jump-to-suggestions-path="/_graphql/GetSuggestedNavigationDestinations"
spellcheck="false"
autocomplete="off"
>
<input type="hidden" data-csrf="true" class="js-data-jump-to-suggestions-path-csrf" value="xHyLNfZi6ZuxkWZce/svjxViPvWLPDV2LosbZiw5ebCC/GhzK66HUhfCS5zaxIQxJqFrjDFjCEZI1B+UBEGScw==" />
<input type="hidden" class="js-site-search-type-field" name="type" >

<div class="Box position-absolute overflow-hidden d-none jump-to-suggestions js-jump-to-suggestions-container">



  • <span>No suggested jump to results</span>

</div>
</label>
</form> </div>
</div>

</div>


Sign in


Sign up

</div>
</div>
</div>
</header>

</div>

<div id="start-of-content" class="show-on-focus"></div>

<div id="js-flash-container">

<template class="js-flash-template">
<div class="flash flash-full js-flash-template-container">
<div class="container-lg px-2" >
<button class="flash-close js-flash-close" type="button" aria-label="Dismiss this message">
<svg class="octicon octicon-x" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z"></path></svg>
</button>

<div class="js-flash-template-message"></div>

</div>
</div>
</template>
</div>

<include-fragment class="js-notification-shelf-include-fragment" data-base-src="https://github.com/notifications/beta/shelf"></include-fragment>

<div class="application-main " data-commit-hovercards-enabled>
<div itemscope itemtype="http://schema.org/SoftwareSourceCode" class="">
<main >

<div class="pagehead repohead hx_repohead readability-menu bg-gray-light pb-0 pt-0 pt-lg-3">

<div class="d-flex container-lg mb-4 p-responsive d-none d-lg-flex">

<div class="flex-auto min-width-0 width-fit mr-3">
<h1 class="public d-flex flex-wrap flex-items-center break-word float-none ">
<svg class="octicon octicon-repo-forked" viewBox="0 0 10 16" version="1.1" width="10" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8 1a1.993 1.993 0 00-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 002 1a1.993 1.993 0 00-1 3.72V6.5l3 3v1.78A1.993 1.993 0 005 15a1.993 1.993 0 001-3.72V9.5l3-3V4.72A1.993 1.993 0 008 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
<span>

</span>
<span>/</span>

write-ups-2016


</h1>

<span>
<span>forked from ctfs/write-ups-2016</span>
</span>

</div>

</div>

<nav class="hx_reponav reponav js-repo-nav js-sidenav-container-pjax clearfix container-lg p-responsive d-none d-lg-block"
itemscope
itemtype="http://schema.org/BreadcrumbList"
aria-label="Repository"
data-pjax="#js-repo-pjax-container">

<span>

<div class="d-inline"><svg class="octicon octicon-code" viewBox="0 0 14 16" version="1.1" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z"></path></svg></div>
<span>Code</span>
<meta itemprop="position" content="1">
</span>

<span>

<div class="d-inline"><svg class="octicon octicon-git-pull-request" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0010 15a1.993 1.993 0 001-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 00-1 3.72v6.56A1.993 1.993 0 002 15a1.993 1.993 0 001-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg></div>
<span>Pull requests</span>
<span>0</span>
<meta itemprop="position" content="4">
</span>

<span>

<div class="d-inline"><svg class="octicon octicon-play" viewBox="0 0 14 16" version="1.1" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M14 8A7 7 0 110 8a7 7 0 0114 0zm-8.223 3.482l4.599-3.066a.5.5 0 000-.832L5.777 4.518A.5.5 0 005 4.934v6.132a.5.5 0 00.777.416z"></path></svg></div>
Actions

</span>


<div class="d-inline"><svg class="octicon octicon-project" viewBox="0 0 15 16" version="1.1" width="15" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4 4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 00-1 1v14a1 1 0 001 1h13a1 1 0 001-1V1a1 1 0 00-1-1z"></path></svg></div>
Projects
<span>0</span>


<div class="d-inline"><svg class="octicon octicon-shield" viewBox="0 0 14 16" version="1.1" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M0 2l7-2 7 2v6.02C14 12.69 8.69 16 7 16c-1.69 0-7-3.31-7-7.98V2zm1 .75L7 1l6 1.75v5.268C13 12.104 8.449 15 7 15c-1.449 0-6-2.896-6-6.982V2.75zm1 .75L7 2v12c-1.207 0-5-2.482-5-5.985V3.5z"></path></svg></div>
Security


<div class="d-inline"><svg class="octicon octicon-graph" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z"></path></svg></div>
Insights

</nav>

<div class="reponav-wrapper reponav-small d-lg-none">
<nav class="reponav js-reponav text-center no-wrap"
itemscope
itemtype="http://schema.org/BreadcrumbList">

<span>

<span>Code</span>
<meta itemprop="position" content="1">
</span>

<span>

<span>Pull requests</span>
<span>0</span>
<meta itemprop="position" content="4">
</span>

<span>

<span>Projects</span>
<span>0</span>
<meta itemprop="position" content="5">
</span>

<span>

<span>Actions</span>
<meta itemprop="position" content="6">
</span>


<span>Security</span>
<meta itemprop="position" content="8">


Pulse

</nav>
</div>

</div>

<include-fragment class="js-notification-shelf-include-fragment" data-base-src="https://github.com/notifications/beta/shelf"></include-fragment>

<div class="container-lg clearfix new-discussion-timeline p-responsive">
<div class="repository-content ">


Permalink


<div class="signup-prompt-bg rounded-1 js-signup-prompt" data-prompt="signup" hidden>
<div class="signup-prompt p-4 text-center mb-4 rounded-1">
<div class="position-relative">
<button type="button" class="position-absolute top-0 right-0 btn-link link-gray js-signup-prompt-button" data-ga-click="(Logged out) Sign up prompt, clicked Dismiss, text:dismiss">
Dismiss
</button>
<h3 class="pt-2">Join GitHub today</h3>

GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.


Sign up
</div>
</div>
</div>

<div class="d-flex flex-items-start flex-shrink-0 flex-column flex-md-row pb-3">
<span>

<details class="details-reset details-overlay branch-select-menu " id="branch-select-menu">
<summary class="btn css-truncate btn-sm"
data-hotkey="w"
title="pwn2win-ctf-2016">
Branch:
<span>pwn2win-ctf-20…</span>
<span></span>
</summary>

<details-menu class="SelectMenu SelectMenu--hasFilter" src="/epicleet/write-ups-2016/refs/pwn2win-ctf-2016/pwn2win-ctf-2016/reverse/timekeeperslock-600/README.md?source_action=show&source_controller=blob" preload>
<div class="SelectMenu-modal">
<include-fragment class="SelectMenu-loading" aria-label="Menu is loading">
<svg class="octicon octicon-octoface anim-pulse" height="32" viewBox="0 0 16 16" version="1.1" width="32" aria-hidden="true"><path fill-rule="evenodd" d="M14.7 5.34c.13-.32.55-1.59-.13-3.31 0 0-1.05-.33-3.44 1.3-1-.28-2.07-.32-3.13-.32s-2.13.04-3.13.32c-2.39-1.64-3.44-1.3-3.44-1.3-.68 1.72-.26 2.99-.13 3.31C.49 6.21 0 7.33 0 8.69 0 13.84 3.33 15 7.98 15S16 13.84 16 8.69c0-1.36-.49-2.48-1.3-3.35zM8 14.02c-3.3 0-5.98-.15-5.98-3.35 0-.76.38-1.48 1.02-2.07 1.07-.98 2.9-.46 4.96-.46 2.07 0 3.88-.52 4.96.46.65.59 1.02 1.3 1.02 2.07 0 3.19-2.68 3.35-5.98 3.35zM5.49 9.01c-.66 0-1.2.8-1.2 1.78s.54 1.79 1.2 1.79c.66 0 1.2-.8 1.2-1.79s-.54-1.78-1.2-1.78zm5.02 0c-.66 0-1.2.79-1.2 1.78s.54 1.79 1.2 1.79c.66 0 1.2-.8 1.2-1.79s-.53-1.78-1.2-1.78z"></path></svg>
</include-fragment>
</div>
</details-menu>
</details>

<div class="BtnGroup flex-shrink-0 d-md-none">

Find file

<clipboard-copy value="pwn2win-ctf-2016/reverse/timekeeperslock-600/README.md" class="btn btn-sm BtnGroup-item">
Copy path
</clipboard-copy>
</div>
</span>
<h2 id="blob-path" class="breadcrumb flex-auto min-width-0 text-normal flex-md-self-center ml-md-2 mr-md-3 my-2 my-md-0">
<span><span><span>write-ups-2016</span></span></span><span>/</span><span><span>pwn2win-ctf-2016</span></span><span>/</span><span><span>reverse</span></span><span>/</span><span><span>timekeeperslock-600</span></span><span>/</span>README.md
</h2>

<div class="BtnGroup flex-shrink-0 d-none d-md-inline-block">

Find file

<clipboard-copy value="pwn2win-ctf-2016/reverse/timekeeperslock-600/README.md" class="btn btn-sm BtnGroup-item">
Copy path
</clipboard-copy>
</div>
</div>

<include-fragment src="/epicleet/write-ups-2016/contributors/pwn2win-ctf-2016/pwn2win-ctf-2016/reverse/timekeeperslock-600/README.md" class="Box Box--condensed commit-loader">
<div class="Box-body bg-blue-light f6">
Fetching contributors…
</div>

<div class="Box-body d-flex flex-items-center" >

<span>Cannot retrieve contributors at this time</span>
</div>
</include-fragment>

<div class="Box mt-3 position-relative
">

<div class="Box-header py-2 d-flex flex-column flex-shrink-0 flex-md-row flex-md-items-center">
<div class="text-mono f6 flex-auto pr-3 flex-order-2 flex-md-order-1 mt-2 mt-md-0">

327 lines (211 sloc)
<span></span>
16.6 KB
</div>

<div class="d-flex py-1 py-md-0 flex-auto flex-order-1 flex-md-order-2 flex-sm-grow-0 flex-justify-between">

<div class="BtnGroup">
Raw
Blame
History
</div>

<div>

<svg class="octicon octicon-device-desktop" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M15 2H1c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h5.34c-.25.61-.86 1.39-2.34 2h8c-1.48-.61-2.09-1.39-2.34-2H15c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm0 9H1V3h14v8z"></path></svg>

<button type="button" class="btn-octicon disabled tooltipped tooltipped-nw"
aria-label="You must be signed in to make or propose changes">
<svg class="octicon octicon-pencil" viewBox="0 0 14 16" version="1.1" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 011.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z"></path></svg>
</button>
<button type="button" class="btn-octicon btn-octicon-danger disabled tooltipped tooltipped-nw"
aria-label="You must be signed in to make or propose changes">
<svg class="octicon octicon-trashcan" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z"></path></svg>
</button>
</div>
</div>
</div>


<div id="readme" class="Box-body readme blob js-code-block-container px-5">
<article class="markdown-body entry-content" itemprop="text"><h1><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Pwn2Win CTF 2016: Timekeeper's Lock</h1>

Category: Reverse
Points: 600
Solves: 0
Description:


<blockquote>

In order to protect their maximum security facilities, the Club employs
an electronic security lock activated by a 256-bit key which changes every
minute. When a Club member is authorized to enter some of these facilities,
he receives this key in hexadecimal format, the same format which is used to
enter the key in the electronic lock’s keyboard. The last year (in 2015),
Project SKY intercepted a key valid for April 1st at 11:00 UTC:
01cd9de119e1231e29b0972a618da6c79fc1f3bd96cee86c93a8068bdc5e4c59,
however we got access to this key only after it was already expired.
It seems that these keys are the same for all facilities, independent from
their geographical location, that is, they vary only with time. This year,
our truck driver Alisson, undercover in the Club’s fleet, was able to
intercept the shipment of one of these locks to a warehouse which is
currently under construction. Quickly, he drafted a block diagram of
the lock’s circuit and generated a dump of the flash memory (N25Q032A),
both contained in the file which we are providing to you. A few minutes
after sending this information through 3G using his Samsung Note Edge™
smartphone, Alisson suffered a tragic transit accident, which means
the Club has probably discovered our plans, so that we have only 48h before
they change all of their electronic lock scheme. Our teams are ready to
deploy next to 3 facilities of critical importance to the Club. They only
need that you send a key valid for the current minute to the address
https://door.pwn2win.party/KEY.


</blockquote>


<h2><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Write-up</h2>
<h3><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Preparing the environment</h3>

Some tools and libraries must be installed in order to run this write-up.



sudo apt-get install libftdi-dev
mkdir -p ~/git; cd ~/git
git clone https://github.com/cliffordwolf/icestorm.git
cd icestorm
git checkout -b ctf eb85e29ff0ca7b9031cf21db3dccaa70b7ef567a
make CXX=g++


  • Set the ICESTORM environment variable to the IceStorm repository path.


export ICESTORM=$HOME/git/icestorm


sudo apt-get install verilator


sudo apt-get install python3

<h3><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Reversing the FPGA bitfile</h3>

We have chosen the iCE40HX8K-CT256 chip to implement this challenge because mature and modern reverse engineering tools are available for it.


The iceunpack and icebox_vlog.py tools from IceStorm are able to transform the FPGA bitfile into an equivalent circuit in Verilog RTL.


This write-up provides a Makefile target to run these tools. Just type:


make chip.v

<h3><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Simulating the circuit given an input</h3>

First, the competitor was expected to set up a working simulation of the FPGA circuit. We provided the sample key mainly to allow such a simulation to be more easily validated, as our circuit has no output pins for flagging errors such as malformed UART signals or NMEA sentences.


The circuit could be simulated with any Verilog simulator, in particular free-software ones, such as iverilog and verilator. However, iverilog is very slow for simulating such a large and complex (decomposed) circuit. A single simulation takes near 2 minutes to run on iverilog in modern hardware. On the other hand, verilator is pretty fast, and runs the same simulation in 3 seconds. Another advantage of verilator is that it allows every internal digital signal to be easily controlled by C++ code during the simulation.


In order to correctly control the input pins, the competitor must be able to compute the duration, in number of cycles, of each bit sent over UART (29.4912×10⁶ / 115200 = 256) and to correctly generate the 8N1 framing.


In this write-up, we simulate the circuit with verilator. A Makefile target is available for building the simulator executables. Compile the sim_input simulator by typing:


make sim_input

Pass the Keypad and GPS UART inputs as arguments to sim_input. It can also optionally receive a third argument to save a waveform dump to a file. At the end of simulation, it outputs lock: 1 if the door is open, or lock: 0 if it is closed.


$ ./sim_input 01cd9de119e1231e29b0972a618da6c79fc1f3bd96cee86c93a8068bdc5e4c59 \
'$GPRMC,110000.000,A,1547.9730,S,4751.8510,W,0.02,31.66,010415,,,A*61' \
dump.vcd
lock: 1

The waveform dump can be opened with GTKWave.


gtkwave dump.vcd

<h3><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Observing the waveforms</h3>


By observing the waveform dump above, several interesting remarks can be made:




  • Signal n2 pulses 10 times. If we observe the pulse position relative to the NMEA UART signal (pin_E6), we discover that the first 4 pulses occur at the stop bit of each character pertaining to the current time (hour and minute) in a $GPRMC sentence. Similarly, the last 6 pulses occur at the stop bit of each character belonging to the current date (day, month and year).




  • Signal n6 pulses 64 times. Each pulse occurs at the stop bit of a hexadecimal digit character received from the keypad (pin_G13).




  • Most signals (n8n14, n17, n19n23, n26, and several others if we scroll down) only present activity (toggling) during a short period of time after both UARTs have finished receiving their data. Therefore these signals are probably related to key calculation.





By zooming around the time when the door opens (pin_B4 becomes high), we can make additional remarks:




  • Signal n4 only becomes high for 4 cycles, just before the door opens.




  • Even more evidence shows that n8n14 and others are related to key calculation, as their toggle rate is quite high (near clock speed), and all activity ceases just before the circuit decides to open the door.




<h3><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Gathering information about registers</h3>

By typing:


make reginfo.h

Our Makefile runs a very simple parser which gathers a list of all the registers present in the chip.v file and their enable signals. The script also prints the table below.


<table>
<thead>
<tr>
<th>Enable signal</th>
<th>Number of registers</th>
</tr>
</thead>
<tbody>
<tr>
<td>1'b1</td>
<td>1762</td>
</tr>
<tr>
<td>n1</td>
<td>50</td>
</tr>
<tr>
<td>n145</td>
<td>10</td>
</tr>
<tr>
<td>n2</td>
<td>48</td>
</tr>
<tr>
<td>n4</td>
<td>256</td>
</tr>
<tr>
<td>n4357</td>
<td>1 (pin_B4)</td>
</tr>
<tr>
<td>n4457</td>
<td>1 (n4456)</td>
</tr>
<tr>
<td>n6</td>
<td>256</td>
</tr>
</tbody>
</table>

Taking into account the behavior observed for the enable signals in the simulation waveforms and the fact that the size of the key is 256 bits, the table above provides evidence that:




  • Registers enabled by signal n6 probably hold the key typed in the keypad, as this signal is activated on each keystroke.




  • Registers enabled by signal n4 might hold the correct key, as they only change (and rapidly stabilize) immediately before the door opens.




<h3><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Locating keypad registers</h3>

Although at this point we have evidence that registers enabled by n6 hold the key typed in the keypad, important issues remain:




  • The key might have suffered some transformation before being stored in the registers. We still cannot be sure that the key is stored exactly as typed.




  • Even if the key is stored exactly as typed, simply knowing which are the members of the unordered set of 256 registers does not help much, since they can be ordered in any of 256! possible permutations.




If the key is transformed at most in a linear way after typed, it should be possible to activate each bit of the key at a time and afterwards study the change it causes in registers.


Typing the command below will employ this approach to map which registers become high when each bit of the key is set to high.


make -j8 keypad_regs.h

Looking at the results, we can conclude that:




  • The key is stored exactly as typed. Each bit of the key is tied to a single register enabled by n6 and vice-versa.




  • The 4 least significant bits of the key affect, besides their respective n6-enabled register, also a single register enabled by 1'b1. These probably form a buffer which stores the last typed hexadecimal digit, but this hypothesis is not needed to solve the challenge.




<h3><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Analyzing registers affected by NMEA input</h3>

If the correct key is computed as a cryptographically-secure hash from the current date and time provided by NMEA, we expect that after each minute, a 50% probability exists of each bit of the key being flipped.


This fact can be exploited to gain more confidence that registers enabled by n4 hold the correct key. Below, we simulate the circuit receiving some random initial date and time, take a snapshot of the register values, then simulate again 11 times, each one incrementing the time by one minute. Finally, we plot how many registers flipped at least once across the snapshots taken after each simulation.



Above we observe that, given enough time, every register enabled by n4 will eventually have changed at least once. As we know the size of the key is 256 bits, then the registers enabled by n4 are rather suspicious of holding the correct key.



Besides registers enabled by n4, the only others affected by a change in date and time (when other inputs are fixed) are a subset of the registers enabled by 1'b1 (above). Going further, although not required to solve the challenge, we can hypothesize that they hold the hash algorithm's internal state. Looking at the size of this internal state, if we knew the circuit implements a NIST-approved hash algorithm, we could even deduce it was SHA-3. ;)


<h3><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Reproducing the plots</h3>

If you intend to plot the figures above, first install the following scientific libraries for Python 3:


sudo apt-get install python3-matplotlib python3-scipy python3-pip
sudo -H python3 -m pip install lmfit

Then run the corresponding Makefile target for each figure.


<h3><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Obtaining the key</h3>

Now that we got an overview of the circuit's behavior, we shall present two different ways to solve the challenge.


<h4><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>The Trickster's Way</h4>

If we assume the correct key is stored in the unordered set of registers enabled by n4, the same issues we encountered when locating keypad registers arise again. The key bits might be ordered in any of the 256! possible permutations. Brute-forcing the correct order is computationally infeasible. Therefore, we need to find an efficient way to sort the key bits.


First, we put the circuit into a state in which the door is open, by providing as inputs to the simulation the sample key given in the problem's statement, and a NMEA sentence containing the corresponding date/time during which that key is valid.


Then, we toggle one of the registers enabled by n4. This causes the door to close. After that, we try to open the door again by toggling each of the keypad bits. When the door opens, it means we have found to which bit of the key that register is related. We repeat this procedure for each of the registers enabled by n4.


This algorithm is very efficient because, at each of the 256² required iterations, we only need to simulate the circuit for a single clock cycle, since the location of the registers holding keypad bits is already known.


Once the key registers are sorted in the correct order, we can simulate the circuit providing any NMEA sentence and afterwards extract the key from these registers.


The tool which implements this method can be compiled by typing:


make extract_hash

The tool may be called passing as arguments any time and date in the HHMM ddmmyy format:


$ ./extract_hash 1100 010415
01cd9de119e1231e29b0972a618da6c79fc1f3bd96cee86c93a8068bdc5e4c59

If no arguments are provided, the tool prints the correct key for the current minute (in UTC).


<h4><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>The Mathematician's Way</h4>

Although the method we just explained is very efficient and relatively easy to implement, it is not general, and would not work:




  • If no sample key was provided in the problem's statement.




  • If the registers holding the correct key did not held it exactly as expected to be typed by the user, e.g. if the hash suffered some final transformation before being compared to keypad bits.




A more general approach is to remember that the problem of finding a set of inputs such that the output of an arbitrary digital circuit goes to logical high is a boolean satisfiability problem.


If we transform the problem to the conjunctive normal form, we can feed it to a SAT solver, which will hopefully find the answer in reasonable time (although there are no guarantees, of course, since SAT is a NP-complete problem).


The Tseytin transformation can be employed to transform a digital circuit to the conjunctive normal form. The equivalent circuits generated by IceStorm only use the following Verilog operations:


<table>
<thead>
<tr>
<th>Operation</th>
<th>Tseytin transformation</th>
</tr>
</thead>
<tbody>
<tr>
<td>c = a & b</td>
<td>(¬a∨¬b∨c)∧(a∨¬c)∧(b∨¬c)</td>
</tr>
<tr>
<td>c = a ⎮ b</td>
<td>(a∨b∨¬c)∧(¬a∨c)∧(¬b∨c)</td>
</tr>
<tr>
<td>d = a ? b : c</td>
<td>(a∨c∨¬d)∧(¬a∨b∨¬d)∧(b∨c∨¬d)∧(¬a∨¬b∨d)∧(a∨¬c∨d)</td>
</tr>
</tbody>
</table>

The solve_circuit.py tool takes:




  • The assignments contained in the Verilog RTL file generated by IceStorm.




  • A problem specification containing:




    • constraints, e.g. the door must be open;




    • known values for some identifiers;




    • identifiers whose value we are seeking for (the <em>incognita</em>).






It parses the assignments using a simple Grako grammar, applies the Tseytin transformations presented above, and calls MiniSat to solve for the value of the <em>incognita</em>.


The problem specification is generated by the solve_hash tool, which simulates the circuit given some NMEA input, lists the keypad registers as <em>incognita</em>, and dumps a snapshot of every other register. The solve_circuit.py tool is automatically called by solve_hash.


To run these tools, first install the following additional prerequisites:


sudo apt-add-repository ppa:pypy/ppa && sudo apt-get update
sudo apt-get install pypy
wget https://bootstrap.pypa.io/get-pip.py && sudo -H pypy get-pip.py
sudo -H pypy -m pip install grako
sudo apt-get install minisat

Then compile the tool:


make solve_hash

The command line arguments accepted by solve_hash are exactly the same as the ones accepted by extract_hash:


$ ./solve_hash 1100 010415
WARNING: for repeatability, setting FPU to use double precision
============================[ Problem Statistics ]=============================
| |
| Number of variables: 12760 |
| Number of clauses: 10543 |
| Parse time: 0.00 s |
| Simplification time: 0.00 s |
| |
============================[ Search Statistics ]==============================
| Conflicts | ORIGINAL | LEARNT | Progress |
| | Vars Clauses Literals | Limit Clauses Lit/Cl | |
===============================================================================
===============================================================================
restarts : 1
conflicts : 0 (0 /sec)
decisions : 1 (0.00 % random) (250 /sec)
propagations : 12760 (3190000 /sec)
conflict literals : 0 (-nan % deleted)
Memory used : 24.00 MB
CPU time : 0.004 s

SATISFIABLE
01cd9de119e1231e29b0972a618da6c79fc1f3bd96cee86c93a8068bdc5e4c59


<h2><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Other write-ups and resources</h2>

</article>
</div>

</div>

<details class="details-reset details-overlay details-overlay-dark">
<summary data-hotkey="l" aria-label="Jump to line"></summary>
<details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast linejump" aria-label="Jump to line">
</option></form><form class="js-jump-to-line-form Box-body d-flex" action="" accept-charset="UTF-8" method="get">
<input class="form-control flex-auto mr-3 linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line…" aria-label="Jump to line" autofocus>
<button type="submit" class="btn" data-close-dialog>Go</button>
</form> </details-dialog>
</details>

<div class="Popover anim-scale-in js-tagsearch-popover"
hidden
data-tagsearch-url="/epicleet/write-ups-2016/find-symbols"
data-tagsearch-ref="pwn2win-ctf-2016"
data-tagsearch-path="pwn2win-ctf-2016/reverse/timekeeperslock-600/README.md"
data-tagsearch-lang="Markdown"
data-hydro-click="{"event_type":"code_navigation.click_on_symbol","payload":{"action":"click_on_symbol","repository_id":54845624,"ref":"pwn2win-ctf-2016","language":"Markdown","originating_url":"https://github.com/epicleet/write-ups-2016/blob/pwn2win-ctf-2016/pwn2win-ctf-2016/reverse/timekeeperslock-600/README.md","user_id":null}}"
data-hydro-click-hmac="47856b81a91236401b8c4ffc03cba54e27e8de781545d534e33b28b436b72b92">
<div class="Popover-message Popover-message--large Popover-message--top-left TagsearchPopover mt-1 mb-4 mx-auto Box box-shadow-large">
<div class="TagsearchPopover-content js-tagsearch-popover-content overflow-auto" style="will-change:transform;">
</div>
</div>
</div>

</div>
</div>

</main>
</div>

</div>


<div class="footer container-lg width-full p-responsive" role="contentinfo">
<div class="position-relative d-flex flex-row-reverse flex-lg-row flex-wrap flex-lg-nowrap flex-justify-center flex-lg-justify-between pt-6 pb-2 mt-6 f6 text-gray border-top border-gray-light ">


<svg height="24" class="octicon octicon-mark-github" viewBox="0 0 16 16" version="1.1" width="24" aria-hidden="true"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg>


</div>
<div class="d-flex flex-justify-center pb-6">
<span></span>
</div>
</div>

<div id="ajax-error-message" class="ajax-error-message flash flash-error">
<svg class="octicon octicon-alert" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 000 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 00.01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg>
<button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
<svg class="octicon octicon-x" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z"></path></svg>
</button>
You can’t perform that action at this time.
</div>

<script crossorigin="anonymous" async="async" integrity="sha512-WcQmT2vhcClFVOaaAJV/M+HqsJ2Gq/myvl6F3gCVBxykazXTs+i5fvxncSXwyG1CSfcrqmLFw/R/bmFYzprX2A==" type="application/javascript" id="js-conditional-compat" data-src="https://github.githubassets.com/assets/compat-bootstrap-59c4264f.js"></script>
<script crossorigin="anonymous" integrity="sha512-6XBdUZGib4aqdruJTnLMOLpIh0VJsGlgQ7M3vndWJIH6YQNv+zqpo1TbCDzjHJ+YYEm4xkEinaY0VsemDUfi9A==" type="application/javascript" src="https://github.githubassets.com/assets/environment-bootstrap-e9705d51.js"></script>
<script crossorigin="anonymous" async="async" integrity="sha512-EDN3kiqMVKpDXq6euD9tcIPeh3xqtWzCcm8mqqLAZOkXwdMo0hSA8Bfg0NqZ8c2n51yU4SlSal3hqgdrus+M2A==" type="application/javascript" src="https://github.githubassets.com/assets/vendor-10337792.js"></script>
<script crossorigin="anonymous" async="async" integrity="sha512-CcKFBqQZKOCZU5otP6R8GH2k+iJ3zC9r2z2Iakfs/Bo9/ptHy6JIWQN3FPhVuS3CR+Q/CkEOSfg+WJfoq3YMxQ==" type="application/javascript" src="https://github.githubassets.com/assets/frameworks-09c28506.js"></script>

<script crossorigin="anonymous" async="async" integrity="sha512-7Evx/cY3o6cyoeTQc+OX5n6X4k+wTJkQnAyjtmpge6F3Hgw511TPF+N0BFvn3IZLaQro6kyC/f0dqhklyssNow==" type="application/javascript" src="https://github.githubassets.com/assets/github-bootstrap-ec4bf1fd.js"></script>



<div class="js-stale-session-flash flash flash-warn flash-banner" hidden
>
<svg class="octicon octicon-alert" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 000 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 00.01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg>
<span>You signed in with another tab or window. Reload to refresh your session.</span>
<span>You signed out in another tab or window. Reload to refresh your session.</span>
</div>
<template id="site-details-dialog">
<details class="details-reset details-overlay details-overlay-dark lh-default text-gray-dark hx_rsm" open>
<summary role="button" aria-label="Close dialog"></summary>
<details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal">
<button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog>
<svg class="octicon octicon-x" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z"></path></svg>
</button>
<div class="octocat-spinner my-6 js-details-dialog-spinner"></div>
</details-dialog>
</details>
</template>

<div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;" tabindex="0">
<div class="Popover-message Popover-message--bottom-left Popover-message--large Box box-shadow-large" style="width:360px;">
</div>
</div>

<div aria-live="polite" class="js-global-screen-reader-notice sr-only"></div>

</body>
</html>

Original writeup (https://github.com/epicleet/write-ups-2016/tree/pwn2win-ctf-2016/pwn2win-ctf-2016/reverse/timekeeperslock-600).