darkelf 로그인 후 파일을 확인한다.
코드 파일을 확인한다.
힌트와 추가된 부분까지만 보겠다.
추가된 부분을 분석한다.
argv[0]이 77이 아니면 if 문을 실행한다. 코드는 아주 간단하다. 지금까지 argv[1], argv[2]를 사용해서 argv[0]이 어떤 것인지는 알 순 있지만 어떻게 해야 할지 고민이 많아진다.
gdb로 메모리 분석한다.
이때, 추가된 부분만 가져오겠다.
level 6 [wolfman]에서 배운 어셈블리 언어의 if 문의 분석 방법을 통해 분석한다.
strlen 함수를 부르고 cmp로 "%eax, 77"을 비교한다. 여기서 %eax 레지스터에는 argv[0]이 들어있고 77과 비교한다.
코드에서는 "!=(JNE)"인데 대우 명제를 취해 "==(JE)"를 사용해 argv[0]이 77과 같으면 main+80번으로 점프하는 어셈블리어가 들어가 있다.
이후 어셈블리 코드는 이전 문제의 코드들과 같다. 이전 문제의 어셈블리 코드를 참고해도 되고 문제가 옆에 있다면 코드를 직접 보면서 메모리 스택을 찾기 바란다.
메모리 스택을 도식화한다.
int i 4byte |
char buffer[40] 40byte |
SFP 4byte |
RET 4byte |
메모리 스택은 항상 보는 것과 같다.
항상 보던 메모리 스택이니 같은 방법으로 페이로드를 만들어 본다.

main에 break를 걸고 인수를 두 개 주고 실행하고 esp를 찾는다.

argv[2]가 "0xbffffc48"에서 시작한다. 페이로드를 실행한다.

페이로드를 실행하면 추가된 if 문에서 오류가 난다.
위에서 언급한 argv[0] 때문이다. 예를 들어 "./orge AAAAA BBBBB"가 있을 때 argv[0]은 "./orge", argv[1]은 "AAAAA", argv[2]는 "BBBBB"이다. 즉, "실행파일의 이름 + ./"이다.
실행파일 이름의 길이 + "./"가 77이 되지 않았기 때문에 오류가 난다.
여기서 어떻게 해야 할지 고민이 많이 되고 문제 풀이도 찾아봤을 것이다. 본인도 몇 개의 문제풀이를 찾아봤는데 그중 몇 개가 해커스쿨의 버그를 사용한 풀이가 있었다.
이 문제에는 버그가 존재하는데 그 버그는 권한을 뛰어넘어 파일의 이름을 바꾸는 버그가 있다.
이 문제의 권한은 darkelf의 권한인데 rename 명령어로 orge 권한의 파일인 orge, root 권한의 orge.c 파일의 이름을 바꿔보면 이름이 변경되는 걸 볼 수 있는데 이것은 모르는 권한 설정에 관련된 무언가 있거나, 버그일 가능성이 크다. 그래서 rename 명령어를 사용하는 게 아닌 F.T.Z level 5에서 다뤘던 심볼릭 링크를 사용한다.
심볼릭 링크를 통해 orge에 링크를 걸어준다.

심볼릭 링크를 걸었으니 페이로드를 실행한다.

argv[0] error는 피했지만 seg fault가 일어난다. 심볼릭 링크로 argv[0] error가 나오지 않는데 다른 오류가 날까? 고민을 많이 했다. 그러면서 다시 처음부터 해보기도 하고 gdb로 다시 주소를 찾아보기도 하고 level 6에서 언급했듯이 gdb로 실행할 때 인수를 많이 넣어서 주소도 다르게 찾아보기도 했지만, 모두다 sge fualt가 일어난다.
많은 실패를 거듭하던 중 어디선가 들었던 것이 생각났다. 아마 어느 강의일듯하다.
위 파일 목록을 보듯이 gdb에서 실행할 수 있도록 orge 파일을 cp 명령어로 "o"라는 이름으로 복사해서 gdb로 열었다.
여기서 잘못된 것이다. 또 gdb로 "o" 파일 main에 break를 주지 않고 main+275에 break를 주고 실행한다면 argv[0] error가 나오는 것을 보고 갑자기 생각났다.
생각이 난 것은 파일의 이름에 따라 주소가 변할 수 있다는 것이었다. 그래서 위 페이로드의 주소는 gdb로 "o"파일을 열어 찾은 주소다. 파일 이름에 따라 주소가 변한다면 gdb로 실행하기 위해 cp를 할 때 77 길이를 맞추기 위해 파일 이름을 75 길이로 정해 cp를 하던지 cp는 쉽게 하고 cp 한 파일에 75 길이의 심볼릭 링크를 걸어서 실행하는 방법이 있다.
본인이 혼자 풀어볼 때 cp를 "o"로 해서 "o"에 심볼릭 링크를 만들어 사용했다.

여기서는 cp로 풀어보려고 한다.

gdb로 "B" * 75 파일을 열고 실행한다.

esp를 찾아본다.

argv[2]의 주소가 "0xbffffc00"에서 시작하고 위에서 찾은 주소와 다른 주소가 나오는 것을 알 수 있다.
페이로드를 작성한다.

뭔가 잘못됐는지 주소를 바꿔서 해봐도 오류가 나고 셸은 실행되지 않는다. 이럴 때는 어디서 오류가 났는지 알 수 있도록 core 파일을 만들어 줘야 한다. core 파일을 만들 때는 자신의 권한에서 seg fault가 나면서 core 파일이 생성된다.

core 파일은 gdb -c 옵션으로 메모리를 볼 수 있다.

esp를 찾아본다.

argv[2]가 제대로 시작하는 주소가 또 다른 주소인 "0xbffffbc0"이다. 여기서 "\x90(NULL byte)"없이 셸 코드가 바로 들어가다 보니 어디서 시작하는지 찾기 힘들 수도 있다. 그러면 셸 코드 앞에 "\x90"를 추가해서 argv[2]가 시작하는 주소를 찾으면 훨씬 편하게 찾을 수 있다.
페이로드를 작성한다.

"\x90"없이 정확한 주소에 넣어서 "Illegal instruction"이 일어나지 않고 셸이 실행됐다.
지금까지 사용하지 않았던 core 파일을 사용했는데 정말 문제가 풀리지 않는다면 core 파일까지 열어서 주소를 확인해보는 방법까지 해봐야 한다. core 파일을 열어서 주소를 확인하면 거의 풀린다. 그래서 위 core 파일이 나오기 전 시도들을 해보지 않고 바로 core 파일을 만들어 푸는 분들도 보았다.
더 보기 밖에서 말했듯이 이 문제에서는 본인이 시도한 실패 사례를 자세하게 언급하고 싶었다. 문제를 풀면서 모르는 부분을 다른 분들의 문제풀이를 통해 배운 점도 있지만, 실패 사례까지 언급해주는 분은 별로 없었고 실패하다가 생각이 났던 것도 있고 배운 점이 있었기 때문에 문제 풀이가 길어짐에도 불구하고 언급하고 싶었다.
실패 사례를 볼 때 "A"를 실행했는지 "B"를 실행했는지 어떤 주소가 들어갔는지를 주의해서 보길 바란다.
문제 분석은 짧지만, 실패 사례를 포함해 풀이는 엄청나게 길다.
혼자 공부하는 중이라면 어디서 물어볼 수도 없고 왜, 어떻게 되는지 모르고 검색으로 나오는 문제 풀이에서 간단히 페이로드만 입력해서 넘어가기 바쁜데 좀 더 자세히 설명해서 나중에 본인이 보더라도 이해할 수 있도록 풀이가 길어짐에도 언급하고 싶었던 것이 많았다.
'System Hacking > 해커스쿨 L.O.B Hacking Zone' 카테고리의 다른 글
해커스쿨 L.O.B level 6 [wolfman] (0) | 2020.05.25 |
---|---|
해커스쿨 L.O.B level 5 [orc] (0) | 2020.05.21 |
해커스쿨 L.O.B level 4 [goblin] (0) | 2020.05.18 |
해커스쿨 L.O.B level 3 [cobolt] (0) | 2020.05.17 |
해커스쿨 L.O.B level 2 [gremlin] (0) | 2020.05.16 |
댓글