https://dreamhack.io/wargame/challenges/1151
Admin의 KEY값을 입력하여 플래그를 획득하는 문제입니다.
플래그 형식은 DH{...} 입니다.
KEY = hashlib.md5(FLAG.encode()).hexdigest()
guest_key = hashlib.md5(b"guest").hexdigest()key의 값은 플래그 값을 바이트로 변환하고, MD5로 해시하고, 16진수 문자열로 변환한 결과입니다.
if cmd != '' or key == KEY:
if not filter_cmd(cmd):
try:
output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
return render_template('flag.html', txt=output.decode('utf-8'))
except subprocess.TimeoutExpired:
return render_template('flag.html', txt=f'Timeout! Your key: {KEY}')
except subprocess.CalledProcessError:
return render_template('flag.html', txt="Error!")
return render_template('flag.html')
else:
return redirect('/')if cmd != '' or key == KEY: 코드 때문에 cmd가 비어있지 않기만 하면(= 아무 문자열만 넣어도) 키 검증을 건너 뛰고 명령 실행 루틴으로 들어가는걸 확인할 수 있습니다.cmd_input도 받습니다.key를 cmd_input 으로 바꾸어 key 입력창을 cmd 입력창으로 바꾸었습니다. 

cmd_input = ls 를 입력해 주었더니 파일 리스트를 확인할 수 있었습니다.
flag.txt를 발견해 cat flag.txt로 접근이 가능할까 하여 입력해 보았지만, 별 다른 반응이 없었습니다. 위에서 알아낸 timeout을 이용해야 함을 알 수 있었습니다.

cmd_input=sleep 6 을 입력해줍니다. sleep는 명령어 중 하나로, 지정한 초 동안 프로세스를 멈추게 하는 명령어입니다. 명령 실행이 5초 이상으로 걸릴경우 key가 출력됨으로 6초동안 멈추게 설정하였습니다. 입력 필터링은 존재하지만, 소문자는 정상적으로 입력 가능하고 sleep이 필터링 단어로 지정되어 있지도 않기에 정상적으로 공격이 가능합니다.
6초 후, timeout이라며 key를 알려주는걸 확인할 수 있습니다. 이를 key 입력칸에 입력해주었습니다.


if cmd != '' or key == KEY: 의 원래 의도는 AND였을 텐데, OR을 사용하여 전부 우회할 수 있게 되었습니다. 논리 조건 하나의 잘못된 사용이 시스템 전체를 위태롭게 할 수 있음을 깨달았습니다.if cmd != '' or key == KEY allowed bypassing key verification if any command was provided.cmd_input, which could be manipulated using Burp Suite.ls revealed files, including flag.txt.sleep 6 triggered the 5-second timeout, which leaked the admin KEY.