문제 링크: https://dreamhack.io/wargame/challenges/46/
view.php preg_match를 통해서 flag를 필터링하는 것을 알 수 있다. 대문자도 필터링한다.
preg_match('/flag:'/i) i가 붙게되면 입력받은 문자를 소문자로 바꿔 매칭 시키고 필터링한다.
char, hex를 쓰는 방법이 있다고 하는데, 방법이 잘못된 것인지 통하지 않았다.
자료를 찾아보니 php wrapper를 통해 우회하는 방법이 있었다. php wrapper를 통해 LFI 공격을 이용한다.(Local File Inclusion 공격 대상 서버에 위치한 파일을 포함시켜 읽어오는 공격이다.)
wrapper의 경우 감싸다라는 의미인데, 코드나 데이터를 둘러싸다 정도의 의미를 갖겠다.
php의 Include 함수는 인자로 전달된 파일을 읽은 후 해당 파일의 내용을 출력한다. 파일의 내용중 php 코드 구문이 존재하면 해당 코드를 실행한다.
file:// — Accessing local filesystem
http:// — Accessing HTTP(s) URLs
ftp:// — Accessing FTP(s) URLs
php:// — Accessing various I/O streams, base64를 통해 encode/decode를 한다.
zlib:// — Compression Streams
data:// — Data (RFC 2397)
glob:// — Find pathnames matching pattern
phar:// — PHP Archive
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — Audio streams
expect:// — Process Interaction Streams
우리는 php:// 즉, 입출력을 통해 flag.php의 값을 읽어오도록 하겠다.
http://host3.dreamhack.games:24017/?page=php://filter/convert.base64-encode/resource=/var/www/uploads/flag
위와 같은 방식으로 하면 view페이지를 거치지 않기 때문에 flag에 대한 필터링을 거치지 않는다.
PD9waHAKCSRmbGFnID0gJ0RIe2JiOWRiMWYzMDNjYWNmMGYzYzkxZTBhYmNhMTIyMWZmfSc7Cj8+CmNhbiB5b3Ugc2VlICRmbGFnPw==
f12를 눌러서 보면 이러한 문자열이 나오는 것을 알 수 있다. 이를 base64에 decode를 하면 flag의 값이 나온다.
http://host3.dreamhack.games:24017/?page=php://filter/resource=/var/www/uploads/flag
이렇게 하니 can you see $flag?라는 문자열이 나왓다. base64를 통해 encode를 하지 않아 <?php> 부분이 보이지 않았음을 알 수 있다. flag값을 base64로 encode해야 해당 문자열이 나와 decode를 시도해볼 수 있다.
참조