힙랩 2부 마지막 과제에 잘 오셨어요 이번 과제는 '띠용, 트롤'이에요
바로... 네
,
시작할게요 우선 표적 바이너리를
소개할게요 영상을 멈추고 직접 취약점을 작성해 보세요 안 돼요
네 중간에 막히면 비디오를 다시 켜고 다음 단계를 같이 연습해요 껍데기가 완성될 때까지
반복하는 거예요 , 헹궈요
네 그럼 지체 없이 "chaensge-tcache_troll" 디렉터리로 들어가 도전
이진법을 살펴보죠
네 체스크액에 따르면 이 이진법에는 렐로의 스택과 카나리아 NX 위치 독립성이 모두 활성화됐습니다
글리벡 버전 2와 연결됐어요 28 tcache가 출석한다는 뜻인데 tcache로
인한 이중 무형 감형은 안 받아도
돼요
챌린지 바이너리를 GDB에 로드하고 실행해서 어떻게 작동하는지 보죠
그게 우리의 도전이죠 쌍성은 쉽게 포기하지 않아요 libc가 쉽게 새죠
이것도 마찬가지예요 ,
필요한 주소는 전부 직접 흘리세요
네 그 외에는 우리가 이미 다뤘던 tcache 쌍성과 아주 유사해요 옵션 1은
tcache 크기로 제한된 덩어리 8개를 요청해 데이터로 채웁니다
옵션 2는 인덱스로 나눠 0에서 시작합니다
네 처음으로 무료 수술에 한계가 있습니다 총 5개를...
일이 흥미로워지겠군요
옵션 3으로 사용자 데이터의 첫 4분의 1칼로드를 읽을 수 있습니다
이것도 인덱스로 하죠 0에서 시작해요
바로 알아채지 못하셨겠지만 이 프로그램은 할당 직후 사용자 데이터를 0으로
만듭니다
네 전에 정복한 쌍성 중엔 이걸 칼로크로 한 곳도 있어요 하지만 아시다시피 칼로크는 이
통로로 하는 게 아니에요
맞아요 그래서 대신 이 프로그램은 행동을 모방해 말로크를 통해 덩어리를 요청하고 데이터를 멘셋으로
0 처리하죠
결과는 같습니다 프로그래머를 정확하게 초기화하는 실험입니다
이거면 시작할 수 있어요
가장 먼저 도전 바이너리에서 버그를 찾아야 합니다
그 후엔, 당신 전략에 필요한 주소를 유출하는 데 집중해요
늘 그렇듯 챌린지 디렉터리엔 pwntools 템플릿 스크립트가 있어요 각각의 프로그램 메뉴
옵션을 감싸는 헬퍼 기능과 함께요
이런 도우미 기능의 사용 예는 템플릿 스크립트 하단에 있습니다
네 지금 멈춰 주세요 힌트가 필요하시면 여기로 돌아오시면 버그를 찾을 수 있어요 초기 전략을
논의해 보죠 ?
행운을 빌어요
네 도청 장치를 찾으셨을 거라고 확신하지만 모든 길을 확인해서 나쁠 건 없죠 혹시 모르니까요
도전 이진법 복사본을 GDB에 로드하고 실행하겠습니다
그럼... 버그가 있는지부터 확인하죠 최소 크기를 요청해서 사용자 데이터 영역이 감당할 수 있는 것보다 더
많은 데이터를 보낼게요 ? 네
GDB를 분석해 봤는데 초과한 흔적은 없어요 계속 찾아보죠
같은 부분을
떼고 다시 읽으려고
해요
오류 메시지는 읽기 후 버그가 없다는 뜻이에요
하지만 그 덩어리를 다시 빼내는 건 성공했습니다
네 정보기관을 열고 더미를 다시 살펴보니 같은 덩어리를 tcache에 두 번 연결했습니다
두 번 이상 오류가 없다는 뜻이죠
좋은 소식이에요 tcache에 영향을 주는 더블 프리 버그를 이용할 방법을 알아냈을
뿐 아니라 글립코 버전 2도 개발하고 있어요 28세, tcache 무첨가 2회 감형은 없어요
유일한 장애물은 전 과정이 aslr의 소유라는 거죠 어떻게든
유출을 위조해야 해요
네 네 우선 libc 주소를 유출해야 해요 이전
쌍성계에서도 성공적으로 해냈거든요 ?
네 문제는 tcache 메타데이터가 힙 주소로만 이루어져 있고 프로그램이 우리 데이터만
저장하기 때문에 libc
주소를 강제로 올리려면 일부를 분리해야 한다는 거죠
가장 빠른 방법은 트캐시 크기 바깥쪽을 제거하는 겁니다
안타깝게도 이 시스템은 그 범위 내에서만 할당돼요
네 일단 티카빈은 다 안 쓰니까 예를 들어서 0x90 티카빈을 채워서 0x90을
무체중 빈에 넣으면 돼요
네 하지만 기본 조건에 따르면 티카빈을 채우려면 덩어리 7개를 빼야 해요 이 바이너리로
5개만 뺄 수 있죠
네 마지막 부분을 보셨다면 글리빅_트너블스 환경을 이용하면
두 가지 문제를 해결할 수 있다는 걸 아실 겁니다
이렇게 하면 훨씬 효율적으로 착취할 수 있을 겁니다
하지만 그게 이진법에 도움이 안 된다면 글리브_트너블스는 이번 도전에서
제외하죠
네 그래도 돌아와서 실험해 보세요 일단 과제를 깨고 나면 원래 방식으로요
문제는 이거죠 어떻게 한 덩어리를 무정지 상태로 빼돌려서 libc 주소를
알아내서 유출하죠?
네 만약 우리가 치치 셀드 필드를 조작할 수 있다면 예를 들어 치치 자체에
속임수를 써서 맬록을 속일 수 있어요 특정 치치빈이 꽉 찬 것처럼 말이죠
그러려면 물이 많이 새야 해요
네 네 , 주소를 흘릴 수 있게요
비디오를 정지시키고 도움이 필요하면 다시 켜세요
그럼 주소를 흘리죠 지금 화면에 제가 시도해 보는 게 있어요 강의 리소스에서
제 스크립트를 가져가세요 템플릿
2번이라고 적혀 있어요
우선 요청한 다음 '바보'라고 적힌 덩어리를 이중으로 풀어줍니다
네 크기는 상관없어요
지금은 tcache 크기로 제한돼 있어요 프로그램이 허용하는 크기는 다 똑같아요 ?
네
네 그리고 그 후에 보안 당국에 두 배로 돌려달라고 요청합니다 '줄자'라고 이름 붙이죠
네 그럼 '터프'로 연결된 덩어리 하나가 남는데 '리커'로
프로그램에 배정돼요
간단한 설정인 걸 아실 겁니다
맞아요 이때 유용한 주소를 흘렸다면 '리커' 청크를 써서 '망할' 청크의 '치카빈 포인터'에
손을 대고 가짜 청크를 연결할 수 있었을 거예요 '치카'에 연결하는 거죠
네 하지만 아직 유용한 주소를 유출하지 않았으니 이 셋업을 이용해 tcache빈 포워드 포인터를
유출할 거예요
네 안타깝게도 '리커'를 할당하면 기존의 '멍청' 청크를 누를
수 있으니 다시 채워 넣어야 해요 ,
다음 대사에서 또 "멍청" 소리가 나오죠 이 단계에선 3번쯤 나올 거예요
네 이미 tcache에 연결됐거든요 말록은 'dup' 청크의 fd에 주소를 부여합니다
사용자 데이터 주소요 tcache를 다루니까요 ?
네 네 할당된 부분에 주소를 적었어요 "거짓말"
이제 '리커' 부분을 읽으면 정보를 흘릴 수 있어요 다음 문장이 그 내용이죠
먼저 읽기 도우미 기능을 써서 '리커' 청크의 사용자 데이터 첫 4음절을 읽어요
현재 힙 주소를 갖고 있죠
pwntools 풀기 () 함수가 사용됩니다 이 작은 엔드 값을 우리 스크립트에서 조작할 수 있는 정수로 변환하기
위해서요
유출된 주소는 그 친구 사용자 데이터예요
16을 빼면 메타데이터 주소가 나오죠
네 여기서 0x250 바이트를 빼면 앞에 tcache가 있고 힙 시작 주소를 얻게 됩니다
'heap'이라는 변수에 기록해 뒀죠
마지막 줄은 단순히 디버깅을 위해 변수를 프린트합니다
네 GDB 옵션으로 스크립트를 실행해서 누수가 정확한지 확인하겠습니다 우연이 아닌지 확인하려고
NOASLR 옵션을 생략하는 거야
실행합니다 ctrl+c로 깨고 'vmmap 명령어로 디폴트 힙 매핑 프린트하기'
힙 시작 주소를 보여줍니다
알트++로 프로그램 창으로 전환하고 제 스크립트의 결과물과 비교해 힙의 위치를
성공적으로 유출하고 계산했음을 확인합니다
네 이 주소들은 여러분의 결과물과 다를 겁니다 ASLR이 사용 중이니까요 하지만
두 값이 일치하는 한 모든 게 정상입니다
이제 libc 주소를 흘릴 준비가 됐어요
네 8마리 중 2마리를 잡았고 5마리 중 3마리를 잡았습니다 하지만 창의력을 발휘하면
이 도전에서 이길 수 있습니다
네 누수 때문에 어디서든 찌꺼기를 뽑을 수 있게 됐습니다 찌꺼기 안에도 말이죠
그렇게 하면 카운트 필드와 입력을 통제할 수 있어요
필즈 네 혼란스럽지 않게 한 덩어리를 빼내는 게 libc 주소를 적는
좋은 방법이에요 안 돼요 하지만 전화 두 통만 더
무료로 하면 합법적으로 그럴 수 없어요
다시 비디오를 멈추고 다음 단계를 계획하세요 libc 주소 유출이 힘들면 다시 재생하세요
네 챌린지 바이너리에서 libc 주소를 유출할 거예요 강의 자료에서 이 스크립트를
다운로드하세요
양식 번호 3번입니다
네 방금 다뤘던 유출 단계예요 두 번째 단계는 '정돈되지 않은 주소 유출'이죠 "정돈되지 않은 주소 유출"
이를 알아보기 전에 누출 단계를 두 가지 변경했습니다
먼저 듀프리커 청크의 크기를 0x90으로 바꿨어요 이렇게 하면 2단계에서 다시 쓸 수 있어서
말록과 풀을 최소화합니다
네 그리고 그다음 교도관도 할당했어요 윗선과 합치는 걸 피하려고요 이유는
곧 알게 될 거예요
그게 '리크 libc' 단계예요 이 단계에 오면 두 덩어리만 남죠 dup/laker
덩어리랑 그 다음 가드 덩어리요
이오를 복사해서 위치를 파악하죠 대본 맨 끝에서부터 1단계 다음 부분까지예요
그리고 나서 GDB와 NOASLR 옵션으로 스크립트를 실행합니다
GDB를 이용해 '비스'로 짐을 검사합니다
네 0x90 사이즈 청크 둡/리커예요 0x90 tcachebin 슬롯에 사용자 주소가 보이고
fd 역시 같은 주소를 가리키고 있습니다 더블 프리 결과입니다
Pwndbg의 '치카빈'을 이용하면 확인할 수 있습니다
네 저희가 착취 대본을 보면 이 덩어리는 '뒤집'이란 이름으로 세 번 풀려났고 현재는 '누출자'란
이름으로 할당돼 있어요
네 유출된 거예요 '샤이커' 덩어리가 티캐빈 fd를 읽어서 주소를 알아냈어요
네 네 0x20은 가드 덩어리예요 나중에 무체중으로 풀었을 때 0x90 덩어리가
맨 위 덩어리와 합쳐지는 걸 막아주죠
말이 나와서 말인데 어떻게 하죠?
네 정지하기 전에 필드 조작을 언급했는데 이제 힙을 유출했으니
그걸 할 기회가 왔죠
네 이 장치는 자칫하면 잘못될 수 있어요 0x90 사이즈로 달라고 하면 돼요
그 부분은 0x90 tcache에서 할당되며 동시에 연결되어 있습니다
네 그리고 이걸 사용해서 0x90 tcache빈 fd를 tcache에 겹쳐 있는 가짜 덩어리를
0x90 tcache빈에 연결합니다
제 스크립트가 바로 그런 일을 하죠
그럼 GDB를 닫고 다시 돌아가죠
'이오'를 빼요 앞서 붙여놓은 줄과
2단계 첫 줄을 보세요
네 0x90 크기의 청크 를 요청하고 있는데 말씀드렸듯이 tcache에 복사된 청크를
배치해서 0x90 tcache빈 fd에 손을 댈 수 있습니다
네 네 tcache 덩어리를 tcache에 연결하는 겁니다 네, tcache요
네 다음 두 줄은 가짜 덩어리를 요청해 이 tcache를 겹치게 합니다
이 줄에 '당근'을 요청하면 가짜 덩어리를 0x90 티카빈의 머리로 옮깁니다 다음 줄은 fake 청크를
요청하고 카운트 필드를 조작하는 데 사용합니다
구체적으로 0x90 tcache를 7로 설정합니다
0x90 카운트 필드는 시작부터 8이고 앞의 7이 널바이트예요
네 그 결과 말로크의 관점에서 보면 0x90 tcache빈은 꽉 찼고 남은 0x90 크기의
덩어리는 무체중으로 연결됩니다 우리가 원하던 대로야
네 다음 줄로 '덩어리' 덩어리를 다시 풀어줍니다 0x90 사이즈라서 무체중으로
연결되죠
네 마지막이자 유일한 덩어리니까 fd는 메인 경기장의 무정체된 부분을 가리킬 거예요
? 네
이제 그 '누출자'를 통해 유출하기만 하면 돼요
이 줄이 그 역할을 하고 있어요
다시 한 번 pwndbg의 짐을 풀어요 () 함수로 유출된 값을 정수로 변환하죠
글립 무체중 '청크'에서 주요 무대까지 거리는 0x60
바이트예요
네 그리고 주요 구역에서 이 값에서 상한선을 빼면 libc 부하 주소를 알 수 있죠
네 "libc"의 "주소" 필드를 이 값으로 채웁니다 앞으로의 모든 기호 조회를 조정하는 거죠 ,
마지막 줄이 디버그를 위해 libc 로드 주소를 출력해요
이제 GDB 옵션으로 템플릿 스크립트를 실행할게요 정확한 결과를 얻기 위해서요
프로그램 창으로 바꾸니 수량과 libc가 다 새요
후자를 복사하고 다시 GDB로 전환하죠
네 ctrl+c로 깨서 'vmmap' 명령을 전달하면 매핑이 된다는 걸 알 수 있습니다
'신포' 명령과 비슷하죠
출력을 보니 우리 계산이 맞았어요
스크립트에서 출력된 주소는 libc 바이너리의 실행 가능한 부분과 일치합니다
잘 진행되고 있어요
네 수량과 리bc를 모두 유출했고 더블 프리 버그까지 더하면 실행의 흐름을 장악할
모든 도구가 있어요 ,
그래 효율적으로 움직여야 해 그래도 libc 누설로 말록 3마리를 잃었고 하나는 무료야 말록은
2마리뿐이고 1마리는 무료로 일을 끝낼 수 있어
됐어요, 우리가 어떻게 정보를 유출했는지 이해했다면 코드 실행을 위해
뭘 할지 생각해 봐요 안 돼요
말록이나 프리스를 다 쓰게 되면 어떻게 하면 나중에 더 효율적으로
쓸 수 있을지 생각해 보세요
다시 비디오를 멈추고 혼자 정리할 수 있는지 봐요 벽에 부딪히면 여기로 돌아와요
네 아직 템플릿 3을 보고 있고요 제 다음 의도를 설명하는 제목을 추가했어요
좋아요, 네 이 바이너리가 너무 큰 요청을 못 하게 해서 크기
인수로 유효한 주소를 전달할 수 없어요 안 돼요
네 물론 장비 하나로 갈 수도 있지만 휴대성이 떨어져서 버전이 아니라
글리벡에 의존해야 하니 시스템을 시도해 보고 싶어요
잠시 전까지만 해도 말록 두 마리와 한 마리가 남았었죠
네 바늘을 작동하려면 말록
두 마리가 있어야 해요 시스템 주소와 함께 바늘을 덮어써야 하죠
단순히 실행하는 것은 안 됩니다 가지고 있는 것을 활용해야 합니다
최적의 방법은 직접 조작하는 거예요
네 한 마리는 트캐쉬를 조작하고 다른 한 마리는 가짜를 요청해 낚싯바늘을
조작하는 거죠 ? 네
네 안타깝게도 이 대본에는 0x90 사이즈 한 덩어리가 정리가 안
된 채로 버려져 있어요
네 하지만 이 시점에서 tcache에 씨를 뿌리고 tcache를 겹치게 했다면 tcache
엔트리에 요청할 수 있습니다
네 이 라인이 뭔지 기억하시길 바랍니다
tcache를 중첩하라고 요청하고 0x90 카운트 필드를 변경합니다
좋아요 네 안 그러면 체액이 새어 나와
네 이래서 대본의 앞부분을 수정해서 뒷부분을 더 효율적으로 만들자는 거예요
Pwntools p8을 이용해 시작하겠습니다 () 기능으로 남은 카운트 필드는 모두 64개입니다
글리벡 2를 다루려면요 30이나 그 이후에는 p32를 사용해야 합니다. 더 많은 카운트 필드를
설명하기 위해 ) 여기서요.
네 네 0x90 tcache에 할당된 용도로요
네 그다음 팩을 이용해서 0x20부터 0x80 tcache 엔트리를 커버하면 0x90 tcache빈 슬롯에
도달합니다
네 네 전 힙 플러스 0x50을 사용합니다 가짜 사용자 데이터의 첫 사분자는
첫 tcache 진입 필드와 겹치죠 , 이 데이터는
순전히 나중에 입력을 절약하기 위한 거죠 tcache 카운트 필드를 조작했으니까요
지금 대안 및 노즐러 옵션으로 스크립트를 검색
중입니다 쓰레기통을 조사한
결과 말로크에 더 이상 전화를 걸지 않았지만 tcache를 겹쳐서 0x90 tcache빈에
연결했습니다
네 말록 한 마리를 태워서 바늘을 겹치는 가짜 덩어리로 다른 말록을 만들 수
있어요 libc를 아직 유출하지 않아서 할 수 없었던 일이죠
공격 스크립트로 돌아가서 요청을 해 보죠
네 네 관리될 겁니다 그것이 할당하는 건 tcache 진입경로와 겹치는데
첫 번째가 0x20 tcache빈이죠
트캐시에 가짜 고리를 연결할 수 있는 기회예요
0x20 티카빈을 쓰는 게 편리할 것 같아요
네 다 끝나면 다음 0x20 크기의 조각은 tcache에 연결한 가짜
조각입니다 요청해서 무료 후크를 덮어쓰자 글리벡 시스템 주소로
이제 시스템으로 전달할 명령줄이 달린 덩어리만 빼내면 됩니다 아무거나 골라도
돼요
누출 단계에서 상단부가 통합되지 않게 막았던 걸 사용할게요
라벨을 붙여요 무료() 도우미 함수에 쉽게 전달할 수 있게요 그리고 사용자 데이터에 명령어를
적어요
마지막으로 취약점 끝에 줄을 하나 더 달아 명령줄 덩어리를 자유롭게 합니다
맞아요 네 이 정도면 충분하겠죠 이 정도면 충분할 거예요
생산 조건에서 착취를 실행하면
껍데기를 얻을 수 있어요
축하해요 '아이코 트롤' 이진법을 깼어요
요약하자면 우린 현대 바이너리에 더블 무첨가 버그를 이용해 힙과 libc 주소를 유출했어요
그럼 포기해요
네 네 그중 하나를 우리에게 할당합니다 ? 네
바로 그 순간 그 순간부터 '누출자'라는 이름의 복사본을 통해 말로크 메타데이터를
읽을 수 있어요
네 이미 공개된 우리 복사본을 풀어서 '리커'의 사용자 데이터에
주소를 적었어요
네 네 ? tcache와 겹쳐진
거요
이 구역을 할당해서 메타데이터를 조작할 수 있었어요
네 0x90을 7로 설정했어요 그래서 말록 박사가 0x90 tcache빈을
꽉 채워서 0x90을 꺼냈을 때 무체계 빈에 연결됐어요 tcache가 '리커' 덩어리에
libc 주소를 적는 대신에요, 안 그래요?
수도회지를 탈출해서 집행의 흐름을 장악하려고 했죠 이걸 하려면 우선 무료 훅을 덮어쓰고
글립코 시스템 주소를 입력합니다 그다음 무료 훅에는
명령줄이 들어 있죠
그 명령은 시스템에 전달됐고 결과적으로 포탄이 됐죠
좋아요 트롤 챌린지 이진법은 여기까지입니다 스스로 이겨 내거나 진전이
있었다면 자신을 자랑스러워해도 됩니다
네 이 두 가지 항목은 렐로 NX 스택 카나리아리를 구성하고 포지션 독립을 적용했습니다
글립코 버전 2와도 연결되어 있습니다 28살이고 버그 한 마리요
버그를 활용해 포탄을 터뜨렸죠 할당량에 제한된 데이터는
말록 8개 무료 5개뿐인데도요
자, 여러분 주석이 달린 개발 스크립트가 작동하길 원한다면 이 강의 리소스에서 솔루션을 다운로드하세요
잊지 마세요 배운 걸 통합하려면 영상을 다시 보는 게 좋아요
힙랩 PDF와 말록 시험대가 도와줄 거예요
학습 자료와 도전적인 점은 여기까지입니다 이제 마지막 영상에서 각자 갈
길을 가보죠