안녕하세요.


저는 공주대학교 컴퓨터공학부 컴퓨터소프트웨어전공 17학번 문승현입니다.


현재 블록체인 기술에 대해 공부를 하여 공부한 내용을 정리하고자 게시글을 작성하였습니다.


미리 읽어주시는 분들께 감사하며 잘못된 지식이 있을 경우 마음 편하게 피드백주시면 감사하겠습니다.


현재 게시글에 대한 깃허브는 아래에 주소를 기입하도록 하겠습니다.


https://github.com/schedutron/SnakeCoin


블록 내부 구조


 class Block:
    def __init__(self, index, timestamp, data, previous_hash):
        self.index = index
        self.timestamp = timestamp
        self.data = data
        self.previous_hash = previous_hash
        self.hash = self.hash_block()

    def __str__(self):
        return 'Block #{}'.format(self.index)

    def hash_block(self):
        sha = hasher.sha256()
        seq = (str(x) for x in (
               self.index, self.timestamp, self.data, self.previous_hash))
        sha.update(''.join(seq).encode('utf-8'))
        return sha.hexdigest()


index : 현재 블록의 위치 (첫 블록 0)

timestamp : 블록이 생성된 시간

data : 블록체인에 포함하고자 하는 데이터

previous_hash = 이전 블록의 해쉬

hash : sha256으로 index + timestamp + data + previous_hash들을 암호화함


함수 분석

* 현재 저는 깃허브에 올라와있는 코드들을 한 곳으로 모아놨으므로 깃허브와 함수 이름 혹은 코드가 다를 수 있습니다.


 
 def make_genesis_block():
    """Make the first block in a block-chain."""
    block = Block(index=0,
                  timestamp=datetime.now(),
                  data="Genesis Block",
                  previous_hash="0")
    return block

make_genesis_block()

위의 함수는 코드를 보시면 아시겠지만 index를 0으로 설정하여 현재 시간과 데이터는 Genesis Block 이라는 문장과 이전 해쉬가 없기때문에 0으로 설정되어 블록이 생성되는 것을 볼 수 있습니다.

첫번째 블록을 만드는 함수라는 것을 알 수 있습니다.



def next_block(last_block, data=''): """Return next block in a block chain.""" idx = last_block.index + 1 block = Block(index=idx,

timestamp=datetime.now(),

data='{}{}'.format(data, idx),

previous_hash=last_block.hash)

return block

next_block(last_block, data='')

인자는 2개로 하나는 이전 블록을 넘겨받으며, 새로 추가할 데이터를 받는 것을 볼 수 있습니다.

idx 는 이전 블록의 인덱스 +1 을 한 값으로 설정된 뒤에 인덱스를 넣으며 새로운 블럭이 생성되는 것을 볼 수 있습니다.

그렇습니다.

이전 블럭을 받아 새로운 블럭을 만드는 함수라는 것을 알 수 있었습니다.



채굴 알고리즘

처음에 블록체인을 공부하다 채굴이라는 개념을 잡기가 많이 어려웠습니다.

멘토님에게 질문을 드렸는데

새로운 블럭을 생성하는 것이 채굴이라는 것을 알게 되었다.


그렇다 이 코드에서 채굴 알고리즘은 있지 않다.


이쯤에서 채굴이 무엇인지 Araboza.


채굴

* 채굴 필요성

   - 공급자 역할

   - 수요공급법칙

* 작업 증명 : (Proof of Work) 

   - 작업 증명은 새로운 블록을 블록체인에 추가하는 ‘작업’을 증명한다는 것이라고 한다.


그렇다면 현재보다 채굴의 난이도를 올리는 방법은 무엇이 있을까?


뭐 딜레이를 줘서 간단하게 난이도를 올리는 방법과 암호화 알고리즘들을 사용하여 브루트포싱 기법으로 때려맞춰서 난이도를 올리는 방법들이 있다고 합니다!


필자는 후자의 방법을 사용하였습니다.


코드는 아래와 같습니다.




 
 def next_block(last_block, data, i):
    """Return next block in a block chain."""
    sw = False
    while(sw == False):
        print("mining...")
        if(base64.b64encode(str(i)) == base64.b64encode(str(random.randrange(0, i+1)))):
            sw = True;
        else:
            sw = False;

    if(sw):
        idx = last_block.index + 1
        block = Block(index=idx, timestamp=datetime.now(), data='{}{}'.format(data, idx),previous_hash=last_block.hash)

    return block


간단한 코드로써 브루트 포싱으로 채굴을 하게 해보았다.

random 함수로 n번째로 생성되는 블럭의 n을 암호화한 값을 랜덤으로 초이스하여 때려맞추는 브루트 포싱으로 채굴되게 해보았다.



난이도는 채굴이 된 블럭 수 만큼 증가하는 것을 볼 수 있었다.


이것에 대해 더 채굴 난이도를 올리고자하면 많은 코인들이 사용하는 암호화 알고리즘을 이용하여 코드를 작성한다면 난이도는 많이 올를 것이라는 것을 알게 되었다.


'0x30 Study > 0x32 Blockchain' 카테고리의 다른 글

g-coin 분석(2)  (33) 2018.03.05
g-coin 분석(1)  (1) 2018.03.03
g-coin 분석(0)  (0) 2018.03.01


부보 토큰은 의료 목적인 대마초 토큰입니다.


해외에서 이미 상용화되어 앱으로 개발되어 사용되고 있었으며 이번에 ICO를 통해 토큰으로 거래되게할 예정입니다.


각 운송되는 트럭들에 위치추적 부품이 달려있어서 블록체인 기술을 통해 유통되는것을 추적도 가능하게 되어 안전한 거래가 될 수 있다는 장점이 있습니다.


위의 내용은 백서에 나와있는 내용들이니 백서를 읽어보심을 추천드립니다.


백서 - https://budbo.io/budbo-whitepaper.pdf


이 부보 회사는 2017년도부터 활동을 하여 많이 알려왔습니다.



최근에 크립토 이코노미 월드투어에 런던에서 부보가 발표를 하였는데

이 다음날 7빌리온이나 팔렸습니다.



이제 곧 암스테르담에 발표를 남겨두고 있습니다.



얼마 남지 않은 1,620,799개 정도 남은 상태에 급하게 얼릉 사시고 싶어하실텐데요!


참여방법을 알려드리도록 하겠습니다.


https://goo.gl/XMVLY4


접속하신 뒤 회원가입을 한 뒤에 



보내실 코인의 종류를 선택하셔서 주소를 생성한 뒤에 그 주소로 코인을 보내면 됩니다.


현재 gazua 프로모션 코드를 이용하면 싼 가격으로 구매가 된다고 합니다.


부보에 대한 정보를 계속 받아보시고 싶으시다면 https://open.kakao.com/o/gT9oxgG 에 들어오시면 감사하겠습니다.


======== 개인 지갑 만드는 법 =========


https://www.myetherwallet.com/ 


먼저 위의 사이트를 접속해주세요.



먼저 사용하시는 비밀번호를 입력하시고 지갑 생성을 눌러주세요.



이렇게하면 지갑이 생성됩니다.


Keystore 파일은 미리 저장! 해주세요!!

이 keystore 파일로 지갑에 접근을 할 수 있습니다.


그 뒤에 I Understand 를 누르시면 



위의 Private Key도 저장해주세요!


키 파일은 파일 안에 지갑 정보가 저장되어 이 파일만 넘겨주면 초기에 입력한 패스워드를 입력하면 접근이 되는것이구요.

Private Key는 지갑에 접근하기 위해 입력하는 비밀번호라고 생각하시면 편할 것 같습니다.


이렇게 키 파일이나 Private 키를 입력하며 지갑에 접근하면 아래와 같은 화면을 볼 수 있습니다.



그리고 저 내 주소에 적혀있는 주소를 부보 프로필에 주소 적는 란에 적으시면 완료입니다 ^^



======== 추가 정보 =========


1. 다 팔리지 않은 토큰들은 소각될 예정


2. 해외 유투버들의 관심이 생기고 있다.


주요기능

공주대학교 공과대학 정문에 있는 피시방 자리 유무를 조회


개발하게 된 이유

기숙사에서 정문까지 10분거리이며 왕복이면 20분이기에 갔다가 자리가 없어서 돌아오면 시간낭비가 되버리기때문에
그래서 만들게 되었다.


프로젝트 이름이 CampPC 인 이유

피시방 이름이 캠프 피시방임.


개발 언어

Python + php + html + css

개발 환경

MAC, Ubuntu


주저리 주저리

사실 이미 다 만들었지만 기록용으로 작성하는 중.


페이스북을 하다가 우연하게 사이트를 발견하였다.



이런 사이트를 발견해서 접속해보니 운동을 위해 도메인도 구매하고 사이트를 운영하는가 싶었다.

매우 착한 사람이며 운동정신이 투철하신분인가 싶기도 했다.



보니까 frame으로 의문의 사이트를 속이기위해 noframe 으로 프레임이 안보이게 숨겨둠

그리고 모바일 유저들을 타겟으로 만든거라고 추측가능했따.

보면 관심이나 다른 기능들은 되지 않는 걸로 봐서 페이크 페이지라는걸 알 수 있었당.



보면 #u_o_6 이 클릭됬을때 아래의 코드들이 실행되는데.

#u_o_6은 바로 로그인 버튼이며 #u_0_2_1, 2 의 내용을 fbid, fbpw 변수에 넣는데 그렇다 이건 우리가 입력한 내용이 저 변수에 들어가서 쇼쇽 쉬식하는 것을 알 수 있다.

그래서 ajax로 submit_login.php로 아이디와 비번을 전송하는데.

이건 실제 페이스북의 사이트에 로그인하는 것이 아닌 자신의 서버에 작성한 php 코드에 전송을 하는것이다.

여기서 개발자의 사이트에 본인의 아이디 비번이 수집될 수도 있다는 점을 조심해야된다.


show_next 함수는 말그대로 아이디 패스워드를 얻었으니 로그인이 되는 것처럼 넘어가는 것이다.



그러타 이거슨 토큰 값을 보여주는 거시다.



걍 로그인을 하고 넘어가면



당연히 에러가 뜬다.
멍청한 개발자는 이런것도 예외처리 안함 ㅎ;;ㅋ;;;
그리고 멍청한 사람들은 저 값을 그대로 밑에다 붙어넣고 서명하기를 누르겠지?
그걸 누르면 아래와 같이 실행된다.



#u_0_6_1 는 서명하기 버튼이다.

클릭 될 경우 아래의 코드가 실행되는 것인데.

현재 붙여넣기한 내용이 비어있으면 넣어달라고 문자를 띄우고 붙여넣으면 이제 실제로 로그인이 안된 값들은 제대로 해달라고 띄우고 그냥 특정 실패 문자열이 있으면 안받아줌.

그리고 제대로 토큰값을 넘겨준 애들한테는 RunToken() 함수를 실행하는



감사하게 우리의 넘겨준 토큰을 서버에 저장하는 것이다.



몽총하게 넘겨준 사람들은 비밀번호를 변경하고 로그아웃을 하자.



참고로 얘네 index숫자.html 에서 숫자만 변경해도 다른 설문 사이트들이 나온다.




이것은 index1의 페이지이당.

보니까 그냥 이슈 터지는 것들마다 추가해서 어그로를 끌어서 토큰을 수집하는 애들이므로 조심합시당.


3줄 요약

0. 이것은 페이크사이트이다.

1. 아이디, 비밀번호, 토큰을 수집한다. (물론 아이디, 비번 수집하는진 자세힌 모름 하지만 전송하는 걸로 봐서는 수집할지도 모름 ㅎ)

2. 비밀번호를 변경하고 로그아웃하자.


UPX Pakking principle

* UPX : 많고 많은 널리 사용되었던 실행 압축 프로그램


PE File : http://blog.hubeen.kr/306

실행압축?

실행압축이란 실행가능한 파일(PE파일)을 대상으로 파일 압축하여 용량과 리소스파일을 보지 못하게 함.
압축된 것을 푸는 방법은 파일 내에 압축해제 코드를 포함하고 있어서 실행되는 순간 메모리에서 압축을 해제시킨 후 실행된다.

Analysis


                                                                                                              [ not pakking.exe Section ]                                                                      [ pakking.exe Section ]                              


위의 이미지는 패킹된 프로그램과 패킹이 되지 않은 프로그램의 차이다.
패킹이 된 프로그램의 크기는 8.00KB에서 6.5KB로 줄어든 것을 볼 수 있으며,
섹션 또한 압축되어 있음을 알 수 있다.

PE File의 기본 구조는 IMAGE_DOS_HEADER - DOS_STUB_CODE - IMAGE_NT_HEADER - TEXT - data - .rsrc 이다.
하지만 압축된 프로그램의 섹션을 보면 UPX0 - UPX1 - .rsrc 로 되있는 것을 볼 수 있다.

그리고 보면 UPX0 섹션에는 RAW Size를 보면 0으로 아무런 값이 들어가있지 않는 청결 순수 이미지를 가진 섹션이라는 것을 알 수 있습니다.



하지만 virtual size는 6000이나 엄청 크다는 것을 볼 수 있습니다.

그렇다면 UPX1에는 압축해제 코드와 원본 데이터가 들어가있다는 것을 예상할 수 있습니다.

그리고 압축해제된 데이터는 upx0에 들어갈 것 같다는 예상을 할 수 있습니다.



그렇다면 이제 올리디버거를 열고 동적 분석을 시작하도록 하겠습니다.



프로그램 실행 전 레지스터와 스택의 상황입니다.



PUSHAD 명령어가 실행된 뒤의 스택의 상황입니다.

PUSHAD 명령어는 레지스터의 모든 값들을 스택에 집어넣습니다. 



ESI와 EDI를 첫번째 섹션과 두번째 섹션 주소로 세팅합니다.

ESI = UPX1

EDI = UPX0



아까 위에서 봤듯이 virtual size는 6000이였음을 보았습니다.

딱 UPX0과 UPX1의 차이가 6000임을 눈으로 직접 볼 수 있습니다.



이 부분은 UPX0 섹션의 데이터 1byte씩 읽어와서 집어넣는 부분이다.


[ UPX1 섹션 데이터 값들 ]


[ UPX0 섹션에 데이터가 차곡차곡 들어간 값들 ]


[ 압축해제 루틴 ]


IAT 복구



함수 이름을 UPX0에서 가져온 뒤 GetProcAddress 함수를 이용해서 함수의 주소를 읽어온다.



그리고 EBX가 가르키는 주소에 함수의 주소를 저장한다.


실제 주소인걸 화긴완료


이제 모든 코드를 압축해제하면 upx0 주소로 점프하는 것을 볼 수 있습니다.


'0x20 Security > 0x22 Reversing' 카테고리의 다른 글

PE File Format  (310) 2016.07.23


오늘 작성할 내용은 ssh config 파일을 설정하여 서버 정보와 유저정보를 적어두면 따로 유저@주소를 적으며 접속을 하지 않아도 되게 되는 매@직!

매우 편리한 기능이라 할 수 있다.


alias에 명령어를 등록해가며 사용하셨다면 그 동안 뻘짓을 하였구나 라고 생각할 수 있을 정도입니다!


먼저 위의 경로로 이동을 해봅시다!



.ssh 폴더는 한번이라도 ssh 접속을 하였다면 known_hosts 라는 파일에 서버의 rsa키 같은 것들이 저장이 됩니다. 


이 곳에 config 파일을 생성하면 편하게 접속이 되게 됩니다!



Host 이름

    HostName 서버의 아이피

    User 계정명

    #IdentityFile 인증서의 경로

#Port 포트 (기본 값은 22)


로 간편하게 등록하고 간편하게 접속이 가능합니다.

인증서라고 하면 pem 같은 인증서를 말합니다.


위와 같이 등록을 한 뒤에 퍼미션을 설정을 해주여야 됩니다.


$ chmod 440 ~/.ssh/config


위와 같이 퍼미션을 설정을 해주었다면 아래와 같이 편하게 접속을 할 수 있습니다.



즐겁게 게으른 생활을 합시다!


'0x20 Security > 0x26 Server' 카테고리의 다른 글

서버를 간지나게 꾸며보자  (0) 2016.10.14
Run ARM ELF for qemu in ubuntu  (0) 2016.08.31
Install mongodb  (0) 2016.07.26

나름대로의 포트폴리오 사이트를 만들기 위해 웹 공부를 시작하기 시작했다.

뭐 웹 해킹 공부도 관심있기도하고 일단 코딩부터 시작할까 한다.



http://getbootstrap.com/

http://materializecss.com/

http://w2ui.com

http://getskeleton.com/

http://foundation.zurb.com/



2시 30분 면접반이였었다.

서산에서 천안 가는 버스 편이 별로 없고 경유지가 많아보여서 좀 많이 일찍 출발했었다.

10시 50분차를 타고 갔는데 

내가 우연히 탔던 버스가 경유를 하지 않고 직통버스여서 너무나 일찍 도착해서 천안캠퍼스를 구경을 했었다.

먼저 적기 전에 교통편을 미리 추천할 겸 적어봐야겠다.


천안 터미널에서 내려서 아래쪽으로 천천히 걸어오면 버스 정류장이 있는데

거기서 100번대의 버스들을 타면 공주대에 도착할 수 있다 ex)  120, 100, 110, 140, 112

와타시는 버스를 많이 타본적이 없어서 너무나 불편했다...

특히나 벨을 언제 눌러야되는지 몰라서 눈치보느라 힘들었다...


그렇게 나는 면접시간에 비해 2~3시간이나 일찍 도착해서 면접 정리도 할 겸 

버스 내리면 바로 대학교 입구 들어가는 곳 쪽에 편의점이 있어서 편의점에서 탄산수 하나랑 볼펜을 사서 자기소개서 뽑은거를 정리를 했다.

딱히 무엇을 외우면서 하는 면접이 아니였고 매우 편한 마음으로 본 면접이라 크게 긴장도 안된 상태라 10분 정도 보다가 노트북을 꺼내서 서버 정리를 했다.

그러다가 알바생 아조씨가 말을 걸어오셔서 대화를 가볍게 나누었다.

알고보니 그 아조씨도 서산에서 일을 한적이 있다고 했다.

이렇게 여러 사람과 말을 해서 더 긴장이 없어진 것 같기도 했다.


그렇게 미리 한번 면접장을 갔더니 미리 입장은 안되니 내려가서 대기하거나 대학교 둘러보라고 해서

둘러보다가 날씨가 쌀쌀하고 분명 대학교 안이니 카페가 있음을 나는 굳세게 믿었고 찾다가 10관? 2층에 카페가 있다는 것을 발견하였다!!! (두두두ㅜ우두둥1!!)


카페에 들어가니 조용하고 사람도 별로 없었다.

게다가 가격이 존나 매우 착함...후;;;

반할뻔했다.

아메리카노 2500원 개꿀;;;


아메리카노 하나 시켜서 노트북하려고 했는데

와이파이 사용하려면 대학교 학생이여야된다...

존나 너무했음 ㅂㄷㅂㄷㅂㄷㅂㄷ

그래서 노트북 안에 있는 바이너리 문제 풀고 지루한 시간을 보내고 면접장에 가서 수험표를 받고 대기장에서 대기를 했었다.


대기실에는 앞에 대학 재학중인 형들이 계셨는데.

지루한 걸 아시는 건지 말도 붙여주시려고 노력했는데

왜인지 모르겠지만 대기실에 있던 사람들은 다 긴장하고 무언가를 달달 외우는 분위기라 대화할 수는 없었다... (아니 원래 할 수 있는데 분위기가 ㅇㅇ;


그렇게 대기를 하는데

처음에는 들어가면 10분 ~ 15분 걸리더니 점점 빨리 끝나갔다.

아무래도 교수님들도 사람이다보니 애들도 다 달달 외워서가서 재미가 없으셨나보다.

그래서 점점 뒤에는 빨리빨리 나오고 빨리빨리 빠졌다.

그렇게 나는 마지막 순번이였고 마지막에 기다리는 김에 앞에 있는 대학생 형이랑 이야기를 나누었다.


※ Q는 필자이며, A가 그 대학 다니고 있는 대학생형이다. 

그리고 필자가 면접을 본지 오래되서 정확한 대화는 기억은 안나고 알맹이만 적을테니 

실제로는 저런 말투로 대화를 안하고 매우 너그럽고 친구와 대화하는 분위기였음.


Q. 몇학년이세요?

A. 3학년이다~ 


Q. 아 그러면 졸업작품 준비하세요?

A. 우리 대학교는 졸업작품 그런거 딱히 없고 하고 싶으면 하고 안하고 싶으면 안하는데

하면 좋지만 작년부터 이런거 없애버린다는 교수님이 있었는데

츤데레처럼 계속 하고 계신다는 식으로 대답해주셨음.


Q. 대학교 1학년때는 무엇을 배워요?

A. 1학년때는 C,C++ 이나 수학을 많이 하고 2학년때부터는 다 전공과목들인데

여기서 게임에서 2차 직업 고르듯이 소프트와 컴공이 있다.

그에 따라 배우는게 약간 다르지만 비슷비슷하다.


이후에 대학생 형이랑 여러 언어와 컴퓨터 지식 관련된 이야기를 했습니다.

그 뒤에 대기하면서 그 형과 이야기 하다가 면접에 들어갔습니다.

교수님들은 2분과 입학사정관님 1분 계셨었습니다.

3대 1 면접이였습니다.


처음에는 긴장을 풀어주시기 위해서 사적인 이야기들을 가볍게 물어보셨습니다.

(확실히 들어가기 전에는 긴장을 안했지만 들어가려니 화이트아웃? 같은 느낌으로 벙~ 했습니다 ㅋㅋㅋㅋㅋ)


※ Q는 면접관님들이며, A가 필자이다.

그리고 면접을 본지 시간이 좀 지나 몇가지의 질문들이 빠질 수도 있음을 미리 알아주었으면 하며,

말투가 딱딱하게 적을 수도 있지만 실제로는 너그럽게 잘 봐주셨다.


Q. 여기에 어떻게 왔나요?

A. 고속버스타고 왔습니다. 


Q. 여기 천안 캠퍼스는 처음 와보는가?

A. 아 몇일 전에 공주 캠퍼스를 가본 적이 있습니다.

하지만 천안 캠퍼스는 처음 와봅니다.

Q. 공주 캠퍼스는 무슨 일로?

A. 충남 인재 장학생 캠프가 공주 캠퍼스에 열려서 장학생 캠프를 참여하기 위해 갔었습니다.


Q. 천안 캠퍼스 처음 올때 어땟는가? 공주캠퍼스와는 많이 비교될텐데

A. 아 좀 허허벌판인 것 같습니다 (웃음) < 이때 미친듯;

Q. 아 그래서 맘에 안드나?

A. 아 아뇨 딱히 대학에 공부와 컴퓨터에 관심 있는 친구를 만나서 많은 경험을 하고 싶어서 왔지 놀러온게 아닙니다.


( 그리고 이제 학생의 긴장감을 풀어주기위해 이런 질문을 했다고 말해주고 본론으로 들어갔습니다. )


Q. 이 과에 지원한 동기는 무엇인가?

A. 저는 초등학생때부터 컴퓨터에 관심이 많아 프로그래밍 언어를 접해 공부를 하였고 중학생때도 계속 공부해서 고등학교를 컴퓨터 고등학교로 진학하려고 했으나,

부모님은 제가 컴퓨터 앞에만 있으시니 게임만 하는 줄 아시고 제가 정말 진지하게 공부하는 것으로 보이지 않으셨기에 타지로 가는 것을 반대하여 컴퓨터 고등학교가 아닌 인근 공업고등학교에 들어가 화학 공부를 해오면서 현재까지도 컴퓨터를 공부해오며 여러 대회들 본선도 참여하고 부모님께서 제가 정말 좋아하는 것을 인식시켜드리며 지원하게 되었습니다.


Q. 본인은 친구와 다투면 어떻게 하는가?

A. 저는 보통 친구와 다투면 먼저 그 자리를 떠난 뒤에 화가 가라앉은 후 "내가 ★★때매 화가 났었다" 라고 

조용조용하게 말하기 때문에 크게 다투는 일은 없었습니다.


Q. 그래도 다투는 일이 있다면 어떻게 했는가?

A. 보통 사과를 하고 다시 친하게 지냈습니다.


Q. 파이썬은 왜 시작했는가?

A. 그때엔 파이썬이 새로 나와 인터프리터 기반의 스크립트 언어이고 매우 편리하다는 이야기를 듣고 공부하게 되었습니다.

많은 모듈들도 있었기에 재미있는 프로젝트들도 해보았었습니다.


Q. 그럼 본인이 프로그래밍 언어들로 프로젝트 했던 것들이 무엇이 있는가?

A. 파이썬으로 한 프로젝트는 영상과 영상을 대조하여 같은 영상인지 판독하는 프로그램을 만들었으며

C#으로는 소켓으로 채팅 프로그램을 만든 적이 있습니다.


Q. 머신러닝? IOT? 비슷한거 물어보셨던 것 같음 ㅇㅇ

A. 제 자기소개서에 나와있듯이 머신러닝은 기계가 데이터를 통해 스스로 학습해가는 것인데 

저는 이러한 점에 흥미를 느껴 머신러닝을 공부하며 텐서플로우로 기계가 숫자를 인식하는 것을 해본 적이 있습니다.

MNIST로 softmax 함수로 학습을 시켜 경사하강법으로 이 모델이 제대로 학습이 되어있는지 0에 가까운 숫자가 나오는 것을 보고 신기했었습니다.

그리고 IOT는 정말 사용자들에게 편리하다고 생각합니다.

냉장고로 집에서 매장까지 가서 구매를 할 필요 없이 집에서 바로 시킬 수 있다는 장점이 잇지만 IOT는 보안에 많이 취약하기 때문에

보안계에 블루오션이라고 생각합니다. 


그 뒤는 좀 사생활적인 이야기가 나옴 ~


Q. 여기까지 면접 질문은 끝이고 마지막으로 준비해온 것이나 할말이 있는가?

A. 제가 알기로는 해킹 동아리가 없는 걸로 아는데 1학년도 들어가서 동아리를 개설할 수 있는가?


Q. 물론이다.

A. 수고하셨슴다


이렇게 면접이 끝이 났고 하고 싶은 말들은 다 하고 왔던 것 같아서 기분이 좋았다.


아무래도 내 학교는 똥통고등학교기에 6개중 4개가 광탈당하는 시점이라 공주대학교 합격이 떳을때도 빨간글씨길래 떨어진 줄 알았다.

사실 지금 생각해도 내가 이렇게 면접 기회를 받아도 되는 걸까 라는 생각을 잠도 못자며 생각한 적도 있었다.

정말 너무 힘들었다.


그래도 이렇게 말할 수 있는 기회를 줘서 너무 속 시원하고 현재는 발표를 기다리고 있다.


12월 16일 

이번 주 금요일.


아, 그리고 공주대에 아는 형이 있어서 점심도 사주시고 카페에서 커피도 사주셨었다.

붙으면 형이 사주신 집에서 똑같이 사드리고 커피도 사드려야지.

안붙으면 뭐 나중에 뵈러 가야지!


[+] 23:13 2016-12-15



[+] 01:38 2018-10-25



이번 18학번 분들이 많이 검색해주신 것 같아서 내년 19학번 분들에게 도움이 될 수 있게 더 적기로 결정하였습니다.


현재 보안 동아리는 개설하여 대외활동과 여러 스터디 및 정기 세미나를 열고 있습니다.


https://www.facebook.com/nimdasec


질문 혹은 문의 있으신 분은 이쪽으로 질문주세요.

질문하실 때 티스토리 면접글을 보고 연락하셨다고 미리 말씀해주세요!

SNS 관리자가 여러명이 있어서 답변이 늦을 수도 있어요!

'0x01 Etc. > 0x02 Timeline' 카테고리의 다른 글

아고라 서명 페이크 페이지 분석  (0) 2017.09.03
일본어 공부를 하자  (1) 2016.07.16
일본 여행 계획  (0) 2016.07.14
DJ 카일 하우스 웹툰 꿀잼 ㄹㅇ  (0) 2016.07.09
백투더백에서 메신저백을 샀다.  (155) 2016.07.02

Whale Browser

"


안녕하세요. 누구나 쉽게 쓰는 브라우저 '네이버 웨일'입니다.

“우주선은 거대한 고래였다”는 SF소설 속

한 줄 표현에서 영감을 받아 지어진 이름과 같이,

'웨일'은 데이터가 넘쳐나는 시대에 정보의 우주를 항해하는

여러분의 우주선이 되고자 합니다.

"
[ 출처 : http://whale.naver.com/story ]

http://whale.naver.com/ 에서 초대코드가 있다면 다운로드가 가능합니다.

저는 아는 동생이 코드가 있어서 덕분에 얻고 사용할 수 있는 기회가 생겼습니다.
아마 곧 2차 베타 테스트 신청을 한다니 그때 이용해서 하시면 될 것 같습니다.

먼저 디자인은 처음 보자마자 매우 심플하고 아름답다고 생각이 들었습니다.


아무래도 크로미움 + 자체 개발 엔진이라 크롬을 사용하신 분들이라면 가볍게 사용할 수 있을 것 같은 기분이 들 수 있었습니다.



아직은 베타버전이라 그런지 확장 앱 스토어가기를 누르면 준비중이라고 뜨지만 crx 파일을 드래그하면 사용이 가능 할 것 같긴 합니다.



설정 창도 보기 쉽게 배치를 해놓은 것 같습니다.

특히 저는 색깔이 마음에 드네요.

눈이 아프지 않는 것 같습니다.



그리고 몰랐지만 whale 브라우저에는 메모리 세이버라는 기능이 있는 것 같습니다.

기사를 검색을 하다 알게 됬지만 배터리 세이버 기능도 있다는 것 같습니다.

아마 노트북 사용자들의 배터리를 조금 더 배려하기 위해 만들지 않았을까 싶기도 합니다.

(위의 배터리 세이버 기능의 추측은 틀릴 수도 있습니다.)


Function

고래의 개쩌는 기능들을 Araboja
두둥!

커스텀 기능


하나의 이미지로 보여드리기 위해 이미지를 편집하였습니다.

탭을 새로 열면 날씨, 시계, 날짜 위젯들을 배치가 가능하며 배경사진을 선택하여 마음대로 커스텀이 가능합니다.

이미지들은 다 예술적이고 아름답다는 느낌을 줍니다.

탭을 열때마다 기부니 너무 좋을지도 모릅니다!


아, 다만 아쉬운 점은 현재는 배경선택에 있는 이미지들만 변경이 가능합니다.

이후에는 사용자가 가지고 있는 이미지로 마음대로 변경이 가능하면 좋을 것 같습니다.


스페이스

이 기능은 의외로 매우 편리한 것 같습니다.


위와 같이 페이지에 들어와서 스페이스를 키고 어떠한 페이지를 누르면 그 페이지로 이동이 되기에

보통 저는 새탭으로 들어가서 봤기에 보기 시작하면 탭이 10개 이상이 넘어가거나 5개는 기본으로 탭을 연 적이 많았습니다.

다만 이 스페이스 기능은 직접 들어갈 필요 없이 스페이스 공간에 한 화면에서 확인이 가능합니다.



졸라 넘나 편한 기능이라고 생각합니다.


사이드바


사이드바를 열게 되면 우측에 버튼들이 나타나게 됩니다.

위에서부터 "웨일 퀵서치", "편의도구", "웨일밸리", "뮤직 플레이어", "도구 추가"가 있습니다.

(아 물론 "편의도구"는 이름이 없지만 여러 많은 도구들이 한 곳에 모여있어서 편의도구라고 칭했습니다.)


웨일 퀵서치


굳이 귀찮게 탭을 하나 더 열어서 검색을 할 필요는 줄은 것 같습니다.

다만 아쉬운 점은 무조건 네이버에서 검색되는 것 같습니다...


편의도구


네, 이렇게 많은 도구들이 한 곳에 모여있습니다.

보통 저는 단위변환을 위해 네이버에 검색을 하며 갔었는데

정말 마음에 드네요 ^~^ !


밸리


음...이 기능은 탭에서 오른쪽 클릭을 한 후 밸리를 추가해서 두고두고 보는 보관함 같은 개념인 것 같습니다.




저의 글을 테스트할 겸 밸리에 추가하고 닫은 뒤 밸리에 가보니 추가가 되잇는 것을 볼 수 있습니다.




그리고 나중에 밸리가 많아지면 검색을 통해 검색어로 찾을 수도 있는 것 같습니다.

저같은 탭을 닫지 못하고 즐겨찾기에 저장하던 저에게는 매우 반가운 기능인 것 같습니다.


뮤직플레이어


이 기능은 "N 뮤직", "벅스", "엠넷", "지니"들을 연동해서 브라우저 내에서 들을 수 있는 기능같습니다.
다만 필자는 유투브나 아이튠즈에서 듣기에 사용할 수 없는 기능이였습니다... (안습


캡쳐

브라우저 내에서 캡쳐가 바로 가능합니다.


전체 페이지를 캡쳐를 해보았습니다.



크롬을 사용할 때는 부분 캡쳐해서 이어붙이거나 

확장 프로그램을 사용했었는데

꽤나 편리한 기능인 것 같습니다.


이외의 기능들은 http://whale.naver.com/ 에서도 확인이 가능합니다.


아마 더 사용은 해봐야겠지만 정말 편리함을 앞세우는 브라우저인 것 같습니다.

'0x01 Etc. > 0x05 Review' 카테고리의 다른 글

[Utils] Vivaldi Browser  (0) 2016.08.12
[Utils] AireCam  (0) 2016.07.22
[Game] Life Is Strange 리뷰  (839) 2016.07.22
[Game] Portal2 리뷰  (0) 2016.07.18
[Game] Youtubers Life 리뷰  (155) 2016.07.18

Format String Bug (FSB)

오랜만에 글을 작성하네요.
이번에 정리할 기법은 FSB입니다.

Format String Bug (FSB)가 일어날 일은 최근에 없지만 뭐,,프로그래머의 실수로 인해 생길 수도 있으니 알아두면 나쁘지 않을 것 같습니다.
먼저 이 글을 읽기 전에 프로그래밍을 해본 적이 있고 Format String에 대해 알고 있으면 편하게 읽으실 수 있습니다.

Format String은 C프로그래밍을 해보셨다면 printf() 함수를 이용하며 포맷에 맞게 출력을 할 때 보실 수 있었을 겁니다.


printf("I'm %s\n, name);


위의 코드는 간단한 name을 출력하는 코드입니다.


Format String Attack은 역시 프로그래머의 게으른 작은 실수로 인해 발생하는 취약점입니다.



/*

case 2

*/

printf("%s", name);


/*

case 2

*/

printf(name);



일반적으로 코드를 작성할 때에는 원하는 문자열을 포맷에 맞게 변수를 넘겨주게 코드를 작성하지만,

어느 몇몇 게으른 프로그래머는 case2 로 코드를 작성을 합니다.


물론 위의 2가지의 코드는 잘못된 코드는 아닙니다.

어떻게보면 case2의 코드가 case1의 코드보다 적은 양의 코드를 작성하고 더 현명하게 보이지만,

case2의 코드로 작성하게 되면 해커들에게 프로그램의 흐름을 바꿀 수 있는 취약점을 만든다는 사실을 깨달아야됩니다.


과연 case2의 코드에서는 무엇이 잘못일까요?


case1의 코드는 printf() 함수를 사용할 경우 출력할 형식 포맷만큼 출력시킬 변수를 인자에 넘겨주게 되지만,

case2의 코드는 사용자의 입력에 따라 지시자의 수가 달라질 수 있게 되므로, 악의적인 공격자에 의해 스택의 내용이 확인될 수 있는 것이 문제입니다!


name에 '%s, %d, %n' 등의 지시자들이 있다면 그 지시자에 맞는 값들을 출력하게 되어 스택의 내용이 보여지게 되는 것입니다!


앗...? 그럼 %n 지시자는 무슨 역할을 하는 지시자일까요?


%n 지시자는 출력된 갯수를 카운트하여 그 값을 주소에 저장을 시키는 지시자입니다!

말로 해봤자 이해가 어려울 수도 있으니 코드를 디버깅하며 이해를 해보도록 하겠습니다!



#include <stdio.h>


int main(int argc, char * argv[])

{

int vlun = 100;


printf("now vlun is %d\n", vlun);

        printf("1234567890%n\n",&vlun);

printf("but, now vlun is %d\n", vlun);

return 0;

}



위의 코드는 간단한 코드이기에 이해를 하실 수 있으실 것입니다!

vlun 변수에는 100이라는 값이 들어있기에 처음 printf 출력에서는 now vlun is 100 라는 문자열이 출력이 될 것이라는 것은 알 수 있습니다.

이제 8번째 라인 코드에서부터가 중요합니다.

위에서 말 했듯이 %n 지시자는 출력된 갯수를 카운트를 하여 그 값을  주소에 저장을 시키는 지시자라고 하였습니다.

앞에 출력되는 "1234567890" 은 총 10개라는 것은 초등학생도 알 수 있습니다.

%n 지시자에 &vlun 주소가 넘겨지며 이 주소에 10이라는 값이 저장이 되게 되는 겁니다!

그렇다면 마지막 출력에서는 but, now vlun is 10 라는 문자열이 출력이 될 것이라 알 수 있습니다.

실제로 그렇게 출력이 되는지 확인을 해보도록 하겠습니다.



실제로 그렇게 출력이 되는 것을 디버깅을 통해 알 수 있었으며, %n 지시자가 무슨 역할을 하는지 디버깅을 통해 이해할 수 있었습니다!


이제 %n 지시자 하나만 알고 있다면 여러분은 fsb attack을 할 수 있습니다!

간단한 2가지 문제를 풀며 이해를 하도록 하겠습니다.


이 2가지의 문제들은 root-me.org 라는 워게임 사이트의 문제입니다.



#include <stdio.h>

#include <unistd.h>


int main(int argc, char *argv[]){

        FILE *secret = fopen("/challenge/app-systeme/ch5/.passwd", "rt");

        char buffer[32];

        fgets(buffer, sizeof(buffer), secret);

        printf(argv[1]);

        fclose(secret);

        return 0;

}



지금까지의 글을 읽어보시고 이해를 하셨다면 위의 문제에서의 취약점이 어디에 존재하는지 한번에 아실 수 있으실겁니다.

printf(argv[1]); 

argv[1] 인자 넘겨주는 값을 그냥 printf 함수로 출력해주는 것을 알 수 있었습니다.

그리고 secret 값이 buffer에 들어가는 것도 볼 수 있네요 (웃음)


그렇다면 매우 많이 문자열을 출력해준다면 시크릿 값을 볼 수 있게 됩니다.



이제 보시다보면 스택 구조의 주소들 중 이상한 문자열이 중간에 껴있음을 알 수 있습니다.


리틀엔디안, 빅엔디안 잘 보시고 플래그를 뽑아내시면 됩니다!


39617044 -> 44706139


2번째 문제는 %n 지시자를 이용하는 문제입니다!!!



#include <stdio.h>

#include <stdlib.h>


int main( int argc, char ** argv )


{


int var;

int check  = 0x04030201;


char fmt[128];


if (argc <2)

exit(0);


memset( fmt, 0, sizeof(fmt) );


printf( "check at 0x%x\n", &check );

printf( "argv[1] = [%s]\n", argv[1] );


snprintf( fmt, sizeof(fmt), argv[1] );


if ((check != 0x04030201) && (check != 0xdeadbeef))

printf ("\nYou are on the right way !\n");


printf( "fmt=[%s]\n", fmt );

printf( "check=0x%x\n", check );


if (check==0xdeadbeef)

    {

printf("Yeah dude ! You win !\n");

      system("/bin/dash");

    }

}



이 문제의 취약점은 어디에 일어날까요?

printf( "fmt=[%s]\n", fmt );


여기서 일어날 것이라는 걸 알 수 있습니다!

이 문제는 매우 친절하게 check의 주소를 알려주고 check를 deadbeef로 값을 바꾸면 되는 걸 알 수 있습니다!! 빠빰!!!

왜 check 값을 0xdeadbeef 로 바꿔야되냐구요? (웃음)


if (check==0xdeadbeef)

{

printf("Yeah dude ! You win !\n");

system("/bin/dash");

}


바로 위의 코드때문입니다!


그렇다면 문제를 직접 풀면서 이해를 해보도록 하겠습니다.



check 의 주소는 0xbffffb78이며 저희가 넘겨준 1이 잘 출력되는 것과 check의 값은 0x4030201이라고 아주 자세하게 알려주고 있습니다.

그렇다면 이 문제를 풀기위해서는 0xbffffb78 주소를 넘겨주고 0xdeadbeef를 넘겨주면 되겠군요?!


앗 하지만 여기서 매우 크나 큰 관문이 생겼습니다.


0xbffffb78의 값은 3221224312 입니다.

int의 범위의 값을 넘어서버렸습니다..

벗어난 값을 입력하게 되면 오버플로우가 떠버릴지도 모른다구요~? (웃음 wwww


그래서 2바이트 2바이트씩 나눠서 넣어주면 됩니다.

0xbffffb78 : fe eb 00 00

0xbffffb7a : 00 00 da ed

이렇게 넣게 된다면?

0xbffffb78 : fe eb da ed


가 되게 되서 0xdeadbeef가 들어가게 되겠죠?!


먼저 우리가 원하는 주소가 스택에 있는지 찾아보기위해 무작위로 원하는 개수 만큼 "-%8x-"*?? 를 넣어줍니다.



이런! 없군요! 하지만 우리가 넘겨준 argv의 값이 출력되는 것을 볼 수 있습니다.

이걸 이용해 우리가 입력한 값으로 주소로 넘겨줄 수 있겠네요?


바로 이렇게 말이죠!



보시면 우리가 입력한 AAAA가 스택에 보이는 것을 볼 수 있어요.

이렇게 되면 우리가 입력한 값이 주소가 될 수도 있다는 것을 깨달을 수 있죠 (큰 깨달음


그렇다면 주소를 넘겨주고 0xdeadbeef를 만들면되겠네요!



익스플로잇 코드는 위와 같습니다! 

이제 알아보도록 하겠습니다.

먼저 check의 주소를 먼저 넘겨주면 스택에 들어가 가젯역할을 할 수 있게 됩니다!

그 후 dummy의 값을 주고 check의 2byte 만큼 높은 주소를 줍니다!

왜 2byte 높은 주소를 주는 이유는 위에 있습니다!

그 후 이제 %8x 로 스택의 현재 넘겨준 가젯의 위치를 잡습니다!

그 후는 계산만 남아있는데요!


먼저 0xbeef가 들어갈 예정입니다.

0xbeef의 값은 48879 입니다.

다만 앞에 있는 값들을 계산해줘야되겠죠?

0xbeef - (4 [0xbffffb48] + 4 [dummy] + 4 [0xbffffb48+2] + 8*7) = 48811 입니다.

그 뒤에는 0xdead - 0xbeef 한 값을 넘겨주면 되겠습니다!

0xdead - 0xbeef = 8126


그렇게 된다면 check의 주소인 0xbffffb48에는 0xbeef이 들어가고 0xbffffb4a에는 0xdead가 들어가 0xdeadbeef가 완성되게 되는거죠!


하지만 여기서 왜 더미가 들어가야될까요?

그 이유는 아래와 같습니다.

현재 포인터는 0xbffffb48을 잡고 값을 들어가게 됬습니다.

%n 지시자를 통해 주소는 4바이트 상승해서 AAAA 인 0x41414141을 잡고 있겠죠!

하지만 %8126c 인 %c 지시자를 사용하게 되어 4바이트 상승하여 그 다음 주소를 잡고 있게 되어 그 주소에 값이 들어가게 되는 것 입니다!


이렇게 위의 2문제를 풀며 Format String Bug(FSB) 기법을 볼 수 있었습니다.

'0x20 Security > 0x21 System' 카테고리의 다른 글

Save Frame Pointer Overwrite (SFO)  (0) 2016.07.25
Buffer Overflow (BOF)  (2) 2016.07.22
About LD_PRELOAD  (0) 2016.07.20
Use After Free (UAF)  (1) 2016.07.13
How main() is executed on linux  (2) 2016.07.04



1. 터미널 창을 간지나게 꾸며보자

2. 입장하거나 입장하려고 할 때에 글씨를 간지나게 띄어보자



이런 밋밋한 터미널 창 말고 간지나게 아름답게 예술적인 터미널을 만들어보겠습니다.


Oh-My-zsh (https://github.com/robbyrussell/oh-my-zsh) 에 접속을 하여 설치를 하세요!



만약 경로가 아래와 같이 깨진다 싶으면 폰트를 설치해주어야됩니다.



폰트 (https://github.com/powerline/fonts) 에서 zip을 받아 설치를 합니다.



이러케 설치를 한 뒤에 터미널의 폰트를 설치한 폰트로 변경해줍니다.



$ sudo apt-get install zsh

$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

$ chsh -s `which zsh`

$ vi ~/.zshrc


그렇다면 아래와 같이 터미널이 이뻐진 것을 볼 수 있습니다.



그리고 이제는 이런거나 이런걸 해봅시다.




저는 메이드를 좋아합니다.

글씨는 아래와 같이 하면 됩니다.


$ sudo apt-get install figlet

$ figlet "문자열"



원하는 그림 같은건 아스키 아트 같은 사이트를 이용하여 위와 같이 원하는 문자열로 뽑으시면 됩니다!


그런 문자열을 이제 이 파일들에 넣으면 됩니다.


 설정파일

 설명

 상태

 /etc/issue

 로컬에서 접속 시도시 보여줄 메세지 파일

 로그인 전

 /etc/issue.net

 원격지에서 접속 시도시 보여줄 메세지 파일

 로그인 전

 /etc/motd

 로컬, 원격 모두에서 로그인 성공 후에 보여줄 메세지 파일

 로그인 후


먼저 위의 설정 파일을 사용하기 위해서는 sshd_config를 변경할 필요가 있습니다.


$ vi /etc/ssh/sshd_config 



:/PrintMotd



PrintMotd no 에서 yes로 변경해줍니다.



:/Banner



주석 처리되있는 것을 지워줍니다.



그렇다면 이제 설정 파일은 다 했습니다.


이제 원하는 문자열을 원하는 파일에 집으시면 됩니다.



/etc/issue.net or /etc/issue



/etc/motd


작성을 다 하셨으면 재시작을 해줍니다.


$ /etc/init.d/ssh restart




'0x20 Security > 0x26 Server' 카테고리의 다른 글

ssh config 파일을 설정해보자!  (62) 2017.02.26
Run ARM ELF for qemu in ubuntu  (0) 2016.08.31
Install mongodb  (0) 2016.07.26

$ sudo apt-get install gcc-arm-linux-gnueabi qemu -y


arm compiler와 qemu 설치합니다.


arm-linux-gnueabi-gcc --version; qemu-system-arm --version



설치&버전 체크합시다.


arm-linux-gnueabi-gcc -staic ./a.c -o a


arm-gcc를 이용하여 컴파일합니다.



제대로 컴파일이 ARM로 되었음을 확인합니다.


qemu-arm ./a 로 실행합니다.


당연히 ./a 로 하면 arm이므로 실행이 되지 않습니다.



잘 되는 것을 볼 수 있습니다.

'0x20 Security > 0x26 Server' 카테고리의 다른 글

ssh config 파일을 설정해보자!  (62) 2017.02.26
서버를 간지나게 꾸며보자  (0) 2016.10.14
Install mongodb  (0) 2016.07.26

pintool.zip

pintool.z01


저번 주말에 해킹캠프에서 핀툴로 문제 풀기라는 주제로 발표를 하였습니다.
좋은 경험이 되었다고 생각됩니다.
더 열심히 공부해서 재미난 주제를 잡아서 더 큰 곳에서 발표를 하고 싶어지네요.




감사합니다.

'0xe0 Project > 0xe1 DOC' 카테고리의 다른 글

The About Technique of Anti-Debugging  (620) 2016.03.31

Vivaldi Browser

"
Vivaldi Browser는 오페라 브라우저를 개발한 '욘 폰 테츠너'가 새로 만든 웹 브라우저입니다.

욘 폰 테츠너는 1994년 오페라 웹브라우저를 만들고, 2011년 회사를 떠났는데요. 

그 후 2년 뒤 비발디테크놀로지라는 벤처기업을 설립하고 새로운 브라우저를 개발해 왔습니다. 

그리고 그 결과가 지난 2015년 1월에 탄생한 비발디 브라우저입니다.

"

[ 출처 : MacNews Tistory ]


https://vivaldi.com 에서 다운로드를 받을 수 있습니다.


Function !

비발디의 개쩌는 기능들을 소개해보게따
두둥!

커스텀 기능






이건 이미 설치하고 난 뒤의 상황이라 이런 창이지만,

설치를 하고 난 다음 실행을 하자마자 커스텀을 하는 창이 뜨게 된다.
탭의 위치나, 스킨이나, 뒷 배경을 마음대로 커스텀이 가능하다.



저는 이렇게 커스텀을 하였습니다.

뭐랄까 우분투의 불여우를 보는 기분입니다.


스피드 다이얼

즐겨찾기로 등록한 웹 페이지 또는 폴더들을 새탭 화면에서 아이콘으로 보여주는 기능입니다.
이 곳에서는 Drag&Drop으로 편히 이동을 시킬 수 있습니다!

탭을 열기 전에 미리 보기


탭에 커서를 올려놓으면 미리보기로 페이지의 내용을 보여줍니다.

일일히 확인하지 않고 들어갈 수 있어서 매우 편리한 기능입니다.


Fast-Forward and Rewind

진짜 어느 브라우저에도 없는 개 쩌는 신기한 기능입니다.
글을 읽고 해석을 잘못한 줄 알고 이해하는 데 좀 힘이 들었습니다...!


되감기 버튼을 누르면 현재 보고 있는 페이지의 가장 기본 도메인 주소로 돌아갑니다.

ex) http://www.facebook.com/hubeener -> http://www.facebook.com


빨리 감기 버튼을 누르면 사이트 소스를 분석하여 자동으로 다음 페이지를 보여줍니다.

ex) http://angdomainti.com/board.php?no=1 -> http://angdomainti.com/board.php?no=2


정말 개 쩌는 기능입니다...20(ㄹㅇ) ;;


여러 웹 사이트를 한 탭에 배치할 수 있는 '탭 타일링'

진짜 비발디는 대박인 것 같습니다.


쉬프트(Shift) 키를 누르고 2개 이상의 탭을 선택한 뒤에 Tile N Tabs을 누르게 되면 이와 같이 변하게 됩니다.



이건 뭐 정말 획기적인 ... 사랑스러운 기능입니다.

더 이상 이리저리 돌아다닐 필요가 없어졌습니다.


웹 브라우저에서 스팟라이트 기능 '퀵 커맨드 필터'


설치를 하고 따로 단축키를 설정하지 않았다면 아래와 같은 단축키로 이용할 수 있습니다.


Windows : F2 Key

Mac : Command + E


비발디의 '퀵 커맨드 필터' 기능은 키보드 만으로 탭을 이동하거나 새로운 윈도우를 열거나 할 수 있습니다.

한 마디로 개 쩝니다.


패널 추가하기


비발디의 웹 패널이라는 기능입니다.

자신이 자주 가는 페이지를 패널로 만들어서 편하게 이동할 수 있습니다.



사실 이건 모바일 사이트에 어울릴 것 같습니다.

그래도 엄청 편리한 기능 ㄷㄷ;

현재 페이지에 메모를 한다 'Notes'


솔직히 이 기능을 쓰긴 쓸까라는 생각을 하지만
현재 페이지에 대한 간단한 메모와 사진을 남길 수 있는 기능입니다.
웹 페이지 링크를 끌어와서 그에 맞는 메모를 작성할 수 있습니다.

크롬 브라우저의 플러그인과 호환

사실 이 기능에서 제일 마음에 들어서 바로 사용하게 되었습니다.
최근에 들어 크롬이 너무 무거워지고 버벅거림을 느끼게 되어서 고민하다 넘어오게 됬습니다.

vivaldi://extensions 앗 이 창 어디서 많이 보시지 않았나요?



비발디는 크롬처럼 '크로미엄' 오픈소스를 이용하여 만들어진 기술이라 크롬용으로 제작된 다양한 확장 프로그램과 호환성을 가지고 있습니다.

무려 apps도 호환됩니다.

완전 개쩝니다.

여기서 반했습니다.


마우스/트랙패드 제스처 기본 지원

사실 저는 이게 좀 마음에 안들어서 그냥 꺼놨습니다.


크롬과 달리 별도로 무엇을 설치할 필요도 없이 마우스/트랙패드 제스처를 지원합니다.

트랙패드 오르가즘을 느끼며 제스처까지 할 수 있습니다.

※ 주의 ※
다른 사람들이 보기에는 마법을 부리는 것으로 보일 수 있습니다.

웹 페이지 색상에 따라 달라지는 탭 막대 색상


웹 사이트에 색상에 따라 탭 막대기 색상도 변경됩니다.


하이버네이션


현재 보고 있는 탭이나 그 외의 나머지 탭들을 'Sleep'(?) 상태로 만드는 기능입니다.

당장 보지 않는 탭들을 주무시게 만들어 메모리 낭비를 방지할 수 있습니다.

탭을 징그럽게 많이 띄우시는 분들이 매우 좋아할 기능 ㅇㅈ합니다.


[ 출처 : 페이스북에서의 아는 누님의 크롬 탭들의 상태 ]

# 저격아닙니다.... (이거 쓰세여 개쩝니다 비발디)


아까 그 누님을 위한 기능 'Tab Stack'


너무 많은 탭들이 열려있다면 이와 같은 기능으로 탭 위에 스택을 쌓을 수 있습니다!

공간 활용 개쩝니다

비발디가 이렇게 개 쩝니다.


Tip !

꿀팁을 소개해보게따
두둥!

How Install Flash

그러타.
한고쿠에서 플래시가 업다 그러면 뭘 하질 모탄다.
바로 쉽게 예를 들자면 티스토리 같은...? ㅎㅎㅎ

0. 플래쉬 사이트 접속하여 다운로드

https://get.adobe.com/flashplayer/otherversions/ 에 접속하여 자신의 환경에 맞는 것을 고르고 PPAPI로 선택한다.


1. 다운 받은 파일을 설치를 한다.


그런 다음에 다운로드를 하여 설치를 해준다.



2. 설치가 됬는 지 확인한다.


설치를 하고 나서는 vivaldi://plugins 에 접속을 하여 설치가 제대로 됬는지 확인한다.



3. 즐긴다!


끝, 즐기시면 됩니다.


[ 출처 : https://help.vivaldi.com/article/install-flash-player-for-vivaldi/ ]


Windows에서의 북마크 + 기록들 Mac으로 동기화하기

비발디의 아쉬움이 있다면 그 것은 바로 동기화입니다...
크롬은 로그인하면 스킨이라던지 플러그인이라던지 .... 히스토리라던지.... 북마크라던지....
다 동기화가 되버리지만 비발디는 그런게 없습니다.

앗, 플러그인은 아무래도 직접 설치를 해줘야될 것 같습니다.

스킨 + 히스토리 + 북마크를 동기화하는 방법은 아래와 같습니다.


C:\Users\UserName\AppData\Local\Vivaldi\User Data\Default 에 들어가게 되면 



이렇게 북마크들과 로컬에서 세팅한 정보들이 이곳에 저장이 되게 됩니다.


여기서 필요한 정보들을 다 챙겨서 압축을 하고 맥북으로 넘겨준 뒤에...!



제가 빼온 파일들입니다.

그냥 다 빼왔었습니다.

아, 이때는 저 폴더를 그대로 가져가면 플러그인도 같이 가지겠지 싶었지만 안됬습니다.

플러그인은 직접 설치하는 것이 답이였습니다...ㅂㄷㅂㄷ

아마 찾아보면 방법은 있을 것 같습니다.



이 경로가 Vivaldi의 Windows에서의 C:\Users\UserName\AppData\Local\Vivaldi\User Data\Default 와 같은 위치입니다.



다 덮어씌워줍니다.

그러면 이렇게 동기화(?)가 됬습니다.



아, 백그라운드의 사진은 환경 설정에서 직접 추가해주셔야됩니다.

이러케 동기화(?)까지 끝이 났습니다.


개쩌는 비발디 씁시다.

속도 + 기능 + 디자인 

모든 면에서 훨씬 나은 비발디 합시다!

'0x01 Etc. > 0x05 Review' 카테고리의 다른 글

[Utils] Whale Browser  (0) 2016.12.02
[Utils] AireCam  (0) 2016.07.22
[Game] Life Is Strange 리뷰  (839) 2016.07.22
[Game] Portal2 리뷰  (0) 2016.07.18
[Game] Youtubers Life 리뷰  (155) 2016.07.18

[ 출처 : 닌자보이 란타로 ]


이 Ada Cracked 시리즈 글을 올릴 때는 이 사진을 이용할 예정이다.



이번 주 고른 프로그램이다.


이 프로그램은 베타 버전때의 파일인데.



사용 기한이 만료되었다며 메세지 창을 띄우고 종료를 해버린다.

메인을 따라가다보면 날짜를 비교하는 부분을 발견할 수 있다.



로컬 시간이랑 임의로 정해둔 0x07DE비교하는 것을 알 수 있다.




여기서 임의로 ECX의 값을 높은 값으로 바꿔주면 된다.


10초 제한도 비교하는 변수(?)명을 알아내서 시간 체크하는 부분을 찾아내면 되겠다.



문자열 발견



0x2710(10000) (1000ms = 1초)

10초와 비교하는 부분을 발견할 수 있었다.


이번 주 과제 끝,

'0x30 Study > 0x31 Reverse Lab' 카테고리의 다른 글

[Reverse Lab 스터디] DLL Injection  (0) 2016.08.10
[ReverseLab 스터디] UPX Packing  (155) 2016.07.26

DLL Injection



이번 글 내용 한 줄 요약할 수 있는 사진을 만들어버렸다...

DLL 인젝션은 말 그대로 다른 프로세서에 DLL을 강제로 박아버리는 것이다.

LoadLibrary() API를 호출하여 DLL을 로딩(Loading) 시키는 것인데.


DLL Injection은 다른 프로세서에 DLL을 삽입시키느냐, 자신의 프로세스에 삽입시키느냐에 따라 로딩시키는 대상에 따라 달라집니다.


What is DLL?

DLL은 Dynamic Linked Library의 약자로서 동적 연결 라이브러리입니다.
흔히 디엘엘 파일 이라고 읽고 드르르라고 읽기도 합니다.
이 DLL 파일은 프로그램 실행 후 동적으로 로드되고, 정적라이브러리에 비해 크기를 줄일 수 있습니다.
게다가 패치, 기능 개선에 효율성이 높습니다.

Purpose of DLL file use

보통 대게 DLL 파일의 사용 목적은 여러가지가 있습니다.

1. 크기

정적 라이브러리에 비해 동적 라이브러리가 크기가 작기 때문에,
실행 파일의 크기를 줄일 수 있습니다.

2. 악성 코드

정상적인 프로세스에 DLL 파일을 삽입하여 악의적인 행위를 합니다.

3. 패치

어떠한 프로그램의 패치가 필요할 때에 DLL Injection을 이용하여 문제가 있는 Data 수정할 수 있습니다.
그 패치가 필요한 프로세스에 침투한 DLL은 메모리들에 접근이 가능하기에 패치가 가능합니다.

그외에도 많겠지만...

Make DLL File in VS2015

New Project - Visual C++ - Win32 Project - DLL(D) - End


이제 코드를 작성하시고 빌드를 하고 DLL을 사용하면 됩니다.


Injector

Code는 아래와 같다.
출처 : http://www.reversecore.com/40


#include "stdio.h"
#include "windows.h"
#include "tlhelp32.h"

#define DEF_PROC_NAME ("notepad.exe")
#define DEF_DLL_PATH ("c:\\Malware.dll")

DWORD FindProcessID(LPCTSTR szProcessName);
BOOL InjectDll(DWORD dwPID, LPCTSTR szDllName);

int main(int argc, char* argv[])
{
    DWORD dwPID = 0xFFFFFFFF;
 
    // find process
    dwPID = FindProcessID(DEF_PROC_NAME);
    if( dwPID == 0xFFFFFFFF )
    {
        printf("There is no <%s> process!\n", DEF_PROC_NAME);
        return 1;
    }

    // inject dll
    InjectDll(dwPID, DEF_DLL_PATH); 

    return 0;
}

DWORD FindProcessID(LPCTSTR szProcessName)
{
    DWORD dwPID = 0xFFFFFFFF;
    HANDLE hSnapShot = INVALID_HANDLE_VALUE;
    PROCESSENTRY32 pe;

    // Get the snapshot of the system
    pe.dwSize = sizeof( PROCESSENTRY32 );
    hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, NULL );

    // find process
    Process32First(hSnapShot, &pe);
    do
    {
        if(!_stricmp(szProcessName, pe.szExeFile))
        {
            dwPID = pe.th32ProcessID;
            break;
        }
    }
    while(Process32Next(hSnapShot, &pe));

    CloseHandle(hSnapShot);

    return dwPID;
}

BOOL InjectDll(DWORD dwPID, LPCTSTR szDllName)
{
    HANDLE hProcess, hThread;
    HMODULE hMod;
    LPVOID pRemoteBuf;
    DWORD dwBufSize = lstrlen(szDllName) + 1;
    LPTHREAD_START_ROUTINE pThreadProc;

    if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )
        return FALSE;

    pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);

    WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName, dwBufSize, NULL);

    hMod = GetModuleHandle("kernel32.dll");
    pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryA");

    hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
    WaitForSingleObject(hThread, INFINITE); 

    CloseHandle(hThread);
    CloseHandle(hProcess);

    return TRUE;


DWORD FindProcessID(LPCTSTR szProcessName)

LPCTSTR szProcessName : 프로세스 이름 [ Ex) notepad.exe, kakaotalk.exe ]

Return : 프로세스 PID 값을 반환합니다.


BOOL InjectDll(DWORD dwPID, LPCTSTR szDllName) 

DWORD dwPID : 프로세스의 PID 값 

LPCTSTR szDllName : DLL 경로 [ Ex) C:\dsadasdas.dll, d:\asdasdas.dll ]

Return : 무조건 True를 반환하나, Handle을 구하지 못할 경우에는 False를 반환합니다.


InjectDll() 함수 코드 설명


if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )
        return FALSE;


먼저 OpenProcess에서 PID의 핸들을 구합니다.

핸들을 구하여 이 프로세스를 제어할 수 있습니다.


pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);

VirtualAllocEx() 함수로 그 프로세스의 메모리 공간에 버퍼를 할당합니다.

dll을 인젝션할 경로의 길이 만큼 할당합니다.


WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName, dwBufSize, NULL);


할당 받은 주소가 담긴 pRemoteBuf에 WriteProcessMemory 함수로 DLL 경로 문자열 #define DEF_DLL_PATH ("c:\\Malware.dll") 를 써줍니다.

이로서 원하는 프로세서 메모리 공간에 DLL 파일의 경로가 적재되었습니다.


hMod = GetModuleHandle("kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryA");

LoadLibraryA를 호출하기 위해서는 그주소가 필요합니다.
그러기 위해 kernel32.dll의 핸들을 구해와서 LoadLibraryA() 의 주소를 얻어냈습니다.


hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
WaitForSingleObject(hThread, INFINITE); 

pThreadProc : 프로세으의 kernel32.dll LoadLibraryA() 주소
pRemoteBuf : 프로세스 메모리에 적재된 dll 경로가 담긴 주소

그 뒤에 CreateRemoteThread로 프로세스에 kernel32.dll LoadLibraryA()를 호출합니다.


'0x30 Study > 0x31 Reverse Lab' 카테고리의 다른 글

[Reverse Lab 스터디] Ada Cracked(0)  (1) 2016.08.10
[ReverseLab 스터디] UPX Packing  (155) 2016.07.26

ppt를 만들던 도중 



이런 시각화가 필요해졌다.


그래서 알아보던 도중 인포그래픽이라는 것을 알게 되었고,

위의 사진 같은 것들을 워드클라우드라고 칭하는 것 같았다.


https://pypi.python.org/pypi/pytagcloud


에서 라이브러리를 설치할 수 있다.


import 하는 도중 아래와 같은 에러를 발견할 수 있었다.


ImportError: No module named pygame


그래서 pygame을 설치해주었다.


http://pygame.org/download.shtml


버전에 맞게 잘 설치해주자.


그리고 ImportError: No module named simplejson


계~~~속 에러가 뜰 수도 있는데.

알아서 잘 설치해주자....



일단 요래 실행이 되면 준비는 된거시다


그리고 아래의 링크를 참고하면 된다.


http://konlpy.org/ko/v0.4.3/examples/wordcloud/

'0x0a Programming > 0x0c Python' 카테고리의 다른 글

Python version 2.7 required, which was not found in the registry.  (0) 2016.08.02
pymongo in mongodb  (0) 2016.07.26
Pokemon Go API in python  (279) 2016.07.23


PIL을 설치하는 도중 이러한 에러 메세지를 발견하였다.


구글링을 해보니 64bit 설치 프로그램 오류라고 한다.


고치는 방법은 레지스트리에 파이썬 경로를 정확히 적어주는 것이다.


HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\InstallPath 키를 생성하고,

InstallPath의 값은 HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.7\InstallPath 값과 동일하게 세팅하면 된다.


아니면 그냥 아래의 코드를 실행해도 된다.



import sys


from _winreg import *


# tweak as necessary

version = sys.version[:3]

installpath = sys.prefix


regpath = "SOFTWARE\\Python\\Pythoncore\\%s\\" % (version)

installkey = "InstallPath"

pythonkey = "PythonPath"

pythonpath = "%s;%s\\Lib\\;%s\\DLLs\\" % (

    installpath, installpath, installpath

)


def RegisterPy():

    try:

        reg = OpenKey(HKEY_CURRENT_USER, regpath)

    except EnvironmentError as e:

        try:

            reg = CreateKey(HKEY_CURRENT_USER, regpath)

            SetValue(reg, installkey, REG_SZ, installpath)

            SetValue(reg, pythonkey, REG_SZ, pythonpath)

            CloseKey(reg)

        except:

            print "*** Unable to register!"

            return

        print "--- Python", version, "is now registered!"

        return

    if (QueryValue(reg, installkey) == installpath and

        QueryValue(reg, pythonkey) == pythonpath):

        CloseKey(reg)

        print "=== Python", version, "is already registered!"

        return

    CloseKey(reg)

    print "*** Unable to register!"

    print "*** You probably have another Python installation!"


if __name__ == "__main__":

    RegisterPy()



'0x0a Programming > 0x0c Python' 카테고리의 다른 글

pytagcloud use to wordcloude  (0) 2016.08.07
pymongo in mongodb  (0) 2016.07.26
Pokemon Go API in python  (279) 2016.07.23

pymongo

pymongo란 python mongo db drive이다.
듣기로는 몽고디비가 그렇게 빠르다고...

install pymongo

$ pip install pymongo



설치 끝.


use pymongo

언젠가 시간 날때 작성하겠음.


https://www.mongodb.com/download-center#community


$ wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-amazon-3.2.8.tgz



$ tar -zxvf ./mongodb-linux-x86_64-amazon-3.2.8.tgz



$ mkdir /opt/nosql

$ mv mongodb-linux-x86_64-amazon-3.2.8 /opt/nosql/mongodb

$ cd /opt/nosql/mongodb

$ mkdir data

$ mkdir config

$ mkdir log


$ vi mongodb.conf



dbpath=/opt/nosql/mongodb

logpath=/opt/nosql/mongodb/log/mongodb.log

logappend=true

port=5050

verbose=true

fork=true

rest=true



$ cd ./bin

$ ./mongod --config /opt/nosql/mongodb/config/mongodb.conf



$ /opt/nosql/mongodb/bin/mongo localhost:2885


MongoDB shell version: 3.2.8

connecting to: localhost:2885/test

Welcome to the MongoDB shell.

For interactive help, type "help".

For more comprehensive documentation, see

http://docs.mongodb.org/

Questions? Try the support group

http://groups.google.com/group/mongodb-user

Server has startup warnings: 

2016-07-26T08:25:14.110-0400 I CONTROL  [main] ** WARNING: --rest is specified without --httpinterface,

2016-07-26T08:25:14.110-0400 I CONTROL  [main] **          enabling http interface

2016-07-26T08:25:14.146-0400 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.

2016-07-26T08:25:14.146-0400 I CONTROL  [initandlisten] 

2016-07-26T08:25:14.147-0400 I CONTROL  [initandlisten] 

2016-07-26T08:25:14.147-0400 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.

2016-07-26T08:25:14.147-0400 I CONTROL  [initandlisten] **        We suggest setting it to 'never'

2016-07-26T08:25:14.147-0400 I CONTROL  [initandlisten] 

2016-07-26T08:25:14.147-0400 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.

2016-07-26T08:25:14.147-0400 I CONTROL  [initandlisten] **        We suggest setting it to 'never'

2016-07-26T08:25:14.147-0400 I CONTROL  [initandlisten] 


끝,

'0x20 Security > 0x26 Server' 카테고리의 다른 글

ssh config 파일을 설정해보자!  (62) 2017.02.26
서버를 간지나게 꾸며보자  (0) 2016.10.14
Run ARM ELF for qemu in ubuntu  (0) 2016.08.31

실행압축 (Packing)

여기서 UPX는 흔하디 흔한 패킹 툴의 하나의 종류이다.
이런 패커들은 실행압축을 하여 실행 파일을 파일의 형태를 그대로 유지를 하고 Size를 최대한 줄여 주는 압축 방식인데.

대게 악성 프로그램들이 이런 압축 방식을 이용하여 분석하는 데에 귀차니즘을 남겨줌.
거기에 안티 디버깅까지 들어가버리면 개 빡친다. ㅇㄱㄹㅇ ㅂㅂㅂㄱ ㅇㅈ? 어 ㅇㅈ


실행되는 순간 메모리에서 압축을 해제하고 실행을 시키는 기술이기에,

어딘가에 압축 해제 루틴이 담겨있어서, 이런 루틴을 지난 후에 실행시킨다는 게 특징이다.


이런 패킹을 사용하는 목적은 아래라고 생각합니다.


1. 파일 자체의 크기를 줄이기 위함

2. 내부 코드와 리소스등을 사용자가 보지 못하게 방해하는 것.

3. 분석을 하지 않게 귀차니즘을 넘겨주기 위해


이라고 볼 수 있습니다.


UPX Packing

먼저 보기 전에 UPX 패킹이 이루어지고 난 뒤에 PE가 어떻게 변경되는지 보도록 하겠습니다.



앗, 딱 봐도 IMAGE_SECTION_HEADER, SECTION 들이 UPX0, UPX1 들로 압축된 것을 볼 수 있습니다.




또 UPX0 SECTION의 RawDataSize를 보면 0으로 되있는 것을 볼 수 있으므로,

파일 내에 존재하지 않는 것을 볼 수 있습니다.

하지만 UPX0 SECTION의 Virtual Size를 보면 알 수 있습니다.

실제 파일에서의 사이즈는 0으로 되어있는데 메모리에서의 사이즈는 큰 것을 볼 수 있습니다.




그렇다면 이유는 압축 해제 코드와 압축된 원본 코드들은 UPX1 SECTION에 존재하다는 것을 예상할 수 있습니다.

그렇다면 파일이 실행이 되면 원본코드는 UPX0 섹션에 해제시킨다는 것을 예상할 수 있겠네요 (웃음)


Analyze

그렇다면 이제 올리디버거로 열어서 분석을 하도록 해보자!


PUSHAD 

CPU 레지스터 값들을 모두 스택에 넣는 명령어입니다.

POPAD

PUSHAD 명령어의 반대로 스택에 넣은 CPU 레지스터 값들을 CPU 레지스터로 복귀시키는 명령어입니다.


처음 실행될 때에 PUSHAD로 CPU 레지스터 들의 값들을 스택에 집어넣는 것을 볼 수 있습니다.




스택에 들어간 것을 볼 수 있습니다.

EAX~EDI의 값들이 순서대로 스택에 들어간 것을 볼 수 있습니다.



그 후에 ESI에 UPX1 시작 주소를 넘겨주어 세팅을 합니다.

EDI에는 0x001CE000(UPX1) + 0xFFFFFFFFFFFE3000 = 0x1B1000(UPX0)


(이 뒤에서 주소가 갑자기 바뀌는데... 디버거가 한번 팅겨서 주소가 달라진 것이니 착각하지마시길 바랍니다!)


아무튼 UPX0의 주소를 스택에 넣고 이제 점프합니다.



EBX에 [UPX1] 주소에 담긴 값을 저장합니다.



그리고 ESI, EDI 레지스터에는 위의 사진과 같이 세팅이 되어있는데.

0x41e000과 0x401000은 UPX1(.data) 주소와 0x401000(.text)주소입니다.



맞는 것을 볼 수 있습니다.



[EDX]에서 값을 가져와서 AL에 쳐박고 

EDI(UPX0)에 복사함을 알 수 있습니다.

FFF2만큼 UPX0에 0으로 초기화하는 부분임을 알 수 있습니다.


이 뒤의 0x40370F주소 이후에 IMAGE_SECTION_HEADER를 채우게 됩니다.



ESI가 가르키는 곳에 있는 값을 EDI에 값들을 복사하는 것을 볼 수 있습니다.



그리고 EDX의 값을 가져와서 EDI에 쑤컹쑤컹하는 것을 볼 수 있습니다.



그리고 이 부분이 압축 해제 루프입니다.



그 뒤로는 IAT 세팅입니다.




퍄퍄 이 곳에서 하나하나 이동시키는 것을 볼 수 있습니다!



그 뒤에 스택에 EAX~EBP까지 PUSH한 후 POPAD를 하는 모습입니다.

POPAD를 한 후의 CPU 레지스터의 상태입니다.



모든 압축 해제 과정이 끝나게 되면 OEP로 점프를 하게 됩니다.



넵!



실제로 패킹 안한 프로그램을 열어보면 같음을 확인할 수 있습니다.



그렇다면 하나의 꼼수를 알아내자면 UPX 패킹일 경우에는 그저 POPAD를 찾아서 그 뒤에 있는 JMP 주소가 oep라는 것을 알 수 있습니다. (웃음)

'0x30 Study > 0x31 Reverse Lab' 카테고리의 다른 글

[Reverse Lab 스터디] Ada Cracked(0)  (1) 2016.08.10
[Reverse Lab 스터디] DLL Injection  (0) 2016.08.10

Save Frame Pointer Overwrite (SFO)

이번에 작성할 기법은 SFO 입니다.
Buffer Overflow(BOF) 가 일어나는 프로그램 취약점을 이용하여 Save Frame Pointer를 주작질을 하여 원하는 주소로 이동시키게 하는 기법입니다.
이 글을 일으시려면 BOF에 대해 알아두셔야 됩니다.

Save Frame Pointer Overwrite (SFO)는 1byte만 Overflow되는 상황에서 사용되는 기법으로, 

save frame pointer(sfp) 1byte를 해커가 주작질함으로서 상위 실행 권한을 얻을 수 있지만,

main 함수에서는 save frame pointer(sfp)를 주작질을 하여도 리턴 주소가 주작되지 않습니다.



Buffer Overflow(BOF) 글에서 SFP에 대해 조금 설명을 짤막하게 적어두고 GDB를 보며 깨달음을 얻도록 하겠습니다.


Save Frame Pointer(SFP)는 이전 함수의 ebp를 저장해 두어 함수의 실행이 끝나고 이전 함수로 돌아가기 위해 저장해두는 공간입니다.

이제 그렇다면 GDB로 직접 보아가면서 깨달음을 얻도록 하겠습니다!


깨달음에 GDB를 박으면 꼼짝모테~!


Open Program in GDB!

먼저 취약점이 존재하는 프로그램을 GDB에서 열어보겠습니다.
아래는 그 프로그램의 코드입니다.


/*
        The Lord of the BOF : The Fellowship of the BOF
        - darkknight
        - FPO
*/

#include <stdio.h>
#include <stdlib.h>

void problem_child(char *src)
{
char buffer[40];
strncpy(buffer, src, 41);
printf("%s\n", buffer);
}

main(int argc, char *argv[])
{
if(argc<2){
printf("argv error\n");
exit(0);
}

problem_child(argv[1]);
}


네, 코드를 어디서 많이 보신 것 같다구요?

넵, LOB의 golem의 소스코드입니다.


딱 보아도 취약점이 존재하다는 것을 발견할 수 있었습니다.

problem_child에 인자를 넘겨주는데,

problem_child 함수안에는 buffer는 40 byte 버퍼를 생성하고,

ctrncpy 함수로 buffer에 받은 인자를 쑤셔 넣지만 41byte 만큼 복사합니다.


buffer 는 40byte만큼 생성됬는데 말이죠 (웃음)

그렇다면 저희는 sfp 1byte를 주작질이 가능하다는 것을 알 수 있습니다.



그렇다면 problem_child에 브포를 설정해놓고 41만큼 넘겨주도록 하겠습니다.



넵, 걸린 걸 볼 수 있습니다.



strncpy 함수 뒤에 걸어주고 버퍼의 값을 확인해보았습니다.



40개의 A와 B가 잘 들어간 것을 볼 수 있습니다.

고로 여기서 볼 수 있는 것은 SFP는 0xbffffa62라는 것을 볼 수 있습니다.


이제 이 SFP를 어떻게 이용하는 지는 바로 이 녀석들이 중요합니다.

leave, ret !


main에서 leave ret이 실행되면서 조작된 SFP가 사용이 되는 것인데요.

이 leave ret은 BOF 글에서 설명을 했었으므로 넘어가겠습니다.


일단 그렇다면 main의 leave에 브포를 설정해주었습니다.



ebp를 확인을 해보면 저희가 주작질을 한 0xbffffa62 임을 확인할 수 있습니다.

그리고 여기서 leave가 실행을 하게 되면.

mov esp, ebp

pop ebp 이므로


ebp 값을 esp에 옮기고,

pop ebp을 하여 ebp에 저장을 하게 됩니다.

다만, pop ebp를 하면서 +4 만큼 증가하게 됩니다.



leave를 수행하고 난 뒤의 레지스터의 상태입니다.

esp에는 0xbffffa62 + 4 값이 되어있는 것을 볼 수 있습니다.


이제 ret을 수행하게 되면,

pop eip

jmp eip


즉, 스택에 쌓여있는 값을 eip에 넣고 해당 eip로 이동을 하게 됩니다.



즉, 0x88c04002이 eip에 저장이 되고, 해당 주소로 이동한다는 것을 알 수 있습니다.



이러한 과정을 통해서 Save Frame Pointer Overwirte(SFO) 기법을 볼 수 있었습니다.

'0x20 Security > 0x21 System' 카테고리의 다른 글

Format String Bug (FSB)  (0) 2016.12.01
Buffer Overflow (BOF)  (2) 2016.07.22
About LD_PRELOAD  (0) 2016.07.20
Use After Free (UAF)  (1) 2016.07.13
How main() is executed on linux  (2) 2016.07.04

먼저 적기에 앞서 winnt.h 헤더 파일을 올려놓겠습니다.


PE File Format

이번에 정리할 것은 윈도우 리버싱에서 알아두어야할 PE 파일이다.
PE는 Portable Excutable)의 줄임말이며,
윈도우에서 사용되는 실행 가능한 파일 형식입니다.
PE 파일은 EXE 파일을 말하는 것이 아니라 SCR, DLL, OCX, SYS, OBJ 들도 포함이 됩니다.
PE 구조를 이해는 API 후킹, 압축 실행 등과 같은 고-오-급 리버싱 기법들의 기본 바탕이 되기도 합니다.
고로 리버싱을 하겠다 하면 이 PE 구조에 대해 빡삭한 지식을 가지고 있어야됩니다.

Preview


어느 실행파일의 PE 구조입니다.

이 PE 헤더에는 이 실행파일을 실행하기 위한 여러가지 정보가 담겨있으며,

PE의 내용을 가지고 DLL을 로드하거나, 리소스를 할당하고 그 외에도 많은 정보들이 담겨있습니다.

이렇게 중요한 정보들이 담겨있는 만큼 PE파일이 잘못된 데이터로 누락하게 되면 실행파일은 실행이 안될 수도 있습니다.


Basic PE File

PE 구조에 대해 알아보도록 하겠습니다.

먼저 이미지를 첨부하고... (쮸글쮸글)
아, 참고로 구글에 검색하고 괜찮은 이미지 긁어왔습니다.

[ 출처 : rednooby.tistory.com ]


PE 구조는 차례대로 DOS Header, DOS Stub, NT Header(File Header, Optional Header), Section Header로 나뉘며,

그 뒤로는 코드를 포함하는 (.text) Section, 

(전역, 정적) 변수를 포함하고 있는 (.data) Section, 

문자열이나 리소스 데이터를 포함하는 (.rsrc) Section이 등장합니다.

그리고 이러한 섹션들 끝에는 NULL padding 이라는 것이 존재합니다.


VA & RVA

섹션마다 
가상메모리에서 해당 섹션을 차지하는 크기(VirtualSize), 
가상 메모리 오프셋(VirtualOffset), 
파일에서 해당 섹션이 차지하는 크기(RawSize), 
파일 오프셋(RawOffset) 들이 있습니다.

가상 메모리의 주소(Virtual Address)

응용 프로그램의 가상 메모리의 절대 주소를 의미합니다.
즉, 이 VA는 로딩되었을 때의 가상 메모리에서의 절대주소입니다.

ImageBase에서부터의 상대주소(Relative Virtual Address)

응용 프로그램의 가상 메모리에서의 상대주소를 의미합니다.
상대주소라고 하면 ImageBase의 기준으로부터 상대주소를 의미합니다.

RVA와 VA의 관계식(?)

RVA + ImageBase = VA

RVA와 RAW의 비례식

RAW - PointerToRawData = RVA - Virtual Address
RAW = RVA - Virtual Address + PointerToRawData

이 비례식에 존재하는 VirtualAddress는 우리가 지금껏 말하고 있던 VA(Virtual Address)가 아닙니다.
VA는 프로그램의 메모리에서의 절대주소라고 적었습니다.
위에 있는 RAW를 구하기 위한 식에서 나오는 VA(Virtual Address)는 Section Header의 멤버인 Virtual Address를 의미합니다. 
Section Header 구조체의 멤버인 VirtualAddress 멤버는 메모리에서 섹션의 시작 주소(RVA)를 의미합니다. 
결론적으로 RAW 비례식에서의 VirtualAddress는 우리가 앞에서 계속 얘기하던 RVA (프로세스 메모리에서의 상대주소)를 말하는 것입니다. 

[ 주황색 말 출처 : 리버싱 핵심원리 ] 

PE 헤더 (Portable Executable Header)

이 헤더라는 것들은 여러가지 필드로 이루어진 하나의 구조체라고 보시면 됩니다.
PE에는 처음에 봤듯이 여러가지 헤더들이 앞에 자리잡고 있으므로 이 PE는 많은 구조체 덩어리라고 말 할 수 있습니다.


먼저 이 헤더들(IMAGE_DOS_HEADER, MS-DOS Stub Program, IMGAGE_NT_HEADER)을 차례대로 살펴보도록하겠습니다.


IMAGE_DOS_HEADER

가장 처음으로 등장하는 IMAGE_DOS_HEADER 입니다.
아래의 코드는 winnt.h 헤더에 있는 도스 헤더의 구조체입니다.


#define IMAGE_DOS_SIGNATURE                 0x5A4D      // MZ

typedef struct _IMAGE_DOS_HEADER {
    WORD  e_magic;      /* 00: MZ Header signature */
    WORD  e_cblp;       /* 02: Bytes on last page of file */
    WORD  e_cp;         /* 04: Pages in file */
    WORD  e_crlc;       /* 06: Relocations */
    WORD  e_cparhdr;    /* 08: Size of header in paragraphs */
    WORD  e_minalloc;   /* 0a: Minimum extra paragraphs needed */
    WORD  e_maxalloc;   /* 0c: Maximum extra paragraphs needed */
    WORD  e_ss;         /* 0e: Initial (relative) SS value */
    WORD  e_sp;         /* 10: Initial SP value */
    WORD  e_csum;       /* 12: Checksum */
    WORD  e_ip;         /* 14: Initial IP value */
    WORD  e_cs;         /* 16: Initial (relative) CS value */
    WORD  e_lfarlc;     /* 18: File address of relocation table */
    WORD  e_ovno;       /* 1a: Overlay number */
    WORD  e_res[4];     /* 1c: Reserved words */
    WORD  e_oemid;      /* 24: OEM identifier (for e_oeminfo) */
    WORD  e_oeminfo;    /* 26: OEM information; e_oemid specific */
    WORD  e_res2[10];   /* 28: Reserved words */
    DWORD e_lfanew;     /* 3c: Offset to extended header */
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;


위 구조체에서는 데이터 타입이 WORD가 16개, WORD 배열이 2개, DWORD가 1개가 존재합니다.
이 헤더에서는 2개의 필더만 유심히 보시면 됩니다.
e_magic, e_lfanew 2개 입니다.


e_magic 

e_magic 필드는 PE 파일이 맞는지 아닌지 체크할 때 사용되며,
처음부터 2byte를 보면 MZ(4D 5A)인 IMAGE_DOS_SIGNATURE로 시작되는 부분이 emagic이 차지하는 공간입니다.

e_lfanew

e_lfanew 필드는 IMAGE_NT_HEADER의 시작 오프셋을 가지고 있으며, 
이 값은 고정되어 있는 값이 아니라 파일에 따라 값이 변경됩니다.
즉 PE 헤더(IMAGE_NT_HEADER)의 주소는 IMAGE_DOS_HEADER의 e_lfanew 필드를 참조하여 알아낼 수 있다는 것입니다.
위에 있는 이 프로그램의 e_lfanew 필드의 값은 0x000000F0이라는 것을 알 수 있습니다.

DOS Stub

스텁 코드(Stub Code)


위의 영역이 DOS Stub 영역입니다.
저 영역을 자세히 보시면 "This program cannot be run in DOS mode" 라는 문자열을 볼 수 있으며,
도스 모드에서 이 파일이 실행되는 것을 막기 위한 것 입니다.
그냥 이 영역은 그다지 신경을 안써도 되는 영역이라고 생각합니다. 

IMAGE_NT_HEADER

이번에는 IMAGE_DOS_HEADER에 이어서 IMAGE_NT_HEADER를 알아보겠습니다.
아래의 코드는 winnt.h 헤더에 있는 NT 헤더의 구조체입니다.


#define IMAGE_NT_SIGNATURE                  0x00004550  // PE00

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;



먼저 적기 전에 IMAGE_DOS_HEADER의 e_lfanew 필드의 값이 IMAGE_NT_HEADER의 오프셋이 맞음을 알 수 있었습니다.


Signature

IMAGE_NT_HEADER의 필드를 살펴보시면 Signature 필드가 가장 처음으로 등장합니다.
데이터 타입이 DWORD이기 때문에 4byte를 차지하며, 이 Signature의 값을 가지고 PE 파일 구조인지 아닌지를 체크를 할 수 있습니다.
Signature의 값은 IMAGE_NT_SIGNATURE 상수 그대로 PE 00(50 45 00 00) 라는 값을 가지고 있습니다.

그리고 Signature 말고도 FileHeader와 OptionalHeader필드가 있는데,
이는 IMAGE_FILE_HEADER, IMAGE_OPTIONAL_HEADER32 구조체를 가지고 있습니다.
이들을 알아보도록 하겠습니다.

IMAGE_FILE_HEADER

이번에는 IMAGE_NT_HEADER에 이어서 IMAGE_FILE_HEADER를 알아보겠습니다.
아래의 코드는 winnt.h 헤더에 있는 FILE 헤더의 구조체입니다.


typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;


IMAGE_NT_HEADER보다 필드가 많은 것을 볼 수 있습니다.
차례대로 알아보도록 하겠습니다.

Machine

Machine 필드는 이 파일이 어떤 CPU에서 실행될 수 있는지를 알 수 있습니다.
아래는 winnt.h 헤더에 정의되있는 Machine 상수입니다.


#define IMAGE_FILE_MACHINE_UNKNOWN           0
#define IMAGE_FILE_MACHINE_I386              0x014c  // Intel 386.
#define IMAGE_FILE_MACHINE_R3000             0x0162  // MIPS little-endian, 0x160 big-endian
#define IMAGE_FILE_MACHINE_R4000             0x0166  // MIPS little-endian
#define IMAGE_FILE_MACHINE_R10000            0x0168  // MIPS little-endian
#define IMAGE_FILE_MACHINE_WCEMIPSV2         0x0169  // MIPS little-endian WCE v2
#define IMAGE_FILE_MACHINE_ALPHA             0x0184  // Alpha_AXP
#define IMAGE_FILE_MACHINE_SH3               0x01a2  // SH3 little-endian
#define IMAGE_FILE_MACHINE_SH3DSP            0x01a3
#define IMAGE_FILE_MACHINE_SH3E              0x01a4  // SH3E little-endian
#define IMAGE_FILE_MACHINE_SH4               0x01a6  // SH4 little-endian
#define IMAGE_FILE_MACHINE_SH5               0x01a8  // SH5
#define IMAGE_FILE_MACHINE_ARM               0x01c0  // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB             0x01c2
#define IMAGE_FILE_MACHINE_AM33              0x01d3
#define IMAGE_FILE_MACHINE_POWERPC           0x01F0  // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_POWERPCFP         0x01f1
#define IMAGE_FILE_MACHINE_IA64              0x0200  // Intel 64
#define IMAGE_FILE_MACHINE_MIPS16            0x0266  // MIPS
#define IMAGE_FILE_MACHINE_ALPHA64           0x0284  // ALPHA64
#define IMAGE_FILE_MACHINE_MIPSFPU           0x0366  // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU16         0x0466  // MIPS
#define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64
#define IMAGE_FILE_MACHINE_TRICORE           0x0520  // Infineon
#define IMAGE_FILE_MACHINE_CEF               0x0CEF
#define IMAGE_FILE_MACHINE_EBC               0x0EBC  // EFI Byte Code
#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
#define IMAGE_FILE_MACHINE_M32R              0x9041  // M32R little-endian
#define IMAGE_FILE_MACHINE_CEE               0xC0EE


이 프로그램에 Machine 필드의 값을 확인해보도록 하겠습니다.


4C 01로 되있으며,

#define IMAGE_FILE_MACHINE_I386              0x014c  // Intel 386.
값과 일치합니다.
그렇다면 intel x86 CPU와 호환한다는 소리가 됩니다.

NumberOfSections

이 필드는 PE 파일을 구성하는 섹션의 수를 나타냅니다.
섹션이 추가되면 이 값은 증가하고 섹션이 없어지면 감소합니다.
이 값을 보고 섹션의 개수를 알아낼 수 있으며, 무조건 0보다는 커야됩니다.
그렇다면 직접 NumberOfSections의 값을 보도록 하겠습니다.


섹션이 9개가 있다고 합니다.



실제로 9개가 존재하는 것을 볼 수 있었습니다.

TimeDateStamp

TimeDateStamp 필드는 이 PE파일이 생성된 시간,
즉 이 파일이 생성된 날짜가 타임스탬프 형식으로 기록이 됩니다.
그러나 이는 확실히 신뢰할 수 없는 값이며, 언제든지 변조가 가능하므로 "아 그렇구나~" 로 보셔야 됩니다.
TimeDateStamp 필드의 값을 확인하도록 하겠습니다.


TimeDateStamp의 값은 0x578F684B로 알수 있으며,

0x578F684B(16)를 10진수로 바꾸면 1469016139(10) 입니다.


http://www.epochconverter.com/
의 사이트에서 표준 시간으로 바꾸게 되면 

실제 파일 시간과 동일함을 볼 수 있습니다.



PointerToSymbolTable

PointerToSymbolTable 필드는 파일의 심볼 내용을 담고 있는 테이블의 오프셋을 저장하고 있고, 없으면 0을 담고 있습니다.


NumberOfSymbols

NumberOfSymbols 필드는 심볼 테이블에 저장된 심볼의 개수를 저장하고 있고, 없으면 0을 담고 있습니다.


SizeOfOptionalHeader

SizeOfOptionalHeader 필드는 IMAGE_OPTIONAL_HEADER 필드에 있는 OPTIONAL 헤더(IMAGE_OPTIONAL_HEADER32)의 크기를 담고 있습니다.

이 필드의 크기는 정해져있는 것 같고 운영체제에 따라 값이 다르기 때문에 

PE로더는 이 필드의 값을 확인하고 IMAGE_OPTIONAL_HEADER의 크기를 처리합니다.



위 그림에서 SizeOfOptionalHeader 필드의 값을 확인할 수 있으며,

값은 0xE0(16)으로 224(10) byte 만큼 차지한다는 것을 알 수 있습니다.


Characteristics

Characteristics 필드는 현재 파일의 형식을 알려주는 역할을 하며,
이 필드의 값을 가지고 실행 가능한 파일인지,
DLL 파일인지, 시스템 파일인지 등의 정보가 들어있습니다.
아래는 winnt.h에 정의된 Characteristics 상수입니다.


#define IMAGE_FILE_RELOCS_STRIPPED           0x0001  // Relocation info stripped from file.
#define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002  // File is executable  (i.e. no unresolved externel references).
#define IMAGE_FILE_LINE_NUMS_STRIPPED        0x0004  // Line nunbers stripped from file.
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED       0x0008  // Local symbols stripped from file.
#define IMAGE_FILE_AGGRESIVE_WS_TRIM         0x0010  // Agressively trim working set
#define IMAGE_FILE_LARGE_ADDRESS_AWARE       0x0020  // App can handle >2gb addresses
#define IMAGE_FILE_BYTES_REVERSED_LO         0x0080  // Bytes of machine word are reversed.
#define IMAGE_FILE_32BIT_MACHINE             0x0100  // 32 bit word machine.
#define IMAGE_FILE_DEBUG_STRIPPED            0x0200  // Debugging info stripped from file in .DBG file
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP   0x0400  // If Image is on removable media, copy and run from the swap file.
#define IMAGE_FILE_NET_RUN_FROM_SWAP         0x0800  // If Image is on Net, copy and run from the swap file.
#define IMAGE_FILE_SYSTEM                    0x1000  // System File.
#define IMAGE_FILE_DLL                       0x2000  // File is a DLL.
#define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000  // File should only be run on a UP machine
#define IMAGE_FILE_BYTES_REVERSED_HI         0x8000  // Bytes of machine word are reversed.


위 상수의 값은 비트 플래그를 사용한 것으로, 2진수 형식으로 증가합니다.


Characteristics 필드의 값이 0x0102라는 것을 볼 수 있으며, 이는 0100과 0002를 합한 값이랑 같습니다.

#define IMAGE_FILE_32BIT_MACHINE             0x0100  // 32 bit word machine.

#define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002  // File is executable  (i.e. no unresolved externel references).


즉, 32비트 머신을 필요로 하고, 실행 가능한 파일이라는 것을 알 수 있습니다.


IMAGE_OPTIONAL_HEADER

이번에는 IMAGE_FILE_HEADER에 이어서 IMAGE_OPTIONAL_HEADER를 알아보겠습니다.
아래의 코드는 winnt.h 헤더에 있는 OPTIONAL 헤더의 구조체입니다.


typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

//
// Optional header format.
//

typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //

    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;

    //
    // NT additional fields.
    //

    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;


IMAGE_OPTIONAL_HEADER 구조체는 PE구조체 중에 가장 크기가 큰 구조체로서, 필드가 상당히 많은 것을 볼 수 있습니다.
이 구조체에서 주목해야할 필드만 쏙쏙 간략하게 보도록 하겠습니다.

Magic

이 필드는 IMAGE_OPTIONAL_HEADER32일 경우에는 0x0B01, IMAGE_OPTIONAL_HEADER64일 경우에는 0x0B02 값을 가지게 됩니다.


위 그림에서 Magic 필드의 값이 0x0B01 값을 가지고 있는 것을 볼 수 있으며,
이는 IMAGE_OPTIONAL_HEADER32 구조체임을 알 수 있습니다.

AddressOfEntryPoint

EP(Entry Point)의 RVA(Relative Virtual Address)의 값을 가지고 있습니다.


ImageBase

PE 파일이 메모리에 로드될 때의 주소를 가르킵니다.
32비트일 경우 가상 메모리의 범위는 0 ~ FFFFFFFF 범위입니다.
ImageBase는 이런 광범위한 메모리 내에서 PE 파일이 로딩되는 시작 주소를 가지고 있습니다.

EXE, DLL 파일은 user memory 영역인 0 ~ FFFFFFF7 범위에 위치하고,
SYS 파일은 kernel memory 영역인 00000008 ~ FFFFFFFF 범위에 위치합니다.

보통은 실행 파일들의 ImageBase는 0x00400000, DLL 파일의 ImageBase는 0x01000000입니다. ( 물론 무조건 이 값을 가지고 있는 것은 아닙니다. )


위의 사진에서 ImageBase의 값은 0x00040000임을 알 수 있습니다.


SectionAlignment & FileAlignment

SectionAlignment는 메모리에서의 섹션의 최소 단위츨 나타내고, FileAlignment는 파일에서의 섹션의 최소 단위를 나타냅니다.
따라서 파일/메모리의 섹션 크기는 반드시 각각 SectionAlignment, FileAlignment 들의 배수가 되어야합니다.


초랭이 : SecionAlignment

주랭이 : FileAlignment


SizeOfHeader

PE 헤더의 전체 크기를 나타냅니다.
파일 시작점에서 SizeOfHeaders Offset만큼 떨어진 위치에 첫번째 섹션이 존재합니다.  


위 사진에서 SizeOfHeader 값은 0x0001F000(16)으로, 헤더의 총 크기는 126976(10)입니다.


Subsystem

이 값을 통해 시스템 드라이버 파일인지, GUI인지 CUI인지 확인이 가능합니다.
아래의 코드는 winnt.h 헤더에 있는 SUBSYSTEM의 정의된 상수입니다.


// Subsystem Values

#define IMAGE_SUBSYSTEM_UNKNOWN              0   // Unknown subsystem.
#define IMAGE_SUBSYSTEM_NATIVE               1   // Image doesn't require a subsystem.
#define IMAGE_SUBSYSTEM_WINDOWS_GUI          2   // Image runs in the Windows GUI subsystem.
#define IMAGE_SUBSYSTEM_WINDOWS_CUI          3   // Image runs in the Windows character subsystem.
#define IMAGE_SUBSYSTEM_OS2_CUI              5   // image runs in the OS/2 character subsystem.
#define IMAGE_SUBSYSTEM_POSIX_CUI            7   // image runs in the Posix character subsystem.
#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS       8   // image is a native Win9x driver.
#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI       9   // Image runs in the Windows CE subsystem.
#define IMAGE_SUBSYSTEM_EFI_APPLICATION      10  //
#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER  11   //
#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER   12  //
#define IMAGE_SUBSYSTEM_EFI_ROM              13
#define IMAGE_SUBSYSTEM_XBOX                 14
#define IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION 16


직접 보게 되면.


위 사진에서는 Subsystem의 값이 0x0003으로 CUI 파일이라는 것을 알 수 있습니다.


NumberOfRvaAndSizes

마지막 필드인 DataDirectory 배열의 갯수를 가지고 있습니다.
PE 로더는 NumberOfRvaAndSizes의 값을 보고 배열의 크기를 인식합니다.


DataDirectory

IMAGE_DATA_DIRECTORY 구조체를 보면 Virtual Address와 Size라는 필드가 존재합니다.
아래의 코드는 winnt.h 헤더에 있는 DataDirectory의 정의된 상수입니다.


// Directory Entries

#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY        4   // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG           6   // Debug Directory
//      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7   // (X86 usage)
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7   // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS             9   // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT            12   // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   // COM Runtime descriptor


IMAGE_DATA_DIRECTORY 구조체의 Virtual Address를 통해 가상 주소를 알 수 있으며, Size를 통해 크기를 알 수 있습니다.

#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory

#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_TLS             9   // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_IAT            12   // Import Address Table

앗, 그렇다면 잠깐 IAT에 대해 알아보기 전에 IMAGE_SECTION_HEADER 먼저 알아보도록 하겠습니다.

이유는 IMAGE_IMPORT_DESCRIPTOR의 주소를 알아내기 위해서는 

RAW 비례식을 이용하여 RVA - IMAGE_SECTION_HEADER의 필드인 Virtual Address를 구하여야됩니다.


IMAGE_SECTION_HEADER

이 구조체는 섹션 테이블이라고도 불리며, 섹션에 대한 정보를 관리하는 구조체라고도 합니다.
이 구조체를 보고 ".text" 섹션, ".code" 섹션, ".rdata" 섹션 등의 대한 정보들을 알 수 있다는 겁니다.
아래의 코드는 winnt.h 헤더에 있는 IMAGE_SECTION_HEADER 구조체입니다.


#define IMAGE_SIZEOF_SHORT_NAME              8

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
            DWORD   PhysicalAddress;
            DWORD   VirtualSize;
    } Misc;
    DWORD   VirtualAddress;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;


위의 코드를 보면 필드는 총 11개가 있습니다.

이 중에 중요한 필드들만 간략하게 보도록 하겠습니다.


Name

필드 명 그대로 섹션의 이름을 나타냅니다.
#define IMAGE_SIZEOF_SHORT_NAME              8
이 상수의 값만큼 이름의 길이가 가능합니다.
말 그대로 최대 8byte까지 가능합니다.
이 필드는 NULL로 비워있을 수도 있으며, 8byte 모두가 차있을 수도 있습니다.

VirtualSize

PE 로더를 통해 PE 파일이 메모리에 로드되고 나서의 메모리에서 섹션이 차지하는 크기를 가지고 있습니다.

VirtualAddress

PE 로드를 통해 PE 파일이 메모리에 로드되고 나서의 해당하는 섹션의 RVA 값입니다.

SizeOfRawData

파일 상에서의 해당 섹션이 차지하는 크기를 가집니다.

PointerToRawData

파일 상에서의 해당 섹션이 시작하는 위치를 담고 있습니다.

Characteristics

섹션의 속성 정보를 플래그로 지닙니다.
아래는 winnt.h에 정의된 Characteristics 상수입니다.


//
// Section characteristics.
//
//      IMAGE_SCN_TYPE_REG                   0x00000000  // Reserved.
//      IMAGE_SCN_TYPE_DSECT                 0x00000001  // Reserved.
//      IMAGE_SCN_TYPE_NOLOAD                0x00000002  // Reserved.
//      IMAGE_SCN_TYPE_GROUP                 0x00000004  // Reserved.
#define IMAGE_SCN_TYPE_NO_PAD                0x00000008  // Reserved.
//      IMAGE_SCN_TYPE_COPY                  0x00000010  // Reserved.

#define IMAGE_SCN_CNT_CODE                   0x00000020  // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA       0x00000040  // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA     0x00000080  // Section contains uninitialized data.

#define IMAGE_SCN_LNK_OTHER                  0x00000100  // Reserved.
#define IMAGE_SCN_LNK_INFO                   0x00000200  // Section contains comments or some other type of information.
//      IMAGE_SCN_TYPE_OVER                  0x00000400  // Reserved.
#define IMAGE_SCN_LNK_REMOVE                 0x00000800  // Section contents will not become part of image.
#define IMAGE_SCN_LNK_COMDAT                 0x00001000  // Section contents comdat.
//                                           0x00002000  // Reserved.
//      IMAGE_SCN_MEM_PROTECTED - Obsolete   0x00004000
#define IMAGE_SCN_NO_DEFER_SPEC_EXC          0x00004000  // Reset speculative exceptions handling bits in the TLB entries for this section.
#define IMAGE_SCN_GPREL                      0x00008000  // Section content can be accessed relative to GP
#define IMAGE_SCN_MEM_FARDATA                0x00008000
//      IMAGE_SCN_MEM_SYSHEAP  - Obsolete    0x00010000
#define IMAGE_SCN_MEM_PURGEABLE              0x00020000
#define IMAGE_SCN_MEM_16BIT                  0x00020000
#define IMAGE_SCN_MEM_LOCKED                 0x00040000
#define IMAGE_SCN_MEM_PRELOAD                0x00080000

#define IMAGE_SCN_ALIGN_1BYTES               0x00100000  //
#define IMAGE_SCN_ALIGN_2BYTES               0x00200000  //
#define IMAGE_SCN_ALIGN_4BYTES               0x00300000  //
#define IMAGE_SCN_ALIGN_8BYTES               0x00400000  //
#define IMAGE_SCN_ALIGN_16BYTES              0x00500000  // Default alignment if no others are specified.
#define IMAGE_SCN_ALIGN_32BYTES              0x00600000  //
#define IMAGE_SCN_ALIGN_64BYTES              0x00700000  //
#define IMAGE_SCN_ALIGN_128BYTES             0x00800000  //
#define IMAGE_SCN_ALIGN_256BYTES             0x00900000  //
#define IMAGE_SCN_ALIGN_512BYTES             0x00A00000  //
#define IMAGE_SCN_ALIGN_1024BYTES            0x00B00000  //
#define IMAGE_SCN_ALIGN_2048BYTES            0x00C00000  //
#define IMAGE_SCN_ALIGN_4096BYTES            0x00D00000  //
#define IMAGE_SCN_ALIGN_8192BYTES            0x00E00000  //
// Unused                                    0x00F00000
#define IMAGE_SCN_ALIGN_MASK                 0x00F00000

#define IMAGE_SCN_LNK_NRELOC_OVFL            0x01000000  // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE            0x02000000  // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED             0x04000000  // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED              0x08000000  // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED                 0x10000000  // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE                0x20000000  // Section is executable.
#define IMAGE_SCN_MEM_READ                   0x40000000  // Section is readable.
#define IMAGE_SCN_MEM_WRITE                  0x80000000  // Section is writeable.


그렇다면 이제 IAT를 ... !


IAT (Import Address Table)

PE 헤더의 최대의 벽은 IAT(Import Address Table)이라고 생각합니다.


두둥!!!


이 IAT는 윈도우 운영체제의 핵심 개념인 프로세스, 메모리, DLL 구조 등에 대한 내용이 함축되어있습니다.

고로 DLL(Dynamic Linked Library)에 대한 지식이 필요합니다.

쉽게 IAT에 말하자면 어떤 라이브러리에서 어떠한 함수를 사용하고 있는지를 기술한 테이블입니다.

[ 말 출처 : 리버싱 핵심 원리 ]

그렇다면 DLL에 대해 먼저 알아보도록 하겠습니다.


DLL (Dynamic Linked Library)

IAT를 알려면 DLL 개념을 짚고 가야됩니다.

동적 링크 라이브러리(영어: dynamic-link library, DLL)는 마이크로소프트 윈도우에서 구현된 동적 라이브러리이다. 
내부에는 다른 프로그램이 불러서 쓸 수 있는 다양한 함수들을 가지고 있는데, 확장DLL인 경우는 클래스를 가지고 있기도 한다. 
DLL은 COM을 담는 그릇의 역할도 한다.

사용하는 방법에는 두 가지가 있는데,

묵시적 링킹(Implicit linking) 

실행 파일 자체에 어떤 DLL의 어떤 함수를 사용하겠다는 정보를 포함시키고 운영체제가 프로그램 실행 시 해당 함수들을 초기화한 후 그것을 이용하는 방법

명시적 링킹(Explicit linking) 

프로그램이 실행 중일 때 API를 이용하여 DLL 파일이 있는지 검사하고 동적으로 원하는 함수만 불러와서 쓰는 방법이 있다.
전자의 경우는 컴파일러가 자동으로 해주는 경우가 많으며, 후자의 경우는 사용하고자 하는 DLL이나 함수가 실행 환경에 있을지 없을지 잘 모르는 경우에 사용된다. (때때로 메모리 절약을 위해 쓰이기도 한다.)

[ 출처 : https://ko.wikipedia.org/wiki/%EB%8F%99%EC%A0%81_%EB%A7%81%ED%81%AC_%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC ]



여기서 IAT는 묵시적 링킹에 대한 매카니즘을 제공하는 역할을 합니다.

아! DLL은 넘어가고!!


Hell o IAT


어서와~!


이 IAT 설명에서 사용할 코드는 아래와 같습니다.



#include <stdio.h>

#include <Windows.h>


int main(int argc, char *argv[])

{

HWND hWnd = FindWindow(NULL, TEXT("Untitled - Notepad"));


if (hWnd) {

printf("있음\n");

}

else

{

printf("없음\n");

}


return 0;

}

 


그렇다면 이제 진짜 확인을 위해 올리디버거로 프로그램을 열어보겠습니다.



0x011A17C7 번지를 보면 FindWindowA를 직접 호출하는 것이 아니라



0x011AA098 번지에 있는 0x7787FFE6값을 가져와 호출을 하는 간접적인 호출 방식이라는 것을 볼 수 있습니다.

(모든 API 호출은 이런 방식으로 되어있습니다.)


0x011AA98 번지는 이 프로그램의 ".text" 섹션 메모리 영역입니다.

0x011AA98 번지의 값은 0x7787FFE6이라는 것을 위에서 볼 수 있었으며,

0x7787FFE6 주소는 바로 이 프로그램의 프로세스 메모리에 로딩된 user32.dll 내에 있는 FindWindowA 함수 주소입니다.


그렇다면 여기서 의문점이 하나가 생기게 됩니다.

엥 이거 완전 바로 0x7787FFE6를 Call하면 좋지 않냐~?!


이 방법은 DOS 시대의 방법이였습니다.

이 프로그램이 생성되는 순간에 이 프로그램이 어떤 윈도우 환경에 실행되는지 알 수가 없으며,

이런 환경에 따라 kernel32.dll, user32.dll 등의 버전이 틀려지게 되고,

FindWindowA함수의 주소가 달라지게 됩니다.


그렇기 때문에 어떠한 환경에서도 FindWindowA 함수의 호출을 보장하기 위해 

컴파일러가 0x011AA98 번지에 미리 공간을 마련해두고 파일이 실행이 된 직후에 PE 로더가 이 공간에 FindWindowA의 주소를 넣어주게 됩니다.

이러한 DLL 내의 함수 주소를 모아놓은 테이블을 만들어놓고 코드 섹션에서 만들어 놓은 테이블을 쓰는 방식으로 관리를 하여 이 테이블을 IAT라고 합니다.


이정도만 알아두면 IAT는 절반은 알았다! 라고 할 수 있을 것 같습니다.


아! PE 파일은 자신이 어떤 라이브러리를 import하고 있는 지 어떠한 구조체에 명시하고 있습니다.

이 아래에서는 그 구조체에 대해 알아보도록 하겠습니다!


IMAGE_IMPORT_DESCRIPTOR

아래의 코드는 winnt.h 헤더에 있는 IMAGE_IMPORT_DESCRIPTOR의 구조체입니다.


typedef struct _IMAGE_IMPORT_BY_NAME {
    WORD    Hint;
    BYTE    Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    union {
        DWORD   Characteristics;            // 0 for terminating null import descriptor
        DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
    } DUMMYUNIONNAME;
    DWORD   TimeDateStamp;                  // 0 if not bound,
                                            // -1 if bound, and real date\time stamp
                                            //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                            // O.W. date/time stamp of DLL bound to (Old BIND)

    DWORD   ForwarderChain;                 // -1 if no forwarders
    DWORD   Name;
    DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;


이 구조체는 6개의 필드 중 중요한 3개의 필드만 보도록 하겠습니다.


앗, 먼저 필드를 보기 전에 IMAGE_IMPORT_DESCRIPTOR의 위치를 찾아야됩니다.

위에서 IMAGE_OPTIONAL_HEADER의 DataDirectory가 기억나시나요?


어이쿠 안나신다고요??!

올리기 귀찮으실테니 이미지를 첨부해드리겠습니다!

(저는 압니다... 올리다가 다 까먹으실 것을요!)



2번째 요소가 Import Directory을 볼 수 있습니다.



초랭이 : VirtualAddress(RVA)

주랭이 : VirtualSize


VirtualAddress(RVA) : 0x0001A000

VirtualSize : 0x000001B4


나머지 Virtual Address를 구하려면 현재 RVA가 어디 섹션에 해당하는지를 알아야됩니다.



위에서 알려드린 IMAGE_SECTION_HEADER 기억나시죠?

앗... RVA가 이 섹션에 숨어있었습니다!



핫핑꾸 색깔로 표시해두었습니다.

위와 같이 0x0001A000이 실제적으로 ".idata" 섹션에 위치하는 옵셋이 됩니다.


".idata" 섹션의 이름은 0x6164692E 이며,

VirtualSize : 0x00000A6A

RVA : 0x0001A000

Size of Raw Data : 0x00000C00

Pointer to Raw Data : 0x00007600


앗, Raw 옵셋을 찾았습니다.



위의 영역이 모두 IMAGE_IMPORT_DESCRIPTOR 구조체 배열이며, 

이 영역 처음부터 20byte까지는 구조체 배열의 첫번째 요소입니다.


DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)

를 알아보기 전에 IMAGE_THUNK_DATA라는 구조체를 보도록 하겠습니다.


IMAGE_THUNK_DATA

아래는 winnt.h 헤더파일의 IMAGE_THUNK_DATA 구조체입니다.



typedef struct _IMAGE_THUNK_DATA64 {

    union {

        ULONGLONG ForwarderString;  // PBYTE 

        ULONGLONG Function;         // PDWORD

        ULONGLONG Ordinal;

        ULONGLONG AddressOfData;    // PIMAGE_IMPORT_BY_NAME

    } u1;

} IMAGE_THUNK_DATA64;

typedef IMAGE_THUNK_DATA64 * PIMAGE_THUNK_DATA64;


#include "poppack.h"                        // Back to 4 byte packing


typedef struct _IMAGE_THUNK_DATA32 {

    union {

        DWORD ForwarderString;      // PBYTE 

        DWORD Function;             // PDWORD

        DWORD Ordinal;

        DWORD AddressOfData;        // PIMAGE_IMPORT_BY_NAME

    } u1;

} IMAGE_THUNK_DATA32;

typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;



IMAGE_THUNK_DATA 필드는 총 4개로 모두 공용체의 멤버이며, 4바이트 공간을 4개의 필드가 공유합니다.


이 이상은 제 지식이 딸려서 적을 수가 없네요 :'(

덕분에 작성하면서 깨달음을 많이 얻었습니다!

생각정리하는데는 글 쓰기가 꿀이네요.

'0x20 Security > 0x22 Reversing' 카테고리의 다른 글

UPX Pakking Principle (UPP)  (1) 2017.07.07

https://github.com/Mila432/Pokemon_Go_API


먼저 Pokemon Go API를 받습니다.


$ git clone https://github.com/Mila432/Pokemon_Go_API


 그 다음 아래와 같은 명령어로 설치를 해주면 됩니다.


$ pip install -r ./requirements.txt


요로코롬하면 준비는 다 끝났습니다.


사용 방법은 간단합니다.



$ python main.py -u test@gmail.com -p Password1004 -t (Google/PTC) -l "Gangwon-do Sokcho-si Cheongbong-ro 3-gil 37, 24904"


이런식으로 넘겨주면 실행이 되게 됩니다.

-t 에 넘겨주는 것은 이 계정이 포케몬 고 트레이너 클럽 계정이라면 PTC를 넘겨주고 구글 계정이라면 Google로 넘겨주면 됩니다.



이렇게 실행이 됩니다.


정확히 사용해본 결과

아마도 이건 그냥 포켓몬 고 Bot을 만드는 데에 사용되는 것 같습니다.

이 코드를 이용하면 그 특정 위치에 포켓몬들이 몇마리 있는지도 만들 수 있을 것 같아서


이번의 프로젝트는 포켓몬 고로 정할까 하고 생각중입니다.


[+] 추가



이런 메일이 날라 올 수 있습니다.

아, 녹화할 일이 생겨서 녹화 프로그램을 찾는 중


처음엔 반디캠을 사용했었다.

하지만 반디캠은 10분 제한에 워터마크까지 박아버리는게 마음에 안들었다.


그래서 오캠을 사용했었다.

하지만 오캠도 점차 광고를 너무 과하게 집어넣기 시작해서 새로운 것을 찾아다니기 시작했는데!


AireCam이라는 녀석을 발견하게 됬다.


https://www.airelive.com/main/home


주소 적어놓겠습니다.



UI도 심플해서 사용하기 매우 편하다.

게다가 10분제한? 워터마크? 그런것도 없다.


아주 좋다.

'0x01 Etc. > 0x05 Review' 카테고리의 다른 글

[Utils] Whale Browser  (0) 2016.12.02
[Utils] Vivaldi Browser  (0) 2016.08.12
[Game] Life Is Strange 리뷰  (839) 2016.07.22
[Game] Portal2 리뷰  (0) 2016.07.18
[Game] Youtubers Life 리뷰  (155) 2016.07.18

https://steamdb.info/app/319630/


왜 인지 모르겠지만.



무료로 배포를 하고 있더라.

그래서 게임을 플레이를 해보았는데.


시간을 앞으로 돌리고 뒤로 돌리고 시간을 후루룹챱챱 돌려먹는 게임이였다.


현재 에피소드1을 하는 중이라 현재로서는 그저 실종된 친구의 단서를 찾아다니는 중인데.


초반에 시간할 때 

숲에서 깨고 학교 사진에도 찍혀있고.

숲에 지도에 해골모양이 있는 걸 보아서는 그 해골 모양이 있는 부분이 살인자? 같은게 있는게 아닐까 하고 생각해본다.


한글패치는 이리저리 찾아다니다가 이 블로그에서 발견하였다.


Life Is Strange 한글패치 : http://blog.naver.com/kibme0325/220624344482


혹시 몰라 나중에 이 블로거님이 파일을 삭제할 수도 있어서 블로그에 올려놔야겠다.


LifeisStrange통합.vol1.egg

LifeisStrange통합.vol2.egg


 신난다!

'0x01 Etc. > 0x05 Review' 카테고리의 다른 글

[Utils] Whale Browser  (0) 2016.12.02
[Utils] Vivaldi Browser  (0) 2016.08.12
[Utils] AireCam  (0) 2016.07.22
[Game] Portal2 리뷰  (0) 2016.07.18
[Game] Youtubers Life 리뷰  (155) 2016.07.18

+ Recent posts