C언어 개념이 확실해야 한다는걸 느끼게 해주는 문제였다...
문제의 C코드를 보면
이러하다!
프린트로 버퍼의 주소를 알려주고..따라서 그냥 버퍼의 처음부터 쉘코드를 박아놓고 sfp까지 의미없는 주소를 넣고 ret에 버퍼의 주소(=쉘코드의 주소) 를 넣기로 했다.
계획한건 하도 간단해서 오히려 sf1보다도 쉽겠구나~했는데...코드를 짜는데 시행착오를 또 너무 많이 겪었다.
이건 성공한 코드지만 처음에는 payload=b'이런 b를 어디서 왜 넣어야하는지 감을 못잡아서 자꾸 오류가 났었다.
b'를 넣는게 바이트임을 알려주는 걸로 알고 있었기에 '\x31'이라고만 적으면 바이트 하나를 리틀 엔디언방식으로 인식하지 못해 b'\x31'로 적어 컴퓨터가 리틀엔디언 방식으로 표현된 0x31로 알아듣게 해주는 용도인가보다~정도로 생각했다
근데 payload+='A'*102 이런식으로 리틀 엔디언이 아닌 문자앞에도 b를 안붙여주니 오류가 떠서 도대체 b의 역할이 뭔지 감이 안온다.
이런 사소한 개념도 정확히 알아야 앞으로 문제푸는데 지장이 없을텐데...아무리 찾아봐도 이 개념이 나와있지 않아 문제풀이시 답답한 부분이 있다.
* 페이로드를 쓰는 과정에서
1) b'str' 이렇게 str앞에 b를 붙이는 정확한 이유 -> 아마 단위가 1바이트 (char) 이라는 뜻인듯
2) 처음에 payload=''를 쓰는 것과 쓰지 않는 것의 차이(''가 어떤 역할을 하고 어떤 의미가 있는지)
-> 그냥 후에+할때 문자로 이어져야 하니까 빈것을 저렇게 표현한 듯
를 확실히 알게 되면 따로 쓰겠다. 이걸 모르니 코드를 짜도 확신이 없고 오류파티만 나서 괴롭기 때문..
그리고 이 문제에서 제일 중요했던건 '어떤 쉘코드를 쓰는지' 였다.
처음엔 25바이트 쉘코드를 사용했다.
* 25바이트 쉘코드 : \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80
근데 이 쉘코드를 사용하니 자꾸 쉘에 들어가지 못했다.
이 때문에 온갖 이유를 생각하며 고민했는데...결국엔 쉘코드 중간에 있는 \x0b 때문임을 드림핵 질문칸의 어떤 분의 답변으로 알게 되었다..
\x0b는 아스키 코드로 문자로 변환하면 tap이다. 근데 scanf("%s")는 빈칸, 탭, 엔터 입력시 입력을 종료한다.
그러니까 중간의 \x0b 일때부터 scanf("%s")가 입력을 중지해 오류가 났던 것이다.
즉 위에 첨부한 저 25바이트 쉘코드는 read로 데이터를 보낼때는 문제가 없지만,
scanf %s로 입력받을시 사용하면 안된다.
따라서 scanf("%s")의 특성을 고려하여 탭이나 빈칸, 개행문자가 없는 26바이트 쉘코드로 자리를 대체했다.
* 26바이트 쉘코드 :
\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80
그래서 최종적으로 쉘에 들어가는데에 성공했다.
교훈 : scanf("%s")로 데이터를 보낼 시 %s의 특성을 고려하여 쉘코드를 넣도록 하자 (빈칸, 탭, 개행문자 없는 것으로)
'Pwnable > DreamHack Wargame' 카테고리의 다른 글
[Dreamhack] ROP 풀이 (2) | 2022.07.12 |
---|---|
[Dreamhack] Return to Library 풀이 (0) | 2022.07.09 |
[Dreamhack] ssp_001 풀이 (0) | 2022.07.08 |
[Dreamhack] Return to Shellcode (canary) 풀이 (0) | 2022.07.01 |
[Dreamhack] Stack buffer Overflow (함께 실습) 풀이 (0) | 2022.06.06 |
댓글