Mommy, what is Use After Free bug?


ssh uaf@pwnable.kr -p2222 (pw:guest)








use after free문제이다


use after free는

 file:///C:/Users/Home/Downloads/USE_AFTER_FREE.pdf

cd80님의 문서를 보고 공부했다.

cd80님의 문서는 읽을때마다 정말 좋은것 같다


class Human에 give_shell()이라는 함수가 있는데


m,w를 free(delete)->reuse(data덮어쓰기)->introduce주소를 give_shell()주소로 덮어쓰기->introduce호출


하면 될 것 같다.


일단 틀은 잡았는데 어떻게 메모리를 들여다 볼지 막막했다.

gdb를 돌ㄹ보아야겠다


(푸는중)




스위치문을 찾았다


1번 옵션 -> introduce()를 콜하는 case 1이 있는 곳(0x400fcd~0x401000(2번시작주소))을 읽어보면


[rbp-38]에 m

[rbp-0x30]에 w가 있을 것 같다.

여기 주소를 한번 따라가 봐야겠다.


m의 주소는 0x01494040

w의 주소는 0x01494090

이라고 생각하고 들어가봤다



두 구조체를 발견했다

나이와 이름을 발견했다.

그렇다면 덮어써야할 함수는 어디있을까?


위의 case1에서 어셈블리를 해석해보면

call rdx라는 함수를 호출하는데 

rdx는 00401570+0x08안의 값이 들어간다


따라가니 <_ZTV3MAN+24>가 있었고 0x004015f0이 있었다.

이게 introduce()의 주소인 것 같다.


그렇다면 getshell()의 주솟값은 어디있을까?ㅠㅠ


일단 3번으로 구조체를 delete한후 2번 옵션으로 AAAA라는 값이 있는 파일을 read해서 data에 넣은후

다시 저 메모리를 방문해 보았따.



아까 introduce()주소와 관련된 곳에 AAAA가 덮어써졋다

user after free 취약점에 의해 발생한 현상이다

(그 밑에 AAAA는 바로 전에 실수로 delete를 안하고 read했더니 들어갔던 값이다... 실수 ㅎㅎ)


그렇다면 우리가 해야할 일은

getshell()로 보내는 값을 찾아서 그 주소값을 파일 내용에 넣은다음

돌리면 getshell()을 실행시킬 수 있다.


아 getshell()어떻게 찾지하다가 



human woman man과 관련된 함수 테이블을 찾아봤따


case1에서 호출하는 것은 0x0040117a의 주소였다

따라가보니



get_shell()은 human의 private성분이었음으로 

아무튼

zt15human의 주솟값을 하나씩 넣어봤다

오 진짜 introduce가 있었다


0x0040117a엔 뭐가있나 해서 들어가보니


shell함수다


ㅠㅠㅠㅠㅠ


 human에 있는 40117a의 주소에서 0x08을 뺀 주소를 보면

0x00401588을 넣어보자



ㅠㅠㅠ


풀이가 너무 정신 없었던 것 같지만 잘 봐주면 좋겠다


풀이를 쓰는건 힘들지만 풀이를 쓰고 나면 머리속에 더 정리가 더 잘 되는 느낌이라

기분이 좋은것 같당



'war game > pwnable.kr' 카테고리의 다른 글

pwnable.kr memcpy 10pt  (1) 2016.10.12
pwnable.kr codemap 10pt  (0) 2016.10.12
pwnable.kr cmd2 9pt  (0) 2016.10.12
pwnable.kr cmd1 1pt  (0) 2016.10.11
pwnable.kr lotto 2pt  (0) 2016.10.11

Daddy bought me a system command shell.

but he put some filters to prevent me from playing with it without his permission...

but I wanna play anytime I want!


ssh cmd2@pwnable.kr -p2222 (pw:flag of cmd1)


지금까지의 문제중 가장 점수 높은 문제다

접속해보자@_@


아 비번이 cmd1의 flag다 



mommy now I get what PATH environment is for :)

저번 포스팅으로 가서 가져왔다







cmd에 =, PATH, export / ` flag를 우회하고 있다


일단 cmd1에서 썻던 방법은 다 필터링 되고 있다ㅠㅠ



처음엔 이렇게도 해봤는데

'가 필터링이었다.. python 스크립트에서 '를 안쓰는 방법을 생각해보았다

는 없었고

bash쉘의 $ 특징을 이용했다


오오 된다된다




'war game > pwnable.kr' 카테고리의 다른 글

pwnable.kr codemap 10pt  (0) 2016.10.12
pwnable.kr uaf 8pt  (0) 2016.10.12
pwnable.kr cmd1 1pt  (0) 2016.10.11
pwnable.kr lotto 2pt  (0) 2016.10.11
pwnable.kr blackjack 1pt  (0) 2016.10.11


#include <stdio.h>

#include <string.h>


int filter(char* cmd){

        int r=0;

        r += strstr(cmd, "flag")!=0;            //flag, sh, tmp문자열 필터링

        r += strstr(cmd, "sh")!=0;

        r += strstr(cmd, "tmp")!=0;

        return r;

}

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

        putenv("PATH=/fuckyouverymuch");        //path환경변수 초기화

        if(filter(argv[1])) return 0;

        system( argv[1] );

        return 0;

}



필터링 우회하는데는 정규식만한게 없는것 같다.








argv에 export를 넣어줘서 path를 다시 넣어주는 방법도 있다.

'war game > pwnable.kr' 카테고리의 다른 글

pwnable.kr uaf 8pt  (0) 2016.10.12
pwnable.kr cmd2 9pt  (0) 2016.10.12
pwnable.kr lotto 2pt  (0) 2016.10.11
pwnable.kr blackjack 1pt  (0) 2016.10.11
pwnable.kr coin1 6pt  (0) 2016.10.11

Mommy! I made a lotto program for my homework.

do you want to play?



ssh lotto@pwnable.kr -p2222 (pw:guest)



#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <fcntl.h>


unsigned char submit[6];


void play(){


        int i;

        printf("Submit your 6 lotto bytes : ");

        fflush(stdout);


        int r;

        r = read(0, submit, 6);


        printf("Lotto Start!\n");

        //sleep(1);


        // generate lotto numbers

        int fd = open("/dev/urandom", O_RDONLY);

        if(fd==-1){

                printf("error. tell admin\n");

                exit(-1);

        }

        unsigned char lotto[6];

        if(read(fd, lotto, 6) != 6){

                printf("error2. tell admin\n");

                exit(-1);

        }

        for(i=0; i<6; i++){

                lotto[i] = (lotto[i] % 45) + 1;         // 1 ~ 45

        }

        close(fd);


        // calculate lotto score

        int match = 0, j = 0;

        for(i=0; i<6; i++){

                for(j=0; j<6; j++){

                        if(lotto[i] == submit[j]){

                                match++;

                        }

                }

        }


        // win!

        if(match == 6){

                system("/bin/cat flag");

        }

        else{

                printf("bad luck...\n");

        }


}


void help(){

        printf("- nLotto Rule -\n");

        printf("nlotto is consisted with 6 random natural numbers less than 46\n");

        printf("your goal is to match lotto numbers as many as you can\n");

        printf("if you win lottery for *1st place*, you will get reward\n");

        printf("for more details, follow the link below\n");

        printf("http://www.nlotto.co.kr/counsel.do?method=playerGuide#buying_guide01\n\n");

        printf("mathematical chance to win this game is known to be 1/8145060.\n");

}


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


        // menu

        unsigned int menu;


        while(1){


                printf("- Select Menu -\n");

                printf("1. Play Lotto\n");

                printf("2. Help\n");

                printf("3. Exit\n");


                scanf("%d", &menu);


                switch(menu){

                        case 1:

                                play();

                                break;

                        case 2:

                                help();

                                break;

                        case 3:

                                printf("bye\n");

                                return 0;

                        default:

                                printf("invalid menu\n");

                                break;

                }

        }

        return 0;

}



 for(i=0; i<6; i++){

                for(j=0; j<6; j++){

                        if(lotto[i] == submit[j]){

                                match++;

                        }

                }

        }

이코드를 잘보면 lotto에 들어있는 6가지 수 중에서 submit한 문자가 하나가 잇으면 match가 6이 된다.

1글자만 맞추면 된다는 것이다.


그래서 111111만 20번은 넣어본것 같다.

for(i=0; i<6; i++){

                lotto[i] = (lotto[i] % 45) + 1;         // 1 ~ 45

        }

33부터 우리가 char형으로 입력할 수 있는 값이다. '!'=33 """=34 '#'=35... '-'=45 .... '0'=48->4 '1'=49->5...


만약 submit으로  1 1 1 1 1 1 을 넣었다면 1=49 이므로 lotto와 맞을 수가 없다

따라서 아스키가 45보다 작은 문자를 넣어줘야한다

######을 넣어봤다.

성공!!



'war game > pwnable.kr' 카테고리의 다른 글

pwnable.kr cmd2 9pt  (0) 2016.10.12
pwnable.kr cmd1 1pt  (0) 2016.10.11
pwnable.kr blackjack 1pt  (0) 2016.10.11
pwnable.kr coin1 6pt  (0) 2016.10.11
pwnable.kr shellshock 1pt  (0) 2016.10.11

Hey! check out this C implementation of blackjack game!

I found it online

* http://cboard.cprogramming.com/c-programming/114023-simple-blackjack-program.html


I like to give my flags to millionares.

how much money you got?



Running at : nc pwnable.kr 9009



첫 화면이다


룰은 대충 이렇다

100만점을 얻어야 flag를 준다는데

1pt인데 너무 길다ㅠㅠ


룰을..영어를 해석해보자.........

1. 이 프로그램은 카드를 랜덤으로 생성한다


2. 각 카드는 하나의 값을 가진다 

숫자카드는 1~10까지

J,Q,K카드는10의 값을

에이스 카드는 11의 값을 가진다

이게임의 목표는 카드 값들의 합을 21로 맞추는것


3.첫번째 두개의 카드를 보고 hit 과 stay를 결정할 수 있다.

hit은 카드의 숫자를 더하고 stay는 당신을 안전하게 한다(?)

카드값이 21을 넘으면 당신의 패배다



ㅁ나ㅣ어리ㅏ 게임이 이해가 안된다

http://cboard.cprogramming.com/c-programming/114023-simple-blackjack-program.html

여기에 소스가 있다 


한꺼번에 배팅을 많이하면 될것같아서 betting하는 함수를 찾아봤다

반복문이 없어서 큰수를 두번써주면 한번에 100000000을 벌수 있다


플래그를 뱉었다!!





'war game > pwnable.kr' 카테고리의 다른 글

pwnable.kr cmd1 1pt  (0) 2016.10.11
pwnable.kr lotto 2pt  (0) 2016.10.11
pwnable.kr coin1 6pt  (0) 2016.10.11
pwnable.kr shellshock 1pt  (0) 2016.10.11
pwnable 1pt mistake  (0) 2016.10.10


Mommy, I wanna play a game!

(if your network response time is too slow, try nc 0 9007 inside pwnable.kr server)


Running at : nc pwnable.kr 9007




python소켓프로그래밍을 배워와야 겠습니다



python re모듈(정규식) https://docs.python.org/3/library/re.html


python 3.5사용중인데 python3.5에서는 socket.send socket.recv를 object bytes로 송수신 하는데

socket.send(message.encode())로 보내줫는데 보내주는 값을 문자열로 받아서 format eroor를 반환한다..

찾아보는중..

이라고 착각하고 삽질 엄청했는데 아님..ㅎㅎ send recv에 문제가 아니라 포트번호를 잘못썼었다..

ㅠㅠㅠ


flag 땄다.. ㅠㅠ


코드




첫 소켓 코딩이었다ㅠㅠ그래서 코드가 좀 더럽긴하다

포트때문에 어이없게 고생했지만 뿌듯 ㅎㅎ

            



'war game > pwnable.kr' 카테고리의 다른 글

pwnable.kr cmd1 1pt  (0) 2016.10.11
pwnable.kr lotto 2pt  (0) 2016.10.11
pwnable.kr blackjack 1pt  (0) 2016.10.11
pwnable.kr shellshock 1pt  (0) 2016.10.11
pwnable 1pt mistake  (0) 2016.10.10

Mommy, there was a shocking news about bash.

I bet you already know, but lets just make it sure :)



ssh shellshock@pwnable.kr -p2222 (pw:guest)




#include <stdio.h>

int main(){

setresuid(getegid(), getegid(), getegid());    //ruid(실재 사용자realuser), euid(유효사용자effectiveuser), suid(파일 소유자setuser)를 getegid()(egid)로                                                                     세팅

setresgid(getegid(), getegid(), getegid());    

system("/home/shellshock/bash -c 'echo shock_me'");

return 0;

}


일단 코드는 되게 짧네요

이걸 이용해서 flag를 따야하는데.. getegid()가 많이 나오므로 plt를 조작하는 건가 생각하면서 삽질좀 하다가 

'

shellshock가 단순히 문제 이름이 아니라 bash의 취약점이라는 사실을 알게되었다.

CVE-2014-6271이라 불린다고 한다.

자세한 설명은 http://blog.naver.com/PostView.nhn?blogId=renucs&logNo=220144713558




shellshock 취약점 진단을 해보니 취약하다는 결과가 나왔다.

이는 bash에서 함수의 정의를 환경변수로 저장하기 때문에 나오는 취약점인데, 함수의 정의 (){return;}후에 원하는 명령어를 넣어주면 bash가 이 함수 정의를 import할때 뒤의 명령어도 함께 실행시켜준다.

예전에 이 취약점으로 떠들석 햇다고 한다. 지금은 리눅스 버전을 update만 하면 공격이 통하지 않는다.




'war game > pwnable.kr' 카테고리의 다른 글

pwnable.kr cmd1 1pt  (0) 2016.10.11
pwnable.kr lotto 2pt  (0) 2016.10.11
pwnable.kr blackjack 1pt  (0) 2016.10.11
pwnable.kr coin1 6pt  (0) 2016.10.11
pwnable 1pt mistake  (0) 2016.10.10

hackerschoolftz_level11~20.pdf

hackerschoolftz_level11~20.docx


문제 : 

We all make mistakes, let's move on.

(don't take this too seriously, no fancy hacking skill is required at all)


This task is based on real event

Thanks to dhmonkey


hint : operator priority


ssh mistake@pwnable.kr -p2222 (pw:guest)


mistake.c를 읽어보았다.


#include <stdio.h>

#include <fcntl.h>             fcntl.h헤더에 대한 글 http://www.joinc.co.kr/w/Site/system_programing/File/Fcntl 


#define PW_LEN 10        

#define XORKEY 1


void xor(char* s, int len){

int i;

for(i=0; i<len; i++){

s[i] ^= XORKEY;

}

}


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

int fd;

if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){ ..**여기서 우선순위로 password를 열수있다. open(~)<0 이 false이므로 fd=false=0

printf("can't open password %d\n", fd);

return 0;

}


printf("do not bruteforce...\n");

sleep(time(0)%20);


char pw_buf[PW_LEN+1];            .pw_buf[11]

int len;

if(!(len=read(fd,pw_buf,PW_LEN) > 0)){  read는 정상실행시 읽은 바이트수 반환이지만, fd=0이면 입력을 받게 된다. 즉 len=~코드는 scanf(%s pw) 

printf("read error\n");

close(fd);

return 0;

}


char pw_buf2[PW_LEN+1];    .pw_buf2[11]

printf("input password : ");

scanf("%10s", pw_buf2);


// xor your input

xor(pw_buf2, 10);        .인풋비트을 1과 xor


if(!strncmp(pw_buf, pw_buf2, PW_LEN)){    .비교해서 같으면 플래그를 딸 수 있다.

printf("Password OK\n");

system("/bin/cat flag\n");

}

else{

printf("Wrong Password\n");

}


close(fd);

return 0;

}


문제에서 단순하게 생각하라고 한다. 결국 첫번째 10글자 인풋은 pwbuf1에 두번째 10글자 인풋은 pwbuf2에 저장된다. xor연산이있으므로 첫번째 10글자에 1을 xor한 값을 두번째 인풋으로 넣어주면된다.






'war game > pwnable.kr' 카테고리의 다른 글

pwnable.kr cmd1 1pt  (0) 2016.10.11
pwnable.kr lotto 2pt  (0) 2016.10.11
pwnable.kr blackjack 1pt  (0) 2016.10.11
pwnable.kr coin1 6pt  (0) 2016.10.11
pwnable.kr shellshock 1pt  (0) 2016.10.11

+ Recent posts