81 lines
3.4 KiB
C#
81 lines
3.4 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using Paca.Mobile.Core;
|
|
using Xunit;
|
|
|
|
namespace Paca.Tests.Mobile;
|
|
|
|
/// <summary>
|
|
/// RED TEAM ATTACK SUITE: P2P QR 페어링 및 미디어 무결성 적대적 공격 테스트
|
|
/// 1. 조작된 체크섬/토큰 주입 시 디코딩 거부
|
|
/// 2. 잘못된 프로토콜 프리픽스 및 악의적 URI 주입 방어
|
|
/// 3. 헤더 매직 바이트 위조(앞 4바이트만 맞고 바디가 절단된 Truncated 공격) 방어
|
|
/// </summary>
|
|
public class MobileP2pAndMediaAdversarialTests
|
|
{
|
|
[Fact]
|
|
public void RedTeam_QrPayload_ChecksumTampering_MustReject()
|
|
{
|
|
var payload = new P2pQrPayload
|
|
{
|
|
Host = "192.168.1.100",
|
|
Port = 52100,
|
|
Token = "token-xyz-123",
|
|
DeviceName = "Desktop-PC"
|
|
};
|
|
var encoded = P2pQrPayloadCodec.Encode(payload);
|
|
|
|
// 페이로드 중간의 토큰 1글자 변조
|
|
var tampered = encoded.Replace("token-xyz-123", "token-EVIL-666");
|
|
|
|
var success = P2pQrPayloadCodec.TryDecode(tampered, out var decoded);
|
|
|
|
Assert.False(success, "[Red Team] 체크섬과 본문 내용이 불일치하는 변조된 QR 페이로드는 거부되어야 합니다.");
|
|
Assert.Null(decoded);
|
|
}
|
|
|
|
[Fact]
|
|
public void RedTeam_QrPayload_InvalidPrefix_Or_CorruptedUri_MustReject()
|
|
{
|
|
Assert.False(P2pQrPayloadCodec.TryDecode("http://attacker.com/fake-pair", out _));
|
|
Assert.False(P2pQrPayloadCodec.TryDecode("paca://invalid?h=1&p=bad&sig=000", out _));
|
|
Assert.False(P2pQrPayloadCodec.TryDecode("", out _));
|
|
Assert.False(P2pQrPayloadCodec.TryDecode(null!, out _));
|
|
}
|
|
|
|
[Fact]
|
|
public void RedTeam_MediaIntegrity_TruncatedPayload_MustDetectCorruption()
|
|
{
|
|
// MP4 매직 'ftyp'는 존재하지만 크기가 6바이트로 잘린 비정상 스트림
|
|
var truncatedMp4 = new byte[] { 0x00, 0x00, 0x00, 0x20, 0x66, 0x74 };
|
|
Assert.False(MediaIntegrityVerifier.ValidateMediaHeader(truncatedMp4, ".mp4"));
|
|
|
|
// 0바이트 파일
|
|
var zeroByteResult = MediaIntegrityVerifier.InspectIntegrity(Array.Empty<byte>(), "video.mp4");
|
|
Assert.False(zeroByteResult.IsValid);
|
|
Assert.Contains("0바이트", zeroByteResult.ErrorReason);
|
|
|
|
// 확장자와 내용물 불일치 공격 (WebM 헤더를 가진 파일을 .mp4로 위장)
|
|
var webmHeader = new byte[] { 0x1A, 0x45, 0xDF, 0xA3, 0x00, 0x00, 0x00, 0x00 };
|
|
var spoofResult = MediaIntegrityVerifier.InspectIntegrity(webmHeader, "fake_video.mp4");
|
|
Assert.False(spoofResult.IsValid, "[Red Team] 확장자(.mp4)와 실제 컨테이너(WebM) 헤더가 불일치하면 무결성 검증이 실패해야 합니다.");
|
|
}
|
|
|
|
[Fact]
|
|
public void RedTeam_MediaIntegrity_Sha256Tampering_MustDetect()
|
|
{
|
|
var validMp4 = new byte[64];
|
|
validMp4[4] = 0x66; validMp4[5] = 0x74; validMp4[6] = 0x79; validMp4[7] = 0x70; // ftyp
|
|
|
|
var correctHash = Convert.ToHexString(SHA256.HashData(validMp4)).ToLowerInvariant();
|
|
var forgedHash = correctHash.Substring(0, 60) + "dead"; // 끝 4자리 위조
|
|
|
|
var result = MediaIntegrityVerifier.InspectIntegrity(validMp4, "test.mp4", forgedHash);
|
|
|
|
Assert.False(result.IsValid);
|
|
Assert.False(result.ChecksumMatch);
|
|
Assert.Contains("불일치", result.ErrorReason);
|
|
}
|
|
}
|