-
JakartaWargame/Microcorruption 2014. 8. 11. 17:34
login 함수를 살펴보면 username을 strcpy로 복사해오고, 그 길이(r11)가 0x21보다 크거나 같으면 프로그램을 종료해버린다.
45ae: 7b90 2100 cmp.b #0x21, r11 45b2: 0628 jnc #0x45c0 <login+0x60> 45b4: 1f42 0024 mov &0x2400, r15 45b8: b012 c846 call #0x46c8 <puts> 45bc: 3040 4244 br #0x4442 <__stop_progExec__>
즉, 우리는 최대 0x20까지만 username을 입력할 수 있다.
조금 더 아래쪽을 보면 [ 0x1f - username의 길이(r11) ] 부분이 있다.
헌데 우리는 0x20까지 입력이 가능했다. 즉 [ 0x1f - 0x20 ] 의 결과로 0xffff(-1)가 나오게 된다.
이후 이 값이 r14에 들어가 0x1ff와 and연산을 하게 되고, 그 결과가 getsn의 인자(입력길이)로 사용되게 된다.
45c8: 3e40 1f00 mov #0x1f, r14 45cc: 0e8b sub r11, r14 45ce: 3ef0 ff01 and #0x1ff, r14 45d2: 3f40 0224 mov #0x2402, r15 45d6: b012 b846 call #0x46b8 <getsn>
즉 username은 0x20 까지밖에 입력할 수 없지만, 위의 방식대로 Integer Underflow 취약점이 발생하게 되고,
이를 이용해 password를 0x1ff 까지 입력 가능하게 된다.
이후 하나의 관문이 더 남아있다. 바로 password의 길이를 체크하는 부분이다.
45fe: 0f5b add r11, r15 4600: 7f90 2100 cmp.b #0x21, r15 4604: 0628 jnc #0x4612 <login+0xb2> 4606: 1f42 0024 mov &0x2400, r15 460a: b012 c846 call #0x46c8 <puts> 460e: 3040 4244 br #0x4442 <__stop_progExec__>
위와 같이 [ username길이 + password길이 ]가 0x20보다 크거나 같으면 프로그램을 종료하는 부분이다.
하지만 자세히 보면 cmp가 아니라 cmp.b 인것을 알 수 있다.
즉, 한 바이트만을 비교한다. 0x21이면 프로그램이 종료되어 버리겠지만 0x100 ~ 0x120 만큼의 입력으로 우회할 수 있다.
즉 payload는 아래와 같다.
username
password
junk
junk
RET
junk
32 Byte
4 Byte
2 Byte
218 Byte
'Wargame > Microcorruption' 카테고리의 다른 글
Addis Ababa (0) 2014.08.14 Santa Cruz (0) 2014.08.04 Montevideo (0) 2014.07.31 Whitehorse (0) 2014.07.31 Johannesburg (0) 2014.07.31