Last active
January 22, 2016 06:29
-
-
Save fbonzon/480a1c7877a34d9f3e93 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/opt/local/bin/php56 | |
| <?php | |
| # Solution to "Bring the noise" challenge of Insomni'hack 2016 teaser. | |
| # | |
| # Time to run: few seconds, almost exclusively for reversing the hash. | |
| # Second part to verify equations is extremely fast. | |
| const REMOTE_HOST = 'bringthenoise.insomnihack.ch'; | |
| const REMOTE_PORT = 1111; | |
| # Constants from given Python code. | |
| const POWLEN = 5; | |
| const Q = 8; | |
| $connection = fsockopen(REMOTE_HOST, REMOTE_PORT); | |
| echo $line = fgets($connection); | |
| $challenge = substr(rtrim($line), -POWLEN); | |
| # Reverse hash by brute force with random data. | |
| $random = fopen('/dev/urandom', 'r'); | |
| while ($challenge != substr(md5($bytes = fread($random, POWLEN)), 0, POWLEN)); | |
| fclose($random); | |
| fwrite($connection, $bytes . "\n"); | |
| # Read equations. Stop processing when we see "Enter solution". | |
| $equations = []; | |
| echo 'Equations:', "\n"; | |
| while (false === strpos($line = fgets($connection), 'Enter solution')) { | |
| echo $line; | |
| $equations[] = explode(', ', rtrim($line)); | |
| } | |
| # Verifies if given solution satisfies given equation. | |
| function verify_equation ($solution, $equation) { | |
| $result = array_pop($equation); | |
| $sum = array_sum(array_map(function ($solution, $coef) { | |
| return $solution * $coef; | |
| }, $solution, $equation)); | |
| # Vibration might decrease result by 1, keep it unchanged or increase it by 1. | |
| if (($sum - $result + 1) % Q > 2) { | |
| return false; | |
| } | |
| return true; | |
| } | |
| # Brute force all solutions. Since digits vary from 0 to 7, we can encode them | |
| # in an integer interpreted as an octal number. | |
| for ($i = 0777777; $i >= 0; --$i) { | |
| $solution = str_split(sprintf('%06o', $i)); | |
| foreach ($equations as $equation) { | |
| if (!verify_equation($solution, $equation)) { | |
| # Abandon solution as soon as one of the equations isn't satisfied. | |
| continue 2; | |
| } | |
| } | |
| # All equations verified, solution is found. | |
| break; | |
| } | |
| echo 'Solution:', "\n", $solution = implode(', ', $solution) . "\n"; | |
| fwrite($connection, $solution); | |
| echo fgets($connection); | |
| fclose($connection); | |
| # Flag: INS{ErrorsOccurMistakesAreMade} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment