.dtors는 쓰기 가능해 보이지만 segfault를 쓰려고 시도합니다.


9

이것은 우분투 9.04, 2.6.28-11 서버, 32 비트 x86입니다


$ cat test.c
main() { int *dt = (int *)0x08049f18; *dt = 1; }
$ readelf -S ./test
...
  [18] .dtors            PROGBITS        08049f14 000f14 000008 00  WA  0   0  4
...
$ ./test
Segmentation fault
$

시작되지 않은 경우 : gcc .dtors는 엘프 실행 파일에 소멸자 세그먼트를 작성합니다 main(). 이 테이블은 오랫동안 쓸 수 있었으며 필자의 경우에는 readelf출력 해야합니다 . 그러나 테이블에 쓰려고하면 segfault가 발생합니다.

읽기 전용 .dtors, plt로 최근에 움직 였다는 것을 알고 있지만 이해하지 못하는 readelf것은 segfault 와의 불일치 입니다.


진짜 질문은 왜 당신이 쓰기를 원하는가?
alex

1
나는 일련의 취약한 프로그램을 깨는 보안 수업을 가르치고 있지만 한 가지 연습은 쉘 코드를 실행하기 위해 .dtors에게 쓰는 것입니다. 더 이상 작동하지 않으며 문제를 추적하려고합니다.
Fixee 2012

불일치는 아마도 일부 데이터 재배치 (읽기 전용으로 표시하기 전에 수정해야하고 어쨌든 지연 될 수 없으므로 일단 고정되면 일정 할 것임) 일 수 있기 때문입니다.
ninjalj

답변:


5

이러한 섹션은 GNU_RELRO (읽기 전용 재배치)로 표시됩니다. 즉, 동적 로더가 모든 재배치를 수정 한 직후 (로드 시간에 지연된 재배치가 없음) 해당 섹션을 읽기 전용으로 표시합니다. 대부분은 .got.plt다른 페이지에 있으므로 치료를받지 않습니다.

ld --verboseRELRO를 검색하면 다음과 유사한 링커 스크립트를 볼 수 있습니다 .

.got            : { *(.got) }
. = DATA_SEGMENT_RELRO_END (12, .);
.got.plt        : { *(.got.plt) }

이는 RELRO 섹션이 12 바이트로 끝나는 것을 의미합니다 .got.plt(동적 링커 기능에 대한 포인터는 이미 해결되었으므로 읽기 전용으로 표시 될 수 있음).

강화 된 젠투 프로젝트에는 http://www.gentoo.at/proj/en/hardened/hardened-toolchain.xml#RELRO 에 RELRO에 대한 문서가 있습니다.


5

실제로 시스템의 어떤 부분이 책임이 있는지 알지 못하지만 왜 실패했는지 알 수 있습니다. .dtors바이너리에서 쓰기 가능으로 표시되어 있지만 ( .ctorsGOT 및 기타 몇 가지 와 함께) 바이너리 에서 메모리에 별도의 쓰기 불가능한 페이지에 매핑되는 것처럼 보입니다 . 내 시스템 .dtors에서 0x8049f14다음을 수행 하고 있습니다 .

$ readelf -S test
  [17] .ctors            PROGBITS        08049f0c 000f0c 000008 00  WA  0   0  4
  [18] .dtors            PROGBITS        08049f14 000f14 000008 00  WA  0   0  4
  [19] .jcr              PROGBITS        08049f1c 000f1c 000004 00  WA  0   0  4
  [20] .dynamic          DYNAMIC         08049f20 000f20 0000d0 08  WA  6   0  4
  [21] .got              PROGBITS        08049ff0 000ff0 000004 04  WA  0   0  4
  [22] .got.plt          PROGBITS        08049ff4 000ff4 00001c 04  WA  0   0  4
  [23] .data             PROGBITS        0804a010 001010 000008 00  WA  0   0  4
  [24] .bss              NOBITS          0804a018 001018 000008 00  WA  0   0  4

실행 파일을 실행하고 확인 /proc/PID/maps하면 다음이 표시됩니다.

08048000-08049000 r-xp 00000000 08:02 163678     /tmp/test
08049000-0804a000 r--p 00000000 08:02 163678     /tmp/test
0804a000-0804b000 rw-p 00001000 08:02 163678     /tmp/test

.data/ .bss여전히 자신의 페이지에 쓸 수 있지만 다른 페이지에는 쓸 0x8049000-0x804a000수 없습니다. 나는 이것이 커널의 보안 기능이라고 가정한다. W ^ X ; Linux에는 PaX 가 있지만 대부분의 커널에는 내장되어 있지 않습니다)

mprotect페이지의 메모리 내 속성을 변경할 수있는으로 해결할 수 있습니다 .

mprotect((void*)0x8049000, 4096, PROT_WRITE);

이로 인해 테스트 프로그램이 충돌하지 않지만 다른 함수의 주소로 .dtors( 0x8049f18) 의 끝 센티넬을 덮어 쓰려고 해도 해당 함수는 여전히 실행되지 않습니다. 그 부분은 알아낼 수 없습니다.

다른 사람이 페이지를 읽기 전용으로 만드는 책임이 무엇인지, 그리고 왜 수정 .dtors이 내 시스템에서 아무런 영향을 미치지 않는지 알고 싶습니다.


3
OP Linux with PaX mprotect가 실행 가능 페이지를 쓰기 가능으로 만들 수 없거나 해당 기능이로 비활성화되어 있지 않으면 이전에 쓰기 가능했던 페이지를 실행할 수있는 경우 paxctl -m.
stribika

@stribika Ah, 알아두면 좋은 점
Michael Mrozek
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.