첫 번째 과제에 오신 걸 환영합니다 네 이 시간에는 문제 해결
방법부터 설명하고 문제 이분법도 알려 드리고 문제 해결을 도와드리겠습니다
도전 패스트빈_dup 디렉터리로
탐색하는 것으로 시작하세요
패스트빈과 공연장에 대해 배운 걸 시험해 볼 거예요
네 두 번째 과제는 정보 유출을 포함한 전면적인 취재를 하는 건데 이건 좀 더 쉽게 시작할
거예요
패스트빈_둡_2 이진법에서 껍데기만 떨어뜨리면 돼요
네 제가 2진법의 초기 조사를 도와드릴게요
비디오를 멈추고 직접 도전하세요
네 막혔거나 진행 상황을 확인하고 싶으면 영상을 다시 재생해요 다음 단계를
알려 줄게요 , 알았죠?
네 그럼 체세크를 사용하는 이진법이 어떤 보호를 제공하는지 배워 보죠
네 지금까지의 모든 것처럼 렐로와 함께 컴파일되어 코드 실행을 하려면 말록
훅에 의존해야 합니다 , 바이너리가 아니라요
스택 카나리아와 NX가 있습니다 이것도 위치 독립이죠 메모리에서 2진법 위치를
모른다는 뜻입니다
네 위치 독립 프로그램들은 바이너리와 힙에 대해 다른 기본 주소를 사용합니다 ASLR
활성화 없이 실행될 때도 다른 값을
볼 수 있습니다 힙 커맨드를 사용할 때와는 다른 값을 볼 수 있죠
마지막으로 글립벡 버전 2와 연결됩니다 tcache 지원 없이 30명요
GDB로 2진법을 실행하면 우리가 다루는 게 뭔지 알게 될 겁니다
libc 유출이 아직 있으니 유용할 거예요
네 덩어리를 더 요청할 수 있어요 이번엔 13개까지죠
그래도 빠른 빈
크기의 덩어리를 요청할 수 있어요 ?
하지만 문제가 있어요 0x70
크기의 덩어리를 요청할 수 없어요
네 즉 0x70 크기의 요청 크기는 할당되지 않는다는 것입니다
예를 들어 0x58 바이트를 사용자 데이터로 요청하면 0x60 크기의 바이트를
할당받을 수 있는데 GDB를 깨고 힙-을 살펴보면 됩니다
하지만 0x59 바이트 요청은 거부됩니다 0x70 크기의 바이트를 할당받기 때문이죠
이 부분이 가장 큰 걸림돌이에요
여러분 기억하세요 지난번 패스트빈 둡 바이너리 실험에 0x70 크기의 덩어리를 요청한
게 결정적이었어요 덕분에 말록 갈고리를 겹치는 가짜 덩어리를 0x7f 크기의 덩어리로 만들 수 있었죠
이봐요 이건 배당금을 받자고 프로그램을 강요하는 게 아니에요
말똥가리의 갈고리를 대체할 방법을 찾아야 합니다 패스트빈덥 기법으로요
프로그램의 나머지 부분은 패스트빈_덥 바이너리와 같아요
'자유' 옵션은 인덱스에 따라 자유 덩어리를 제공하고
더블 프리 버그는 여전히 존재합니다
'이번엔 표적 선택권이 없습니다' '우리의 유일한 목표는 포탄 투하니까요'
Pwntools 템플릿 스크립트가 있어요
libc 기호는 libc를 통해 접근할 수 있어요 심
상징적인 이름, libc를
예로 들게요 심 메인 아레나를 위한 메인 아레나
그리고 pwndbg 명령이나 기능 혹은 One_gadget tool에서 메모리를 새로고침해야
한다면 pdf의 부록 a를 살펴보면 됩니다 네 다시 쓰시길 강력히 권고합니다
특히 패스트빈과 위쪽 포인터 사이의 접점을요
이제
공격할 계획을 짜요
이 무첨가 프로그램을 이용해서 패스트빈 둡을 만들 수 있어요
문제는... 이거죠 '어떻게 패스트빈 둡을 이용해서' '말록의 갈고리를 덮을 수 있지?'
'0x70 크기의 덩어리를 요청하지 못하면 말이야' 잠시 영상을 멈추고 얼마나 멀리 갈 수 있는지
보세요 수소 수술이 필요하면
최선을
다해 도울게요
여러분 혼자 다 할 수 없다고 걱정하지 마세요 어려운
도전이 될 테니까요 ? 네 행운을 빌어요
템플릿 스크립트 복사본에 몇 줄을 추가했어요
보세요 덩어리에 글을 쓸 때마다 메모리에서 다른 글자를 써서 표시합니다 메모리 덤프의
특정 덩어리를 식별하기가 좀 더 쉬워지죠 ????
네 네 '프리' 옵션을 사용해서 0x50 패스트빈에 넣었습니다 특별한 건 없어요
이미 사용하던
견본 크기일 뿐이죠
그리고 같은 크기를 요청하고 패스트빈
fd에 덧씌웠어요 네 보통은 여기에 가짜 덩어리의 주소를 적는데 지금은
고정할 만한 공간이 없어요 그러니까 가짜 덩어리죠
네 그리고 0x50 패스트빈의 큼직한 덩어리 B와 A도 요청했어요 그래야 제 가짜 덩어리가 이
경우에는 쓰레기 같은 가치가 0x50 패스트빈의 대표가 되죠 ?
네 보통 이 시점에서는 가짜 덩어리를 할당하지만
여기까지 온 성과를 생각해 보죠
GDB와 NOASLR 옵션으로 스크립트를 실행하겠습니다
패스트빈에 따르면 내 쓰레기 가격은 '0x50 패스트빈' 상단에 있어요 주 경기장을
직접 점검한 결과 나의 0xdeadbeef 값은 0x50 패스트빈에 있다
패스트빈 둡은 본질적으로 경기장에서 기억을 조작하게 해줍니다
가짜 덩어리를 만들 때 유용할 수도 있어요
이 섹션 리소스에서 제 스크립트 복사본을 다운로드할
수 있어요 템플릿 2번이라고 적혀 있죠 다시 비디오를 정지시키고 좀 더 진행이 되는지 보세요
지금까지 도움 없이 잘 버텼다면 정말 대단한 거예요
네 만약 실패하더라도
걱정 마세요 이런 도전은 쉽지 않고 며칠은 아니더라도 몇 시간씩 걸리는 게 정상입니다
특히 개발 개발이 처음이라면요
네 네 시스템 같은 건 맨 페이지를 읽기 기능과
대시 셸 가장 중요한 건 해커처럼 생각하기
좋아요
네 제 스크립트에 줄을 더 추가했어요 이것도 다시 말하지만
템플릿 넘버
3이라고 하죠 ??
네 첫 부분은 아까와 같지만 가비지
0xdeadbeef 값을 페이크 사이즈 필드로 바꾼 겁니다 0x61이요 그 자리에 메인 아레나로
들어갈 거예요 ?
아직 모르신다면 저 크기 필드를 이용해 메인 아레나에 페이크 청크를 링크하겠습니다
그게 이 대본의 2부예요
이번에는 0x60 패스트빈을 상대로 패스트빈 둡을 실험했습니다
메인 경기장을 가로지르는 가짜 청크를 연결했어요
네 메인_arena 플러스 0x20이 제 061 사이즈 필드를 정렬합니다
아까 저기서 작성했어요 Fake 청크 사이즈 필드요
네 그리고 0x60 크기의 덩어리를 두 개 더 요청했어요 그럼 다음에 제 가짜 덩어리를 0x60 패스트빈에
할당받을 수 있죠
GDB 아래에 제 스크립트를 실행해서 보여드리겠습니다
네 네 '패스트빈'에 따르면 제 가격은 0x61로 0x50 패스트빈 위에 올라
있고 0x60 패스트빈은 주최 측에 연설하러 갔습니다
둘 다 서로 다른 패스트빈 둡에서 나온 거예요
경기장을 직접 살펴보면 그 두 가지 가치가 어디에 있는지 알 수 있죠
이건 0x50 패스트빈 슬롯이고 이건 0x60 슬롯이에요
네 네 안 그러면...
네 0x61은 0x60 패스트빈 크기로도 적당한 크기라서
패스트빈 크기는 문제가 안 돼요
제가 직접 0x60 크기의 덩어리를 요청해서 데이터를 입력해 보겠습니다
네 다시 GDB로 돌아와서 메인 아레나를 보면 0x59 바이트가 대문자 y를 나타내는
데이터들이 적혀 있습니다
즉 패스트빈 둡을 이용해서 메인 아레나에 가짜 사이즈 필드를
설정하고 두 번째 둡으로 할당하면 아레나에 저장된 맬록 메타데이터를 덮어쓸
수 있습니다 예를
들어, 포인터요
다시 한번 영상을 멈추고 다른 게 나오는지 보세요
조언이 필요하면 여기로 와요
한 줄 더 추가했어요
네 네 아까 수동으로 한 것처럼요 네, 맞아요
그리고 리소스에서 멀리 떨어진 제 스크립트 복사본도 가져옵니다 템플릿 넘버 4라고 표시된 곳이죠
네 이번엔 맨 위까지
데이터를 썼어요 그리고 다시 덮어썼죠 말록 후크
16 , 마이너스 16 네 아레나를 소개받았을 때 위쪽 뿔을 잠깐 언급했는데
포스의 집 기술에서 간접적으로 다뤄야 했죠
네 네 그리고 프리바늘 근처에는
적당한 크기가 없어요
스크립트를 실행하고 메인 아레나를 버려서 상태를 보여드리죠
네 가짜 0x60 청크가 보이죠
일부 사용자 데이터는 쓰레기로 채워졌고
상단 포인터는 덮어쓰기 됐어요
네 네 말록은 위쪽부터 시작한다고
생각하니 이 주소도 말록의 갈고리 중 하나인 셈입니다 말록이 가장
큰 덩어리를 찾는 곳이 됐죠 ?
힘의 집 이제 힘의 집 마지막 단계까지 거의 똑같은 상황이에요
이제 상부에서 작동할 요청만 하면 돼요 말록 갈고리를 덮어씌울
수 있게요 패스트빈이 비어 있는 크기는 다
돼요 0x20 크기의 덩어리를 손으로 요청하죠
하지만 이번에는 그렇게 간단하지 않습니다 글리벡이 상단부 덩어리에 문제가 있다는 걸 감지했습니다
그 집은 글리벡 버전 2를 사용했어요 28, checksec 출력에서 기억하실 이진법은
GLIBC 버전 2를 사용합니다 30
PDF '감량' 섹션에 글리벡 버전 2가 있어요 29번은 가장 큰 덩어리로 견고함을
확인했습니다
GDB로 돌아가면 _int_malloc으로 전환 '프레임과 '컨텍스트 코드' 명령을 발부하면' 체크를 볼
수 있습니다
상단의 덩어리를 av>시스템_mem이라는 것과 비교하고 있어요 av는 힙을 관리하는 Arena를 나타내는
변수입니다 이 경우 메인 Arena-sis_mem은
현재 아레나에서 커널에서 체크아웃한 메모리 양입니다
익숙한 값이죠 0x21000은 힙의 초기 크기입니다
말록이 네 뭔가 잘못된 것이 분명하고
활동을 중단할 겁니다
네 현재 글리벡 주소를 위조품 크기로 쓰고 있어요 system_mem 값보다
훨씬 크죠 ? 네
다시 멈춰서 이 문제를 어떻게 극복할지 생각해 보세요 다른
덩어리와 마찬가지로 맨 위 덩어리도 16바이트씩 나란히 있을 필요는 없습니다
이 부분 외우는
데 도움이 필요하면 비디오를 다시 켜요
네 제일 큰 덩어리를 처리하고 있었어요 가짜 글립코 주소와 메인
아레나 시스템_mem 값을 비교했더니 너무 크더라고요 , 그래서...
맞아요 이 수표를 통과하려면 첫 패스트빈 둡 쌍성 판독기에 썼던 방법을
써야 해요
네 지금까지 보여드린 모든 건 이 섹션 리소스에서 다운로드
가능합니다 템플릿 5번으로 표시된 리소스요
제가 수정해서 맨 위의 포인터를 덮어썼어요
네 바늘을 마이너스 16에서 35로 줄였어요 지난번과
같은 값이죠 그래서 0x7f라는 확실한 크기를 얻었어요
36을 사용해도 돼요 가장 덜 중요한
바이트가 aslr 사용이지만 총량은 언제나 system_mem보다
작죠
스크립트를 실행하고 메모리를 맨 위 부분에 놓습니다
네 이제 맨 위 덩어리는 system_mem보다 훨씬 작은 크기 필드를
갖습니다 안전하게 한 덩어리를 요청해서 말록 훅을 덮어씌울 수 있죠
네 쓰레기도 계산해 주세요 상부 지역에서 말록 갈고리까지의
거리를 계산해야 해요 ? 네, 맞아요
저번엔 19바이트나 썼잖아
네 껍데기를 벗으려면 한 가지 장치를 써야 합니다 첫 패스트빈 둡 바이너리처럼
요청 크기가 제한돼 있어 주소를 통과할 수 없습니다
네 PDF 부록 A에는 가젯 도구의 사용 예가 있습니다 다시 알려드리자면요
이 과제의 마지막 문제가 있습니다 혼자서는
이해 못 해도 괜찮아요 주변적인 문제만 다뤄봤으니까요 하지만 시간을 갖고 생각해보세요
글립코 글립코에서는 장비가 하나뿐이라는 걸 알 수 없어요
하지만 도구가 인쇄하는 제약이 보이는 것만큼 엄격하지 않다는 걸 배웠죠
네 대시 셸의 맨 페이지를 보세요
특히 명령줄로 전달될 수 있는 인수로 그러므로 argv 배열로 가게 되는 거죠
,
지금 비디오 멈추고 마지막 단계에 집중해요
천천히 하세요
정말 막혔다 싶으면 비디오를 다시 켜고 도전을 마무리하죠
좋아요
이 외동 장비를 작동시켜 보죠
좋아요 지난번 패스트빈 둡 바이너리에 썼던 것과 같은 장치를 골랐어요 스택 포인터에 0x50을
더하면 null이라는 제약 조건이죠
네 이 지점을 따라잡고 싶다면 템플릿 6번이라고 적힌 이 섹션 리소스에서
제 스크립트를 다운로드하세요 좋아요, 대본에 대사를 추가해서 제가 고른 도구의
주소로 말록 갈고리를 덮어썼어요
네 지금은 저 줄이 말록 갈고리를 가비지 값으로 덮어쓰는 것에 유리하게 주석을 달았습니다
네 이렇게 하면 정확한 지점에서 멈출 수 있습니다 프로그램 컨텍스트를
검사할 수 있습니다
이 선 아래에는 말록에게 보내는 신호가 있어요 이 도움의 기능이 말록 갈고리로 신호를 보내는 거예요
스크립트를 실행할 때 일반적인 디버깅 옵션과 제가 제공한
쓰레기 주소 세그폴트 프로그램을 실행할 때요? , 네
이제 '스택 14'를 이용해 제약이 충족되는지 확인할 수 있습니다
네 스택 포인터 더하기 0x50은
무효가 아니지만 주소를 읽을 수 있으니 안전하다는
건 알죠 ?? 네
네 안타깝게도 널도 아니에요 그래서 지난번에
이 장치를 써서 빠져나왔죠 , 하지만
하지만 우리가 통제하는 기억을 가리키긴 하죠
네 네 대상자에 상응하는 대문자
L을요
네 이 상황은 물론 프로그램에 의존하죠
쌍성계에서는 운이 안 따를지도 몰라요
네 이번 경우에는 첫 번째 논거를 조작해서 대시 셸에 전달하면 실패를
피할 수 있으니 운이 좋았어요
선생님 대시를 실험해 보셨다면 잘못된 주장에 민감하다는 걸 아실 거예요 ? 네
존재하지 않는 옵션이나 파일 이름을 전달하면 셸이 생기지 않습니다
더 나쁜 건 첫 번째 인수가 유효하다고 해도 계속 인수를 구문 분석해서 잘못된 것이나 읽을
수 없는 것에 무효가 나올 때까지 한다는 거예요
대시맨 페이지를 검색해 보셨다면 이 문제에 대한 몇 가지 해결책을 발견하셨을
겁니다
첫째 대시가 유효한 파일 이름을 만나면 다음 명령을 구문 분석합니다
다음 인수는 무시하고요
커맨드를 디스크에 쓸 수 있다면 이게 실행 가능한 옵션이죠
네 두 번째 더 실용적인 해결책은 's' 인수를 통과하는
것입니다 인수는 stdin의 커맨드를 읽기 시작하고 다음 주장은 무시합니다
편집기에게 돌아가서 유일한 장치의 주소를 말록 갈고리에 입력하는 줄로 바꿀게요
스크립트를 실행합니다
"M은 L을 열 수 없다"라는 오류를 프린트합니다 네 그 문자열들은 제 스크립트에 덩어리 표시를 위해 사용한
데이터에서 온 거죠 그래서 제가 "l" 마커를 "s" 옵션으로 대체하고 문자열을 무효화하는 걸
잊지 않으면 제작 조건에서 스크립트를 실행합니다 GDB와 NOASLR 옵션
없이요 드디어 셸을 얻었어요 여러분도 얻길 바랍니다
요약하자면 2진법 버그와 libc 유출이 있었지만 0x70 크기의 청크를 요청할 수 없었어요
거시기 0x70
그래서 더블프리를 이용해 패스트빈덥을 두 번 공격했죠
네 네 두 번째를 메인 아레나에
배치하고 위쪽의 덩어리를 덮어씌웠죠 ? 네
위에 있는 네 안 그러면 안
보이니까요
그리고 맨 위에 있는 덩어리에 요청해서 장치의 주소로 맬록 갈고리를 덮어씌웠어요
네 하나의 가젯 제약이 충족되지 않았죠 하지만 우리가 첫 번째 변수를 호출된
대시 셸에 넘겼기 때문에 stdin 옵션을 통과시킬 수 있었습니다 대시 구문
분석을 피하고 마침내 우리에게 셸을 줬죠 ?
네 이번 챌린지를 위한 코멘트 달린 개발 프로그램은 이 섹션 리소스에서 이용 가능합니다
네 PDF도 꼭 검토하세요
기억 상쇄를 위해 아레나 레이아웃이나 패스트빈 둡 기술 pwndbg 명령어,
pwntools 기능을 기억해야 한다면요
하나의 장치에 두 개 이상의 언쟁을 제어하면 큰 장점이 있습니다 세투이드 바이너리를 공격한다고 가정하고
챌린지를 하나로 만들게요
네 취약점을 실행하면 제가 얻는 셸은 스크립트를 실행하는 사용자의
소유가 됩니다 대부분의 요즘 셸은 실제 uid와 맞지 않으면 효율적인 uid를 재설정하기
때문입니다
이런 상황에 대비한 안전장치예요 네 시스템을 사용할 때는 () 함수
이건 우리가 할 수 있는 게 별로 없습니다 셸을
호출할 때쯤이면 이미 유효한 UID를 초기화하기 때문이죠 하지만 1가젯을
사용할 땐 대시 첫 호출에 인수를 바로 전달합니다
이 동작을 무력화하는 'p' 옵션을 통과시킬 수 있다는 뜻이죠
네 네 그건 나중에
아직 필요한 스트딘 옵션으로 남겠죠 그게 나중에
스크립트를 실행하면 셸이
생겨요
하지만 이번에는 효과적인 UID를 재설정하지 않습니다
마지막 부분은 문제를 풀기 위해 꼭 필요하진 않지만 도구 하나로 할 수 있는 멋진 기술이죠
자 첫 번째 게임 이진법이 즐거웠길 바랍니다 도움 없이 풀었다면 정말 대단한
거죠
아니면 당연한 거고요
아까도 말했지만 아주 어렵게 설계됐어요
어쨌든 교훈을 얻었길 바라요 맞아요 다음 영상에서는
말록의 내부를 다시 살펴보고 더미 활용 기술을 알아보겠습니다 링크를
끊는 거죠