
웹 상에서는 interact with Robot 버튼 이외에 별 다른 기능을 수행할 수 없었다.
바로 코드 상으로 가서 파악하였다.
nginx 서버와 node.js 서버가 구축되고 있는 걸 확인할 수 있다.
flag는 환경 변수에 저장돼있는 것을 확인하였다.
*여기서 sed 명령어는 환경 파일에 하드코딩돼 있는 환경 변수 값을 실제로 설정된 값으로 변경하는 과정을 하는데 사용된다.
현재 default.conf에서 두 개의 가상호스트(alley, guardian)를 설정하여 리버스 프록시를 사용하고 있다.
해당 서브도메인에 접근하려면 각 서브도메인 이름에 $SECRET_ALLEY를 추가한 Host 헤더 값으로 요청을 보내야 nginx에서 이를 분기하여 요청을 전달한다.
여기서 alley는 기본값으로 세팅이 돼있어 아무런 작업 없이 해당 엔드포인트에 접근할 수 있다.
package.json에서 발견된 취약점이다.
alley: index.html 렌더링해서 반환 -> 여기서 guardian 엔드포인트 접근 가능
think: 요청 헤더값을 json 형식으로 반환
guardian
현재 guardian 엔드포인트로 진입하기 위해서는 SECRET_ALLEY을 알아야한다. 이를 알기 위해서는 현재 default.conf에 적용된 로직의 허점을 이용하면 된다.
현재 alley 서브 도메인의 요청 처리에서는 Host 헤더값을 명시하지 않을 경우 기본값으로 설정된 alley.SECRET_ALLEY으로 요청을 전달한다.
이를 토대로 Burp Suite 상에서 Host 헤더를 지우거나 빈 값으로 해서 요청을 보냈는데 400 에러가 떴다.
이는 HTTP/1.1 프로토콜 규격상 Host 헤더가 필수이기 때문에, 이 제약사항을 우회하기 위해선 1.0 프로토콜을 사용해야해서 curl 명령어를 통해 HTTP/1.0 프로토콜로 요청을 보냈다.
curl -s --http1.0 -H "Host:" http://154.57.164.74:31983/think
그랬더니 응답이 잘 왔고, alley.firstalleyontheleft.com으로 설정된 것을 확인할 수 있었다.
현재 이 필터링은 앞서 말했듯이 hostnmae이 localhost으로 끝나거나 localhost이면 통과되는 로직이다. 여기서 중요한 점은 헤더에 Flag값이 추가돼서 요청을 보내는데, 이때 헤더 값을 보여주는 /think로 요청을 보내면 그 응답값을 받아와 렌더링해주니 그냥 http://localhost:1337/think로 quote를 정의해서 요청을 보내면 flag 값을 받아올 수 있다.