"!xxx%s%s%s%s%s%s%s%s"의 특별한 점은 무엇인가요?

"!xxx%s%s%s%s%s%s%s%s"의 특별한 점은 무엇인가요?

나는 연결되어 있다유닉스 혐오자의 핸드북그리고 우연히 발견한 내용은 다음과 같습니다(149페이지).

주제: 관련 Unix 버그

1991년 10월 11일

W4115x 동급생—

활성화 레코드, 매개변수 전달 및 호출 규칙에 대해 이야기하는 동안 다음을 입력해야 한다는 것을 알고 계셨습니까?

!xxx%s%s%s%s%s%s%s%s

C 쉘이 즉시 충돌을 일으키나요? 이유를 아시나요?

생각해 볼 질문:

  • 를 입력할 때 쉘은 무엇을 합니까 !xxx?
  • 입력할 때 입력한 내용과 어떤 관련이 있습니까 !xxx%s%s%s%s%s%s%s%s?
  • 이것이 쉘을 충돌시키는 이유는 무엇입니까?
  • 이 문제를 피하기 위해 쉘의 문제가 있는 부분을 어떻게 (상당히 쉽게) 다시 작성할 수 있습니까?

그냥 궁금해서 문제가 무엇인지 설명할 수 있는 사람이 있습니까? 당연히 Google에서 문자열을 검색해도 도움이 되지 않았습니다. 메시지에서 다른 참조를 검색하면 메시지의 다른 사본만 제공될 뿐 설명은 제공되지 않습니다.

답변1

25년 전 조개껍데기의 유래를 파헤치고 싶지는 않지만

그것은형식 문자열 취약점.

쉘에 다음 코드가 포함되어 있는 경우

printf(str);

str사용자 입력에서 가져온 문자열은 어디에 있으며, 그 내용은 printf사용된 형식 문자열이 됩니다. 인쇄 인수가 가리키는 문자열을 알려줍니다 %s. printf인수가 지정되지 않으면(위에서 언급한 대로 형식 문자열만) 함수는 스택에서 일부 추가 데이터를 읽고 이를 포인터로 따릅니다. 매핑되지 않은 메모리에 액세스하여 프로세스가 중단될 수 있습니다.

어느 정도 메시지의 문구도 그러한 해결책을 암시한다고 생각합니다. 예를 들어 를 입력하면 !xxx쉘은 분명히 오류 메시지를 인쇄합니다 !xxx: event not found. 거기에서 print 를 시도하는 것은 큰 도약이 아니며 !xxx%s%s%s%s%s%s%s%s: event not found이는 형식 문자열 취약점을 의미합니다.


이러지 말았어야 했는데 소스코드를 살펴보니여기( 4.3BSD-Tahoe/usr/src/bin/csh, 1988년부터).

findev(cp, anyarg)존재하다sh.lex.c일치하는 역사적 사건을 찾는 함수인 것처럼 보입니다. 연결된 struct Hist호출 목록을 반복합니다 Histlist. 아무것도 발견되지 않으면 를 seterr2(cp, ": Event not found");호출합니다 noev(). cp여기서는 기록에서 문자열을 검색하는 것처럼 보입니다.

seterr2()변수를 err매개변수의 연결로 설정하고 여러 위치에서 err사용합니다 .if (err) error(err);process()sh.c. 마지막으로 error()(에서sh.err.c)에는 전형적인 형식 문자열 취약점이 포함되어 있습니다.if (s) printf(s, arg), printf(".\n");

다른 곳에서는 error()인수와 함께 호출됩니다(예: ). 따라서 첫 번째 인수가 형식 문자열일 수 error("Unknown user: %s", gpath + 1);있다는 아이디어가 분명합니다 .error()

기록 교체 기능을 완전히 이해했다고 말하면 부정직한 것입니다. C에서 주석 처리되지 않은 수동 문자열 처리입니다. 이는 역사적 대체에서 특별한 의미를 가지지만 %첫 번째 문자(예: )가 호출된 !%이후에만 특별히 처리되는 것을 볼 수 있습니다 .findev()

관련 정보