Advertisement
Guest User

Untitled

a guest
Mar 18th, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.66 KB | None | 0 0
  1. so r11 becomes the length of the password
  2.  
  3. It moves the value of 43B4 into r15
  4. This is the location just before the password.
  5. It compares it to r11.
  6.  
  7. So the value of 43B4, which is the character s in the username, must be a value greater than the length of the password.
  8. Let's test it again, and see if the address changes when lengths change.
  9.  
  10. We will do a password of 5 characters, and username of 10.
  11.  
  12. r11 = 5, so r11 is the length of the password
  13. r4 = 43cc still, so it still grabs 43B4
  14.  
  15. Ahha! 43B4 is normally set to the value 10, which is 16 in hex. So normally it compares to the password length.
  16. The thing is, the username storage can overwrite this address. So as long as we make 19th character in our username a value
  17. which is greater than the length of our password we will not be halted at 45ec.
  18.  
  19. r4 is still 43cc, so next it grabs the value at 43B3m which is 08.
  20. It sticks this in r15, and compares it to r11.
  21. r11 = length of our password, r15 = hard coded value of 8.
  22. It does a JC to skip a halt. This means the length of our password must be greater than the value at 43B3.
  23.  
  24. So, what have we learned so far:
  25.  
  26. Password length must be greater than value at 43B3, and less than the value at 43B4.
  27. We can control these addresses by overflowing the username, so they can be whatever we need them to.
  28. Let's keep going for now. We are going to fail this check, so we do: let r15 = 2
  29. Now it just has to be greater than 2.
  30.  
  31. Next it looks like preparation to make the syscall to 7d, which is the password check and flag setting.
  32. For now, I'm going to assume this will always fail and we are going to need to overwrite the return address after the login function.
  33. Let's just step past it and keep an eye on r4, which seems to be an anchor for refercing addresses during tests.
  34.  
  35. Yep, it's still 43cc. It looks like it then tests 43A0 for zero. This is a hard coded area in the memory which we have no control over.
  36. This will always be 0, unless by some luck we guess the right password and the int call to 7d sets it to something else.
  37. Not likely, so expect it to be 0.
  38.  
  39. That jumps us to the password incorrect and skips the unlock function. That's fine, we plan on this happening and want to instead overwrite the return.
  40.  
  41. It looks like there's one last program halt to avoid at 465a before the function can return.
  42. It checks 43C6 for a null byte. If it's not null it will halt the program.
  43. This is checking for a password overflow and ensuring there's a null byte here.
  44. 43C6 is the 17th character of the password. Since the limit is 16 characters this must be a null byte.
  45.  
  46. So we can't overflow using the password, but we can overflow using the username.
  47. This will write over 43C6, but since the password memcpy is after the username memcpy, the password will correctly stick a null byte here
  48. as long as we use a 16 character password.
  49.  
  50. This should allow us to overflow the username, setting the return address, ensuring our hardcoded length values work against the checks, and
  51. sticking the address 444a in it's place to jump to the door unlock.
  52.  
  53. so for our username, since s is the password max length, and u is the min length, we just need to be observant here.
  54. The rest will fill with more garbage until we find what positions overwrite the return address, and the password will simply be 16 characters.
  55.  
  56. Alright, so lets craft some arcane passwords here and get some magic happening.
  57. First let's ensure we can set the hardcoded values of min/max length with an overflow.
  58.  
  59. 43B4 = max length (pass)
  60. 43B3 = min length (pass)
  61.  
  62. We will put a break at 45EC, right before the first jump after max length check.
  63. in the password abcdefghijklmnopqrstuvwxyz, r = min length and s = max
  64. so convert to hex, and replace the ascii codes 72(r) and 73(s) with 01 and 9f.
  65. Remember, we can't use null bytes so we can't use 00, so this is the lowest and highest checks possible.
  66. This leaves us with: 6162636465666768696a6b6c6d6e6f7071019f7475767778797a
  67.  
  68. For our password, anything with 16 chars is fine.
  69. AAAAAAAAAAAAAAAA
  70.  
  71. Let's put these and and check our special addresses.
  72.  
  73. > read 43b3
  74. 43b3: 019f 4141 4141 4141 ..AAAAAA
  75. 43bb: 4141 4141 4141 4141 AAAAAAAA
  76. 43c3: 4141 0000 0000 0000 AA......
  77. 43cb: 0040 4400 0000 0000 .@D.....
  78.  
  79. Hey look at that, 01, and 9f!
  80.  
  81. R11 is also the length of our password, 16, so all is going as expected.
  82. If we put a break at 4666, just before login returns, we should successfully avoid all traps and reach it.
  83. Let's try that and C.
  84.  
  85. Success! The PC then grabs the return address of 4440.
  86. Hey wait... I see it there, it's address 43cc and 43cd, 40 and 44 respectively.
  87. We will attempt to overwrite this with 444a.
  88.  
  89. We can see our username starts at address 43a2
  90. 16 characters later we are at 43b2.
  91. 16 more = 43c2. 10 characters later, or A, we are at 43CC.
  92.  
  93. So, at exactly 42 characters we hit 43CC.
  94. So character 42 must = 4a, and character 43 must = 44.
  95. Character 18 = 01
  96. Character 19 = 9f
  97. Let's python this up.
  98.  
  99. '41'*17 + '019f' + '41'* 22 + '4a44'
  100.  
  101. So it's 17 + 2 = 19
  102. + 22 = 41
  103. + 2 = 43
  104.  
  105. username:
  106. 4141414141414141414141414141414141019f414141414141414141414141414141414141414141414a44
  107.  
  108. password:
  109. 42424242424242424242424242424242
  110.  
  111. Let's run it:
  112.  
  113. > read 43b3
  114. 43b3: 019f 4242 4242 4242 ..BBBBBB
  115. 43bb: 4242 4242 4242 4242 BBBBBBBB
  116. 43c3: 4242 0041 4141 4141 BB.AAAAA
  117. 43cb: 4a44 0000 0000 0000 JD......
  118.  
  119. Hey that looks good! 01 and 9f as min/max.
  120.  
  121. > read 43c6
  122. 43c6: 4141 4141 414a 4400 AAAAAJD.
  123. 43ce: 0000 0000 0000 0000 ........
  124. 43d6: 0000 0000 0000 0000 ........
  125. 43de: 0000 0000 0000 0000 ........
  126.  
  127. Uh oh, looks like our null byte check may fail, let's break right before it.
  128. Yep, it fails, we missed the null byte by 1. Adding a 17th character to the password should fix this.
  129.  
  130. > read 43c6
  131. 43c6: 0041 4141 414a 4400 .AAAAJD.
  132. 43ce: 0000 0000 0000 0000 ........
  133. 43d6: 0000 0000 0000 0000 ........
  134. 43de: 0000 0000 0000 0000 ........
  135.  
  136. Yes! It looks good, and lets check our return address:
  137.  
  138. read 43cc
  139. 43cc: 4400 0000 0000 0000 D.......
  140. 43d4: 0000 0000 0000 0000 ........
  141. 43dc: 0000 0000 0000 0000 ........
  142. 43e4: 0000 0000 0000 0000 ........
  143.  
  144. Oops... math is hard. We are off by one character in the username before the overwrite.
  145.  
  146.  
  147. 4141414141414141414141414141414141019f41414141414141414141414141414141414141414141414a44
  148. 4242424242424242424242424242424242
  149.  
  150. > read 43c6 1
  151. 43c6: 0041 4141 4141 4a44 .AAAAAJD
  152.  
  153. > read 43cc 1
  154. 43cc: 4a44 0000 0000 0000 JD......
  155.  
  156. Perfect, we have the null byte check passing, and the return address as 444a.
  157.  
  158. There's that beautiful message: If you were not connected to the debug lock, the door would now be open. Now reset the CPU and type "solve" to run on the real lock, without the debugger. The CPU completed in 12835 cycles.
  159. Let's solve it.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement