728x90

안드로이드 보다가 하기 싫어서 누가 이 문제가 쉽다고 해서 풀었다..

Sometimes, pwnable is strange... hint: if this challenge is hard, you are a skilled player.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
char flag[100];
char password[100];
char* key = "3\rG[S/%\x1c\x1d#0?\rIS\x0f\x1c\x1d\x18;,4\x1b\x00\x1bp;5\x0b\x1b\x08\x45+";
void calc_flag(char* s){
        int i;
        for(i=0; i<strlen(s); i++){
                flag[i] = s[i] ^ key[i];
        }
        printf("%s\n", flag);
}
int main(){
        FILE* fp = fopen("/home/blukat/password", "r");
        fgets(password, 100, fp);
        char buf[100];
        printf("guess the password!\n");
        fgets(buf, 128, stdin);
        if(!strcmp(password, buf)){
                printf("congrats! here is your flag: ");
                calc_flag(password);
        }
        else{
                printf("wrong guess!\n");
                exit(0);
        }
        return 0;
}

문제 설명 안읽고 처음에 역연산 코드 짜다가 생각해보니 변수가 두개인 일차방정식을 어째 푸냐 이건 아니다 해서

 

문제설명을 보아하니 뭔가 함정이 있다 싶어서 fp에서 뭔 오류가 생기나보다 해서 계속 쳐다 봐도 문제가 없다.

 

그냥 password가 permission denied였다. ㅋ..

 

congrats! here is your flag: Pl3as_DonT_Miss_youR_GrouP_Perm!!

728x90

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

[pwnable.kr] cmd1  (0) 2020.10.10
[pwnable.kr] random  (0) 2020.10.09
[pwnable.kr] passcode  (0) 2020.10.08
[pwnable.kr] mistake  (0) 2020.10.03
[pwnable.kr] lotto  (0) 2020.09.23
728x90

Mommy! what is PATH environment in Linux?

#include <stdio.h>
#include <string.h>

int filter(char* cmd){
        int r=0;
        r += strstr(cmd, "flag")!=0;
        r += strstr(cmd, "sh")!=0;
        r += strstr(cmd, "tmp")!=0;
        return r;
}
int main(int argc, char* argv[], char** envp){
        putenv("PATH=/thankyouverymuch");
        if(filter(argv[1])) return 0;
        system( argv[1] );
        return 0;
}

코드가 간단해서 빨리 풀었다.

strstr함수는, 

dojang.io/mod/page/view.php?id=371

 

C 언어 코딩 도장: 44.3 문자열 안에서 문자열로 검색하기

이번에는 문자열 안에서 문자열로 검색하는 방법을 알아보겠습니다. strstr 함수는 문자열 안에서 문자열을 검색하며 string (find) string에서 따왔습니다(string.h 헤더 파일에 선언되어 있습니다). strs

dojang.io

자세한건 위에서 읽어보면 되고, 우리가 생각해야하는건 flag, sh, tmp라는 문자열이 검색되면 (cmd에서) strstr함수는 1을 리턴한다. 따라서 flag, sh, tmp를 쓸수 없다. 

근데 선배가 가르쳐준게 있었는데 파일이름뒤에 *를 붙이면 뒤에 긴 이름은 생략할 수 있다.

 

입력한 값은 system(여기에)들어가는데, /bin/cat flag라는 구문을 넣어주면 된다.(사실 넣어준다는 표현보다는 cmd1이 실행되는 동안 실행시켜준다 가 맞는 표현같다.)

strstr함수를 우회하려면  /bin/cat fla*를 보내면 될듯.

mommy now I get what PATH environment is for :)

728x90

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

[pwnable.kr] blukat  (0) 2020.10.12
[pwnable.kr] random  (0) 2020.10.09
[pwnable.kr] passcode  (0) 2020.10.08
[pwnable.kr] mistake  (0) 2020.10.03
[pwnable.kr] lotto  (0) 2020.09.23
728x90

Daddy, teach me how to use random value in programming!

#include <stdio.h>

int main(){
        unsigned int random;
        random = rand();        // random value!

        unsigned int key=0;
        scanf("%d", &key);

        if( (key ^ random) == 0xdeadbeef ){
                printf("Good!\n");
                system("/bin/cat flag");
                return 0;
        }

        printf("Wrong, maybe you should try 2^32 cases.\n");
        return 0;
}

c언어를 배울때 rand함수는 srand를 해주기 전엔 random값이 아니라고 배웠다.

 

gdb로 rand의 첫번째 값을 확인해서 deadbeef랑 xor연산을 해준 값을 넣어주면 끝난다.

 

18에 bp를 걸어주고

 

 

0x6b8b4567 xor 0xdeadbeef = B526 FB88 >> 3039230856 (10진수)

 

Mommy, I thought libc random is unpredictable...

 

728x90

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

[pwnable.kr] blukat  (0) 2020.10.12
[pwnable.kr] cmd1  (0) 2020.10.10
[pwnable.kr] passcode  (0) 2020.10.08
[pwnable.kr] mistake  (0) 2020.10.03
[pwnable.kr] lotto  (0) 2020.09.23
728x90

Mommy told me to make a passcode based login system. My initial C code was compiled without any error! Well, there was some compiler warning, but who cares about that?

#include <stdio.h>
#include <stdlib.h>
void login(){
        int passcode1;
        int passcode2;

        printf("enter passcode1 : ");
        scanf("%d", passcode1); #########4
        fflush(stdin);

        // ha! mommy told me that 32bit is vulnerable to bruteforcing :)
        printf("enter passcode2 : "); 
        scanf("%d", passcode2);  ########5

        printf("checking...\n");  ########5
        if(passcode1==338150 && passcode2==13371337){
                printf("Login OK!\n");
                system("/bin/cat flag");
        }
        else{
                printf("Login Failed!\n");
                exit(0);
        }
}
void welcome(){
        char name[100];
        printf("enter you name : ");   ##########2
        scanf("%100s", name);
        printf("Welcome %s!\n", name);########3
}
int main(){
        printf("Toddler's Secure Login System 1.0 beta.\n"); #######1

        welcome();
        login();

        // something after login...
        printf("Now I can safely trust you that you have credential :)\n");
        return 0;
}

읽어보니깐 scanf에서 &가 없어서 passcode 1, 2를 주소로 인식한다. 즉 입력한 주소값으로 이동시킬 수 있다.

 

그리고 name을 입력받을땐 배열이므로 &가 없는게 맞는듯..

 

got/plt를 이용하여서 풀거다.

 

name변수와 passcode1변수의 거리가 112-16 = 96인데 name에서 100개를 입력받으므로 마지막 8바이트는 passcode1에 들어갈 것이다.

passcode1에 fflush함수의 got값을 넣어주면 scanf오류때문에 해당 주소에 overwrite할 수 있다.

fflush의 got는 0x804a004, 

그러면 우리가 원하는 주소인 

cat flag를 넣어주면 된다.

 

또한 scanf에서 %d로 받기 때문에 마지막 주소는 10진수로 바꿔줘야 한다.

 

(python -c 'print "\x90"*96+"\x04\xa0\x04\x08"+"134514147"') | ./passcode

 

Sorry mom.. I got confused about scanf usage :(

728x90

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

[pwnable.kr] cmd1  (0) 2020.10.10
[pwnable.kr] random  (0) 2020.10.09
[pwnable.kr] mistake  (0) 2020.10.03
[pwnable.kr] lotto  (0) 2020.09.23
[pwnable.kr] flag  (0) 2020.09.23
728x90

연산자 우선순위때문에 코드에 오류가 있다고 한다.

 

코드를 보면, 

#include <stdio.h>
#include <fcntl.h>

#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){
                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];
        int len;
        if(!(len=read(fd,pw_buf,PW_LEN) > 0)){
                printf("read error\n");
                close(fd);
                return 0;
        }

        char pw_buf2[PW_LEN+1];
        printf("input password : ");
        scanf("%10s", pw_buf2);

        // xor your input
        xor(pw_buf2, 10);

        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;
}

 

password라는 파일을 fd로 읽어온 후 사용자에게 입력을 받아서 xor연산 후 비교하는 구조이다.

힌트로 연산자 우선순위가 있어서 요걸 어디에다가 써먹지 생각을 해보다가 pw비교문에선 오류가 없는것같아 

fd로 읽어오는 부분을 보니, 잘못된게 바로 보였다.

c언어에선 대입연산자가 항상 최하위로 외우고 있었는데 대입이랑 비교연산자를 섞어놨으니 의도한 대로 코딩이 안되었을것이다.

 

 

//(open함수 링크 >>

 

비버퍼링 파일 열기 함수 - open()

앞으로 open(), creat(), read(), write(), lseek(), close() 함수에 대해서 차례로 살펴볼 것이다. 여섯개...

blog.naver.com

문제의 코드는 fd = open(경로, 읽기전용, 뭔 권한(?) ) < 0 인데 password파일은 잘 열릴꺼니깐 리턴값은 파일 디스크립터일것이고, 0보다 작지 않다. 그러면 연산자의 리턴값은 0, 따라서 fd에 0이 들어가고 키보드사용 표준 입력인데다가 

sleep함수도 있으므로 그냥 입력하는게 pw_buf1에 들어간다.

그 후엔 pw_buf2같은건 그냥 입력하면 되고, xor연산을 잊으면 안된다.

 

a는 ascii로 97이고 1과 xor하면 96, `이다.

Mommy, the operator priority always confuses me :(

 

728x90

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

[pwnable.kr] random  (0) 2020.10.09
[pwnable.kr] passcode  (0) 2020.10.08
[pwnable.kr] lotto  (0) 2020.09.23
[pwnable.kr] flag  (0) 2020.09.23
[pwnable.kr] bof  (0) 2020.09.23
728x90

Mommy! I made a lotto program for my homework. do you want to play?

misc같은 문제를 풀고싶어서 lotto 를 지금푼다. 

#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;
}

 

코드에 논리적 오류가 있는게, 보통 lotto는 6개를 다 맞아야 1등하는데 위 코드대로면 1개만 맞아도 6개가 다 맞는것처럼 인식한다.

또한 입력을 char로 받아서 확률은 더 높아진다. 

sorry mom... I FORGOT to check duplicate numbers... :(

728x90

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

[pwnable.kr] passcode  (0) 2020.10.08
[pwnable.kr] mistake  (0) 2020.10.03
[pwnable.kr] flag  (0) 2020.09.23
[pwnable.kr] bof  (0) 2020.09.23
[pwnable.kr] collision  (0) 2020.09.22
728x90

Papa brought me a packed present! let's open it.

그냥 우분투로 파일을 확인해보니, 

elf인데 실행이 안되는것 보니 뭔 작업을 해야할것 같다.

 

윈도우에서 ida로 까보면, 

함수 3개중에 1개만 열려서 어떻게 할까 하다가 string을 뒤져보니 upx가 보였다.

우분투에서 언팩한 다음 다시 윈도우로 넘겨주었다.

 

이제 아주 잘 열린다.

flag가 바이너리 파일 안에 있다고 했으므로, 조금 뒤져보면 나온다.

UPX...? sounds like a delivery service :)

728x90

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

[pwnable.kr] mistake  (0) 2020.10.03
[pwnable.kr] lotto  (0) 2020.09.23
[pwnable.kr] bof  (0) 2020.09.23
[pwnable.kr] collision  (0) 2020.09.22
[pwnable.kr] fd  (0) 2020.09.22
728x90

Nana told me that buffer overflow is one of the most common software vulnerability. Is that true?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
	char overflowme[32];
	printf("overflow me : ");
	gets(overflowme);	// smash me!
	if(key == 0xcafebabe){
		system("/bin/sh");
	}
	else{
		printf("Nah..\n");
	}
}
int main(int argc, char* argv[]){
	func(0xdeadbeef);
	return 0;
}

주어진 c코드다.  main에서 func로 전달한 인자, overflowme의 값을 바꿔주면 된다.

우리는 입력을 overflowme에 할 수 있고, 비교를 하는건 key이므로 overflowme와 key사이의 거리를 찾으면 된다.

이렇게 gdb로 찾아도 되고 

ida로 확인해봐도 된다.

거리는 52바이트이므로 dummy 52byte + 4byte(cafebabe)


daddy, I just pwned a buFFer :)

728x90

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

[pwnable.kr] mistake  (0) 2020.10.03
[pwnable.kr] lotto  (0) 2020.09.23
[pwnable.kr] flag  (0) 2020.09.23
[pwnable.kr] collision  (0) 2020.09.22
[pwnable.kr] fd  (0) 2020.09.22

+ Recent posts