1. Overview


 

원격 서버의 소스를 편리하게 작업할 수 있는 VScode "Remote VScode"를 통해 작업할 경우 원격 서버의 코드 파일이 로컬 드라이브에 저장된다.

 

 

 

2. Body


 

코드가 저장되는 경로는 다음과 같다.

C:\Users\[UserName]\AppData\Local\Temp\[랜덤명]\[remote_server_path]

 

[그림 1] 저장된 소스파일

 

 

3. Conclusion


 

당연한 사항이지만 사용자 입장에서 코드가 저장되는 사실을 인지해야하고 저장되는 경로를 파악하고 있어야 한다고 생각한다.

 

 

'개발 > Setting' 카테고리의 다른 글

VScode remote development environment settings (with rmate)  (0) 2019.04.24

1. Overview


 

VScode를 활용하면 원격 서버의 환경을 그대로 활용하여 로컬환경에서 개발할 수 있다.

본 게시글은 VScode를 활용하여 rmate를 세팅하는 방법에 대해 기록하였다. 기본적인 세팅은 References의 블로그를 참고하였다[1][2].

 

 

2. Body


 

세팅에 필요한 순서는 다음과 같다.

  1. VScode 환경 세팅 (로컬)
    • "Remote VScode" 확장 프로그램
    • "Remote.Onestartup" : True 세팅
  2. Rmate 설치 (서버)
  3. Trouble Shoothing (번외)

 

 

2.1 VScode 환경세팅

Vscode의 Extensions 탭에서 "Remote VScode"를 검색하여 설치한다. (Windows Shortcut : Ctrl + Shift + X)

[그림 1] "Remote VScode" 확장 프로그램 설치

 

설치가 완료된 후 VScode의 설정을 수정한다. (Windows Shortcut : Ctrl + ,)

(File -> Preferences -> Settings)

설정 화면 호출 후 "Remote" 검색하여 "Remote:Onestartup" 하단 메뉴를 체크한다.

[그림 2] "Remote:Onestartup" 세팅

 

 

 

2.2 Rmate 설치

서버에서의 Rmate 설치는 References에 기록한 블로그의 명령어를 활용하였다.
입력한 명령어는 다음과 같다.

$wget https://raw.githubusercontent.com/sclukey/rmate-python/master/bin/rmate
...
$chmod +x ./rmate
$mv ./rmate /usr/local/bin/rmate

 

 

 

2.3 접속

접속은 로컬 환경에서의 PowerShell을 통해 명령어를 입력하여 쉽게 접속할 수 있다.

접속에 필요한 명령은 다음과 같다. ssh 포트를 변경했을 경우 "-p" 이후의 명령을 입력하면 된다.
ssh -R 52698:127.0.0.1:52698 [Remote_Server_User]@[Remote_Server_Address] -p [Port num]

 

ssh 접속이 완료된 상태에서 작업할 파일명을 아래의 명령어 형식에 맞게 입력한다.
rmate -p 52698 [/경로/파일명.py]

 

 

 

3. Trouble Shoothing


간단한 과정이지만 중간중간 문제가 발생한 사항은 다음과 같다.

 

  1. Couldn't connect to TextMate!
  2. Exception: Could not connect to textmate : Connection refused

 

 

3.1 Couldn't connect to TextMate!

해당 문제는 한 로컬에서 ssh 를 2개 이상 접속하고 rmate 명령어를 작성했을 때 출력되는 에러이다. 해당 문제는 호출 되어 있는 여러개의 ssh를 하나만 남겨놓고 종료하고 다음 과정을 수행하면 해결할 수 있다.

 

 

Vscode에서 F1을 누른 후 Remote:Stop Server를 통해 서버를 정지하고 Remote:Start Server 를 통해 재실행한다.

[그림 3] "Couldn't connect to TextMate!" 문제 해결[3]

 

 

 

3.2 Exception: Could not connect to textmate : Connection refused

해당 문제는 로컬에서 ssh 접속 과정에서 "127.0.0.1"을 "localhost"로 입력하였을 때 발생한다. 해결 방법은 단순히 "127.0.0.1" 을 사용하면 된다.

[그림 4] "Exception: Could not connect to textmate : Connection refused" 문제 해결[4]

 

 

4. Conclusion


본 게시글에서는 VScode를 통해 원격 개발 환경을 세팅하는 과정을 기록하였다.

이를 통해 VScode를 에디터로 사용하는 사용자들에게 편리함을 줄 수 있을 것으로 기대한다.

 

 

 

5. References


[1] https://thrillfighter.tistory.com/458

[2] https://mj-youn.github.io/2018/10/12/VSCode-Remote-File-edit/

[3] "Couldn't connect to TextMate!", https://github.com/sclukey/rmate-python/issues/2

[4] "When attempting to open files via rmate file never opens", https://github.com/rafaelmaiolla/remote-vscode/issues/55

'개발 > Setting' 카테고리의 다른 글

VScode rmate 작업시 Temp 파일 저장 확인  (0) 2019.04.25

1. Overview



Python을 사용하여 'HWP Parser' 제작중 BinData의 내부 Stream에 대해 Decompress를 수행하던 도중 발생한 Trouble에 대해 서술한다.


2. Structure



HWP File Format에 관련하여 한컴 오피스는 홈페이지를 통해 공식 문서를 제공한다.


그 중 BinData 스토리지에는 그림이나 OLE 개체와 같이 문서에 첨부된 바이너리 데이터가 각각의 스트림으로 저장된다.


Parser 제작 과정에서 해당 한글 문서 파일의 악성 유무 판별을 위해 Decompress를 수행해야 했다.


[그림 1] BinData Area



Decompress에는 Python zlib을 활용하였다. 보편적인 zlib의 Decompress 구문은 다음과 같은 에러를 출력했다.


zlib.error: Error -3 while decompressing data: incorrect header check


[그림 2] 에러 확인


3. Trouble Shooting



문제해결을 위해 검색 도중 다음과 같은 글을 확인할 수 있었다.


글에 따르면 메모리에 저장할 수 있는 크기를 초과하는 Stream (또는 파일 입력) 크기 문제로 인해 위의 에러가 발생했을 것이라고 한다. 실제 메모리 크기를 초과한 것이 아닌 버퍼 기본 크기를 초과했기 때문이다.


이를 해결하기 위한 방법은 Stream을 버퍼링으로 처리하고 Decompress를 수행하는 방법이 존재한다. 함께 제공된 솔루션 소스코드는 다음과 같다[1].

 
import zlib
f_in = open('my_data.zz', 'rb')
comp_data = f_in.read()
zobj = zlib.decompressojb()  # obj for decompressing data streams that won’t fit into memory at once.
data = zobj.decompress(comp_data)


위의 방법과 같이 버퍼링을 적용하고 테스트를 진행했을 때 또 다시 동일한 에러가 뜨는 것을 확인했다.


조금 더 찾아보던 도중 다음과 같은 글을 찾을 수 있었다.


[그림 3] wbit 관련 솔루션[2]



위 글에서는 wbit 옵션을 -15로 정의하면 에러가 해결된다고 제시했다. zlib 모듈 공식 홈페이지에서 제공하는 문서에 따르면 WBITS의 의미는 다음과 같다.


[표 1] MAX_WBITS의 의미[3]

The wbits argument controls the size of the history buffer (or the “window size”) used when compressing data, and whether a header and trailer is included in the output. It can take several ranges of values, defaulting to 15 (MAX_WBITS):

  • +9 to +15: The base-two logarithm of the window size, which therefore ranges between 512 and 32768. Larger values produce better compression at the expense of greater memory usage. The resulting output will include a zlib-specific header and trailer.
  • −9 to −15: Uses the absolute value of wbits as the window size logarithm, while producing a raw output stream with no header or trailing checksum.
  • +25 to +31 = 16 + (9 to 15): Uses the low 4 bits of the value as the window size logarithm, while including a basic gzip header and trailing checksum in the output.


MAX_WBIS 값은 15를 가지며 이를 -로 선언하면 -15 값으로 정의되기 때문에 에러를 해결할 수 있다.


이를 적용한 소스코드는 다음과 같다.


 
def bin_data(ole,bin_list):
    print ()
    print ('[+] BinData Information')
    for content in bin_list:
        if content[0] == 'BinData':
            print ('   - File Name : %s' %content[0]+'/'+content[1])
            bin_text = ole.openstream(content[0]+'/'+content[1])
            print ('   - File Size : %s' %ole.get_size(content[0]+'/'+content[1]))
            data2 = bin_text.read()
            print ('   - Hex data ~20bytes(pre-Decompress) : %s' %data2[:20])
            zobj = zlib.decompressobj(-zlib.MAX_WBITS)
            data3 = zobj.decompress(data2)
            print ('   - Hex data ~20bytes(Decompress) : %s' %data3[:20])
            f = open('./'+content[1]+'_Decom.txt','wb')
            f.write(data3)
            f.close
            print ()


결과는 다음과 같다.



[그림 4] 정상적으로 Decompress 완료된 Stream



4. References



[1] https://stackoverflow.com/questions/32367005/zlib-error-error-5-while-decompressing-data-incomplete-or-truncated-stream-in?rq=1


[2] https://daehee87.tistory.com/m/508?category=404227


[3] https://docs.python.org/3/library/zlib.html

포스팅을 시작하기전에 사용한 툴은 다음과 같다.


  1. 파이썬2

  2. XAMPP (Maria DB)

  3. HeidiSQL (DB GUI)



1. 개요



해당 포스팅에는 시나리오가 있다. 악성코드 분석 중 대용량의 자료유출 흔적이 발견되어 대용량의 방화벽 로그를 확보하였다. 해당 로그를 보고 자료유출 흔적을 찾고 공격자의 위치를 찾아내는 것이다.




2. 분석



직접 수집한 데이터가 아니기 때문에 데이터에 대한 많은 정보를 공개할 수는 없다.



▶ 초기 데이터 분석

초기 데이터는 113GB의 텍스트 파일이다.

내부 내용은 [날짜 및 시간], [ID], [severity], [sys], [sub], [name], [action], [fwrule], [src_mac], [dst_mac], [src_ip], [dst_ip], [length], [srcport], [dstport] 로 이루어져있다.  이 로그를 생으로 분석하기에는 불필요한 정보가 너무 많다. 필요 / 불필요를 나누는 기준은 위의 개요에서 언급했듯 목적에 맞춰서 기준을 선정할 것이다.


데이터는 [날짜 및 시간], [src_mac], [dst_mac], [src_ip], [dst_ip], [length], [srcport], [dstport] 를 파싱하여 최적화할 것이다. 우리의 목적은 DB에도 연동하는 것이기 때문에 각 필드 값 또한 최적화를 수행해야 한다.




▶파싱 소스 작성

파싱을 위한 파이썬 소스는 Git에 올려둔 링크로 대신하겠다.
https://github.com/swpose/sw_python2/blob/master/firewall_git.py

코딩 실력이 많이 부족하여 속도는 고려하지 않고 작성하였다. 이후 추가적인 최적화를 위해 수정해보도록 하겠다.



3. DB 연동



DB 연동은 XAMPP를 이용하여 서버를 생성하였다.

해당 도구는 우리가 흔히 사용하는 서버를 쉽게 사용할 수 있도록 해준다. 나는 MySQL을 사용하였다.




HeidiSQL 도구는 데이터를 조회할 때 쿼리가 아닌 GUI로 편리하게 볼 수 있도록 해주는 도구이다. DB를 많이 다뤄보지 않은 사람이나 초심자들이 사용하면서 감을 잡기에는 좋을 것 같다.



위의 두개의 도구는 일반 설치함에 있어서도 별도의 어려움이 존재하지 않기에 설치방안에 대해서는 언급하지 않겠다.

위의 두개의 도구를 활용하면 간단한 쿼리문만으로도 DB를 조회할 수 있다.
우리가 원하는 데이터는 대량유출에 대한 증거를 찾는 것이다.
결과부터 말하면 위의 length의 역순으로 정렬하여 큰 용량을 찾으면 될 것이다. 이를 위해 사용한 쿼리문은 다음과 같다.


DBname = f_log / Table name = firewall 

  1. mysql –uroot;
  2. use f_log;
  3. LOAD DATA LOCAL INFILE "C:/log_output.csv" INTO TABLE f_log.firewall FIELDS TERMINATED BY ",";
  4. select count(*) from firewall;
  5. select * from firewall order by ID desc limit 50;



데이터 연동 중 데이터를 조회하였다. 대충 저런식으로 DB에 연동된다.

4. 결론



초대량의 데이터에서 원하는 정보를 파싱하여 DB에 연동함으로써 원하는 정보를 빠르고 정확하게 찾을 수 있고 침해 사고의 대응하는데 도움이 될 수 있을 것이라는 생각을 하였다.



'개발 > Python' 카테고리의 다른 글

zlib Decompress issue  (0) 2019.02.12
BeautifulSoup vs Scrapy  (0) 2019.01.06
크롤링(Crawling)이란? 또는 파싱(Parsing)이란? 스크래핑이란?  (0) 2019.01.06

* BeautifulSoup

1. html문서에서 원하는 정보를 손쉽게 가져올 수 있는 방법을 제공

2. 자동으로 인코딩을 유니코드로 변환해서 UTF-8로 출력

3. lxml, html5lib 파서를 이용함


* Scrapy

1. web scraper framework

2. 다양한 selector 지원

3. 파이프 라인

4. 로깅

5. 이메일


(혼자 공부하며 참고하기 위해 본문 내용을 그대로 가져왔습니다. 문제시 삭제 조치 하겠습니다.)


크롤링(Craling)이란?

크롤링은 웹 크롤러(web crawling)에서 출발한 말로 무수히 많은 인터넷 상의 페이지(문서, html 등)를 수집해서 분류하고 저장한 후에 나중에 쉽게 찾아볼 수 있도록 하는 역할을 하는 일종의 로봇이다.


그래서 크롤링은 데이터를 수집하고 분류하는걸 크롤링이라고 한다.


다이아몬드 광산에 예를 들면 2만평짜리 광산이 있는데 이 중에 다이아몬드가 주로 나오는 곳이 입구에서 직진해서 200미터 떨어진 부분과, 입구에서 오른쪽으로 꺾어서 400미터 떨어진 부분이라는 이런 정보가 어디에 있는지에 대한 위치를 분류하는 것이라고 보면 된다.


파싱(Parsing)이란?


파싱(Parsing)은 어떤 페이지(문서, html 등)에서 내가 원하는 데이터를 특정 패턴이나 순서로 추출하여 정보로 가공하는 것을 말하는 것이다. 다이아몬드가 많이 나오는 위치로 이동을 일단 한 후에 돌을 많이 캔다음에 다이아몬드만 쏙쏙 뽑아서 보석으로 가공하는 과정하고 비슷하다고 보면 된다.


스크래핑(Scraping) 이란?

데이터를 수집하는 모든 작업을 말한다.



'데이터분석'에 대한 이야기가 많이 나오면서 크롤링, 파싱에 대해 궁금해 하는 사람들이 많이 있고 나도 크롤러, 파서, 스크래퍼를 주로 개발 하다보니 미묘한 차이가 궁금해서 한번 찾아보았다.


요즘은 그냥 인터넷에서 프로그램으로 데이터를 추출해서 사용하는 작업을 크롤링, 파싱 등으로 혼용해서 쓰는 것 같다. 경계가 모호한 말이기도 하고 크롤러를 만들다 보면 파싱 기능이 들어가고 파서를 만들려면 크롤링 하는 기능이 일부 들어가기도 하는 등의 일도 많기 때문.



출처

[1] https://en.wikipedia.org/wiki/Web_crawler#Nomenclature
[2] https://en.wikipedia.org/wiki/Parsing

'개발 > Python' 카테고리의 다른 글

zlib Decompress issue  (0) 2019.02.12
방화벽 로그파일 파싱 및 DB 연동  (0) 2019.01.06
BeautifulSoup vs Scrapy  (0) 2019.01.06

+ Recent posts