일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- PICO CTF
- 책
- 백준
- PHP
- HTML
- 설치
- picoCTF
- 리뷰
- 파이썬
- 기울기
- 우분투
- 순전파
- 신경망 학습
- flag
- C언어
- sgd
- 소프트맥스 함수
- AdaGrad
- 오차역전파법
- 역전파
- 코딩
- 신경망
- Python Challenge
- Python
- 아파치
- CTF
- Apache2
- 딥러닝
- PostgreSQL
- FastAPI
- Today
- Total
Story of CowHacker
Pwnable_Bof 본문
포너블 3번째 문제를 풀어 볼것이다.
버퍼오버플로우가 소프트웨어의 취약점이라는게 사실 이라고 묻는 질문에 다운로드 링크 2개가 있고
,nc 접속 주소가 있다.
bof.c 링크 부터 들어가 c파일을 확인해봤다.
일단, main함수 부터 봤다. 메인 함수 인자에는 argc라는 변수에 argv형식으로 값을 넣어 주는 거 같았다.
그리고 main함수 안에 func해놓고 0xdeadbeef값을 반환하게 해 놓았다.
이제 위로 가서 func 함수를 봤다.
여기서는 overflowme[32]라고 overflowme라는 변수에 32 바이트를 준다는걸 알수 있었다.
그리고 gets로 값을 받아 if 문으로 또는 else문으로 가는 형식이였다.
여기서 if 문으로 가기 위해선 overflowme의 값이 oxcafebabe 가 되야 했다. 그래야 비로소 shell을 딸수 있게 보였다.
c파일 해석은 이쯤 해두고 다음 단계로 넘어 갔다.
c파일 다운 링크 위에꺼를 다운해서 실행 시켜 봤더니 되지 않았다.
이번에는 cat으로 열어 보았다. 다 깨진 글이 였다. 깨진글 == gdb 로 해야 겠구나 생각했다.
( 아직은 내가 잘 몰라서 깨진 글이라고 하는데 전문 용어가 뭔지 궁금하다. )
gdb로 연뒤 disassemble main 명령어를 써서 main함수를 어셈블리어로 봤다. 이유는 어떻게 함수가 돌아 가는지 과정 그 자체를 알기 위해서다.
아직은 어셈블리어와 어색한 사이여서 처음부터 끝까지 해석은 못하겠어서 눈에 보이는것만 봤다. +9에 deadbeef라는 부분 이 deadbeef는 아까 c파일에서 func가 반환하는 값이였다. 그래서 바로 밑에 보니 call 하고 func에게로 가는듯 한 모습이 보였다.
disassemble func로 func함수를 열어봤다.
더 길고 복잡했다. 구글링을 해본 결과 cmpl라는 녀석이 c언어에서 if 역할을 하는 녀석이라고 했다.
그렇다는 말은 +40이 아까 c파일의 if 부분이라는거다.
if문을 다시 생각해 보면 key값이 0xcafebabe이면 실행 한다는 거였다.
그 key값은 overflowme값에 있으니 이 overflowme 가 어디에 있는지도 알아야했다.
구글링 해본 결과 lea라는 녀석이 연산과 관련된 거라고 했다.
그래서 나는 +29 저부분을 overflowme부분이라는걸 추측할수 있었다.
음.... 그런데 이미 main함수에서 func는 0xcafebabe값이 아닌 deadbeef값을 반환 하도록 되있었다.
그런데 어찌 그 값을 0xcafebabe로 바꾼단 말인가...??
구글링을 또 해보았다.
buffer overflow라는 걸 통해 그것이 가능하게 된다고 했다. 원리는 처음 배정된 버퍼크기인 변수가 있는데 그 버퍼크기를 넘긴 값을 주면 그 값 이후에는 다른 영역으로 까지 값이 넘어간다걸 이용하는거다. 그 넘어간 값을 이용하는것이 바로 buffer overflow라는 것이다.
그래서 나는 생각했다. overflowme 라는 녀석은 32바이트로 정해 졌는데 그 값이 넘어간 값을 넣으면 어찌 될지 말이다.
그럼 이제 +40 즉 if 문까지 브레이크포인트를 걸어 놓고 실험을 해볼거다.
왜 하필 +40에 브레이크포인트를 줬냐면 gets에서 값을 받고 비교를 하는 구문이 +40구간 이기 때문에 그 비교 하는 과정을 알아보기 위함이다.
그리고 이제 run을 해 볼려고 명령어를 쳣는데 허가 거부라고 처리가 되지 못했다.
원인을 구글링으로 알아보니 실행 권한이 없어서라고 했다.
역시나 x 즉, 실행권한이 없었다.
나는 그냥 777 권한을 줘버렸다.
이제 x, 실행 권한이 생겼다.
다시 break를 +40에 걸고 run을 해보았다 이제는 가능해졌고 무엇을 입력 하라는 커서가 떳길래 나는 a를 32개 쳐 엔터를 눌렀다.
주소값을 보는 명령어는 x/이다 그리고 이제 뒤에 숫자는 그 숫자 만큼 본다는 것이다. 또 w는 4byte단위로 본다는 것이고 x는 16진수로 본다는 것이다.
그래서 내가 친 명령어를 해석해보면 x/ 메모리 주소값을 볼것인데 40 개를 볼것인데 그걸 w 4byte단위로 x 16진수로 보여달라는 것이다. 그리고 뒤 $esp는 esp 즉 스택의 젤 마지막 주소 부터 메모리 주소값을 보겠다는 것이다.
내가 a를 32 번 입력한 값이 처음 몇바이트에 저장되며 또 저장된후 몇 바이트에 deadbeef값이 반환이 되는지 봤다.
일단, a는 아스키코드로 61이다 그 61이 시작하는 부분은 지금 사진을 보면 32 바이트 부터 시작이 된다. 그리고 61 값이 끝난 시점 이후 20바이트후에 deadbeef값이 반환이 되는걸로 보인다.
그럼 총 32 + 20 바이트해서 52 바이트라는 곳에 deadbeef값이 아닌 0xcafebabe값을 넣어 주면 되겠지? 라고 생각했다.
저기서 의문점이 하나 들었는데 왜 ;cat을 넣는냐는 것이다. 그냥 (python -c 'print "a" * 52 + "\xbe\xba\xfe\xca"') | nc pwnable.kr 9000으로 하면 안돼는것인가?? 해서 구글링을 해봤는데 저렇게 cat이라는 명령어가 없으면 프로그램이 바로 종료 되기 때문에 꼭 cat명령어와 같이 표준 입력을 받아서 표준 출력을 해주게 만들어야 한다고 했다.
그 cat명령어가 | ( 파이프 ) 로 실행파일과 연결이 되어 있어 프로그램이 종료 되지 않는다고 했다.
그래서나는 (python -c 'print "a" * 52 + "\xbe\xba\xfe\xca"';cat) | nc pwnable.kr 9000 으로 명령어를 입력했다.
shell권한을 땃는지 ls를 하니 파일들이 나왔고 flag파일도 있었다.
cat flag 해서 flag 값을 얻었다.
'공부 > Pwnable' 카테고리의 다른 글
Pwnable_Random (2) | 2020.07.24 |
---|---|
Pwnable_Passcode (0) | 2019.12.16 |
Pwnable_Flag (0) | 2019.11.30 |
Pwnable_collision (0) | 2019.11.24 |
Pwnable_fd (0) | 2019.11.20 |