
DARPA 작업의 IPMI 자료
IPMI를 탐구하기 위한 소프트웨어를 작성했고, 여기에 그 결과 중 일부를 소개합니다. 흔히 하는 탐지, 데이터 수집, 감사 같은 주기를 돌려보려고 했습니다. 각 단계는 적어도 저에게는 그 자체로 꽤 흥미로운 문제로 드러났습니다.
**참고/정보 ** - IPMI를 탐구하는 새 도구를 공개했습니다 - https://github.com/zenfish/zipmi - 그리고 Qemu에서 BMC를 가상 시스템으로 실행하기 위한 Qemu 레시피/이미지 등을 https://github.com/zenfish/zbmc에 공개했습니다.
http://fish2.com/ipmi 에서 제공하는 논문 및 자료들
다음은 원격 BMC의 계정을 추측하고, 그 해시를 추출한 뒤, (HMAC 해시된) 비밀번호를 크래킹하려고 시도하는 작은 Perl 프로그램입니다. 궁금한 분들을 위해 간단히 글을 써 두었습니다. 주석이 많이 달려 있어 어느 정도 유용하게 쓰일 수 있을 것입니다.
IPMI 사양에 따르면 인증 없이도 원격 시스템의 암호를 가져올 수 있다고 하지만, 실제로 이를 수행하는 도구는 알지 못합니다(모두 인증을 요구합니다. 물론 원한다면 원시 16진수 바이트를 입력할 수도 있겠지만요!). 그래서 이 작은 도구를 작성했습니다. 대부분 ipmitool 출력을 따르려고 했는데, 그 과정에서 해당 유틸리티의 버그를 발견한 것 같습니다(마지막 줄에서 때때로 시스템이 잘못 해석되는 것처럼 보이는 쓰레기 데이터를 내보냅니다). 하지만 테스트할 시스템이 충분하지 않으니 확실하지는 않습니다. 어쨌든... ipmi-get-ciphers.py.
다른 용도가 없더라도 Cipher0 시스템을 찾아내는 데 유용합니다(참고 - 이는 단순히 지원되는 암호를 알려줄 뿐이며, 실제로 활성화되어 있다는 뜻은 아닙니다). 그런데 실제 환경에는 흥미로운 것들이 존재합니다.
여기에는 두 개의 프로그램이 있습니다. 하나는 간단한 Python 원격 프로버이고(Perl이 점점 싫어지고 있다는 말씀을 드려야겠군요), 다른 하나는 FreeIPMI의 유틸리티를 사용하여 인증된 구성 데이터를 가져오는 프로그램입니다.
BMC에 단일 패킷을 보내고 응답을 곰곰이 분석하는 작은 Python 프로그램입니다(50% 이상이 인라인 주석, gzip 압축 시 2.5k). 단일 패킷만으로 무엇을 할 수 있냐고 물으실 수 있겠지만, 우선 IPMI에 대한 10가지 이상의 다양한 보안 테스트가 가능합니다. 시작이든 끝이든, 결국 패킷 하나일 뿐입니다 :) Python과 BMC, 그리고 UDP 포트 623으로의 열린 경로가 필요합니다. 사용법은 간단히 "ipmi-get-auth.py target"입니다.
이를 극한까지 밀어붙이면... 음, 위의 것을 모든 채널, 모든 권한, 모든... 음, 대충 감이 오시겠죠. 강박적인 분들을 위해(왜 그런 동작을 하는지 알고 싶다면 주석이나 제가 작성한 글을 읽어보세요!)
mega_chan.py /
Mega mega mega ... chan chan chan...
그리고 시스템에 Get Device ID 패킷(IPMI v2 사양 250페이지 참조)을 보내는 간단한 프로그램입니다. 이론적으로는 인증 없이 작동해야 합니다. 제가 실시한 작은 조사에서 약 90%의 시스템이 이에 응답했습니다(모두 유효한 정보를 제공한 것은 아니지만요!). 때로는 벤더 및 모델 번호 같은 기타 정보를 얻을 수 있지만, 더 흥미로운 점은 전통적으로 네트워크를 통해 얻기 어려운 고유 ID를 실제로 얻을 수 있다는 것입니다.
get-ipmi-guid.py /
Get Device ID
Supermicro는 BMC의 비밀번호 파일 노출과 관련하여 몇 가지 문제를 겪어 왔습니다. 예를 들어 다음 글과 다른 분석 글들을 참조하세요:
a-penetration-testers-guide-to-ipmi
이 스크립트를 사용하려면 간단히 다음과 같이 입력하면 됩니다:
dump_SM.py password_file
제 환경에서는 잘 동작합니다. 보증은 없습니다. 보장도 없습니다. 등등.
음, UDP 포트 623과 통신할 수 있다면 원격 시스템이 IPMI를 실행 중인지 알아내는 것은 꽤 간단합니다. 하지만 데이터 센터 내부에 있지 않은 한, 대부분의 사람들은 UDP를 차단합니다. 그리고 설령 차단하지 않더라도... UDP 스캐닝은 상상할 수 있는 한 가장 느립니다. 그래서 저는 현재 유서 깊은 Nmap과 ipmiping(FreeIPMI Gnu 도구에서 제공)을 활용한 두 가지 기본 방법을 사용하고 있습니다. 가장 쉬운 방법은 다음과 같습니다:
</p> <p>
Nmap이 대규모 네트워크 스캐닝에서 ipmiping보다 훨씬 효율적이므로, 이 방법은 Nmap이 호스트의 UDP 623이 열려 있다고 알려줄 때만 사용됩니다.
</p> <p>
좋든 싫든 이 포트는 종종 차단되므로, 대부분의 경우 IPMI가 실행 중인지 간접적으로 알아내려면 다른 방법이 더 유력합니다.
</p> <p>
포트는 지시적 능력과 Nmap이 해당 포트를 열림, 필터링됨 또는 기타 상태로 발견했는지 여부에 따라 가중치가 부여됩니다.
</p> <p>
Nmap은 또한 연결된 서비스의 배너를 표시할 수 있습니다. 저는 정규 표현식을 사용하여 대상을 찾습니다. 예를 들어 "iLO"와 "DRAC" 문자열은 시스템이 HP의 Integrated Lights Out 서비스, 즉 iLO를 실행 중일 수 있다는 좋은 지표입니다.
</p> <p>
<strong>참고:</strong> 현재 저는 브로드캐스트 핑 방법(자신이 위치한 서브넷을 매우 빠르게 훑는 방법)을 사용하지 않습니다. 이 방법의 효과에 대한 데이터가 전혀 없기 때문입니다. 동작할 때는 매우 빠르지만, 임의 스캔의 제어와 신뢰성을 허용한다고 느끼지 못했습니다. 제 시스템 세 대 중 두 대(Dell과 HP)는 RMCP 핑에 응답했습니다. idiscover(ipmiutil discover)를 통한 브로드캐스트 핑에는 아무도 응답하지 않았습니다. 그러나 모두 아래의 제 Python 감사 도구에는 응답했습니다.
</p> <p>
불행히도(당연히도!) 통신과 네트워크의 유령이 개입합니다. nmap은 포트가 열려 있는지 아닌지(열림, 닫힘, 필터링됨 등)에 대해 여러 가지 다른 이유를 제시합니다. 또 다른 표에는 열린 포트에 "open|filtered"(Nmap이 표현할 수 있는 대로) 히트보다 더 많은 점수를 주는 가중치 집합이 있습니다. nmap을 해석하고 가중치를 부여하는 것은 다소 답답한 면이 있지만, 그게 인생입니다.
</p> <p>
모든 가중치를 취하고 모든 점수를 합산하면 IPMI 확실성 수준을 얻게 됩니다. 임시 테스트에서 15점 이상이면 시스템이 IPMI를 실행 중이라는 강력한 지표임을 발견했습니다.
</p> <p>
현재 나는 다양한 임계값(아니오, 가능성 있음, 아마도, 예)을 가지고 있다. 테스트에서 - 내 서버 외에 다른 서버에 대한 알려진 접근 없이 - 그것은 상당히 잘 작동하는 것처럼 보인다. 즉, 내가 의심스럽다고 생각하는 것들과 위의 기본 사고 모델이 실제로 특정 서버들을 상위로 끌어올리고 무작위 호스트들은 그대로 둔다. 다만 오탐에 관한 실제 문제가 있다 - 많은 방화벽이 nmap에게 어떤 포트든 뭔가 있는 것처럼 보이게 하는 듯하다(희귀한 포트 하나둘을 끼워 넣을까 생각했다 (예를 들어 포트 1과 31313 같은 것을 듣고 있다면, 아마 *정말로* 그것을 듣고 있는 건 아닐 것이다!)
</p> <p>
하지만 이것이 이 주제에 대한 최종 결론이 되려는 것은 아니다. IPMI 배너에 대한 괜찮은 데이터를 얻는 것은 상당히 간단해야 하며, 내 추측으로는 대량의 시스템을 신속하게 스캔하는 데 있어 단연 최선의 방법일 것이다.
다음은 위의 내용을 구현하는 네 개의 Perl 조각이다. 하나는 스캔하고, 하나는 해석하며, 나머지 둘은 가중치 부여에 사용된다. 이것은 연구 도구 또는 개념 증명이며 프로덕션 스캐너는 아니지만, 합리적인 출력을 생성한다.
필수: Nmap 버전 6.
| ipmi_scan.pl - 기본 IPMI 스캐너, Nmap을 사용하며 가능한 경우 ipmitool도 사용 |
| ipmi_scan man page - 위의 man 페이지 |
| post_ipmi_scan.pl - 위의 출력을 파싱하여 가중치가 적용된 결과를 출력 |
| j_vendor.pl - 몇 가지 기본 벤더 데이터... 어느 벤더가 어느 포트를 사용하는가? |
| j_weights.pl - 위에 대한 몇 가지 기본 벤더 가중치 |
사용법은 다소 특이하지만 꽤 간단하다. root로 실행해야 한다. 많은 출력을 원하면 verbose(-v)를 사용한다.
스캔은 대상 이름에 대응하는 한 쌍의 결과 파일을 생성한다(슬래시는 밑줄로 변환된다). 그 파일들에 대해 후처리기를 실행하기만 하면 된다. 역순 숫자 정렬을 거치면 더 흥미로운 순서가 된다. 10을 넘는 것은 의심스럽다고 할 수 있으며, 20을 넘으면 IPMI가 실행 중일 가능성이 꽤 확실하다.# standard run: ./ipmi_scan.pl -A -v -O yes 192.168.0.0/24 # fast ./ipmi_scan.pl -tcp -v 192.168.0.0/24 # kitchen sink ./ipmi_scan.pl -A -v -O high 192.168.0.0/24
이 경우에는 terse 플래그(-t)를 사용하여 출력을 최소한으로 줄였다.