free_hook을 system 주소로 덮어도 작동하는 이유가 궁금합니다.

우선 stdout 주소를 활용해 free_hook 주소를 알아내고
payload = p64(free_hook) + p64(0x400a11) # mov edi, '/bin/sh' 주소
payload를 위와 같이 설정해서 free_hook을 덮어써서 free가 호출되면
0x400a11 rdi를 '/bin/sh'로 설정하고
0x400a16으로 진행해서 system을 호출하는 것이 맞는지 궁금합니다.

stdout 주소를 활용해 free_hook주소와 libc에 존재하는 system 주소를 모두 알아내고
payload = p64(free_hook) + p64(system) # system = libc_base + libc.symbols['system']
payload를 위와 같이 설정했을때 rdi 레지스터에 따로 값을 지정하지 않았음에도 flag를 획득할 수 있었습니다.
처음에는 free_hook이 system으로 덮어씌워졌으므로 system(ptr) -> system(free_hook 주소값)이 호출되어서
이게 어떠한 이벤트를 발생시키지 않고 두차례 진행된 후에 main함수에 존재하는 system('/bin/sh')가 호출된건가 싶었습니다.
그래서 payload = p64(free_hook) + p64(stdout)으로 테스트를 해봤는데 이 경우에는 flag를 획득할 수 없더라구요.
별도의 매개변수를 설정하는 단계 없이 free_hook을 libc의 system으로 덮어써도 flag를 획득할 수 있는 이유가 궁금합니다.

#pwnable
작성자 정보
답변 3
avatar
wyv3rn
무플 방지 위원회장

다른 방법도 많이 있을거라 생각됩니다만..
일단 코드에 셀을 실행시켜주는 함수가 있기에
free(ptr)이 프로그램을 종료시키지만 않으면 셀이 실행됩니다.

1 아니요. free(주소값)이 실행될텐데, 해당 주소를 프리할 수 없어 에러가 발생할겁니다.
2 stdout 주소는 어떤 함수를 실행하는 주소가 아니기에 에러가 발생할겁니다. 1번과 같은 이유입니다.

2023.05.05. 21:53
avatar
wyv3rn
무플 방지 위원회장

댓글이 변경되었네요.
free에 인자는 말 그대로 프리될 주소를 이야기 하며 해당 주소를 프리하려합니다.
거기 특정 옵코드가 들어간다고 실행되는게 아닙니다.

프리훅에 값이 들어가면 해당 함수를 실행합니다. 여기서도 마찬가지로 함수를 실행하는거지 옵코드를 실행하는 것이 아닙니다.
만일 정상적인 함수 주소가 아니라면 오류가 발생하겠죠 ㅎㅎ

2023.05.05. 22:51
Dreamer
강의 수강: 1

제가 이해하고 있는 부분이 맞는지 알고 싶습니다.
free_hook을 main함수를 disassemble 했을 때 system을 call하기 전 레지스터 값을 세팅하는
[mov edi, '/bin/sh']에 해당하는 주소 0x400a11으로 덮어 썼습니다.
free함수가 호출되고 덮어씌워진 free_hook이 null이 아니기 때문에 해당 함수인 0x400a11을 실행합니다.
여기까지가 제가 이해하는 부분인데 이게 맞는지 궁금합니다.

그리고 hook overwrite할 때 https://learn.dreamhack.io/102#4
hook overwirte 강의에 의하면 free를 수행하기 전에 __free_hook이 가리키는 함수를 먼저 실행한다고 합니다.
그러면 __free_hook이 가리키는 함수를 실행하고 free를 다시 실행하는건지 알고 싶습니다.

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