index.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <link rel="canonical" href="http://127.0.0.1/mind-the-gap/">
  8. <link rel="shortcut icon" href="../img/favicon.ico">
  9. <title>Mind the gap - Google CTF 2023 | Retrospective</title>
  10. <link href="../css/bootstrap.min.css" rel="stylesheet">
  11. <link href="../css/font-awesome.min.css" rel="stylesheet">
  12. <link href="../css/base.css" rel="stylesheet">
  13. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/styles/github.min.css">
  14. <script src="../js/jquery-1.10.2.min.js" defer></script>
  15. <script src="../js/bootstrap.min.js" defer></script>
  16. <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js"></script>
  17. <script>hljs.initHighlightingOnLoad();</script>
  18. </head>
  19. <body>
  20. <div class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
  21. <div class="container">
  22. <a class="navbar-brand" href="..">Google CTF 2023 | Retrospective</a>
  23. <!-- Expander button -->
  24. <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar-collapse">
  25. <span class="navbar-toggler-icon"></span>
  26. </button>
  27. <!-- Expanded navigation -->
  28. <div id="navbar-collapse" class="navbar-collapse collapse">
  29. <!-- Main navigation -->
  30. <ul class="nav navbar-nav">
  31. <li class="navitem">
  32. <a href=".." class="nav-link">Home</a>
  33. </li>
  34. <li class="dropdown active">
  35. <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">misc <b class="caret"></b></a>
  36. <ul class="dropdown-menu">
  37. <li>
  38. <a href="./" class="dropdown-item active">Mind the gap</a>
  39. </li>
  40. </ul>
  41. </li>
  42. <li class="dropdown">
  43. <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">pwn <b class="caret"></b></a>
  44. <ul class="dropdown-menu">
  45. <li>
  46. <a href="../write-flag-where/" class="dropdown-item">Write flag where</a>
  47. </li>
  48. </ul>
  49. </li>
  50. </ul>
  51. <ul class="nav navbar-nav ml-auto">
  52. <li class="nav-item">
  53. <a href="#" class="nav-link" data-toggle="modal" data-target="#mkdocs_search_modal">
  54. <i class="fa fa-search"></i> Search
  55. </a>
  56. </li>
  57. <li class="nav-item">
  58. <a rel="prev" href=".." class="nav-link">
  59. <i class="fa fa-arrow-left"></i> Previous
  60. </a>
  61. </li>
  62. <li class="nav-item">
  63. <a rel="next" href="../write-flag-where/" class="nav-link">
  64. Next <i class="fa fa-arrow-right"></i>
  65. </a>
  66. </li>
  67. </ul>
  68. </div>
  69. </div>
  70. </div>
  71. <div class="container">
  72. <div class="row">
  73. <div class="col-md-3"><div class="navbar-light navbar-expand-md bs-sidebar hidden-print affix" role="complementary">
  74. <div class="navbar-header">
  75. <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#toc-collapse" title="Table of Contents">
  76. <span class="fa fa-angle-down"></span>
  77. </button>
  78. </div>
  79. <div id="toc-collapse" class="navbar-collapse collapse card bg-secondary">
  80. <ul class="nav flex-column">
  81. <li class="nav-item" data-level="1"><a href="#mind-the-gap" class="nav-link">Mind the gap</a>
  82. <ul class="nav flex-column">
  83. </ul>
  84. </li>
  85. </ul>
  86. </div>
  87. </div></div>
  88. <div class="col-md-9" role="main">
  89. <h1 id="mind-the-gap">Mind the gap</h1>
  90. <p>You are given a script <code>minesweeper.py</code> and text file <code>gameboard.txt</code>. Invoking the python script requires <code>pygame</code> to be installed.</p>
  91. <pre><code>pip install pygame
  92. </code></pre>
  93. <p>It takes several seconds to load. After loading we get a minesweeper game</p>
  94. <p><img alt="minesweeper" src="../images/mine-the-gap.png" /></p>
  95. <p>Inspect the script and search for CTF / FLAG etc.</p>
  96. <p>We see this part of the code</p>
  97. <pre><code class="language-python"> if len(violations) == 0:
  98. bits = []
  99. for x in range(GRID_WIDTH):
  100. bit = 1 if validate_grid[23][x].state in [10, 11] else 0
  101. bits.append(bit)
  102. flag = hashlib.sha256(bytes(bits)).hexdigest()
  103. print(f'Flag: CTF{{{flag}}}')
  104. else:
  105. print(violations)
  106. </code></pre>
  107. <p>Basically we need to solve it, and the we will be able to reconstruct the flag from the solution.</p>
  108. <p>Inspect <code>gameboard.txt</code> -- it looks like the board in a simple text format.</p>
  109. <p>The board seems very structured. It looks like putting one mine will collapse a lot of other cells, but not all.</p>
  110. <pre><code class="language-bash">❯ wc gameboard.txt
  111. 1631 198991 5876831 gameboard.txt
  112. </code></pre>
  113. <p>The board is 1600 x 3600 cels. It is huge. It is not possible to solve it by hand.</p>
  114. <p>We need to solve the board with code.</p>
  115. <p>Idea 1 use backtracking, and pray to be fast enough.</p>
  116. <p>Idea 2 skip backtracking and use SAT solver (Z3). This is what we did.</p>
  117. <p>With Z3 we can create variables and create constraints on the values they can get, then ask for a solution. If there is a solution, Z3 will give us the values for the variables. Z3 will find a solution in a reasonable™️ time.</p>
  118. <p>Check the code to generate the solution. With the solution we can easily generate the flag by using the code from the game.</p>
  119. <pre><code class="language-python">import z3
  120. with open('gameboard.txt') as f:
  121. data = f.read().split('\n')
  122. rows = len(data)
  123. cols = len(data[0])
  124. print(rows, cols, flush=True)
  125. solver = z3.Solver()
  126. vars = {}
  127. def get_var(i, j):
  128. assert data[i][j] == '9'
  129. if (i, j) not in vars:
  130. vars[i, j] = z3.Int(f'var_{i}_{j}')
  131. solver.add(0 &lt;= vars[i, j])
  132. solver.add(vars[i, j] &lt;= 1)
  133. return vars[i, j]
  134. for i in range(rows):
  135. for j in range(cols):
  136. if data[i][j] in '12345678':
  137. flags_on = 0
  138. pending = []
  139. for dx in [-1, 0, 1]:
  140. for dy in [-1, 0, 1]:
  141. if dx == 0 and dy == 0:
  142. continue
  143. nx = i + dx
  144. ny = j + dy
  145. if 0 &lt;= nx &lt; rows and 0 &lt;= ny &lt; cols:
  146. if data[nx][ny] == 'B':
  147. flags_on += 1
  148. elif data[nx][ny] == '9':
  149. pending.append(get_var(nx, ny))
  150. if not pending:
  151. continue
  152. solver.add(z3.Sum(pending) + flags_on == int(data[i][j]))
  153. print(len(vars))
  154. for i in range(rows):
  155. for j in range(cols):
  156. if data[i][j] == '9':
  157. assert (i, j) in vars
  158. print(&quot;Solving...&quot;)
  159. print(solver.check())
  160. for (i, j), v in vars.items():
  161. if solver.model()[v] == 1:
  162. print(i, j)
  163. </code></pre></div>
  164. </div>
  165. </div>
  166. <footer class="col-md-12">
  167. <hr>
  168. <p>Documentation built with <a href="https://www.mkdocs.org/">MkDocs</a>.</p>
  169. </footer>
  170. <script>
  171. var base_url = "..",
  172. shortcuts = {"help": 191, "next": 78, "previous": 80, "search": 83};
  173. </script>
  174. <script src="../js/base.js" defer></script>
  175. <script src="../search/main.js" defer></script>
  176. <div class="modal" id="mkdocs_search_modal" tabindex="-1" role="dialog" aria-labelledby="searchModalLabel" aria-hidden="true">
  177. <div class="modal-dialog modal-lg">
  178. <div class="modal-content">
  179. <div class="modal-header">
  180. <h4 class="modal-title" id="searchModalLabel">Search</h4>
  181. <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
  182. </div>
  183. <div class="modal-body">
  184. <p>From here you can search these documents. Enter your search terms below.</p>
  185. <form>
  186. <div class="form-group">
  187. <input type="search" class="form-control" placeholder="Search..." id="mkdocs-search-query" title="Type search term here">
  188. </div>
  189. </form>
  190. <div id="mkdocs-search-results" data-no-results-text="No results found"></div>
  191. </div>
  192. <div class="modal-footer">
  193. </div>
  194. </div>
  195. </div>
  196. </div><div class="modal" id="mkdocs_keyboard_modal" tabindex="-1" role="dialog" aria-labelledby="keyboardModalLabel" aria-hidden="true">
  197. <div class="modal-dialog">
  198. <div class="modal-content">
  199. <div class="modal-header">
  200. <h4 class="modal-title" id="keyboardModalLabel">Keyboard Shortcuts</h4>
  201. <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
  202. </div>
  203. <div class="modal-body">
  204. <table class="table">
  205. <thead>
  206. <tr>
  207. <th style="width: 20%;">Keys</th>
  208. <th>Action</th>
  209. </tr>
  210. </thead>
  211. <tbody>
  212. <tr>
  213. <td class="help shortcut"><kbd>?</kbd></td>
  214. <td>Open this help</td>
  215. </tr>
  216. <tr>
  217. <td class="next shortcut"><kbd>n</kbd></td>
  218. <td>Next page</td>
  219. </tr>
  220. <tr>
  221. <td class="prev shortcut"><kbd>p</kbd></td>
  222. <td>Previous page</td>
  223. </tr>
  224. <tr>
  225. <td class="search shortcut"><kbd>s</kbd></td>
  226. <td>Search</td>
  227. </tr>
  228. </tbody>
  229. </table>
  230. </div>
  231. <div class="modal-footer">
  232. </div>
  233. </div>
  234. </div>
  235. </div>
  236. </body>
  237. </html>