회원가입 및 로그인 기능이 있고, 로그인을 하게되면 session 방식으로 쿠키값이 설정된다.
웹 루트 디렉터리에는 localhost로 요청을 보내야지 사용이 가능한 이름 변경 페이지와 url과 키,값을 인자로 주고 send할 수 있는 기능이 존재한다.
php 7.0버전으로 역직렬화 공격에 취약한 버전으로 구성돼있다. flag는 /$(openssl rand -hex 8)_flag.txt으로 랜덤하게 생성된다.
또한 mariadb-server가 실행중이다.
*stretch는 데비안 9 버전(legacy)의 코드명이다. 이는 오래된 버전의 데비안 환경에서 패키지를 설치하여 문제 서버 환경을 동일시 하기 위함이다. 오래된 아카이브 저장소는 유효 기간 정보가 만료된 경우가 많기에 저장소의 유효 기간 정보 체크를 하는 기능을 껐다.
각종 엔트리포인트가 되는 실행 파일을 활성화한다.
4개의 프로시저(저장된 DB용 함수)가 존재한다. searchUser, registerUser, loginUser, editName.
여기서 searchUser는 name 파라미터를 받아서 쿼리를 수행하는 함수인데, CONCAT함수를 사용하여 쿼리 문자열을 직접 만들고 PREPARE/EXECUTE를 통해 실행한다.
여기서 PREPARE은 쿼리문을 실행 가능한 상태로 만들어주고 EXECUTE를 통해 실행하는 동적 SQL이다.
여기서 CONCAT함수를 통해 입력값을 그대로 쿼리문에 이어붙이기 때문에 SQL injection에 취약하다.
SELECT * FROM users WHERE name = 'name'으로 해석되는데 '를 악의적으로 끼워넣어 문자열을 탈출해 쿼리문을 조작할 수 있기 때문이다.
엔트리 포인트이다. 만약 세션에 id가 없다면(로그인이 안돼있다면) 로그인 페이지로 리다이렉트시킨다. 이후 만약 별다른 action이 없을때 현재 세션의 사용자 이름을 사용해 프로시저(searchUser)를 호출한다. 조회된 행성과 이모지를 선택하여 렌더링해준다.
다음으로는 edit action에 대해서 설명한다. index.php에서 edit action은 이름 변경 기능인데, localhost로 보낸 요청만 허용한다.
SSRF -> SQL injection -> RCE
다음으로 index.php에서는 이름 변경 기능이 있다. 이 기능은 Localhost로 보낸 요청만 허용하는데 위에 SSRF를 이용하여 요청을 보낼 수 있다. 여기서 변경되는 이름에 SQL injection payload를 입력하면 취약한(CONCAT을 사용하여 문자열을 이어붙임) 프로시저인 searchUser를 트리거하여 SQL injection 공격이 가능하다.
' UNION SELECT 1, "", 3, 4, "Somewhere" INTO OUTFILE '/var/www/html/shell.php' -- -
이런 payload를 통해 /var/www/html/shell.php에 웹쉘을 업로드할 수 있다. (다른 경로는 권한 부족으로 업로드가 안됨.)
현제 또 다른 제약은 세션 데드락으로 요청 응답이 1초 이내에 오지 않는 점이다. (session_start함수)
여기서 url은 motherland.com으로 끝나야하고, 그 url을 parse_url로 파싱한 host 부분을 curl 옵션으로 지정한다. 그 이전에 filter_var를 통해 url을 필터링한다. 이떄 filter_var를 우회하는 방법이 기술돼있는 사이트가 있었다.
https://medium.com/@themiddleblue/php-ssrf-techniques-9d422cb28d51
여기에 따르면 0://evil.com:80;google.com:80/ 인 형식으로 요청을 보낼 시 filter_var를 우회하고 curl 요청도 evil.com:80으로 보낸다고 한다.
이를 이용해 sql injection을 수행하면 된다.