[KakaoTalkPC] 카카오톡 PC 버전 분석 (1)

KakaoTalk PC

KakaoTalk PC

 

블르그 글을 다시 쓰기 시작한 이 기운을 타고 한가지 정도 더 써볼까 합니다.

도대체 무슨 놈의 블로그가 카카오톡 시리즈가 끝나자마자 (뭐..사실 끝난지는 8개월이 넘었습니다만..) 다른 주제 글 하나 쓰고 또다시 카카오톡으로 돌아오는가 싶으시겠지만.. 공유하면 재밌을만한 정보가 생겨서 쓰게 되었으니 이해를…쿨럭

일단 형식상(?) 시리즈 번호를 붙여놨지만.. PC버전 관련 얘기는 이 포스팅이 처음이자 마지막이 될지도 모르겠군요.
사실 오늘 여기에 적으려는 내용 이외에는 모바일 버젼과 특별히 다른점이 없기 때문입니다.

본문의 내용은 편의상 반말을 사용하도록 하겠습니다. 훗.

 

KakaoTalk PC Beta

때는 바야흐로 3월 말. 많은 관심속에 카카오측에서 PC 버전에 대한 CBT (클로즈베타)를 시작했다.
작년.. 그러니까 2012년 8월쯤 LOCO 프로토콜을 분석한 이후 미루고 미루다가 블로그 포스팅을 한것이 12월.
사실 누군가가 응용해서 쓸만한 PC/Mac 클라이언트를 만들어주기를 내심 기대하고 있던 나로써는 살짝 실망(?)했던것은 사실이다.

하지만 문득 재미난 생각이 들었다.

모바일에서 돌아가는 코드는 안드로이드나 iOS나 앱 권한이 명백하여 카카오톡 앱에서 취약점을 찾는다고 할지언정 폰 장악은 어려운것이 현실이고, 심지어 자바의 String이나 Obj-C의 NSString같은 녀석들을 가지고 문자열 오퍼레이션을 하는 프로그램들에서 memory corruption 류의 버그를 찾기란 하늘의 별따기인것이다. (물론 찾는다고 해도 exception handler가 잡아서 친절하게 처리해주니 실제 공격가능성은 현저히 낮다)

그렇지만 PC에서 돌아가는 코드는 분명 C++을 사용하여 개발했을것이라는 느낌이 들었다. 일단 C#이 개발하기엔 훨씬 편하더라도 그만큼 분석당하기도 쉽기 때문에 최근에 보안쪽에 신경을 상당히 많이 써온 카카오라면 이쪽은 선택하지 않을것 같았다. 뭐 물론 성능면에서도 MSIL보다는 ASM이 빠를테니 좋겠지만 퍼포먼스 critical한 어플리케이션이 아니니까 별 신경은 쓰지 않았을듯.

이 말인즉슨, 카카오톡 PC버전은 말그대로 현재 사용자 권한으로 돌아가고 있는 native code라는 점이다. 모든 native code 프로그램들이 그러하듯 코드가 secure하지 않아서 취약점이 생긴다면 바로 유져의 보안에 금이 가는것이다. 브라우져 익스플로잇이 매우 위험한 것도 이 이유다. 사용자가 이용하는 프로그램 자체를 공격함으로써 특정 (보통은 악성) 코드를 실행할 수 있게 되는것이다.

요런 생각을 하고 나니 왠지 궁금해졌다. 카카오팀이 꽤나 실력이 좋은 개발자들을 가지고 있는것은 사실이지만 세상에 완벽한것은 없고 개발자는 실수할 수 밖에 없다는 진리에 따라.. 분명 취약점이 어딘가에는 존재할것이라는 생각이었기 때문이다.

KakaoTalk PC Beta

KakaoTalk PC Beta

이당시에 나는 카톡 계정을 만들지도 않은 상태였기 때문에 베타테스트 신청은 물론이고 신청기간이 지나고나서야 알게되었기 때문에 베타버전을 받을 수가 없었다 -_- (게다가.. 추첨운은 정말 없는지라 신청을 했다해도 됐을리 만무하다..쿨럭)

그래서 지인에게 손을 벌려 카카오톡 PC 베타버전 인스톨러를 받았고, 혹시나 있을지 모를 워터마킹 (사용자 추적) 걱정에 실제로 실행은 하지 않고 정적으로만 분석할 생각이었다. 나중에 안 사실이지만, 계정으로 로그인을 할때 베타유져인지 아닌지 확인하는 루틴이 있었던듯 싶었으나.. 누군가 아주 간단히 bypass하는 사태가 일어났었다ㅋㅋ..

관계자분과 확인한 결과 예상대로 Man-in-the-Middle 방법을 사용하였다고 한다. 지금은 고쳐진 상황 :)

어찌되었든 인스톨러를 손에 넣었으니 압축을 풀어보았다..흠흠..

KakaoTalk PC Beta Installer

KakaoTalk PC Beta Installer

일단 프로그램을 IDA에서 열어보기도 전에 직감한게 있었다..
그렇다.. 그저 메신져 프로그램일뿐인 바이너리가 무려 2MB가 넘는것이 아닌가..
아무리 그 당시에 카카오톡을 괴롭혔다고(?) 해도 설마 베타때부터 Themida 패킹 카드를 꺼내들줄이야.

알만한 사람들은 알겠지만 패커계에서도 가장 악명높기로 유명한것이 Themida/WinLicense 패커다.
기본적인 안티리버싱/안티디버깅 기술은 물론이고 custom VM (심지어 RISC/CISC 종류도 나뉜다..)을 통한 코드 보호를 하기 때문이다.

이런 문제 때문에 백신이나 IDS/IPS 솔루션들이 이런 바이너리를 정적이나 동적으로 분석하기는 매우 어렵고, 이걸 노리고 악성코드를 Themida로 패킹하는 malware writer들이 많다. 이런 이유에서 validate된 certificate을 가지고 있지 않은 Themida로 패킹된 바이너리들은 기본적으로 위험요소 또는 바이러스로 감지되는 경우가 많다 (보통 malware 제작자들은 valid한 certificate을 사용하지 않는다).

Digital Code Signature for KakaoTalk PC

Digital Code Signature for KakaoTalk PC

물론 카카오톡은 valid한 code signature를 사용하므로 백신으로부터 오탐되는 일은 거의 일어나지 않겠지만.
분석자 입장에선 빡세긴 매한가지이다..

장난 섞인 진담으로는 “Themida 패킹이 되어있으면 그냥 포기하는게 마음이 편하다”라고 할 정도로 귀찮다.
하지만 불가능은 없는 법. 해킹은 1%의 영감과 99% 노가다가 있으면 해결될때가 많다. 그걸 버틸 수 있느냐의 싸움일뿐.

문제는 그 당시의 나는 Plaid CTF 준비로 정신이 없었고, Themida를 손수 언패킹하기엔 그럴만한 동기부여가 되지않았다.
이 자리를 빌어서 말하자면, 솔직히 신선한 충격이었다. 카카오팀에게 무언가 한방 맞은 느낌? ㅎㅎ
그래서 일단 다음을 기약하고 손을 놨다.

 

5 Months later…

이렇게 저렇게 바쁘게(?) 살다보니 어느새 5개월이라는 시간이 훌쩍 지나있었다.

그 사이에 카카오톡 PC버전은 오픈베타 테스팅 기간을 거쳐 정식 릴리즈까지 나온 상태였고, 주위에서도 차츰 PC버전을 사용하는 사람이 늘어났다.
(-_-.. 이젠 메세지 보내기가 편하다며 받는사람 입장 생각안하고 무한 진동을 느끼게 해준 친구들도 몇몇..)

내 작은 iPhone4 화면에서 카톡을 치다보면 오타도 많이나고 참 인내심을 강제로 기를때가 많은데..
왠지 PC버전은 사용하기가 싫었다.. 뭔가 지는 기분이 들어서 ㅋㅋ..

그래도 어쨋든 한 번 받아서 다시 뜯어보기로 마음을 먹었다.

KakaoTalk PC v1.0.3

KakaoTalk PC v1.0.3

주중에는 생각할 여유도 직접 작업할 엄두도 안나서 주말까지 기다렸다.
불편한 진실이지만 요즘에는 주말에 너무나도 할게 없어서 잉여스럽게 보내고 있기 때문에..
Themida 언패킹 놀이가 제격이라고 생각들었… 이래서 내가 여자친구가 없나보다 (흠흠..)

그리하여 8월 17일 토요일!

KakaoTalk PC Login View

KakaoTalk PC Login View

일단 이번에는 실행을 시켜봤다. 인터넷에서 봤던 그대로다.. 뭐 딱히 다른걸 기대한건 아니지만.
다행히(?) 지난 5개월동안 “모두의 X블”이라는 게임을 잠깐 했었어서 카카오계정은 만들어둔 상태였다.

로그인을 해봤더니. 잘된다.
살며시 종료를 하고 언패킹 준비를 했다.

사실 본문에서 언패킹 및 분석 요령을 짚고넘어가려고 했는데.. 생각보다 너무 범위가 커질것 같아서 나중에 기회가 되면 아예 새로운 글 하나로 작성해야할것 같다는 생각이 들어서 여기에는 자세히 적지 않겠다. 요점만 말하자면 Themida의 눈을 피하기 위해서는 SSDT 후킹과 kernel mode 디버깅이 거의 필수라는 점이다. 어느정도 안티디버깅 루틴들을 bypass하고 나서는 실제로 VM Protect로 virtualized된 코드들을 다시 x86 코드로 변환시켜야하고 그 이후에는 보호된 Import Table을 고쳐주어야한다.

근데 이게 사실 몇십줄짜리 간단한 프로그램이면 모르겠지만.. 어느정도 feature-full한 메신져 프로그램은 아예 다른 이야기다.
그래서 노가다를 하다말고 결국엔 그냥 필요한 부분만 추출해내는정도로 언패킹 작업을 마쳤다.

즉, runnable한 fully unpacked 프로그램은 만들어내지 못했는데.. 아무래도 스크립트를 돌려서 작업해야만 가능할 것 같다.

TalkChatRoom::LocoCommand_WRITE_ResultHandler

TalkChatRoom::LocoCommand_WRITE_ResultHandler

뭐.. 어찌됐든 필요한건 정적 분석으로도 충분하기 때문에 굳이 runnable한 언팩본은 필요가 없었다.
위 스크린샷은 TalkChatRoom.cpp에 구현되어있는 LocoCommand_WRITE_ResultHandler 함수..
(물론, C++인지라 inheritance구조를 잡았냐에 따라서 틀릴수도 있겠다 -_-)

그렇다. 사실 카카오톡의 분석이 어려운 이유는 Themida로 패킹이 걸려있기 때문이 아니었다.
패킹은 그저 빙산의 일각이었을뿐.. 역시 리버싱을 하면서 가장 역겨운(?)것은 C++ 컴파일러가 만들어낸 코드 분석이다…
넘쳐나는 virtual function들과 상속구조 ㅠㅠ..
일단 30여분정도 들여다보며 바로바로 알아본 녀석들은 label해나갔다.

동적 링크를 하는 라이브러리는 libeay32.dll, libssl32.dll 그리고 LiteUnzip.dll 뿐인걸로 봐서는 JSON parser는 아마 직접짜서 static하게 링크한듯 싶다.
Static 링크를 한 프로그램들은 분석하기가 짜증나지는데 분석속도를 확연히 올려주는 symbol이 없기 때문이다.
왠만한 어플리케이션들은 거의다 strip 과정을 거쳐서 릴리즈 되기 때문에 symbol이 있는 경우는 많지 않지만 이 수많은 (약 15000개 이상) 함수들 중에 중요한것을 고르고 그 중에서 필요한 녀석들을 lable하는 작업은 몇시간에서 몇십시간정도 걸릴 수 있는 작업이기 때문에.. 정말 정말 깊게 들어가고 싶지 않은 이상 안하는게 건강에 좋다.

어쨌든. 내가 사실 이 분석을 시작한건 알아내고 싶었던 한가지가 있었기 때문이다.

카카오톡 PC에서는 어떤 로그인 절차가 이루어지나요?

.. 라는 질문을 받았고, 나도 궁금해졌다. 분명 모바일과는 다를터 — 왜냐하면 모바일에선 딱히 로그인을 할 필요 없기 때문이다.

 

Logging in…

분석 과정을 적기에는 귀찮으니까 알아낸 부분에 대해서 끄적여보도록 하겠다.
(….제목에 ‘분석’이 있긴 해도 간단히 결과물만 공유하고 싶은 마음에 글을 시작했기 때문이라고 변명을 대어본다..)

일단 PC버전에서의 로그인은 총 3단계 정도로 보면 된다.

코드상에서는 LoginDlg에서 카카오 서버에 request를 보내는 함수들을 호출하여 로그인을 시도한다.
JSON 형태로 된 response가 돌아오고, 이 결과에 따라서 다음으로 진행한다.

1. 로그인 필드에 이메일 주소와 비밀번호를 넣고 로그인을 시도하면 첫번째로 다음과 같은 HTTPS request를 전송한다.

HTTPS request를 전송하는 페이지는 https://sb-talk.kakao.com/win32/account/login.json 이고, 모바일 버전과 마찬가지로 custom A 헤더와 User-Agent 헤더를 덧붙여 보낸다.

POST 데이터에 해당하는 필드들은 자명한 이름을 가지고 있기 때문에 굳이 설명하진 않겠다. 아직 어떤식으로 device_uuid를 생성하는지는 분석하지 않았다.

여기서 서버가 리턴하는 JSON의 status 값이 -100이면 이메일 주소와 비밀번호 조합이 성공적으로 인증되었음을 나타낸다.
(내부적으로는 status 값에 120을 더하여서 switch/case에 사용한다)

Status 12 – 이유있는 에러 (비밀번호가 틀렸다던가.. message 필드에 정확한 에러메세지를 보내줌)
Status 30 – 로그인 에러 (존재하지 않는 이메일 주소거나 비밀번호가 너무 짧을 경우 ?)
Status 500 – internal 에러 (필수 필드를 누락한 경우)
이 외에도 -101, 31, 32 와 같은 status code가 있지만 뭘 뜻하는지 알아내는건 독자들의 몫 ^_^?

 

2. PC Registration에서 컴퓨터를 (반)영구 인증할것인지 일회 인증할것인지 고르면 다음과 같은 HTTPS request가 전송된다.

KakaoTalk PC Registration

KakaoTalk PC Registration

언뜻보면 Step 1의 request와 똑같아 보이지만 예리한 독자들은 눈치챘을것이다. 새롭게 추가된 once=false 데이터를.
그리고 영어를 못하는 사람들도 쉽게 알 수 있을정도로 쉬운 필드명이다.

그렇다. 다들 예상했겠지만 once 필드의 값을 통해 사용자가 반영구적 등록을 원하는지 일회성 등록을 원하는지 서버에 알린다.
once가 true라면 1회 등록, false라면 반영구적 등록이다.

이 작업이 성공적으로 처리되면 status 코드 0이 돌아오고, 바로 KakaoTalk님으로부터 모바일폰으로 카톡이 온다.
이 카톡 메세지는 PC 인증 번호인 4자리 숫자를 보여준다.

여기까지 오면 다 한거다.

One-time registration Pop-up

One-time registration Pop-up

이제 유져가 위의 프롬프트에 인증 코드를 넣었을때 보내지는 request만 흉내내면 로그인 및 인증 과정이 끝난다.

*** 참고: 사실 위의 작업을 두가지 스텝으로 나누었지만 Step 2만 해도 정상적인 로그인이 가능하다. 하지만 프로그램상에서 실제로 이렇게 세 스텝으로 나누어서 진행하기 때문에 조금더 카톡PC 답게 하려면 이렇게 진행하는것이 좋다.

 

3. 자신의 카톡으로 전달된 PC 인증코드를 넣으면 다음과 같은 HTTPS request가 전송된다.

자, 이번에도 역시 비슷해 보이지만 두가지 데이터가 추가되었다.

forced라는 녀석과 passcode인데.. forced가 정확히 뭘하는 녀석인지는 분석하지 않았다..
뭐 이미 다른데서 로긴 되어있으면 강제로 로그아웃시키고 로그인하라는 소리인가..?

하튼 우리가 눈여겨봐야할 부분은 passcode이다. 그냥 카톡으로 전송받은 네자리를 넣어주면 된다.
passcode가 정확하다는 가정하에, once가 true일 경우에는 로그아웃을 하는 순간 서버상에서 세션키를 revoke 시켜버린다.
그리고 false일 경우에는 사용자가 해당 컴퓨터를 unregister하기 전까지는 세션키가 유지된다.

성공적으로 인증하게 되면 status 코드는 0이 리턴되고, 차후 LOCO/HTTPS 프로토콜에서 사용될 세션키인 sessionKey, 유져 고유번호인 userId, 국가 ISO코드인 countryIso, 그리고 국가번호인 countryCode 필드들이 넘어온다.

아무래도 여러분이 관심있어하는 부분은 단연 sessionKey가 아닐까 생각된다 :)

——————–

여기까지 성공적으로 실행했다면 이제 자기 계정에 대한 유효한 sessionKey를 습득할 수 있게 된 것이다.
그렇다. 루팅이나 탈옥 없이도 자기가 사용하던 계정의 세션키를 추출할 수 있게 된것이다!! (물론 같은 세션키는 아니지만 ㅎㅎ)

*** 참고: 만약 once를 false로 설정하여 반영구 인증을 했다면, 그 이후부터는 인증에 사용된 device_uuid와 name을 Step1에서 넣어주면 바로 Step3의 결과 JSON이 반환된다 — 하지만 세션키/디바이스아이디 조합을 잃어버리지 않는한 다시 인증할 필요는 없다.

 

4. 마무리 및 사용법

세션키를 얻었으니 사용해야할 것 아닌가?

하지만 너무 반가워하기 전에 프로그램이 로그인 후 하는 행동들을 지켜보자…
성공적인 세션키 습득 후에는 해당 계정의 세팅을 불러온다.

여전히 HTTPS request를 이용한 (하지만 이번엔 POST가 아닌 GET) 방식이다.

새롭게 추가된 헤더가 있는데 바로 S 헤더다. 모바일 버전 구현을 보신분이라면 알겠지만 S 헤더는 세션키를 담고있다.
(결론적으로, 서버단에서는 이걸로 인증을 하는 셈이다.)

근데 이 세션키라는게 그냥 단순히 위의 스텝에서 얻은 세션키가 아니라 그 세션키에 연동되어있는 디바이스아이디를 조합한 형태의 세션키이다.
사실 이부분은 모바일에서도 마찬가지기 때문에, 그리 새로운 개념은 아니다…

조합법은 간단하다: 세션키-디바이스아이디 형식이다. 가운데 – (하이픈)을 넣어주면 완성!
(참고로, 디바이스 아이디는 base64 인코딩 된 형식을 가지고 있다. 덕분에 조합하고 나면 꽤나 긴 세션키가 되버린다.)

세팅을 요청하면 계정의 이메일 주소, 최근 사용 카톡PC 버전, 대화명, 닉네임, 프로필사진, 폰번호, 현재 상태 (available) 등을 돌려준다.

다음으로는 차단된 사용자를 불러오고.. (GET /win32/friends/blocked.json?)

그 다음엔 꽤나 익숙한 update.json을 통해 친구목록 동기화를 한다.

이 부분의 스펙은 모바일 버전과 동일하다고 봐도 되겠다.

어찌됐든, 이런저런 초기화가 끝난 후에는 LOCO 프로토콜을 이용한 메세지 전송 및 수신을 한다.
이 부분은 모바일과 크게 다를게 없을것 같아서 (크게 다르다면 프로토콜을 만든 이유가 없으니..) 더이상 파헤치지는 않았다.

이걸로 “카카오톡 PC는 로그인을 어떻게 처리하는가”에 대한 궁금증은 풀렸고, 간단한 Proof-of-Concept 코드도 작성이 가능했다.
뭐.. 워낙 간단하긴 하지만, 혹시라도 필요한 분들에게 도움이 될까 싶어 올려둔다. (requests 패키지는 따로 설치하시길..)

*** 참고: 여기서 COMP_NAME과 DUUID는 사실 아무 문자열을 넣어도 상관없다. 단지 카카오톡 서버측에서 검열하기가 편해질 뿐 :)

예전에 내가 분석해둔 LOCO 프로토콜 블로그 시리즈를 바탕으로 깔끔한 python 라이브러리를 만들어서 github에 올려두신분이 있어서.. 실제 메세징 기능은 이 라이브러리를 추천하려고 했었는데 지금 찾아보니 사라져있다…. 뭐지 이 난감한 상황은..? (구글링을 잘하면 찾을수도 있겠지만, 정 안되면 예전 블로그 글 보고 구현들 하시길 바란다.. 좋은 연습이 될듯!)

——————————

일단 이정도로 PC 버전 분석 첫번째 시리즈(?)를 마치고자 한다.
사실 더이상 분석해봐야 새로운 무언가가 나올게 없기 때문에 다음 시리즈가 있을거라곤 장담하지 못하겠다…

하지만 글을 쓰는 동안에 재미난 아이디어가 생각나서 한번 실험을 해보고 결과 또한 재미있다면 다음 시리즈에서 공유하도록 하겠다.

——————————

긴 글 읽어주셔서 감사합니다!
질문이 있으시면 댓글이나 이메일을 보내주시면 됩니다.

 

You may also like...

35 Responses

  1. halla says:

    위에 status code -101로 저와 같은 곳에서 막혔던 분을 위해… 덧글 남깁니다.
    모바일 카카오톡에서 PC 카카오톡 설정에 들어간 후 모든 기기의 인증 해제를 하시면 위 PoC 코드가 제대로 동작합니다~

  2. 김대 says:

    사용하신 툴이 어떤건가요?

  3. 김대현 says:

    자료 정말 감사합니다.

    어셈블리가 나온 이미지 툴이름이 IDA Pro 인가요?

    네트워크패킷은 와이어샤크로 분석을 하신건가요?

    • Cai says:

      방문해주셔서 감사합니다 :)

      말씀해주신대로 어셈블리가 나온 이미지는 IDA Pro의 스크린샷이고, 네트워크 패킷 분석은 와이어샤크로 했습니다.

  4. 전민재 says:

    안녕하세요 글 잘봤어요:)
    제가 스터디 그룹 과제가 더미다패킹 분석과 언팩이라 그래서 혹시 카카오톡 베타 install아직도 가지고 계시다면
    alswoska123@naver.com로 보내주실수 있나요?

  5. Won Lee says:

    데이터 부분은 어찌 되나요?
    몇년간 전화기 상에서 사용해오던 메세지들을(늘 titanium backup을 사용해 모든 데이터를 잘 백업하고 복구하며
    전화기를 Reset, Upgrade시 보관) 최근 전화기 교체를 위해 백업/복구 작업을 실패했습니다.

    실패한 이유는 제 예상에는
    Titanium backup이 업데이트 되면서 Super Su에 세팅을 바꾸어 주어야했는데 그 부분을 확인하지 못했고,(기존 전화는 KitKat)
    새로운 전화기가 lollipop이었는데 titanium backup이 같은 Super Su세팅과 더불어 여러곳에 찾아보니
    불안한 부분 또한 있는듯 했습니다. (어찌되었든 초기 백업이 성공적이지 못한점이 가장 큰 이유입니다.)

    결국은 원래 전화 재인증실패로 파일 리셋부분 예상과…
    백업파일이 문제가 있다는 부분은 인지하지 못한째 원래 전화에 다시 Restore해서
    다시 백업하려던 작업으로 전화기 원본 파일들을 모두 Overwrite해버린 상황이 되어버렸네요.

    궁금해 이것저것 찾아보다 이 사이트에 와보게 되었는데 굉장히 전문가 이신분이니시 왠지 방법이 있지 않을까라 생각이 들더군요.
    특히 PC용 버젼에 Cache처럼 사용된 데이터가 생각나서 이렇게 여쭈어 봅니다. 의견 부탁드립니다.

  6. SSD says:

    카카오톡 관련질문은 아닙니다만 혹시 파라미터 형식으로 값이넘어가는 고전게임을 분석할때 방법이있을까요?

    웹 -> 파라미터 -> 즉시접속
    단순실행 -> ID/PW -> 접속

    두가지루트로 접속하던 게임입니다.

    • Cai says:

      웹을 통한 게임 실행방식이면 active x등을 통해 파라미터 넘겨서 프로그램 실행하는것을 말씀하시는건가요? 방법은 여러가지가 있겠지만 웹->activex 사이를 모니터링 하시면 어떤 인자가 넘어가는지 보실 수 있겠죠.

  7. KnifeLemon says:

    포스팅 관심있게 읽었습니다.
    일단.. 대단하시네요. 분석을 한다는게..
    정보 감사합니다.

  8. gompang says:

    잘보고 갑니다

  9. 나이스 says:

    좋네요. 간단한 리버싱은 최근에도 했었는데 언패킹까지는 못해봤었는데 좋은 내용 감사합니다.

Leave a Reply

Your email address will not be published. Required fields are marked *