glibc-2.23
#1. 함수 살펴보기
strtok() 함수는 문자열을 0 또는 그 이상의 비어 있지 않은 토큰의 시퀀스로 분할한다. strtok()에 대한 첫 번째 호출 시 구문 분석할 문자열을 str로 지정해야 한다. 동일한 문자열을 구문 분석해야 하는 각 후속 호출에서 str은 NULL이어야 한다.
일단 string.h 에 선언되어있는 함수이다
strtok는 target 문자열을 특정 문자를 기준으로 잘라내는 역할을 하며
반환값은 잘라낸 문자열의 시작주소 값을 반환한다
예로 123;456 을 입력받으면 123과 456을 분할하는 상황에서 효율적으로 쓰일 수 있겠다
# 취약점
나쁜 의도로 사용되는 부분은 "바로 잘라낸 문자열의 시작주소 값을 반환" 하는 부분이다
왜 이 부분이 위험한지 한번 살펴보자
역시 직접 보는게 좋으니 strtok 를 사용한 코드를 작성해보았다
그리고 아래의 결과물을 잘 봐보자
strtok 의 반환값을 받은 p의 주솟값이 출력된 모습이다
이렇게 p가 반환된 주솟값을 초기화하지 않고 저장하고 있다면
p가 재사용되는 경우 큰 문제가 발생할 수 있다
예로 위의 예시와 달리 buf 가 동적할당된 변수였고
이후 buf 가 free되고 다른 변수가 그 자리에 들어서게 되면
동일한 위치를 가르키고 있던 p는 새로운 변수를 가르키고 있게 된다
여기에 p를 통해 값을 조작할 수 있는 상황이 생긴다면
변경할 수 없는 값들을 변경할 기회를 얻게되는 것이다
# 예시
https://sf-jam.tistory.com/69
# 삽질
# 욕심이 과했어
포인터 p에 값이 계속 갱신되는 것과 마지막까지 남아있다는 것을 보여주려고 아래와 같이 코드를 짰다
알고보니 반복문 종료조건이 틀렸다
그리고 위와 같은 경우는 취약하지 않다
만약 이해가 안된다면 어떤 부분에서 취약한것인지 다시한번 읽어보자
+ 예시 문제의 코드에서 취약점을 찾으려고 보면 정확히 이해하는데 도움이 될 수 있다
# 32bit vs 64bit
취약점 설명을 할 때 작성한 코드랑 동일한 코드를 64bit 로 컴파일하면
포인터 p 가 가르키고 있는 값을 출력하다가 죽어버린다
그리고 이를 부검해본 결과
printf("strtok result : %s\n",p); 에서 죽은 것이였고
strtok의 반환형이 4byte라 8byte 주솟값을 갖는 64bit 에서는
포인터 p를 통해 값을 출력할 수 없었다
하지만 heap 에 할당하여 해당 취약점을 쓸 경우 죽지않고 잘 출력한다
heap 의 주소는 4byte 이하이기 때문이다
'System Hacking > Study Notes' 카테고리의 다른 글
개인 서버 만들기 (with. GCP) (0) | 2020.06.16 |
---|---|
Large bin attack (0) | 2020.05.04 |
Calloc Flow Control (0) | 2020.04.29 |
내 힙(heap) 어때? (0) | 2020.04.06 |
pwndbg> command (0) | 2020.01.13 |