본문 바로가기

2. Reversing (리버싱)/1) Write UP

[2023.05.20] 씽씽이 활동보고

 

활용강의: 해킹 대회를 위한 시스템 해킹 프로토스타 완벽 풀이집

 

 

섹션 1. stack - 쉘코드 생성, 리눅스 어태치 방법

 

▼Hints
  - At this point in time, it might be easier to use someone elses shellcode
  - If debugging the shellcode, use \xcc (int3) to stop the program and return to the debugger
  - remove the int3s once your shellcode is done

 

※쉘코드란?

→ 쉘을 실행하는 코드

- return 주소 위에 EBP나 버퍼 같은 것들이 올라간다.

- ret까지 덮다가 밑에 코드도 넣을 수 있고 여기에 쉘코드를 넣는다.

- 프로그램 상에는 코드가 없었는데 우리가 임의로 스택에다가 코드를 넣을 수 있게 된다. 따라서 우리가 원하는 쉘코드를실행할 수 있게 된다.

 

 

-       쉘코드를 넣어서 실행하게 만드는 구조.

-       ‘msfvenom -l | grep linux’를 입력하면 리눅스 관련된 쉘코드 페이로드가 나타난다.

-       간단하게 쉘만 가져올 수 있도록 linux/x86/exec를 이용한다. (x86 32비트이기 때문에 x64를 이용한다.)

 

-       CMD로 실행할 bin쉘을 옵션을 주고 f 옵션을 통해 파이썬을 출력 포맷으로 정한다.

 

-       stack5.py 파일 코드

 

-       stack5.c 파일 코드

 

▶ASLR 끄기

-> echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

 

-       stack5.c 파일을 실행하면 입력 후 엔터를 쳐도 아무런 변화도 없다.

 

-       gdb를 이용해 stack5 메인 호출을 확인했다.

 

-       100개의 패턴을 만든 후 파일을 실행시켜 값을 넣는다.

 

-       리턴값에서 멈추는 것을 볼 수 있다.

 

-       offset값이 72인 것을 확인했다.

-       따라서 페이로드 수정이 따로 필요없다.

 

-       return이 실행되면 return address값은 0x7fffffffded8이고 이 값이 RIP에 저장된다.

 

-       뒤에 버프가 따라올 수 있게 페이로드 뒤에 버프를 넣어 코드를 수정한다.

-       파일을 실행하면 값을 넣지 못했는데 프로그램이 죽어버리기 때문에 pause를 넣는다.

 

-       실행이 멈춘 것을 확인할 수 있다. (키보드 누르면 이어서 실행됨.)

 

-       pid (실행때마다 바뀜)을 넣어 멈춘 상태에서 gdb를 실행한다.

 

-       중간에 브레이크 포인트가 걸린 것을 확인했다.

 

-       return하는 곳에 브레이크 포인트를 걸어준다.

-       0x7fffffffded8이 리턴되면서 그 다음인 0x7fffffffde10이 실행된다.

 

-       stack5.py 파일 코드를 수정해주고 interactive를 삽입한다.

 

-       버전이 달라서 그런지 실행에 실패했지만 강의에서는 셸 획득에 성공했다.

 

 

 

#어태치 방법#

  1. pwn 프로그램에 pause()를 사용해서 잠시 멈춘다.

  2. gdb ./stack5 <pid>

  3. 디버깅 하고 싶은 부분이 break를 건다. (b *main+38)

  4. 디버거를 계속 실행한다. (conti)

  5. pwn 프로그램에 엔터를 누른다. (sendline 실행됨)

  6. 익스플로잇이 성공했는지 확인한다.

 

 

섹션 1. stack - 또다른 해결 방법 ret2lib

 

- 칼리 리눅스에서 32bit 프로그램 실행을 위한 라이브러리를 설치한다.

 

- system 함수를 return에 넣어 실행시킨다.

- stack에 bin쉘을 넣을 것이다.

 

→ 괄호를 채워보자!

- dummy는 의미없는 값으로 채울 것이기 때문에 '0xFFFFFFFF'로 채운다.(위치를 맞추기 위한 방편)

 

- 브레이크 포인트를 메인에 걸고 'disas main'을 통해 확인한다.

 

- 'disas system'을 통해 원하는 주소를 확인할 수 있다. ('print system'도 가능)

- '0xf7e117e0'이 시스템 시작하는 주소이다.

 

- system에 시작 주소인 '0xf7e117e0'를 넣는다.

 

- find '/bin/sh'을 통해 bin쉘의 위치를 찾는다. (0xf7f50968)

- ASLR이 0으로 설정되어 있어야 항상 같은 위치로 올라온다.

 

→ 완성된 코드