Dreamhack : basic_rop_x64


코드를 보면 read 함수를 통해 입력을 받고 write 함수를 통해 입력 받은 데이터를 출력하는 걸 알 수 있다.
버퍼의 크기는 0x40이지만 read 함수로는 0x400만큼 입력 받을 수 있기 때문에 bof 터트릴 수 있다.

쉘을 따기 위해서는 system 함수를 호출해야 하는데, system 함수의 주소를 알 수 없으므로 system 함수의 주소를 구해야 함
# leak
72바이트의 문자를 채우고 실행할 함수의 인자을 먼저 적어줌
① pop rdi; ret 가젯
② rdi : write 함수 인자 1 - 1
③ pop rsi; pop r15; ret; 가젯
④ rsi : write 함수의 인자 2 - e.got['write']
⑤ r15 : 아무거나 채워줌
⑥ ret : write 함수의 주소
▶ write(1, read_got, rdx 값) : read함수의 주소 출력
# input "/bin/sh" → bss
system 함수의 인자인 "/bin/sh\x00"를 bss 영역에 적어주어야 함.
① pop rdi; ret; 가젯
② rdi : read 함수 인자 1 - 0
③ pop rsi; pop r15; ret; 가젯
④ read 함수의 인자 2, 3
4-1 : bss의 시작 주소 + 0x200만큼 떨어진 곳에 입력 받은 데이터를 넣음.
4-2 : 아무거나 채움
⑤ ret : read 함수의 주소
▶ read(0, bss + 0x200, rdx의 값)
payload를 보내기 전에는 libc_base의 주소를 알 수 없기 때문에 system 함수의 주소를 구할 수 없음 → payload를 나눠서 보내야 함.
payload를 보내고, libc_base를 구한 다음,
libc_base주소와 system 함수의 offset을 더해 system 함수의 주소를 구함
(32bit - 라이브러리 시작 주소 '\x7f')
다시 main 함수를 호출해서 bof를 터트릴 기회를 만듦.
72바이트의 문자를 채우고 실행할 함수의 인자을 먼저 적어줌
① pop rdi; ret 가젯
② rdi : system 함수 인자 - "/bin/sh\x00" 문자열이 있는 주소
③ ret : system 함수의 주소
