xz
5.6.0
(version and) 명령을 사용하여 출시된 백도어에 대해 읽어보셨을 것입니다 5.6.1
.
악의적인 커미터는 관리자의 신뢰를 얻고 일부 코드를 빌드에 삽입합니다.sshd를 대상으로 하고 백도어 생성.
모든 Linux 배포판의 다른 파일 .o
도 동일한 백도어의 영향을 받을 수 있습니다.
악의적인 커미터가 여기서 성공적으로 수행한 작업은 다른 곳에서도 수행할 수 있습니다. 아마도 몇 년 전이겠지...
Linux 배포판 설계자가
이러한 백도어를 기꺼이 제거하려는 경우, 손상된 실행 파일(전환된 빌드 프로세스에 의해 생성됨)을 어떻게 계속 찾아야 합니까?
지금까지 본 방법은 다음과 같습니다.
생성된 모든 Linux 명령에 대해 모든 빌드 프로세스를 확인하세요.
확인해야 할 git 저장소가 많은 것 같습니다.또한 기존
.o
파일을 각각 분해
하고 해당 어셈블리 코드를 살펴보고 실행 파일이 수행해야 하는 작업과 일치하는지 확인하세요.
이 백도어를 추적하려면 어떤 다른 방법을 사용해야 합니까?
답변1
귀하의 2. 옵션은 실행 가능하지 않으며 1. 옵션을 포함해야 합니다. "해야 할 일"이 무엇인지 어떻게 알 수 있나요? 예, 소스 코드에는 수행해야 하는 작업이 나와 있습니다. 그러나 최신 바이트/머신 코드의 분해는 이를 생성하는 데 사용된 원본 C/C++/rust/... 코드와 거의 완전히 다르게 보입니다. libreoffice calc를 분해하여 그것이 오피스 제품군의 스프레드시트 편집기 구성 요소이고 "날짜별 정렬" 기능이 이 작업을 한 시간 안에 수행하는지 확인할 수는 없습니다. 매우 간단한 것을 알아내려면 몇 시간이 걸리고 많은 경험이 필요하며 도구는 , liblzma처럼 복잡한 라이브러리 전체로는 할 수 없고, Firefox처럼 복잡한 라이브러리로는 100년 안에도 할 수 없을 것입니다.
따라서 다른 방향을 확인해야 합니다. 내가 얻고 있는 기계어 코드가 검토된 소스 코드를 실제로 번역한 것입니까?
소스 코드를 객체 파일의 기계어 코드로 변환하는 방법은 무엇입니까? 맞습니다. 컴파일러를 실행합니다. 컴파일러는 어떻게 실행하나요? 프로젝트의 빌드 시스템을 사용합니다.
그것이 바로 처음에 공격을 받는 것입니다.
따라서 삽입을 "볼" 수 있는 유일한 방법은 인간의 코드와 도메인 지식을 사용하여 전체 코드 트리에 대한 심층적인 검토를 수행하는 것입니다. 당신이 그것을 조사할 때 그것을 설명해줄 무언가를 개발한 사람이 본질적으로 필요합니다. 바로 거기에 또 다른 타당성과 또 다른 신뢰 문제가 있습니다! 악의적인 코드 삽입은 빌드 시스템의 수정된 M4 코드(언어)에서 발생합니다.빌드 시스템 작성자를 포함하여 잘 알려져 있습니다.너무 신비해서 아무도 그것을 이해하지 못하고 다른 사람의 코드를 복사합니다.
자동으로 무엇을 할 수 있나요? 익스플로잇 내용을 보면하다일단 로드되면 백도어 라이브러리와 완전히 다른 소프트웨어 기능을 수정합니다. 이를 감지하는 것은 쉽지 않습니다. 소프트웨어에서 항상 수행하기 때문입니다. 프로그램이 공유 객체를 로드할 때마다 해당 공유 객체의 초기화 함수가 실행되고, 마지막으로 의미하는 바에 관계없이 라이브러리를 초기화하고 채워 넣습니다. 기호(즉, 이 라이브러리에서 사용되는 함수의 함수 이름)를 함수의 주소로 변환하는 테이블의 항목입니다. 간단히 말해서, 그것은동적 링크.
자, 이 해커가 매우 우아하게 한 일은 엉망이었습니다.다른심지어 자신의 상징도 아닙니다. 안타깝지만 현재 우리는 이에 대한 적절한 보호 장치를 갖추고 있지 않습니다. 부분적으로는 플러그인 API부터 런타임 스케줄러(예: GCC ifunc
기능)에 이르기까지 너무 많은 기능이 이에 의존하기 때문입니다. 이 모든 것을 달성할 수 있다는 점에 유의하세요.당신이 어떻게 생각하든 상관없어.
예를 들어, 나는 어느 정도 참여하고 있습니다.도서관다양한 프로세서에 대한 벡터 최적화, 직접 최적화 및 컴파일러 최적화 버전이 포함된 수학 커널("C 컴파일러의 대상인 모든 것", "MMX 지원이 포함된 x86용", "AVX2 지원이 포함된 x86_64용", " aarch64 + NEON", "altivec이 포함된 PPC용", ... 및 이들의 조합). 하지만 모든 것이 실현되는 것은 아닙니다! 따라서 어떤 경우에는 "일반 C" 구현으로 대체해야 할 수도 있습니다.
이제 소비자가 호출하는 함수는 multiply_two_vectors(float* out, const float* vec1, const float* vec2, int num)
그렇지 않은 것처럼 보이지만 multiply_two_vectors_on_CPU_with_MMX_SSE_SSE2_SSSE3_AVX_AVX2(…)
라이브러리는 추가 런타임 오버헤드 없이 CPU에 대해 "마법처럼" 가장 빠른 구현을 선택합니다. 어떻게? 초기화 함수가 들어와서 최상의 구현을 식별하는 벤치마크 테이블에서 값을 가져오고 가장 빠른 함수의 주소를 테이블에 넣습니다 multiply_two_vectors
. 그게 다야. GCC를 사용하여 동일한 기능을 얻을 수 있지만 ifunc
GCC가 있는 시스템에서만 작업할 수 있습니다. Linux에서는 작동하지만 clang으로 컴파일된 Linux 시스템이나 Mac OS에서는 작동하지 않습니다. 다른 BSD에서도 작동하지만 작동하지 않습니다. Windows에서는 작동하지 않으며 clang으로 컴파일된 Linux 시스템에서는 작동하지 않습니다. 인텔 ICC가 아닌 IBM zOS에서... 이 라이브러리에는 심각한 문제가 있습니다.
따라서 다른 많은 라이브러리와 마찬가지로 초기화 시 자체 예약을 수행합니다. 따라서 초기화 함수의 실행 내용을 변경하기 위해 심볼 테이블 항목을 수정하는 것이 흔한 광경이다. 그러나 이러한 초기화와 상황이 바뀔 수 있다는 사실이 이러한 악용으로 이어지는 원인의 일부입니다. 따라서 ifunc
조회 사용이나 사용자 정의 공유 객체 파일 이니셜라이저 자체는 무언가가 의심스럽다는 것을 보장하지 않습니다. 실제로 코드는 대부분의 경우 컴파일러에 의해 자동으로 생성되며 일부 사용 사례에 맞게 최적화될 수 있습니다.
문제는 더욱 심각합니다. 이러한 모든 수정 사항은 완벽하게 정상적인 라이브러리 코드에서도 수행될 수 있습니다. 내 라이브러리는 multiply_two_vectors
초기화 프로그램이 아닌 실행 중인 프로세스에 대해 함수가 패치되었는지 확인 하고 필요한 경우 모든 호출을 해당 함수로 바꾸 printf
거나 printf("chickens!\n")
원하는 모든 나쁜 작업을 수행할 수 있습니다. 문제는 실제로 프로그램 공간이 아닌 프로그램 공간의 일부를 건드릴 수도 있다는 것입니다.대개그러나 이것은 또한 매우 경험적 실현이며 생태계 전반의 분석으로 쉽게 변환되지 않습니다. 함수가 호출될 때만 수정이 발생하는 경우(실제로는 SSH 데이터를 처리하는 데 필요한 함수) 누군가가 압축 해제 후 정확히 133700바이트 길이의 패킷을 보내면 어떻게 될까요? 이 동작을 "우연히" 실행할 수는 없습니다.
실제로 맬웨어는 행동 탐지를 회피하기 위해 많은 작업을 수행하는 경우가 많습니다. 예를 들어, 많은 바이러스는 현재 프로세스에 디버거가 연결되어 있거나 가상 머신에서 실행 중이거나(적어도 데스크톱 사용자를 대상으로 하는 경우) 실행 중인 장치의 IP 주소를 감지하면 아무 작업도 수행하지 않습니다. 그들은 이란의 우라늄 가스 원심분리기에서 작동되었습니다(스턱스넷(Stuxnet)을 기억하십시오!).
따라서 배포판에 권장할 "한 가지"가 없다는 것을 알게 될 것입니다. 물론 "읽고 신뢰한 코드만 릴리스하도록 주의"하는 것은 좋은 일이지만 그것이 그들이 원하는 일이고 이상적으로는 어쨌든 여전히 달성할 수 없습니다.
이 경우 취약점은 tarball에만 존재하며 업스트림 git 저장소에는 존재하지 않습니다. 따라서 "타르볼을 사용하지 말고 git repo를 사용하십시오!"는 또 다른 좋은 권장 사항이지만 일부 배포판에서는선호하다그리고필요하다그들은 개발자가 마지막 패키지 빌드 기반인 git 해시를 삭제하지 않는 것에 의존하고 싶지 않기 때문에 타르볼을 사용합니다. 이것은 양날의 검입니다!