10 코인 개인적으로 궁금한 점 질문 드립니다(라이브러리 주소 관련)

rop.c 파일을 컴파일한 후 libc 종류를 직접 찾아내는 걸 한 번 해 보고 싶었는데... 뭔가 잘 안 돼서 질문 드립니다.

  1. 환경
    Ubuntu: 22.04.4 LTS
    gcc: gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)

===========================================================

  1. 과정
    (1) rop.c 파일 생성(해당 워게임에서 제공해준 파일과 동일하게 생성)
    (2) gcc -o rop rop.c -fno-PIE -no-pie 으로 rop.c 컴파일
    (3) readelf -d rop 결과
    image.png
    (4) ldd rop 결과
    image.png

=> 위의 readelf와 ldd 결과를 보고, rop에서는 libc.so.6 라이브러리를 사용한다고 생각하여 다음과 같이 readelf 명령어로 해당 라이브러리 파일에서 printf와 puts 함수를 찾았습니다.
puts의 마지막 12비트는 e50이며, printf의 경우는 6f0입니다.

  • readelf -s /lib/x86_64-linux-gnu/libc.so.6 | grep "puts"
    image.png

  • readelf -s /lib/x86_64-linux-gnu/libc.so.6 | grep "printf"
    image.png

=> 그런데 gdb rop을 실행한 후 p puts/p printf로 확인해 보았을 때는 마지막 12비트가 위의 라이브러리 파일에서 확인한 것과 다릅니다.
image.png

제가 이해한 바로는 마지막 12비트가 동일하여 그것을 이용하여 libc base도 계산하고 libc 버전도 알아낼 수 있는 것으로 알고 있는데, 혹시 제가 잘못 알고 있는 것이 있는지 문의 드립니다...

#pwnable
작성자 정보
답변 1
질문자가 채택한 답변입니다. 좋은 지식을 공유해줘서 고마워요!
avatar
mini-chip
Perfect 10

안녕하십니까. 선생님께서 올리신 마지막 캡쳐본에서 p putsp printf는 libc의 puts와 printf가 아닙니다. 바이너리 내부에 있는 plt 코드의 주소입니다. 나중에 GOT overwrite 등의 기법을 공부하신다면 더 깊게 배울 기회가 있으실건데, plt는 libc 파일 내부에 있는 것이 아닌 실행 파일에 있는 코드이며, 실행 파일 내부에서 libc의 코드를 실행하기 위해 libc와 연결해주는 코드라고 이해하시면 편할 것 같습니다. 실행 파일에서 처음 puts 혹은 printf를 호출했을 시에 puts@pltprintf@plt가 실행되게 되고 아직은 libc의 코드가 실행되지 않습니다. plt에서는 실제 libc의 puts함수 혹은 printf함수 주소를 먼저 알아낸 뒤 해당 주소로 jmp하는 방식의 코드가 수행되고 있습니다. 여기서는 자세한 부분은 생략하겠습니다.
정리하자면, 잘못 알고 계신 것은 아니며, gdb rop에서 찾은 주소가 libc의 puts printf함수의 주소가 아닌 plt 코드의 주소였기에 혼동을 겪으신 것 같습니다.

2024.08.15. 15:17
질문에 대한 답을 알고 계신가요?
지식을 나누고 포인트를 획득해보세요.
답변하고 포인트 받기