Try to be the expert.

Ainsetin's Hacking & PS & Math

Hacking/HackCTF

HackCTF offset Write-up

Ainsetin 2019. 12. 29. 01:03

offset 문제는 뭔가 새롭다. 한번 도전해보자.

 

 

우선 바이너리 보호 기법부터 살펴보자.

 

 

와우.... 지금까지 보지 못한 장면이다. 대표적인 보호 기법이 거의 다 걸려 있다. 즉 우리는 직접 Code, Stack, Data 영역을 실행할 수 있는 권한뿐만 아니라 RET 변조, 쉘 코드 사용까지 전부 다 막혔다는 뜻이다. 다시 말해, 건드릴 수 있는 부분이 한정적이라는 뜻이다.

 

우선 단서를 찾기 위해 IDA에서 이 바이너리를 파헤쳐보았다.

 

main()
select_func(&s)

 

요약하자면, s 문자열을 받아 select_func 함수에서 이 문자열이 "one"이면 one 함수를 return하고 아니면 two 함수를 return 하는 프로그램이다.

 

특징으로는 Basic_FSB문제처럼 return에 함수 이름이 들어가는데, 함수 이름이 곧 주소(포인터)이기 때문에 가능하다.

 

그렇다면, return하는 주소나 값을 내가 바꾼다면 프로그램이 알아서 내가 원하는 것을 실행시켜주지 않을까?

 

stack에서는 다양한 레지스터가 존재하는데, 감사하게도 return값을 저장하고 있는 eax가 존재한다. 그 값이 있는 곳을 원하는 주소로 변조하면 flag를 획득할 수 있을 것 같다.

 

0x000006D8에 위치해 있는 print_flag()

또, 너무 고맙게도 flag를 출력해주는 함수가 주어져 있었다. 그럼 gdb로 stack을 확인해보자.

 

 

select_func 함수를 디스어셈블해보니 예상한 대로 call eax를 하는 것을 볼 수 있었다. 따라서 eax의 값을 바꾸면 되는데...

 

 

우선 call eax 부분인 select_func+85에 break를 하고 s 문자열에 a를 조금 넣어보았다.

 

 

일반 gdb에서는 레지스터를 확인하기 위해 'info reg' 명령어를 치면 된다.

 

gdb-peda에서는 reg, code, stack을 자동으로 보여준다.

 

아무튼, eax의 값을 확인하니 0x56555600이다. 이 값이 있는 부분을 덮어 씌우면 되겠다. stack을 확인해보자.

 

 

처음 0x61이 나온 이후로부터 30byte를 더 가면 eax 값이 있는 것을 확인할 수 있다. 따라서 dummy를 30byte 준 다음 print_flag() 주소를 0x56555600에 덮어 씌우면 될 것이다.

 

exploit code는 다음과 같다.

 

 

실행해보면,,!!

 

 

flag가 출력되는 것을 볼 수 있다.

'Hacking > HackCTF' 카테고리의 다른 글

HackCTF Yes or no Write-up  (0) 2020.01.06
HackCTF BOF_PIE Write-up  (0) 2020.01.06
HackCTF Simple_Overflow_ver_2 Write-up  (0) 2019.12.23
HackCTF x64 Simple_size_BOF Write-up  (0) 2019.12.23
HackCTF x64 Buffer Overflow Write-up  (0) 2019.12.23