2019. 1. 20. 23:32ㆍSystem Hacking/FTZ
안녕하세요! 오늘은 FTZ level 9
풀이를 해보도록 하겠습니다!
문제의 코드를 보니
아래처럼 적혀있네요!
main 함수 안에
main 함수안에 지역변수로
buf2가 10바이트 선언되고
buf가 10바이트 선언되네요!
지역변수는 stack에 쌓이는데!
먼저 선언된 순서로 stack에 쌓이게 되니!
buf가 buf2보다 위에 있겠네요!
스택은 높은주소에서 낮은 주소로 쌓이니!
아래처럼요!
<스택 구조>
[낮은 주소] buf[10]
buf2[10]
(saved) EBP
[높은 주소] EIP(return address)
그리고 출력을 하네요!
오버플로우가 가능하다 = it can be overflow
그리고 fgets함수로 사용자로부터 입력을 받네요!
stdin=standard input(표준 입력)으로 40 byte를 입력받아
buf에 저장하네요!
그러면 여기서 왜 overflow가 발생할까요?
1) buf의 크기를 보세요! 몇 byte죠? 10!
2) 표준 입력으로 받아서 buf에 저장하는 데이터는 몇 byte죠? 40!
그릇의 크기가 10인데 40을 담죠!
그러면 나머지 30은 어디에 담길까요?
바로 뒤에 있는 장소에 담기겠죠!
이 상태에서 바로 밑에 있는
코드를 보면, strncmp를 하네요!
문자를 비교한다= string compare!
buf2 와 문자열 go를 앞에서부터 2글자!
buf2의 앞에서 두 글자와, 문자열 go의 두 글자!
strcmp은 비교문자가 같으면 0이 나오거든요!
그래서 같으면 good skill이라고 출력!
setuid 함수원리는 정확히는 모르겠지만
level10으로 권한상승시켜주고
level10의 쉘이 떨어지네요!
자 일단 가서! 봅시다!
/usr/bin 폴더로 가서!
bof를 실행시키고
a를 12개 넣었어요!
왜냐?
위의 스택구조에서 buf아래에 바로 buf2니까
buf를 10글자로 채우고
그 이후부터 입력은 buf2에 입력되니까요!
즉 buf에 a 10글자 + buf2에 a 2글자 넣으면
buf2 앞에 2글자가
aa가 되니까요!
물론 buf2의 2글자가 go여야지
문제가 풀리지만
일단은 실험용으로 다른 값을 넣어보고
반응을 살펴봤습니다!
근데 저는 일단 해당 소스를 컴파일하고
gdb로 분석해보고 싶어서
hint에 있는 소스코드 긁어와서
tmp 파일로 이동해서 vi 9.c
파일을 생성하고
아래와 같이 소스를 붙여넣었습니다!
나와서 gcc로 -g -o 설정주고 컴파일을 해서
9라는 파일이 생성 될걸 확인하였고,
저는 이것을 바로 gdb로 분석해보기로 하였습니다!
뭐 시작에는 프롤로그가 있죠
push %ebp
mov %esp, %ebp
%가 있으면 intel 방식이 아니라
왼쪽에서 오른쪽으로 진행되요!
sub $0x28, %esp
0x28만큼 스택공간을
ebp 주소에서 빼서
지역변수와 다른 것들을 사용하기 위해
할당한 건데,
공학용 계산기로 돌려보면
Hex(16진수) 28은 = 40이네요!
20 바이트만 할당해도 되는데
buf, buf2가 각각 10이니까요..
왜 40을 했을까????
흠...
어찌 됐든, 저희는 buf2의 시작주소
buf의 시작주소를 알아내면 문제는 쉽게 풀립니다!
여기서 저는 이렇게 풀었습니다!
buf의 주소는 fgets의 인자로 넘어가고
buf2의 주소는 strncmp의 인자로 넘어가기에
그때를 딱 포착하기로 했습니다!
원래 함수를 call 하기 이전에
함수의 인자들을 push 하거든요!
함수인자는 역순으로 push 돼요!
fgets(buf,40,stdin)이면
stdin이 제일먼저 push
40이 다음 push
buf가 마지막으로 push
fgets <main+47> 에서 마지막으로 push되는 eax
0xffffffd8의 값을 갖고 있구요!
strncmp <main+69> 에서 마지막으로 push되는 것도
eax인데 이 값의 경우
0xffffffe8이네요!
그러면 다 나왔네요!
0xffffffe8-0xffffffd8=하면 두 버퍼간의 거리!
그 거리만큼 채워주고 바로 그 뒤에 go를 넣으면
문제가 풀리겠네요!
공학용 계산기에서 16진수
e8-d8하니까 = 16(10진수) 나오네요!
즉 buf의 시작 지점과 buf2의 시작 지점
사이는 16byte!
그래서 일단 제가 아까 컴파일한
9를 실행시키고 16글자 a+go를 입력하니
아래와 같이 good skill!이 뜨네요!
이제 이걸 원래 프로그램가서 실행시키면 문제가 풀려요!!
근데 이 방법 말고도 좀 야매로 푸는 방법도 있어요!
어차피 buf와 buf2 사이에 공간을 모르니
일단 시도를 계속 해보는거죠!
왜 멍청하게 시도하는데?!
어차피 처음에 ebp에서 40만큼만 빼서
buf buf2가 각각 10 바이트인데
일일이 손으로 해봐도 풀릴 것 같아서요 ㅎ
그래서 계속 시도하다 보니 아래와 같이
4번째 시도에서 아래와 같이 성공이 뜨네요!
사실 더 야매인 방법은 계속 go를 넣는거죠!
"어차피 go가 buf2 자리에 들어가야하는데
어딘지 모르니 그냥 모든 공간을 go로 채우자"
라고 생각해서 go만 주구장창 떄려박으면 풀리죠 ㅎㅎ
어쨌든 이렇게 문제를 풀어보았고
오늘도 고생하셨습니다!
'System Hacking > FTZ' 카테고리의 다른 글
[어설픈] 해커스쿨 FTZ level 11 문제풀이 (0) | 2019.01.22 |
---|---|
[어설픈] 해커스쿨 FTZ Level 10 문제풀이 (0) | 2019.01.21 |
[어설픈] 해커스쿨 FTZ Level 8 문제풀이 (0) | 2019.01.18 |
[어설픈] 해커스쿨 FTZ Level 7 풀이 (0) | 2019.01.17 |
[어설픈] 해커스쿨 FTZ level 6 문제풀이 (0) | 2019.01.16 |