풀면서 몇 가지 배운 점을 나열하도록 하겠다.
p/x $fs_base
를 한 결과와 vmmap
을 한 결과를 비교해 보면,
libc가 매핑된 주소 바로 아래에 fs_base
가 위치해 있음을 알 수 있다.
즉, libc 바로 아래에 TCB, static TLS가 위치해 있는 것이다.
$fs_base
와 스레드의 스택($rsp) 모두 [anon_7ffff75a5]에 속한다.rsp < $fs_base
인 것을 확인할 수 있다.
두 스레드의 canary값은 같은 것을 알 수 있다.
canary 값을 fs_base
에 옮기는 과정을 보면 알 수 있는데, 커널에서 만들어 놓은 랜덤 값을 복붙해서 생성하는데, 랜덤 값은 처음에 만들어지고 바뀌지 않는다.
그러므로 모든 스레드의 canary값은 같다고 할 수 있다.
물론 당연하겠지만, main thread(thread 1)와 non-main thread(thread 2)의 TCB 위치는 다르다.
왜냐하면 각각의 스레드마다 TCB, TLS는 독립적으로 메모리에 존재하기 때문.
사실 이 문제를 풀 때, main thread의 master canary를 조작해서 exploit을 하려고 하였으나, 모종의 이유로 실패했다.
시도 방법은 다음과 같다.
하지만 여기서 문제가 발생했는데, scanf 함수에서 내부적으로 참조하는 변수가 바로 main thread의 TLS에 존재했다는 점이다.
-> main thread의 TLS는 함부로 건들지 말자...
여러 번 스레드를 생성해 본 결과, 스레드의 스택이 main thread의 TLS의 아래에 하나씩 달라붙는 것을 확인.
pthread_join()
을 수행했을 때 할당된 세그먼트가 할당 해제될 줄 알았으나, 그렇지는 않은 것을 확인하였다.
대신, 그 이후에 pthread_create()
를 수행했을 때, 새로운 thread는 LIFO의 형식으로 stack과 TLS를 할당받는 사실을 확인할 수 있다.