네 오늘 배울 내용은 글립코에서 진행되는 tcache라는 프로그램입니다 글립코
2에서 소개됐죠 2017년 26살요 네 기본을 다 배웠으면
이 개념을 소개한 이유를 강의 마지막에 설명할게요
지금은 tcache가 뭔지 어떻게 작동하는지 알아보죠
Tcache는 스레드 캐시란 뜻이에요
네 말로크 제이슨의 아이디어를 빌려왔는데 '제마목'으로 알려져 있었죠 솔라리스
운영 체제 때부터 쓰던 용어예요
글리벡 스레드 캐시는 서로 다른 스레드 사이의 리소스 경쟁을 완화합니다
네 글록 말록은 한 공연장에 실을 여러 개 붙이지 않으려고 새 공연장을
만들고 실마다 수북이 쌓는다
맞아요 하지만 한 과정에 이용 가능한 코어의 개수에 따라 동시 공연장 수가 제한됩니다
이 한계에 도달하면 새로운 스레드가 다른 스레드와 함께 사용됩니다
네 문제가 될 수 있어요 말록은 출입이 불가해서 경기장의 출입을 통제하기 위해 자물쇠를 사용합니다
네 스레드가 메모리를 요청할 때 자신의 요청을 완료하기 위해 하나 이상의 스레드가 같은 아레나를
공유하길 기다려야 합니다
이 시나리오로 인한 경기 침체를 막기 위해 tcache가 도입됐습니다
글리벡 2호실요 네 26, 그 이후 각 스레드마다 tcache가 있는데 작은
경기장이라고 생각하면 돼요 거기에만 접근할 수 있죠
네 실이 한 덩어리를 빼면 그 스레드의 아레나에 연결하지 않고 말로크가 그 스레드의 tcache에
연결해요 ?
네 이제 스레드가 말로크에게 요청하면 자신의 tcache에서 한 덩어리를 받을 수 있습니다
공유 경기장에서 할당을 완료할 때까지 기다릴 필요가 없죠 ,
네 늘 그렇듯 맬록 인스턴스를 배울 때 데모 바이너리로 이 개념을 실행해
보겠습니다
tcache_dup 디렉터리로 가서 GDB에 데모 바이너리를 로드합니다
메인 기능에 브레이크 포인트를 설정하고 '런' 명령을 발령합니다
계속하기 전에 'vmmap libc'라고
입력하세요 글리벡 버전을 보면 2입니다 tcache가 디폴트로 활성화되어야 한다는 뜻이죠
글리벡 버전을 2년 뒤에 다뤘어요 네 25. tcache 없이 컴파일된 libc
바이너리를 사용했는데 라이브러리 경로에서 "no_tcache" 확장을 보셨을 겁니다
강의 1부 초반에 이 부분에 대해 주의를 끌었습니다 tcache가 뭔지 몰랐다면
아무 의미 없었을 겁니다
여러분 오해하실 수 있어요 글립의 후반 버전이 실제와 다르게 행동한다는
걸 알아주세요 저도 가볍게 결정한 게 아닙니다
네 네 tcache를 생략한 가장 큰 이유는 우리가 배운 기술은 원래 TCache 도입
전에 GLIBC 버전을 겨냥했기 때문에 포함하지 않았기 때문이에요
하지만 현재의 상태로도 나중 버전과 활용할 수 있죠
곧 알게 될 겁니다 tcache는 우리가 익숙한 방식으로 조정할 수
있다는 걸요
네 게다가 tcache는 맬록의 착취 완화 효과를 반감하게 됩니다 tcache를
사용하지 않는 대상보다 더 쉽게 착취하죠
걱정 마세요 지금까지 배운 기술을 tcache를 활성화한 글립벡과
같은 방식으로 활용할 수 있어요
네 어떤 경우에는 몇 가지 더 어려움을 겪어야 했지만 종종 그게
더 쉬웠어요
네 이렇게 뒤늦게 tcache를 도입하면서 복잡하지 않게 기술을 배울 수 있었고
글립벡의 후기 버전에서 나타나는 완화 효과에 대처하는 법도 배운 것 같아요
이제 제 논리에 만족하셨길 바랍니다 쇼를 진행하는 동안에는요
네 소스 패널을 보면 이 프로그램의 첫 번째 업무는 최소한의 크기의 두 덩어리를
요청하는 겁니다 어떻게 생겼는지 아니까
'다음 2'로 실행하세요
이제 '비스'로 기본 힙을 검사합니다
저기... 이상한 일이 일어났어요 큰 덩어리가 있는데 0x250 크기의 덩어리가 앞에 있어요
?
이게 메인 스레드예요
네 Tcache는 할당된 것으로 다른 것과 마찬가지로 자유, 통합 할당됩니다
네
맞아요 인라인 아레나도 소리만큼 위험하긴 하죠 다음 도전에서는 이 점을
활용할 겁니다
네 싱글 스레드 프로그램을 디버깅할 때 일반적으로 힙 시작에서 메인 스레드의 tcache를
봅니다 이렇게요 하지만 다른 스레드와 아레나를 공유하면 그들의 tcache는 힙 어느 곳이라도 할당될
수 있습니다
네 '컨텍스트'는 'ctx'로 줄여서 '코드' 명령어로 쓰입니다 다음 프로그램은 무료 청크입니다
네 지금까지 배운 바로는 이 두 덩어리는 패스트빈으로 갈 거예요 tcache가
작동 중이니 과연 그럴까요? ? 네
'next'를 쓰면 다시 검사할 수 있습니다
네 네 , 바로 그거예요
값이 증가했고 이 사변어드는 사용자 데이터의 주소를 갖고 있습니다
상황을 설명할게요
실 은닉처는 'count'와 'entries'로 구성된 두 지역으로 구성돼 있습니다 각각
64개씩이죠
참가자들은 경기장의 쓰레기통이라고 생각할 수 있죠
일반 경기장 패스트빈과 비슷하네요
네 이 '상자'들은 각각 잘 연결되어 있고 순환되지 않고 맨 뒤에 있는 공짜 덩어리의
끝이죠
이 목록에는 특정 크기의 조각이 있어요 0x20부터 0x410까지요
맞아요 사실 소위 말하는 치카빈과 패스트빈의 유일한 차이점은 최대
크기라는 점이에요 치카빈은 메타데이터가 아니라 사용자 데이터 주소로 참조해요
'count' 영역은 각 티카빈에 있는 덩어리가 총량입니다
네 첫 번째 집계는 0x20 체체빈에 덩어리가 얼마나 있는지 나타내고 두 번째 집계는
0x30 체체빈과 일치해요 다 있죠 0x410 통에 마지막 개수를
적었습니다
카운트 필드는 글리벡 버전 2에서 1바이트예요 26살부터 2살까지요 버전 2에서는 29 바이트와
2바이트 길이죠 30살 이후로요
네 0x290 덩어리 안에 0x250이 아니라 tcache가 있으면 셀 수 있는 영역이 넓어지니까
글리벡 2가... 30개 이상의 제품을 사용합니다
네 '컨텍스트 코드' 명령은 B 청크가 풀린다는 걸 알려줍니다 그렇게 하도록 하죠 힙을
다시 검사합니다
네 pwndbg가 b 덩어리를 0x20 tcache빈에 연결했어요 이제 더 많은 변화를
볼 수 있어요
네 네 즉, 티카빈은 0x20 티카빈의 중심에 있다는
거죠 ? 네
0x20 카운트 필드는 이제 2가 됩니다 0x20 티카빈에 덩어리가 2개 있으니까요
네 뱁스 데이터의 첫 4분의 1을 포워드 포인터로 재포인팅해서 뱁스 데이터로
바꿨어요
a의 fd는 null이에요 리스트의 끝이란 뜻이죠
현재 스레드의 tcache 개요를 Pwndbg의 'tcache' 명령과 함께 볼 수 있습니다
네 '치카체빈'을 이용해 더 자세히 검사할 수 있습니다 사용 중인 통의
크기와 덩어리 개수를 알려 주고 통에 든 덩어리 주소도 알려 주죠
말씀드렸듯이 치차빈은 맨 뒤에 들어가요
네 'context code'를 보면 C&D에 0x20 크기의 두 요청이 있습니다 'next
2'로 만들어 주세요
정보를 조사해서 'c'와 'd'로 반환값을 출력합니다
네 이 주소들을 보면 프로그램이 역순으로 덩어리를 할당했어요 풀려났죠 티차빈은
맨 마지막에 먼저 나갔고요
네 좋아요, 마지막으로 tcache에 맞는 최대 크기를 확인합니다 삽입 '컨텍스트 코드'를
보면 이 프로그램은 0x410 크기의 덩어리를 요청합니다 'next 2'를 사용하세요
네 힙을 검사할 때 할당된 큰 부분을 프린트하지 않으려면 'vis 3'을 사용하세요
네 마지막 tcache 항목입니다 0x410 크기의 주소가 들어 있죠 'tcache빈'의
지시로 확인했습니다
0x410 카운트 필드도 증가했습니다
네 네 위에 있는 통합을 피하기 위해 사이에
Guard 청크를 할당합니다
'다음 3'을 이용해 마지막 3줄을 실행하세요
네 네 '치카빈' 확인 결과 0x420 크기의 덩어리는 방해받지 않았습니다
이 정도 크기라면 당연한 반응이죠 , "치카빈"
네 네 tcache에 대해 더 알아야 하지만 지금은 다음 사항만 기억하면
돼요 Tcache는
한 무리에 할당된 미니 경기장이에요 사이즈가 다양해요 네 패스트빈과
거의 똑같이 행동하죠 메타데이터 대신 사용자 데이터에 포인터를
쓴다는 점만 빼고요
네 이 데모에서 명확하지 않은 한 가지는 스레드 tcache가 일반 아레나보다 우선한다는
겁니다
예를 들어 0x50 크기의 덩어리를 꺼내면 0x50 패스트빈이 아니라 tcache에 걸릴 겁니다
네 그리고 같은 이유로 0x80 크기의 덩어리를 요청합니다 tcache에 0x80 크기의 덩어리가
있다면 패스트빈 스몰빈, 비체인지빈 때문에 tcache를 할당받을 수 있습니다 ,
tcache는 속도를 위해 설계됐으니 말이 되죠
네 사실 tcache 할당 코드는 인트말록에 들어가지 않고도 반환할
수 있습니다 말록을 들어 올리는 기능이죠
물론 속도에는 대가가 따릅니다 그 대가가 얼마나 컸는지 곧 알게 되겠죠
데모 바이너리에서 벗어나 이 기술을 이길 때가 됐어요
그 기술은 '치샤치 둡'이라고 불립니다 패스트빈 둡과 비슷하기 때문이죠
네 출처가 불분명해요 설령 그렇다 해도 한 사람에게만 공을 돌리는 건 싫지만요
워낙 간단한 기술이라 글리브 맬록이 독자적으로 개발한 건 해커들이 잘
알 테니까요
늘 그렇듯 표적 바이너리에 대한 확인부터 하죠
네 출력 결과 일반적인 렐로 스택과 카나리아 NX 비자유 바이너리의
조합으로 나옵니다
글리벡 버전 2와 연결되어 있어요 28
네 "no_tache" 확장이 없다는 것은 제가 정상적으로 컴파일 했음을 의미합니다 그러므로 tcache가
이용 가능하도록 해야겠죠
tcache_dup 바이너리를 GDB에 로드하고 실행합니다
네 리크사가 우리를 맞이합니다 익숙한 번호 메뉴도 있죠 옵션 1은 덩어리를 4개까지 요청합니다
트캐쉬 범위 안에 있을 거예요 0x410 크기의 크기도 포함해서요
네 성공적인 할당에요 여기에 데이터를 입력하라고 나와요
8바이트까지 받아요 ? 네
옵션 2는 0에서 인덱스로 할당된 덩어리를 자유롭게 합니다
마지막으로 옵션 3은 tcache dup 기술을 익힌 후 임의로 작성할
타깃 데이터를 출력합니다
GDB에 들어가 'vis'로 힙을 검사해 모든 게 우리 예상대로인지 확인합니다
네 요청한 부분이에요 이제 풀어서 0x20 티카빈과 연결했어요 '티카빈'의 지시에
따라서요 '티카빈'
목표 데이터는 이 2진법 데이터 섹션의 '대상' 기호에 있습니다
잠시 후 화면 정지 장면이 나옵니다 , 잠시 후 이 바이너리에서 버그를 찾고 tcache에서
덩어리를 요청하는 것에 익숙해질 수 있을 거야
좋아요, 자신 있으면 이 2진법을 활용해 봐요 기술에 대해
설명하기도 전에요 맞아요 전례가 없는 일이죠 하지만
글릭에 실을 캐시를 도입했다고 이미 암시했듯이 말로크에는 큰 보안이
적용됐어요
버그를 찾고 싶다면
원시적인 글자를 임의로 만들어 보세요
네 뭐든 다 고르면 여기로 와서 같이 치셰이 둡 기술을 살펴보죠
버그를 찾아서 활용해서 원시적인 글을 쓸 수 있길 바라요
못 찾으면 걱정 마세요 처음부터 다시 시작해서 도청기를 찾을 겁니다
tcache_dup 바이너리를 GDB에 로드해 실행합니다
메뉴에서 최소 크기의 메뉴판에는
?
네 네 요청된 청크의 사용자 데이터에 들어가서 버그가
없어요 안 터져요,
계속하죠 메뉴 출력하기를 눌러 더블프리를 시도합니다 인덱스 0에서
두 줄로 풀어주세요
네 보통 프로그램 오류 메시지는 '이 청크는 이미 풀려났다'거나 글리벡이 중단했다는
건데 더블 프리로 인해서 감면 효과가 나타났죠
네 이 바이너리에 오류 메시지를 프로그래밍하는 걸 잊지 않았다고
약속합니다 그러니 힙을 살펴보죠 뭔가 이상한 일이 일어났는지요
pwndbg가 제가 꺼낸 0x20 덩어리를 티카빈에 두 번 연결했어요
네 맞아요 0x20 tcache빈 수치가 2예요 0x20 tcache빈 자체에 나온 혈관의
주소가 있어요 ? 네, 맞아요
네 네 , 이 경우
이런 걸 본 적이 있어요 패스트빈 둡 기술을 배울 때요 1부에서요
네 패스트빈 둡은 혼자 묶은 목록을 동그랗게 만들었어요 우리가 한 것과 똑같죠
네 이 바이너리에 두 번 없는 버그가 있는데 tcache에 같은 걸 두 번 넣기 위해 사용했어요
왜 중단하지 않았죠? 네 맞아요 확실히 tcache가 패스트빈처럼 작동한다면 더블
프리 완화 규정을 물려받았을 거예요
속도를 내기 위한 대가죠 글라이벡 버전에서는 2 이전의 현금이 활성화되어 있습니다 29번, tcache에서 이중으로
무료로 확인할 수 없습니다
이렇게 같은 덩어리를 계속 풀어 줘도 아무 문제 없다는
거죠
그럼 패스트빈 둡이 합선되고 두 번째 단계를 무시하면 돼요 이중
프리 편견을 건너뛰고 인라인 말로크 메타데이터로 건너뛰는 거죠
네 이 개념에 익숙하시니까 GDB를 닫겠습니다 그리고 이 기술인 pwntools 템플릿 스크립트를
복사할 거예요
여러분이 선택한 편집기에 있는 템플릿 복사본을 엽니다
네 네 맬록((( 'size'와 'data' 인수를 갖고 옵션 1은 프로그램 메뉴에서
래핑합니다 그리고 free((( 간단히 '인덱스' 인수를 갖고 옵션 2를 래핑합니다
스크립트의 아래로 스크롤하면 도우미 함수의 일반적인 사용 예제를 볼 수 있습니다
지금은 최소한의 크기를 요청한 후 풀어주기만 해요
정리하기 위해 예제 헤더와 주석을 제거하겠습니다
제가 방금 GDB에서 한 걸 복제하는 것으로 시작하죠 두 배 없는 버그를 두 번째로 활용하는 겁니다
그러면 A 덩어리가 0x20 티카빈과 두 번 연결되죠
네 다음 주문은 0x20 사이즈 사이즈로 주문한 티카체빈 A가 들어옵니다
청크 A는 프로그램에 할당되고 0x20 tcache빈에 연결됩니다
네 패스트 빈 둡 기술로 인라인 맬록 메타데이터를 덮어쓴 방식으로 이 상황을
이용할 수 있어요 구체적으로 말하면 청크 A의 포워드 포인터로 가짜 청크를 tcache에
연결하는 거죠
기억하세요 네 메타데이터 대신입니다 이 말은 fd를
덮어쓰면 목표 데이터를 가리킬 수 있다는 거죠 16 바이트가 아니라요
스크립트에 두 줄을 추가했으면 GDB와 NOASLR로 실행하세요
GDB를 이용해 '비스'로 짐을 검사합니다
보이죠 네 0x20 tcachebin
슬롯이죠
네 0x20 티캐빈 수치가 1이에요 통에 한 덩어리밖에 없다는 뜻이죠 ? 네,
맞아요
네 네 "A 청크 A 'tcacac빈'의 명령에 따르면 청크 a의 포워드 포인터는
프로그램 데이터 섹션에 있는 우리의 임의로 쓴 대상인 x의 주소를
갖고 있습니다
네 타깃 데이터를 덮어쓰기 하는 데 몇 걸음 안 남았어요 최소 크기 두 개만 요청하면
돼요 둘 다 0x20 tcache빈으로 할당되죠
A를 먼저 쏘고 표적을 겹치게 가짜를 쏠 겁니다 여기로 보내는 데이터로 표적을 덮어쓸
수 있어요
이렇게 한 다음 옵션 3이 성공했는지 확인할 수 있습니다
그런 것 같네요 네 이 기술을 이용해서 임의로 원시적인 글을 썼어요
맞아요 정말 간단해요
GDB 창으로 돌아가서 답변되지 않은 질문들을 해결하죠
크기 확인은 어떻게 됐는지 궁금하시겠죠 네 패스트빈 텁을 할 때는 패스트빈
크기 검사를 피하기 위해 가짜 크기를 만들거나 찾아야 해요
하지만 트캐시는 그런 완화가 안 돼요
네 목표물 근처에 메모리를
놓으면 가짜 덩어리의 크기가 0이라는 걸 알 수 있습니다 덩어리 크기 면에서는 무효나 다름없죠
네 Tcache 도입이 글리벡 힙 실행에 보안에 악영향을 끼쳤다는
게 무슨 뜻인지 이해하셨길 바랍니다
필드 검사는요? 네 우리가 직접 하기 전에 0x20의 티카체빈 수치는 1이었어요
통에 한 덩어리밖에 없다는 뜻이죠 , 한 덩어리
하지만 두 덩어리를 요청했어요 덩어리 A와 가짜 덩어리요 글립벡 버전 2
이전에는요 네 30 말로크는 티카빈을 셀 때 카운트 필드를 쓰지
않습니다 '비스'로
이 힙을 검사하면 0x20 티카빈 카운트 필드가 감겨 있는 걸 알 수 있죠
그럼 편집자에게 돌아가 취재를 마무리하겠습니다
이제 네 청크 a를 반환하고 같은 크기의 다른 요청을 하면 Fake 청크를
반환합니다 Fake 청크라고 할 수 있습니다 우리는 가짜 맬록 메타데이터를
준비하지 않았기 때문입니다 ?
그런 요청을 추가하면 생산 조건에서 착취를 실행하세요
메뉴를 보기 위해 반환을 누를 수 있습니다 그런 다음 옵션 3을 선택해 대상 데이터를 프린트합니다 이제
제어할 수 있어야 하죠
꽈당 넘어뜨리기 기술은 여기까지입니다
요약하자면, 목표 바이너리와 글리벡 버전 2가 연결됐어요 28은 디폴트로 활성화된 tcache를 가지고
있습니다
네 네 ,
글리벡 2회 전에요 네 29 tcache는 이중으로 조정할 수 없어서 같은 부분을
연속으로 두 번 풀었어요
네 tcache에서 같은 굵기를 요청했습니다 무료와 할당을 동시에 남겨두고요
패스트빈 둡 시나리오를 활용한 것과 비슷한 방식으로 청크의 티캐빈 fd를
복사해서 가짜 청크의 주소를 넣었어요
좋아요, 다음 복제 청크를 다시 요청했어요 우리 가짜 청크는 tcache에 연결되고요
네 마지막으로 드디어 ????
보세요 보시다시피 트캐치 둡은 간단하면서도 강력한 기술이에요 더블 프리 완화나
현장 크기 확인을 안 해서 활용하기 쉽고 잠재적 목표물에 제한이 없습니다
네 지금까지 tcache에 대해 배운 걸 요약하고 싶으시면 이 영상의 일부를 다시 보시거나
HeapLAB PDF의 'tcache' 부분을 확인하세요
강의 리소스에서 사용할 수 있는 솔루션 스크립트도 있습니다
네 더 깊이 들어가기 전에 새 기술에 대해 좀 더 알고 싶은데요 새 기술이라면 어떤 게 있을까요?
네 좋아요 별로 힘들지 않을 것 같네요 그럼 알아서 하세요
지금 멈추고 한번 해 보세요
네 금방 찾으셨을 거예요 하지만 혹시라도 문제가 생기면 같이 소라껍질이나
떨어뜨리죠
네 늘 그렇듯이 우리가 임의로 쓰는 걸 기반으로 복사하거나 편집할 수 있어요 저처럼 말이죠
,
우선 새로운 대상을 임의로 작성해야 합니다 네 이진법적이라 할당량은 4개로 제한돼 있어요
이미 도달했으니 프리 훅이
합리적인 선택 같아요
네 네 "타겟"
tcache는 사용자 데이터에 포인터를 사용하니 이 값을 조정할 필요가 없죠
이렇게 하면 바늘이 겹치는 가짜 덩어리를 연결할 수 있습니다
됐어요, 다음 다음은 "() 함수
네 가짜 고리가 고리와 겹치니까요 시스템으로 고리를 덮어쓸 거예요
네 알다시피 자유 후크를 이용하려면 명령문을 한 덩어리에 써야 합니다
아무 거나 써도 되죠
마지막으로 명령 문자열이 들어있는 부분을 빼줍니다
네 무료 훅을 덮어썼거든요 시스템 주소로요 명령에 포인터를 전달하는
것과 같죠 이 경우엔 'bin/sh'예요 시스템에 () 함수요
모든 게 준비되면 생산 조건에서 착취를 실행할 수 있고 껍데기를 받게 될
겁니다
겨우 4개인데 나쁘지 않은 결과입니다
좋아요 방금 한 건 간단해요
초기의 필체를 바탕으로 바늘을 목표로 삼고 시스템 주소를
입력했어요 안 돼! 네 네 ?
네
앞서 말씀드렸듯이 tcache의 존재는 개발을 쉽게 할 수 있습니다 지금까지
우리가 착취한 쌍성 중 일부가 글리벡 버전과 연결되면 어떤 영향을 받을지
생각해 볼 가치가 있죠
토끼의 집을 예로 들게요 글립코 2와 연관됐다면요 28 이 바이너리에서는
빠른 크기의 덩어리 4개만으로도 셸을 떨어뜨릴 수 있습니다 여기에서
한 것처럼요
그렇습니다 사실 빠른 요청을 허용하지 않던 토끼 하우스도 이 작은 공격에
취약할 겁니다 tcache의 범위는 패스트빈을 훨씬 뛰어넘으니까요
맞아요 제 생각에는 이런 것 때문에 착취가 더 흥미로운 것 같아요 프로그램 내 버그는 여러 방식으로
취약할 수 있습니다 호스트 운영 체제가 어떤 글라이벡 버전을 쓰느냐에 따라서요
다음 영상에서는 tcache 인터널에 대해 더 알아보겠습니다 tcache 감량에 관해서도요
글립코 후기 버전에서 도입된 거죠
자, 그럼 그 전에 강의 리소스에서 사용 가능한 바이너리에 대한 솔루션 스크립트가 있습니다
말록 시험대도 잊지 마세요 더 실험하고 싶다면요
다음 영상에서 만나요