일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- property
- xss game
- document
- xss game 풀이
- sql injection
- object
- 자바스크립트
- 백준 알고리즘
- jQuery
- 메소드
- Pwndbg
- htmlspecialchars
- 객체
- element 조회
- blind sql injection
- python
- 함수
- burp suite
- 배열
- github
- IF문
- 백준 파이썬
- lord of sql injection
- window
- suninatas 풀이
- 포인터
- 조건문
- 김성엽 대표님
- 파이썬
- 사칙연산
Archives
- Today
- Total
power-girl0-0
[pwnable] mistake 풀이 본문
728x90
Hello~ 안녕하세요! o(*°▽°*)o
1. 문제
flag, mistake, password의 바이너라 파일이 존재하고, mistake에 대한 c코드가 주어진다.
#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;
}
2. 풀이
위 코드를 살펴보면, 크게 3가지 조건이 존재하는 것을 알 수 있다.
① password파일을 open후, read함수를 통해 10byte값만큼 읽어, pw_buf에 저장한다. ② 10byte만큼 값을 입력받은 후, xor한다. 그 값은 pw_buf2배열에 존재한다. ③ pw_buf와 pw_buf2의 값이 같으면, flag값이 출력된다. |
하지만, 아래 코드를 자세히 살펴봐야한다.
if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){
printf("can't open password %d\n", fd);
return 0;
}
if조건문에서 연산자 우선순위에 의해, =보다 <가 먼저 실행된다.
즉, open함수에 대한 return값과 0을 비교해서 나온 결과값 false가 fd에 들어가게 되는 것이다.
따라서, read함수의 fd값은 0이 되어서 password를 읽어오는 것이 아니라 값을 입력받게 되는 것이다.
그래서 pw_buf에 공격자가 원하는 값을 삽입할 수 있게 되는 것이다.
이후 pw_buf에 넣은 값을 xor하여 입력값으로 넣으면,
pw_buf와 pw_buf2의 값이 같아지게 되어서 flag를 얻을 수 있는 것이다.
아래는 디컴파일하면서, 공부했던 것이다.
기록해두고, 나중에 참고하려고 적어둔다. ( 부분만 가져온 것임. )
(gdb) disas main
Dump of assembler code for function main:
0x00005555555549a1 <+0>: push rbp
0x00005555555549a2 <+1>: mov rbp,rsp
0x00005555555549a5 <+4>: sub rsp,0x40
0x00005555555549a9 <+8>: mov DWORD PTR [rbp-0x34],edi
0x00005555555549ac <+11>: mov QWORD PTR [rbp-0x40],rsi
0x00005555555549b0 <+15>: mov rax,QWORD PTR fs:0x28
0x00005555555549b9 <+24>: mov QWORD PTR [rbp-0x8],rax
0x00005555555549bd <+28>: xor eax,eax
0x00005555555549bf <+30>: mov edx,0x100
0x00005555555549c4 <+35>: mov esi,0x0
0x00005555555549c9 <+40>: lea rdi,[rip+0x208] # 0x555555554bd8
0x00005555555549d0 <+47>: mov eax,0x0
0x00005555555549d5 <+52>: call 0x555555554810 <open@plt>
'''
(gdb) x/s $rip+0x208
0x555555554bd8: "/home/mistake/password"
eax 0x3 3 //open함수의 리턴값은 3임.
'''
0x00005555555549da <+57>: shr eax,0x1f
''' eax에는 0값이 들어감. :: 참고로 0x1f는 31임.
※ 중요 ※
양수인지, 음수인지 shr 31 로 알 수 있다.
왜냐하면 컴퓨터는 1과 0만 알기 때문에, shr31만으로도 양수인지 음수인지 알 수 있는 것이다.
즉, eax에서 shr 31하면, 0이 나오게 된다.
// 1은 음수, 0은 양수를 의미함.
'''
0x00005555555549dd <+60>: movzx eax,al
0x00005555555549e0 <+63>: mov DWORD PTR [rbp-0x28],eax
0x00005555555549e3 <+66>: cmp DWORD PTR [rbp-0x28],0x0
0x00005555555549e7 <+70>: je 0x555555554a09 <main+104>
''' cmp했을 때 두 수의 값이 0으로 같기 때문에, <main + 104>로 이동함. '''
0x00005555555549e9 <+72>: mov eax,DWORD PTR [rbp-0x28]
0x00005555555549ec <+75>: mov esi,eax
0x00005555555549ee <+77>: lea rdi,[rip+0x219] # 0x555555554c0e
0x00005555555549f5 <+84>: mov eax,0x0
0x00005555555549fa <+89>: call 0x5555555547d0 <printf@plt>
// "can't open password %d\n"
0x00005555555549ff <+94>: mov eax,0x0
0x0000555555554a04 <+99>: jmp 0x555555554b39 <main+408>
0x0000555555554a09 <+104>: lea rdi,[rip+0x216] # 0x555555554c26
0x0000555555554a10 <+111>: call 0x5555555547a0 <puts@plt>
'''
(gdb) x/s $rip+0x216
0x555555554c26: "do not bruteforce..."
'''
0x0000555555554a15 <+116>: mov edi,0x0
0x0000555555554a1a <+121>: mov eax,0x0
0x0000555555554a1f <+126>: call 0x555555554800 <time@plt>
// time(0)
3. flag 획득
필자는 pw_buf에 'hellohello' 값을 넣어주고,
pw_buf2에 'hellohello' xor연산한 'idmmnidmmn'값을 입력하여 flag를 획득하였다.
Bye~ 안녕히계세요! ヽ(≧□≦)ノ
728x90
'War game > pwnable.kr' 카테고리의 다른 글
[pwnable] cmd2 풀이 (0) | 2022.02.21 |
---|---|
[pwnable] cmd1 풀이 (0) | 2022.02.20 |
[pwnable] random 풀이 (0) | 2022.02.13 |
[pwnable] flag 풀이 (0) | 2022.02.12 |
[pwnable] collision 풀이 (0) | 2022.02.09 |
Comments