문제는 app.alert()가 전달받은 JavaScript 값을 문자열로 변환하는 과정에서 발생합니다.
공격자는 PDF의 OpenAction을 통해 문서가 열리자마자 아래와 같은 JavaScript가 실행되도록 구성할 수 있습니다.
app.alert(app.activeDocs, true);
이 경우 app.activeDocs는 정상적인 문자열 객체가 아니라 NULL에 해당하는 값으로 평가됩니다. 그러나 Nitro PDF Pro 내부 구현은 이 값을 적절히 검증하지 않고 JS_ValueToString() 및 JS_GetStringChars()로 전달합니다.
취약한 흐름은 아래와 같이 단순화할 수 있습니다.
app.alert(value, true)
→ JS_ValueToString()
→ JS_GetStringChars()
→ dereference crash
실제 취약 경로에서는 인자가 단순 문자열이 아닌 경우 JS_ValueToString()을 호출한 뒤, 그 반환값을 그대로 JS_GetStringChars()에 전달합니다.
if ( argc != 1 || (v16 = *argv, (*argv & 7) != 0) )
{
v30 = JS_ValueToString(a1, *argv);
StringChars = JS_GetStringChars(v30); // crash
}
문제는 app.activeDocs가 NULL임에도 불구하고, 반환값이 실제 유효한 문자열 객체인지 충분히 확인되지 않는다는 점입니다. 이후 JS_GetStringChars()는 전달받은 포인터를 문자열 객체라고 가정하고 내부 멤버를 참조합니다.
__int64 __fastcall JS_GetStringChars(__int64 *a1)
{
v1 = *a1;
...
}
이때 a1이 NULL 또는 유효하지 않은 포인터일 경우 Access Violation이 발생하며, Nitro PDF Pro는 즉시 종료됩니다.
