실행하자마자 오류가 난다. 코드를 보자.
#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;
}
모르는 것을 정리해보자
char *strstr(const char *haystack, const char *needle);
haystack 문자열에서 needle문자열과 일치하는 부분의 시작 위치에 대한 문자열 pointer를 return한다.
(건초더미(haystack)에서 바늘(needle)을 찾는 함수이다.)
존재할때, 문자열 pointer 반환. 존재하지 않을때, NULL반환
저번에 산술연산자 우선순위가 있었으므로 이참에 정리를 해보자.
1 |
x++ x-- ( ) [ ] . -> (자료형){값} |
증가 연산자(뒤, 후위) 감소 연산자(뒤, 후위) 함수 호출 배열 첨자 구조체/공용체 멤버 접근 포인터로 구조체/공용체 멤버 접근 복합 리터럴 |
→ |
2 |
++x --x +x -x ! ~ (자료형) *x &x sizeof |
증가 연산자(앞, 전위) 감소 연산자(앞, 전위) 단항 덧셈(양의 부호) 단항 뺄셈(음의 부호) 논리 NOT 비트 NOT 자료형 캐스팅(자료형 변환) 포인터 x 역참조 x의 주소 자료형의 크기 |
← |
3 |
* / % |
곱셈 나눗셈 나머지 |
→ |
4 |
+ - |
덧셈 뺄셈 |
→ |
5 |
<< >> |
비트를 왼쪽으로 시프트 비트를 오른쪽으로 시프트 |
→ |
6 |
< <= > >= |
작음 작거나 같음 큼 크거나 같음 |
→ |
7 |
== != |
같음 다름 |
→ |
8 | & | 비트 AND | → |
9 | ^ | 비트 XOR | → |
10 | | | 비트 OR | → |
11 | && | 논리 AND | → |
12 | || | 논리 OR | → |
13 | ? : | 삼항 연산자 | ← |
14 |
= += -= *= /= %= <<= >>= &= ^= |= |
할당 덧셈 후 할당 뺄셈 후 할당 곱셈 후 할당 나눗셈 후 할당 나머지 연산 후 할당 비트를 왼쪽으로 시프트한 후 할당 비트를 오른쪽으로 시프트한 후 할당 비트 AND 연산 후 할당 비트 XOR 연산 후 할당 비트 OR 연산 후 할당 |
← |
15 | , | 쉼표(콤마) 연산자 | → |
!= // += // 순으로 우선순위가 있으므로 0과 다르면 r+=을 하는 것 같다.
Q1. 굳이 !=0 을 명시해 줄 필요가 있었을까?
Q2. char 형으로 r을 선언했어야 되는데 왜 int형으로 선언했을까?
우선 실험을 해보자
실험 1. a ~ z에서 a 다음에 b를 찾는 strstr()함수가 있으면 어떻게 될까?
#include <string.h>
#include <stdio.h>
int main(int argc, char **argv) {
char *ptr;
ptr = strstr("abcdefghijklmnopqrstuvwxyz", "op");
ptr = strstr("abcdefghijklmnopqrstuvwxyz", "uv");
printf("%s\n", ptr);
return 0;
}
해당 코드는 uv부터 출력이 된다. (+=는 컴파일이 안된다.) 뭔가 실험이 증명이 안되는 느낌....
putenv() 함수 : 환경변수를 추가하거나, 기존의 환경변수의 값을 변경할 수 있다. name=value 형식으로 이루어지며, name이 기존 환경변수에 이미 존재하고 잇는 것이라면 값의 변경이 이루어지며, 그렇지 않을 경우 추가.
env 명령어로 현재 환경변수를 확인할 수 있다.
코드분석은 나름 끝났다고 생각하는데, 감을 잡지 못하겠다. write-up을 참고한다.
r += strstr(cmd, "flag")!=0;
r += strstr(cmd, "sh")!=0;
r += strstr(cmd, "tmp")!=0;
해당 코드는 필터링 코드였다! flag, sh, tmp 을 필터링 하기 때문에 다른 방법으로 flag를 읽어야 한다.
./cmd1 "/bin/cat *"
입력하면 된다. 1점짜리문제는 뭔가 허무하다.
mommy now I get what PATH environment is for :)
'pwnable' 카테고리의 다른 글
[Toddler's Bottle] shellshock (0) | 2024.05.11 |
---|---|
[Toddler's Bottle] black jack (0) | 2024.05.11 |
[Toddler's Bottle] lotto (0) | 2024.05.11 |
[Toddler's Bottle] blukat (0) | 2024.05.11 |
[Toddler's Bottle] leg (0) | 2024.05.11 |