Wargame/pwnable2017. 7. 25. 23:45

pwnable.kr 사이트의 bof 문제를 보면 다음과 같다.


download URL이 제공된다. 일단 다운로드를 받자.


c코드는 다음과 같다.

코드를 분석해보자.

1. main 함수 내에서 func 함수를 호출한다.

2. func 함수를 호출하면서 인자로 0xdeadbeef 를 전달한다.

3. func 함수는 인자로 int 형 변수 하나를 받는다.

4. func 함수 내에서 char형 배열 overflowme를 선언한다.

5. 변수명이 굉장히 노골적이다.

6. gets 함수를 호출해 overflowme 변수에 입력값을 저장한다.

7. 인자로 받은 값과 0xcafebabe를 비교한다.

8. 같으면 bash 실행

9. 다르면 Nah.. 출력


코드 분석을 통해 알아낸 것은 func 함수의 인자인 key 값을 변조해야 한다는 것이다.

그렇다면 어떻게 key 값을 변조할 수 있을까??

해답은 gets 함수에 있다.

gets 함수는 인자로 받은 변수에 데이터를 쓰는 함수인데, 사용자가 입력한 값을 문자열로 저장을 한다. 이 때, 변수의 크기를 넘겨서 쓸 수 있다. 즉, BOF가 발생한다.


payload를 어떻게 만들 수 있을까?

payload를 만들기 위해서는 우선 해당 프로그램을 disassemble 해야 한다.

필자는 ubunt에서 gdb 툴을 이용해 disassemble을 했다.


우선, bof 파일을 다운로드를 받은 뒤 gdb명령을 사용한다.

gdb -q bof

-q 옵션은 gdb 버전 정보 등을 출력하지 않는 옵션이라고 생각하면 된다.


set disassembly-flavor intel

이 명령어는 gdb 명령어로 intel 문법을 이용하도록 설정한다. gdb는 기본 문법이 AT&T이다.


다음 명령어로 main 함수를 디스어셈블 해보자.

disas main

main 함수를 디스어셈블해 보여준다.


main 함수의 스택을 표현하면 다음과 같다.


 

 0xdeadeef

 <-ESP

 

 

 

 

 

 

 

 

 

 EBP->

 SFP

 

 

 ret

 


func 함수를 호출할 때의 스택의 모습이다.


다음 명령으로 func 함수를 디스어셈블하면 다음과 같다.

disas func

func 함수를 디스어셈블해 보여준다.


이 함수에서 보아야 할 부분은 <+29>부터 <+35> 까지이다.

<+29>

overflowme 변수의 시작 위치와 크기를 알 수 있다.

<+32>

overflowme 변수를 esp에 저장하므로써 gets 함수 호출을 준비한다. 즉, 매개변수 설정

<+35>

gets 함수 호출


양이 조금 많아 보이지만 실제로는 작은 조각에 불과하다. 겁먹지 말고 일단 스택을 표현해보자.


 

overflowme 변수의 주소 

 <- ESP

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

overflowme 변수 메모리( 44바이트 ) 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

EBP -> 

 SFP

 

 

 ret

 

 

 func 함수의 매개변수 Key값

 


func+35 부분까지 진행 하면 위와 같이 스택을 표현할 수 있다.

ESP에 oveflowme 변수의 주소를 저장하고 gets 함수를 호출한다.

gets 함수가 반환이 되면 overflowme 변수에 입력된 값을 저장한다.

여기서 44바이트를 초과해서 입력을 해주면 아래 SFP, ret 그리고 func 함수의 매개변수인 key의 값까지도 변조가 가능하다.


key값을 변조하기 위해서 얼마나 입력해야 할까?

overflowme 변수는 44바이트 크기를 받았다. 여기에 더해 SFP, ret 까지 덮으면 그 다음이 key 값이다. 즉, 8바이트를 더한 52바이트를 입력한 후 다음 4바이트가 key값이 되는 것이다.


필자는 python을 이용해 payload를 작성했다.

payload는 다음과 같다.


(python -c 'print "A"*52 + "\xbe\xba\xfe\xca"'; cat) | nc pwnable.kr 9000


그 결과 bash/sh 이 실행이 됨을 볼 수 있다.

flag 를 읽어보자 



'Wargame > pwnable' 카테고리의 다른 글

[pwnable.kr] collision  (0) 2017.06.25
[pwnable.kr] fd  (0) 2017.06.18
Posted by Imp3rio
Telegram Bot2017. 6. 26. 22:54

이전 포스팅에서 python으로 Bittrex wrapper 라이브러리를 이용해 Bittrex API를 사용했다.

이번 포스팅은 이를 이용하여 telegram 봇으로 특정 코인의 가격을 알려주는 기능을 만들어 보자.


우선 telegram bot과 관련된 내용은 이전 포스팅을 참고하길 바라며, 이번 포스팅에서는 다루지 않는다.


[그림 1] Bittrex API 문서


Bittrex API 문서를 내려보면 [그림 1] 부분을 확인할 수 있다.

①을 보면 Request 예제가 있다. 주소창에 ①을 넣으면 결과로 ②를 확인할 수 있다.

②에서 여러 정보들 중 현재 시장가격을 확인할 수 있다.

이 Request 예제를 활용할 수 있는 함수가 있는지 python wrapper 코드를 찾아보자.

[그림 2] bittrex.py Bittrex 클래스 함수 get_market_summaries()


코드를 확인해 본 결과 [그림 1]의 ① 을 이용하는 함수는 정의되어 있지 않고 get_market_summaries() 함수만 정의되어 있다. 이 함수의 기능을 읽어보면 마켓 전체의 정보를 가져온다.

이 함수를 이용해 원하는 코인의 정보를 얻을 수 있지만, 전체 정보에서 찾아내는 것보다 [그림 1]의 Request 를 이용하는 것이 더 좋아 보인다.

* for문을 돌려 찾아내는 것보다 한번의 요청으로 원하는 데이터를 얻어오는 게 더 빠를 것 같다.


이를 인지한 상태에서 [그림 1]의 결과를 다시 보면 다음과 같다.

[그림 3] [그림 1]의 결과로 얻는 정보


[그림 3]에서 확인할 수 있는 정보들 중에 Last 부분이 현재 시장가이다. 하지만 단위가 BTC 단위이기 때문에 가격을 인지하는 것이 쉽지가 않다. 따라서 달러로 변환시켜 달러가격으로 표시하도록 하자.


[그림 4] BTC의 달러 가격 확인


Bittrex에서는 BTC, ETH, USDT를 기준으로 가격을 각각 표시를 하며, 각 기준으로 거래할 수 있는 코인의 종류가 모두 다르다.

BTC는 USDT로 거래할 수 있는 코인이기 때문에 달러 가격을 확인할 수 있다.

[그림 4]의 Last 부분이 바로 현재 BTC의 달러 가격이다.


지금까지 확인한 정보들을 가지고 만든 코드는 다음과 같다.


bittrex_telbot.py


위 코드는 bittrex wrapper 라이브러리를 참고하여 작성했으며, 이 코드의 기능은 60초마다 BTC 코인( 비트코인 )과 EDG( 엣지리스 ) 코인의 가격을 텔레그램 봇으로 보내준다.


지금까지 특정 코인의 가격을 받아보는 텔레그램 봇을 만들어봤다.

Bittrex API와 python wrapper 라이브러리를 참고하면 더 많은 기능을 추가할 수 있다.

Posted by Imp3rio
Telegram Bot2017. 6. 26. 15:17

Bittrex API문서는 여기에서 확인할 수 있다.

API 문서는 자주 봐야 하기 때문에 봇이 완성될 때까지는 닫지 않도록 한다.


[그림 1] Bittrex API 페이지


Bittrex API 페이지는 [그림 1]과 같다. 

API 이용자들이 쉽게 사용할 수 있도록 GO, Ruby, node.js, python 언어의 wrapper 라이브러리를 제공하고 있다.

필자는 python을 이용하기 위해 python 라이브러리 링크를 타고 들어가보자.

* 필자는 python 2.7.10 버전을 사용하고 있다. 

[그림 2] Github python-bittrex 페이지


[그림 2]와 같이 Github 사이트가 열린다.

해당 라이브러리를 사용하기 위해 clone or download 버튼을 눌러 ZIP 형식으로 다운로드 받는다.

다운받은 python-bittrex.zip 파일을 압축 해제한 뒤 python을 이용해 설치한다.

이를 위해  커맨드 혹은 터미널을 열어 압축 해제한 폴더에 이동한 뒤 아래 명령어를 이용한다.

python setup.py install


위 명령어를 커맨드 창에 입력하면 설치가 완료된다.


bittrex wrapper 라이브러리를 사용할 환경을 모두 설정했다.

이제 실제로 동작하도록 python 코드를 짜면 된다.

python 코드를 작성할 때 [그림 1] 과 [그림 2] 사이트를 모두 봐야 한다.


우선 간단하게 'BTC-EDG' 마켓에 대한 정보를 가져오는 코드이다.


위 코드는 get_markets() 함수가 JSON 형식으로 데이터를 반환해 주면 그 값을 이용해 BTC-EDG 관련된 부분만 출력하도록 되어 있는 코드이다.

API_KEY와 SECRET_KEY는 Bittrex에서 발급받은 키를 넣어주면 된다.


API 문서 및 Github 코드를 바탕으로 필요한 코딩을 하면 된다.


지금까지 Bittrex wrapper 라이브러리를 이용한 간단한 마켓 정보를 출력해 봤다.

다음 포스팅은 Bittrex 시세 정보를 telegram 봇으로 알림 받는 것에 대한 내용이다.

Posted by Imp3rio