diff --git a/README.org b/README.org index e2dd323..117d497 100644 --- a/README.org +++ b/README.org @@ -2,6 +2,8 @@ Solutions to the [[http://www.boundvariable.org/task.shtml][2006 ICFP Programming Contest]]. +*Warning: spoilers below!* + ** Universal Machine The Universal Machine is implemented in [[um.c]]. Compile it with =make= @@ -11,3 +13,33 @@ and run it on a UM program: ./um sandmark.umz # benchmark ./um codex.umz #+end_src + +Get the next program: + +#+begin_src sh + echo '(\\b.bb)(\\v.vv)06FHPVboundvarHRAk\np' | ./um codex.umz > codex_output + tail -c +196 codex_output > umix.um +#+end_src + +** QVICKBASIC + +The fixed program is in [[hack.bas]]. We find the passwords of =ohmega= +and =howie=. + +** Passwords found + +| user | password | +|--------+---------------| +| ohmega | bidirectional | +| howie | xyzzy | +| ftd | falderal90 | + +** Publications found + +#+begin_src +INTRO.LOG=200@999999|35e6f52e9bc951917c73af391e35e1d +INTRO.MUA=5@999999|b9666432feff66e528a17fb69ae8e9a +INTRO.UMD=10@999999|7005f80d6cd9b7b837802f1e58b11b8 +INTRO.QBC=10@999999|e6ee9c98b80b4dd04814a29a37bcba8 +INTRO.OUT=5@999999|69ca684f8c787cfe06694cb26f74a95 +#+end_src diff --git a/hack.bas b/hack.bas new file mode 100644 index 0000000..b749122 --- /dev/null +++ b/hack.bas @@ -0,0 +1,115 @@ +V REM +------------------------------------------------+ +X REM | HACK.BAS (c) 19100 fr33 v4r14bl3z | +XV REM | | +XX REM | Brute-forces passwords on UM vIX.0 systems. | +XXV REM | Compile with Qvickbasic VII.0 or later: | +XXX REM | /bin/qbasic hack.bas | +XXXV REM | Then run: | +XL REM | ./hack.exe username | +XLV REM | | +L REM | This program is for educational purposes only! | +LV REM +------------------------------------------------+ +LX REM +LXV IF ARGS() > I THEN GOTO LXXXV +LXX PRINT "usage: ./hack.exe username" +LXXV PRINT CHR(X) +LXXX END +LXXXV REM +XC REM get username from command line +XCV DIM username AS STRING +C username = ARG(II) +CV REM common words used in passwords +CX DIM pwdcount AS INTEGER +CXV pwdcount = LIII +CXX DIM words(pwdcount) AS STRING +CXXV words(I) = "airplane" +CXXX words(II) = "alphabet" +CXXXV words(III) = "aviator" +CXL words(IV) = "bidirectional" +CXLV words(V) = "changeme" +CL words(VI) = "creosote" +CLV words(VII) = "cyclone" +CLX words(VIII) = "december" +CLXV words(IX) = "dolphin" +CLXX words(X) = "elephant" +CLXXV words(XI) = "ersatz" +CLXXX words(XII) = "falderal" +CLXXXV words(XIII) = "functional" +CXC words(XIV) = "future" +CXCV words(XV) = "guitar" +CC words(XVI) = "gymnast" +CCV words(XVII) = "hello" +CCX words(XVIII) = "imbroglio" +CCXV words(XIX) = "january" +CCXX words(XX) = "joshua" +CCXXV words(XXI) = "kernel" +CCXXX words(XXII) = "kingfish" +CCXXXV words(XXIII) = "(\b.bb)(\v.vv)" +CCXL words(XXIV) = "millennium" +CCXLV words(XXV) = "monday" +CCL words(XXVI) = "nemesis" +CCLV words(XXVII) = "oatmeal" +CCLX words(XXVIII) = "october" +CCLXV words(XXIX) = "paladin" +CCLXX words(XXX) = "pass" +CCLXXV words(XXXI) = "password" +CCLXXX words(XXXII) = "penguin" +CCLXXXV words(XXXIII) = "polynomial" +CCXC words(XXXIV) = "popcorn" +CCXCV words(XXXV) = "qwerty" +CCC words(XXXVI) = "sailor" +CCCV words(XXXVII) = "swordfish" +CCCX words(XXXVIII) = "symmetry" +CCCXV words(XXXIX) = "system" +CCCXX words(XL) = "tattoo" +CCCXXV words(XLI) = "thursday" +CCCXXX words(XLII) = "tinman" +CCCXXXV words(XLIII) = "topography" +CCCXL words(XLIV) = "unicorn" +CCCXLV words(XLV) = "vader" +CCCL words(XLVI) = "vampire" +CCCLV words(XLVII) = "viper" +CCCLX words(XLVIII) = "warez" +CCCLXV words(XLIX) = "xanadu" +CCCLXX words(L) = "xyzzy" +CCCLXXV words(LI) = "zephyr" +CCCLXXX words(LII) = "zeppelin" +CCCLXXXV words(LIII) = "zxcvbnm" +CCCXC REM try each password +CCCXCV PRINT "attempting hack with " + pwdcount + " passwords " + CHR(X) +CD DIM i AS INTEGER +CDV i = I +CDX IF CHECKPASS(username, words(i)) THEN GOTO CDXXX +CDXV i = i + I +CDXX IF i > pwdcount THEN GOTO CDXLV +CDXXV GOTO CDX +CDXXX PRINT "found match!! for user " + username + CHR(X) +CDXXXV PRINT "password: " + words(i) + CHR(X) +CDXL END +CDXLV PRINT "no simple matches for user " + username + CHR(X) +CDL REM +CDLV REM the above code will probably crack passwords for many +CDLX REM users so I always try it first. when it fails, I try the +CDLXV REM more expensive method below. +CDLXX REM +CDLXXV REM passwords often take the form +CDLXXX REM dictwordDD +CDLXXXV REM where DD is a two-digit decimal number. try these next: +CDXC i = I +CDXCV DIM j AS INTEGER +CDXCVI DIM k AS INTEGER +D IF i > pwdcount THEN GOTO DL +DV j = I +DVI k = I +DX IF CHECKPASS(username, words(i) + CHR(XLVII + j) + CHR(XLVII + k)) THEN GOTO DXXXV +DXV k = k + I +DXVI IF k < XI THEN GOTO DX +DXVII j = j + I +DXX IF j < XI THEN GOTO DVI +DXXV i = i + I +DXXX GOTO D +DXXXV PRINT "found match!! for user " + username + CHR(X) +DXL PRINT "password: " + words(i) + CHR(XLVII + j) + CHR(XLVII + k) + CHR(X) +DXLV END +DL PRINT "no matches for user " + username + CHR(X) +DLV END diff --git a/umix.um b/umix.um new file mode 100644 index 0000000..acedfae Binary files /dev/null and b/umix.um differ