2013/07/30

Volatility Linux Profile - CentOS


작년 9월에 Volatility에서 사용할 리눅스 프로파일을 만드는 방법에 대해서 포스팅한 후 한참을 삽질만 하다가
귀찮아서 관둘까 하는 찰나에 Volatility에서 조만간 리눅스용 프로파일을 만들어서 공개하겠다...라고 해서 기대하고 있었는데
국내 환경에서 가장 많이 사용되는 CentOS는 6.3버전의 64비트 버전 꼴랑 하나만 있더군요..
국내 환경은 CentOS 5.8이 제일 많은데 말이죠..
그들이 만들지 않은 이유가 있지 않을까 생각되면서도 언제까지 기다리고만 있을 순 없어서
삽질의 삽질의 닭질을 거듭 반복한 결과 CentOS 5.7 ~ 6.3까지 프로파일을 만들었습니다. ;-)

프로파일 만드는 방법은 여기를 참조하시면 되고
프로파일을 만들기 위해 필요한 필수 패키지는 다음과 같습니다.

kernel-devel
kernel-headers
elfutils
elfutils-devel

커널 패키지는 현재 설치된 커널과 동일한 패키지를 설치하셔야 하며 여기서 검색해서 사용하시면 됩니다. 배포판이 다르더라도 버전만 맞으면 됩니다.



CentOS는 yum으로 업그레이드를 하면 각각 마지막 배포판 버전(5.9, 6.3)으로 업그레이드 됩니다.
만약 분석할 메모리의 커널 버전이 만들어둔 프로파일의 커널 버전과 일치하지 않을 경우 새롭게 만들어주셔야 합니다.

프로파일은 module.dwarf 파일과 System.map 파일이 필요합니다.
System.map 파일은 조사 대상 서버에서 추출해서 사용하면 되고
module.dwarf 파일은 조사 대상 서버에서 컴파일해서 사용하는게 가장 정확하겠지만
패치버전(2.6.18)까지만 맞으면 정상적으로 동작했었습니다. (RHEL에서 테스트)

위 목록 중 RHEL5의 경우 디폴트는 2.6.18-8.el5 버전이었고 조사 대상은 2.6.18-164.el5PAE 버전이었는데
조사 대상 서버에서는 System.map 파일만 추출해서 가져오고 module.dwarf는 vmware에 설치한 RHEL5에서 컴파일해서 사용했습니다.
즉, 프로파일을 만들기를 원하는 운영체제와 커널 버전이 있다면 직접 설치해서 module.dwarf 파일을 만들어서 가지고 있으면 됩니다.
각각의 패치버전에 대한 프로파일까지 만들고 싶었지만 yum으로 업데이트하면 가장 최신으로만 업데이트가 되기 때문에
중간중간에 있었던 커널 버전에 대한 프로파일을 만들려면.......(상상이 가시나요? ㅜ.ㅜ)

리눅스 서버의 경우 커널 업데이트를 잘 하지 않기 때문에
각 배포판별로 디폴트 커널에 대한 프로파일만 가지고 있어도 무난할 것으로 보입니다.


프로파일은 계속해서 필요할 때마다 만들어 나갈 예정입니다.

Volatility Linux Profile Download by demantos


프로파일 사용에 있어서 문제가 있으시면 언제든지 demantos@gmail.com 으로 메일 보내주시면 감사하겠습니다~!!



2013/06/25

Dadong’s JSXX 0.44 VIP DeObfuscation Code


공다팩이나 다동이나 Gondad에 대한 용어는 다들 잘 아실꺼라 생각하고 생략하겠습니다.

올해 코드게이트에서도 툴 시연이 있었고 발표자료도 공개되어 있습니다.

그리고 dadong으로 난독화되어 있는 코드에 대한 분석글들은 인터넷에 있으니 찾아보시고 참고하시면 되겠습니다.

그나마 지금까지 보아 왔던 분석글들은 중간중간 특정 내용에 대한 설명이 빠져 있어서 이해하는데 좀 애매하게 되어 있었는데요

Kwang Guevara님 블로그 보니 설명이 잘되어 있었습니다.

매번 난독화된 코드와 난독화 해제하는 함수, 키값을 찾아서 수정해주고 브라우저에 여러서 확인하는게 귀찮아서 파이썬으로 작성해보았습니다.



코드가 허접해도 참아주시기 바랍니다. ;-)


#-*- coding: cp949 -*-

import sys
import re
from struct import *

key = ""
res_filename = ""
obfCode = ""
deobFunc = ""

def splitObfCode() :
 global obfCode
 global deobFunc
 global key
 
 obfList = []
 print "[+] Extracing obfuscated code..."
 with open(sys.argv[1], 'r') as ef:
  for x in ef.readlines():
   if re.search("eval.+?unescape.+?[=](\'\")?[0-9A-Fa-f]", x):
    for s in range(len(x.split("\""))):
     obfList.append(x.split("\"")[s])
 print "[+] Extracting deobfuscate function and find divide key"
 for x in range(len(obfList)):
  if len(obfList[x]) >= 5000:
   obfCode = obfList[x]
  elif len(obfList[x]) >= 1000 and len(obfList[x]) <= 2000:
   deobFunc = obfList[x].replace('\\/', '/').replace('\\\\', '\\')
   buf = deobFunc.split(";")
   for s in range(len(buf)):
    if "%=" in buf[s]:
     key = int(buf[s].split("=")[1])
  else:
   pass

def letsgo(code, func, divkey) :
 a = ""
 b = 0
 c = 0
 d = ""
 
 print "[+] Deobfuscate..."
 for i in range(0,2):
  for t in range(len(func)):
   c = ((c&127)<<25) | ((c&4294967168)>>7) + ord(func[t])
   c = unpack("l", pack("L", c))[0]
  a+="1"

 if c < 0:
  c = c & 0xffffffff
 
 qq = 1
 for t in range(0, len(code), 2):
  if t >= 8: # (1<<3)
   a = t % 8
  else:
   a = t
  b = int(hex(c)[a+2:a+4], 16)+qq
  qq+=1
  
  if re.match('^(\d{4})', str(b+744)):
   b = b % divkey
  d += chr((int((obfCode[t] + obfCode[t+1]), 16))^b)
 
 rf = open("%s" % res_filename, "w")
 rf.write(d)
 rf.close()

def main() :
 global res_filename
 if len(sys.argv) >= 2:
  splitObfCode()
  res_filename = sys.argv[1].split('.')[0]+"_decode.txt"
  letsgo(obfCode, deobFunc, key)
 else:
  print "Usage: %s dadong_obfuscated_filename" % sys.argv[0]

if __name__ == "__main__" :
 main()




2013/03/07

Codegate Forensic 500 문제를 풀기 위해 알아두어야 할 개념


지난주에 Codegate Prequal이 있었는데요..
Forensic 500번 문제가 VBR과 MFT Entry 정보를 통해 이미지 파일을 복구하는 문제였습니다.
어설픈 지식으로 인해 문제를 풀지는 못하였지만 이제라도 알게 되었으니 다행이라 생각되며
잊어버리지 않기 위해 기록해두었습니다.

아래 이미지가 복구해야하는 문제의 그 이미지입니다.


전체적으로 잘 서술된 내용은 링크를 걸어두겠습니다.

Codegate 2013 Forensic 500 by Deok9

그림으로 그려봤습니다. ( 그림으로 그려야 이해가 잘되는 1人입니다. ;-) )



문제의 핵심은 속성의 내용이 너무 커서 MFT Entry에 다 포함시키지 못할 경우 추가적인 클러스터를 할당 받아 저장하는 방식인 Non-resident 속성에 대해서 알고 있냐 없냐 였습니다.
마지막 부분에 있는 22 3D 02 B7 06 22 DF 00 F3 28 22 78 01 56 E4 이 여러 군데 흩어져 있는 파일의 내용에 대한 길이와 오프셋을 나타내고 있습니다. (Cluster Runs 또는 Data Runs)

foremost와 같은 툴을 이용해서 카빙을 하면 첫번째 런리스트에 있는 내용만 카빙이 되어 정상적인 이미지가 보이지 않으며 결국 이 분할된 데이터들을 합쳐서 정상적인 파일을 만드는 것이 문제의 목적이었습니다.

Cluster Runs(Data Runs)에 대한 개념은 아래 링크에서 확인해보시면 잘 이해가 가실겁니다.
(thanks Deok9)

http://www.reddragonfly.org/ntfs/concepts/data_runs.html


추가적으로 참고할 사이트들입니다.

http://www.pc-3000flash.com/eng/help/help_information/ntfs/data_runs.htm
http://www.writeblocked.org/resources/NTFS_CHEAT_SHEETS.pdf


굳이 CTF를 위한 지식이 아닌 포렌식 조사 과정에서 결정적인 증거자료가 될 수 있는 파일들이 분할되어 있을 경우 런리스트에 대한 개념이 잡혀 있다면 파일을 정상적으로 복구해낼 수 있을 것입니다.



2013/01/16

Java Applet JMX 0day Remote Code Execution 취약점(CVE-2013-0422) 분석보고서



2013년도 Impact 강한 취약점으로 시작하였습니다.

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0422


늦은감이 있지만 작성한 분석보고서 공유합니다. (with hyoub9un)

https://docs.google.com/file/d/0BwzSDSFKiUkiai0yZnFZMzlwQmc/edit

잘못된 부분이나 추가할만한 내용 있으시면 메일이나 댓글로 주세요~