'll Hacker
2주차 강의. 모의해킹 대비 OWASP top 10으로 뽀개기 심화스터디 본문
A02️⃣: Cryptographic Failures
민감한 데이터 노출의 원인이 암호화이라고 생각해서 이름을 변경했다고 한다.
암호화 시스템이 실패하면 악의적인 행위자가 암호화된 데이터에 무단으로 액세스하여 이를 해독하고 자신의 이익을 위해 악용할 수 있다. 암호화 실패로 인해 발생하는 가장 중요한 위험 중 하나는 개인정보 노출이다. 조직과 개인은 재무 정보, 의료 기록 및 개인 식별 정보와 같은 기밀 데이터를 보호하기 위해 암호화에 의존한다. 암호화 시스템이 실패하면 이 정보는 도난 및 오용에 취약해진다.
이것 때문에 하나의 사건이 있다.
SK텔레콤 유심 정보 유출 사고
2025년 4월 18일 , SK텔레콤 의 홈 가입자 서버(HSS) Home Subscriber Server.
namu.wiki
유심이 대칭키 기반 인증방식을 사용했다. 즉 인증 서버와 유심에 같은 키가 저장돼 있었고, 메시지와 그 MAC을 가지고 인증 방식을 사용했다. - 교수님이 그랬음.. 그만큼 키 관리가 중요하다.
안전하지 않은 구현이나 약한 알고리즘과 같은 암호화 결함은 공격자가 암호화된 데이터를 해독하는 데 악용될 수 있다. 악명높은 Heartbleed 버그와 같은 TLS 취약성은 해커가 보안 연결을 가로채서 전송된 데이터의 기밀성과 무결성을 손상시킬 수 있도록 한다. 암호 해싱 취약성도 심각한 위험을 초래하는데, 제대로 해싱되지 않은 암호는 쉽게 해독되어 시스템에 대한 무단 액세스를 허용할 수 있기 때문에 위험하다.
암호화 오류의 원인은 다음과 같다:
- 약한 키 생성
- 알고리즘 결함
- 적절치 못한 암호화 시스템
- 사이드 채널 공격
매핑된 CWE | 최대 발생률 | 평균 발생률 | 평균 가중 익스플로잇 | 평균 가중 영향 | 최대 범위 | 평균 범위 | 총 발생 횟수 | 총 CVE |
29 | 46.44% | 4.49% | 7.29 | 6.81 | 79.33% | 34.85% | 233,788 | 3,075 |
주목할 만한 공통적 CWE는 CWE-259, CWE-327, CWE-331 이다.
CWE-259 : Use of Hard-coded Password
하드 코딩된 비밀번호란? 프로그램 코드 안에 고정된 형태로 저장된 비밀번호이다. 즉, 프로그램 코드안에 비밀번호를 적는 것이다.
하드코딩된 비밀번호는 일반적으로 시스템 관리자가 감지하기 어려울 수 있는 심각한 인증 실패로 이어진다. 감지되면 수정하기 어려울 수 있으므로 관리자는 완전히 비활성화해야할 수도 있다.
* 하드코딩된 비밀번호의 2가지 주요 변형
case1: 인바운드 변형 - 사용자가 서버로 접근하거나 데이터를 업로드하는 상황에서 문제 발생한다.(서버에 업로드)
- 제품 설치 시 기본 관리자 계정과 고정된 비밀번호가 자동으로 생성된다.
- 이 비밀번호는 제품을 설치할 때마다 항상 동일하게 설정된다.
- 관리자 입장에서는 비밀번호를 바꾸고 싶어도, 프로그램을 직접 수정하거나 다시 빌드하지 않으면 변경 불가능
- 환경 변수나 설정 파일로 바꿀 수 없고, 소스코드에 직접 들어있기 때문임. - 결과적으로, 제품을 설치한 모든 조직이 같은 비밀번호를 사용하게 되므로, 하나만 뚫려도 나머지도 위험해진다.
즉, 변경하거나 비활성화할 수 없다라는 말은 사용자가 이 비밀번호를 설정 파일이나 UI로 바꿀 수 없고, 코드를 수정해서 새로 컴파일해야만 바꿀 수 있다.
case2 : 아웃바운드 변형 - 클라이언트가 서버에서 데이터를 받는 경우에 문제 발생한다.(서버에서 다운로드)
- 예: 클라이언트가 백앤드 서버에 접근할 때 필요한 인증 정보를 코드에 하드코딩하는 경우
- 백엔드 서비스에 접근하려면 인증이 필요한데, 프로그래머가 비밀번호를 프론트엔드 앱에 직접 하드코딩한다.
- 사용자는 이 앱을 분석하거나 디컴파일해서 그 비밀번호를 손쉽게 추출가능
- 특히 클라이언트 측에 저장된 비밀번호는 바이너리 분석 도구로 쉽게 확인되므로 더 큰 보안 위협이 된다.
OpenAI API 키 설정
openai.api_key="sk-proj-........A"
...
...
이 코드는 누구나 소스코드나 깃 저장소에서 API 키를 볼 수 있다. 악의적인 사람이 이 키를 가져가면, OpenAI API를 도용하거나 비용을 유발하는 악용이 가능하다. 특히 공개된 GitHub 저장소에 올릴 경우, 키는 몇 분만에 봇에 의해 수집된다.
보안적으로 올바르게 키 관리
M1) 환경변수로 API 키 관리
# 환경 변수 설정 (Linux/macOS)
export OPENAI_API_KEY="sk-proj-..."
# Windows
set OPENAI_API_KEY=sk-proj-...
import os
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
M2) .env 파일 사용한다 (파이썬에서 python-dotenv) 이 .env파일 .gitignore에 추가하기
# ini 확장자 파일
OPENAI_API_KEY=sk-proj-...
from dotenv import load_dotenv
import os
import openai
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")
관련 CVE:
- CVE-2022-29964 : 2022년 4월 29일까지 Emerson DeltaV 분산 제어 시스템(DCS) 컨트롤러와 IO 카드에서 비밀번호가 오용되었습니다. WIOC SSH는 하드코딩된 자격 증명을 통해 루트, DeltaV 또는 백업 계정으로 셸에 액세스할 수 있도록 합니다
- CVE-2022-37555 : 개, 고양이용 IoT 피더용 텔넷 서비스에 비밀번호가 하드코딩되어 있음
- CVE-2021-35033 : 사전 구성된 암호 관리 기능이 있는 Zyxel NBG6818, NBG7815, WSQ20, WSQ50, WSQ60 및 WSR30 펌웨어의 특정 버전에 있는 취약점으로 인해 로컬 공격자가 장치를 분해하고 USB-UART 케이블을 사용하여 장치를 연결하거나 인증된 사용자가 원격 지원 기능을 활성화한 경우 공격자가 장치의 루트 액세스 권한을 얻을 수 있습니다.
CWE-327 : Use of a Broken or Risky Cryptographic Algorithm
손상되었거나 위험한 암호화 알고리즘이나 프로토콜 사용
안전하지 않은 암호화는 민감한 정보를 노출하거나, 예상치 못한 방식으로 데이터를 수정하거나, 다른 사용자나 기기의 신원을 스푸핑하거나 기타 영향을 미치는데 악용될 수 있다.
EVP_des_ecb();
Cipher des=Cipher.getInstance("DES...");
des.initEncrypt(key2);
function encryptPassword($password){
$iv_size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "This is a password encryption key";
$encryptedPassword = mcrypt_encrypt(MCRYPT_DES, $key, $password, MCRYPT_MODE_ECB, $iv);
return $encryptedPassword;
}
DES 사용했다. 요즘은 AES로 사용된다.
DES는 Feistel 구조이다.
Feistel 암호⏬
샤논의 개념을 채용해 1973년에 개발된 최초의 암호시스템이다.
Feistel 암호의 특성은 대부분의 대칭키 암호 시스템에 적용된다.
페이스텔 암호에서는 평문 P 가 왼쪽과 오른쪽으로 반반씩 나뉘어 구성된다.
P = (L0, R0)
페이스텔 암호에서는 라운드라는 암호화의 단계를 여러 번 반복해서 수행하도록 되어있다. 각 i = 1, 2, 3, .... n 번째 라운드에서 새로운 왼쪽 반과 오른쪽 반은 다음 규칙에 따라 계산된다.
Li = Ri-1
Ri = Li-1 ⊕ F(Ri-1, Ki)
여기서 Ki 는 i 번째 라운드에서 사용되는 서브키이고 F 는 라운드 함수이다. 서브키는 키 스케줄 알고리즘에 따라 키 K 로 부터 얻어진다. 최종 암호문은 마지막 라운드의 출력이다.

페이스텔 암호의 작동 방식
① 라운드 입력을 L 과 R 로 나눈다.
② R 을 라운드 함수 F 로 보낸다.
③ 라운드 함수 F 는 R 과 서브키 k 를 입력으로 사용하여 랜덤하게 보이는 비트를 계산한다.
④ 얻어진 비트열과 L 을 XOR 해 다음 라운드 R 의 입력이 된다.
⑤ 현재 라운드의 R 은 다음 라운드 L 의 입력이 된다.
페이스텔 암호의 장점은 특정한 라운드 함수 F 와 무관하게 복호화 할 수 있다는 점이다. 복호화는 암호화의 역순으로 진행하면 된다. 복호화는 다음과 같이 진행된다.
Ri-1 = Li
Li-1 = Ri-1 ⊕ F(Li-1, Ki)
즉, 페이스텔 암호의 복호화는 서브키를 사용하는 순서를 역으로 하는 것만으로 실현 가능하기 때문에 암호화와 복호화를 완전히 동일한 구조로 실현할 수 있다.

페이스텔 암호의 복호화
함수 F 의 출력이 정확한 길이의 비트를 생성한다면 어떠한 함수 F 도 페이스텔 암호에서 라운드 함수로 사용될 수 있다. 특별히 함수 F 의 역함수가 존재할 필요도 없다. 그렇다고 해서 가능한 모든 F 에 대해 페이스텔 암호가 안전한 것은 아니다. 페이스텔 암호의 또 한 가지 장점은 모든 안전성 문제가 라운드 함수 문제로 귀결된다는 것이다. 따라서 페이스텔 암호에 대한 분석은 함수 F 에 초점이 맞추어진다.
[출처] 페이스텔 암호(Feistel Cipher)|작성자 별의수다
암호화 과정은 두 개의 치환(P-박스)와 16개의 페이스텔 라운드 함수로 구성된다.
두 개의 P-박스 중 하나는 초기 치환, 다른 하나는 최종 치환이라고 한다.
짧은 키를 사용한다. DES 암호화 알고리즘 중, 비선형 방식과 선형 방식이 존재한다. 선형방식은 XOR, 자리바꿈, 순환이동 등으로 역연산이 가능하다.
취약한 암호화 알고리즘은 base64, MD5, SHA1, DES 등등등이 있다.
관련 CVE:
- CVE-2008-4120 : 민감한 데이터를 난독화하기 위해 “XOR”만 사용
- CVE-2002-2058 : 공격자는 각 옥텟을 MD5 해시값 ‘20’으로 나누어 개인 IP주소를 유추가능
- CVE-2005-2946 : 이 제품의 기본 구성에서는 기존에 사용 가능한 더 강력한 알고리즘 대신 MD5를 사용하여 인증서 위조를 간소화.
CWE-331 : Insufficient Entropy
암호학적 기능(예: 암호화 키 생성, 난수 생성 등)을 구현할 때 충분한 엔트로피(무작위성)을 사용하지 않아 발생하는 보안 취약점이다. 이 취약점은 난수 생성기나 암호학적 키가 예측 가능하게 되어 공격자가 이를 악용할 수 있는 가능성을 높인다.
엔트로피⏬
정보 이론에서 무작위성, 불확실성을 나타냄
보안분야에서 데이터를 예측할 수 없는 정도를 측정한다. 엔트로피가 높을수록 데이터가 예측하기 어려워지며, 이는 암호화 키나 난수 생성의 안전성을 높이는데 필수적이다.
ex1. 사용자 세션에 대한 고유한 임의 식별자 생성
function generateSessionID($userID){
srand($userID); // srand함수는 난수 생성 함수
return rand();
}
PRNG의 시드는 항상 사용자의 ID이므로 세션 ID는 항상 동일함.
따라서 공격자는 모든 사용자의 세션ID를 예측하고 세션을 하이재킹 가능하다.
PRNG⏬
개발할 때 게임에서 랜덤 아이템 뽑기에서 확률이 무작위로 정해지는데 이럴 때 무작위(랜덤)이 필요.
하지만 사실상 컴퓨터는 사용자가 시키는대로 실행하기 때문에 자체에서 무작위성을 만들 수 없어서 불가능하다!!
그래서 나온것이 PRNG임
PRNG는 수학을 이용해 난수에 가까운 숫자를 생성하지만 실제로는 무작위가 아닌 숫자를 생성하는 알고리즘이다
PRNG는 seed(시드)라고 하는 초기값이 필요한데 수학을 사용해서 초기 값으로부터 무작위적이고 예측 불가능한 숫자를 생성. 시드는 PRNG의 출력을 결정하기 때문에 결과값은 절대 무작위가 될 수 없어서 가능하면 예측할 수 없는 시드를 만들어야한다. 이를 엔트로피(예측불가능성)라고 함.
ex2. statistical PRNG를 사용하여 구매 후 일정 기간 동안 활성 상태를 유지하는 영수증의 URL을 생성
String GenerateReceiptURL(String baseUrl) {
Random ranGen = new Random();
ranGen.setSeed((new Date()).getTime());
return(baseUrl + ranGen.nextInt(400000000) + ".html");
}
이 코드는 Random.nextInt 함수를 사용하여 생성하는 영수증 페이지에 대한 고유 식별자를 생성함.
Random.nextInt 함수는 statistical PRNG이므로 공격자가 생성하는 문자열을 쉽게 추측가능
영수증 시스템의 기본 설계에도 결함이 있지만 암호화 PRNG와 같이 예측가능한 영수증 식별자를 생성하지 않는 난수 생성기를 사용하면 더 안전할 것임.
관련 CVE:
- CVE-2001-0950 : C rand( )를 사용하여 세션 토큰을 생성하는데 사용된 무작위 데이터가 충분하지 않음. 또한, 인증서/키 생성의 경우 엔트로피가 낮을 때 차단되지 않는 소스를 사용.
예방 방법
- 애플리케이션에서 처리, 저장 또는 전송되는 데이터를 분류하고, 개인정보보호법, 규제 요구사항 또는 비즈니스 요구사항에 따라 어떤 데이터가 민감한지 식별한다.
- 민감한 데이터를 불필요하게 저장하지 말것. 불가피시 암호화 필수임.
- 최신의 강력한 표준 알고리즘, 프로토콜, 키가 있는지 확인하고 적절한 키 관리를 사용한다.
제23조 (민감정보의 처리 제한)
① 개인정보처리자는 사상, 신념, 노동조합, 정당의 가입, 탈퇴, 정치적 견해, 건강, 성생활 등에 관한 정보, 그 밖에 정보 주체의 사생활을 현저히 침해할 우려가 있는 개인정보로써 대통령령으로 정하는 정보(=민감정보)를 처리하여서는 안된다.
다만, 각 호의 어느 하나에 해당하는 경우는 예외:
1. 정보주체에게 제15조 제2항 각 호 또는 제17조 제2항 각 호의 사항을 알리고 다른 개인정보의 처리에 대한 동의와 별도로 동의를 받은 경우
2. 법령에서 민감정보의 처리를 요구하거나 허용하는 경우
② 개인정보처리자가 제1항 각 호에 따라 민감정보를 처리하는 경우에는 그 민감정보가 분실, 도난, 유출, 위조, 변조 또는 훼손되지 않도록 제29조에 따른 안전성 확보에 필요한 조치를 해야한다.
③ 개인정보처리자는 재화 또는 서비스를 제공하는 과정에서 공개되는 정보에 정보주체의 민감정보가 포함됨으로써 사생활 침해의 위험성이 있다고 판단할 때에는 재화 또는 서비스의 제공 전에 민감정보의 공개 가능성 및 비공개를 선택하는 방법을 정보주체가 알아보기 쉽게 알려야 한다.
출처:
- TLS와 같은 보안 프로토콜을 사용하여 전송 중인 모든 데이터를 암호화하고 Forward Secrecy 암호, 서버의 암호 우선순위 지정한다. 보안 매개변수 사용한다. HTTP Strict Transport Security와 같은 지시문을 사용하여 암호화 시행한다.
Forward Secrecy⏬
개인 키가 노출된다고 하더라도 암호화된 데이터가 암호화된 상태로 유지되도록 한다.
각각의 통신 세션마다 고유한 세션 키를 사용하거나 세션 키를 개인 키와 별도로 생성하는 경우에 가능하다. 어느 하나의 세션 키가 손상되더라도 공격자가 해당 세션만 해독할 수 있을 뿐 다른 세션은 모두 암호화된 상태로 유지된다.
출처 : https://www.cloudflare.com/ko-kr/learning/ssl/keyless-ssl/
- 민감한 데이터가 포함된 응답에 대한 캐싱을 비활성화한다.
- 데이터 분류에 따라 필요한 보안 제어 적용한다.
- FTP, SMTP와 같은 기존 프로토콜을 사용하여 중요한 데이터를 전송하지 말 것
- Argon2, scrypt, bcrypt, 또는 PBKDF2와 같은 작업요소를 포함하는 강력한 적응형 및 솔트 해싱 함수를 사용하여 비밀번호를 저장한다.
- 초기화 벡터는 작동 모드에 맞게 선택해야한다. 많은 모드에서 이는 CSPRNG(암호학적으로 안전한 의사 난수 생성기)를 사용하는 것을 의미이다. nonce가 필요한 모드의 경우 초기화 벡터에 CSPRNG가 필요하지 않는다.
모든 경우에 초기화 벡터는 고정키에 두 번 사용해서는 안된다. - 단순 암호화 대신 항상 인증된 암호화를 사용한다.
- 키는 암호학적으로 무작위로 생성되어야 하며 바이트 배열로 메모리에 저장되어야한다.
- 적절한 경우 암호화 무작위성이 사용되고 예측가능한 방식이나 낮은 엔트로피로 시딩되지 않았는지 확인한다. 대부분의 최신 API는 개발자가 보안을 얻기 위해 CSPRNG가 난수를 생성하기 위해 사용되는 초기값, 즉 시드를 설정하는 것을 요구하지 않는다.
- MD5, SHA1, PKCS 번호 1 v1.5와 같은 더 이상 사용되지 않는 암호화 기능과 패딩 방식을 사용하지 말 것.
공격 시나리오 예: 사이트가 모든 페이지에 TLS를 사용하거나 적용하지 않거나 약한 암호화를 지원하지 않은 경우
공격자는 안전하지 않은 무선 네트워크를 모니터링하고, HTTPS에서 HTTP로 연결을 downgrade해서 요청을 가로채고(MITM 공격(중간자 공격)), 사용자의 세션 쿠키를 훔친다. 그런 다음 공격자는 이 쿠키를 재생하고 사용자 세션을 하이재킹하여 사용자의 개인 데이터에 액세스하거나 수정한다.
출처:
https://owasp.org/Top10/A02_2021-Cryptographic_Failures/
https://blog.naver.com/wnrjsxo/221707377342
'Hacking > EVI$ION(교내 해킹동아리)' 카테고리의 다른 글
4주차 강의. 모의해킹 대비 OWASP top 10으로 뽀개기 심화스터디 (2) | 2025.05.24 |
---|---|
3주차 강의. 모의해킹 대비 OWASP top 10으로 뽀개기 심화스터디 (0) | 2025.05.24 |
1주차 강의. 모의해킹 대비 OWASP top 10으로 뽀개기 심화스터디 (1) | 2025.05.17 |
0주차 강의. OT 모의해킹 대비 OWASP top 10으로 뽀개기 심화스터디 (1) | 2025.05.12 |