티스토리 뷰
안녕하세요 오늘 포스팅할 주제는 "지뢰 찾기 리버싱!" 입니다.
카테고리에 나온 것 처럼 지뢰 찾기를 통해서 DLL Injection을 해보려고 합니다
DLL Injection에 앞서 간단하게 DLL Injection에 대해서 설명하고 넘어가겠습니다
1. DLL ?
컴퓨터를 하다보면 .dll 이라는 파일들을 자주 볼 수 있습니다.
자 그럼 이런 DLL(Dynamic Link Library) 들은 무엇일까요?
먼저 A라는 프로그램과 B라는 프로그램이 있으며, 두 프로그램 모두 C안에 있는 함수들을 사용한다고 가정해봅시다.
C는 A와 B모두에게 사용되니깐 A와 B모두에게 C가 존재해야 합니다
그림으로 본다면 이런 상황이겠죠
개발자들은 항상 극단적인 상황을 생각해봐야합니다.
그렇다면 C가 필요한 프로그램이 100개이고 100개의 프로그램을 동시에 돌린다고 생각해봅시다.
C가 들어간 프로그램이 100개이고 C가 100개가 동시에 실행이 될 것입니다.
정말 이런 안타까운 자원낭비가 있을 수 없습니다.
그래서 개발자들이 생각해 낸 것이 DLL(Dynamic Link Library)입니다.
그림을 보면서 이해를 해봅시다.
이런식으로 DLL을 따로 분리한뒤 A에서 C.dll의 함수를 갖고 올 수 있도록 하는 것입니다
그렇다면 앞서 극단적인 상황에 대해서 생각해봅시다
100개의 프로그램 안에 C를 100번 모두 넣어서 실행해야 할까요?
정답은 "아닙니다"입니다.
왜냐하면 C.dll이란 DLL을 메모리상에 올리고 이 DLL에서 필요한 함수들만 계속 갖다 쓰면 되기 때문입니다.
그렇다면 이 프로그램은 프로그래머가 만든 DLL만 쓰는가?
아닙니다. 바로 이부분을 이용해서 사용자가 원하는 작동을 하도록 DLL을 만든 뒤, Injection을 하여 프로그램이 원하는 동작을 하도록 만들 수 있습니다.
바로 이것이 "DLL Injection"입니다.
그렇다면 원하는 동작을 하도록 만들기 위해선 프로그램이 어떻게 실행되고 어떤 기능들을 하는지 알 필요가 있습니다.
그래서 필요한 것이 바로 "리버싱"입니다.
앞으로 해볼 DLL Injection은 "지뢰 찾기" 게임을 이용해서 실습해볼 예정입니다.
"지뢰 찾기" 게임에서 지뢰를 클릭했을 때 모든 지뢰의 위치가 표시됩니다. 바로 이 기능을 하는 함수를 찾을 것 입니다.
따라서 "지뢰 찾기" 리버싱을 해보도록 하겠습니다.
실습환경 : Win7 32bit
리버싱은 x32dbg와 치트엔진을 이용하겠습니다.
처음에는 x32dbg만 이용해서 리버싱을 진행했습니다. x32dbg를 이용해서 찾다가 보니 어떠한 부분을 계속 반복하는데 의미 있어 보이는 어셈명령어들은 아니였습니다. 어떤 이유였는지 처음에 모르고 시간을 쓰다가 알게 됐습니다.
바로 SEH_Record[1] 로의 포인터 라는 글자를 찾을 수 있습니다
네 바로 Dynamic AntiDebugging의 일종의 예외처리를 하는 부분입니다.
SEH를 이용해서 디버깅중인지, 브레이크 포인트가 걸렸는지 등의 예외를 확인할 수 있습니다.
이러한 안티디버깅은 프로그램 내부의 중요한 함수들이나 flow들을 EBP의 값을 0xFFFFFFFF의 값으로 덮어 씌우면서 숨길 수 있습니다.
그래서 값을 스캔할 수 있는 치트엔진을 이용해보자라는 생각에 치트엔진을 사용했습니다
먼저 지뢰와 관련된 함수이므로 지뢰의 개수의 값을 변경해가며 스캔하여 지뢰 개수의 값을 담고 있는 주소를 찾습니다.
이런식으로 값에 40을 First Scan -> 10을 입력하고 Next Scan 을 누르면 지뢰의 갯수를 담고있는 주소를 쉽게 찾을 수 있습니다.
실제로 지뢰의 갯수를 담고 있는지 확인을 하기 위해서 Value의 값을 1로 바꾸고 Active를 클릭해서 1로 고정해봅시다.
오 정말로 지뢰의 갯수가 1이 되었고 바로 게임이 끝난 것을 확인할 수 있습니다.
그렇다면 게임이 재시작 될 때마다 이 값을 참조를 한다는 것을 생각할 수 있을 겁니다.
값부분에 오른쪽클릭을 해서 치트엔진의 "Find out what accesses this address"의 기능을 사용해봅시다.
이 값을 참조하는 주소들을 찾는 기능입니다.
저 기능을 킨 뒤 게임을 재시작하고 이곳 저곳 클릭을 하다보면 참조한 주소들이 뜨고 몇번 참조를 했는지 Count가 됩니다.
이렇게 여러가지가 뜨는데 그중 중요하게 봐야할 부분은 바로 빨간색 상자가 쳐진 주소입니다.
클릭을 하며 잘 비교해보면 지뢰 또는 지뢰가 아닌 곳을 클릭하면 저 주소의 Count값이 하나씩 증가하게 됩니다.
그렇다면 클릭을 할 때마다 저 주소가 지뢰의 총 갯수를 참조한다는 의미인데 매우 의심스럽습니다.
저 부분에 BreakPoint를 걸고 게임을 진행해봅시다.
먼저 이런식으로 Show disassembler를 누른뒤 해당 주소를 클릭한 뒤 오른쪽 클릭후 BreakPoint를 걸 수 있습니다.
그럼 이렇게 클릭을 했을 때 멈추는 것을 확인 할 수 있습니다.
브레이크 포인트를 풀어주고 이 주소다음에 어떻게 어셈이 진행되는지 Break and trace instructions의 기능을 사용해봅시다
처음에 한번 클릭한 뒤에 두 번째 클릭할 때 Break and trace instructions를 해줘야합니다
왜냐하면 처음에 지뢰를 클릭하는 것을 방지하기 위해서 처음 지뢰라면 지뢰의 위치를 옮겨주는 기능이 있기 때문입니다.
그러면 이런 Tracer를 얻을 수 있습니다. 저는 파란색 상자안의 주소가 수상한 느낌이여서 저곳에 BreakPoint를 걸고 게임을 다시 실행해봤습니다.
먼저 이런식으로 게임이 멈췄고 Step Over를 누르는 순간
오!! 이런식으로 지뢰를 다 보여주면서 멈췄습니다..!!
그렇다면 저 함수가 바로 끝나기 직전의 지뢰를 다 보여주는 함수라는 것을 알 수 있습니다.
실제로 Step Over를 하다보면 다음 call 부분에서 게임이 끝나버립니다.
사실 리버싱을 하는 동안에는 이 방법이 바로 떠오르지 않아서 x32dbg의 참조기능을 활용해서 바텀 업 방식의 이상한? 리버싱을 했습니다.
원하는 함수를 찾고 난 뒤 블로그에 정리하며 다시 해보니 정말 간단하게 찾을 수 있게 됐습니다.
동시에 치트엔진의 다양한 기능과 x32dbg의 다양한 기능들을 찾을 수 있게 됐습니다.
직접 하다 보면 SEH뿐만 아니라 Timing Check를 하는 안티디버깅도 만날 수 있습니다!
다음 포스팅에서는 원하는 함수의 주소를 찾았으므로 메뉴를 누르면 저 코드를 후킹해서 지뢰를 보여주는 DLL을 만들어 Injection 해보도록 하겠습니다.
- Total
- Today
- Yesterday
- Docker daemon
- aiomysql
- express 아키텍쳐
- service docker start
- 마노시피유정렬
- 어셈블리 최댓값 찾기
- 2024년 회고
- fastapi 비동기 처리
- 탈단 후 입대
- docker.sock
- chrome extension
- and will not be enabled for virtual device 'serial0' will start disconnected
- systemctl start docker
- pwnable#basic_exploitation_003#dreamhack#dreamhack.io#SSG
- JS 개발
- 정보보호병
- 2023 화이트햇
- 군 취약점 제보
- Mano-CPU-Programming
- vmware 화면 버벅거림
- ict 인턴십
- Win7#Win7지뢰찾기#Win7 지뢰찾기#지뢰찾기#Win7 32bit#32bit#MineSweeper.exe#MineSweeper#WinMine
- fastapi
- Mano-CPU Sort
- whitehat
- Mano-CPU
- 탈단
- BlackBoard Helper
- the virtual printing feature is globally disabled on this system
- Mano-CPU 최댓값 찾기
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |