Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 11개 있습니다.)
.NET Framework: 404. 리플렉션을 이용해 닷넷 LicenseManager를 우회할 수 있는 사례
; https://www.sysnet.pe.kr/2/0/1565

.NET Framework: 428. .NET Reflection으로 다차원/Jagged 배열을 구분하는 방법
; https://www.sysnet.pe.kr/2/0/1653

.NET Framework: 537. C# - Reflection의 박싱 없이 값 형식을 다루는 방법
; https://www.sysnet.pe.kr/2/0/10866

.NET Framework: 685. C# - 구조체(값 형식)의 필드를 리플렉션을 이용해 값을 바꾸는 방법
; https://www.sysnet.pe.kr/2/0/11312

.NET Framework: 785. public으로 노출되지 않은 다른 어셈블리의 delegate 인스턴스를 Reflection으로 생성하는 방법
; https://www.sysnet.pe.kr/2/0/11583

.NET Framework: 842. .NET Reflection을 대체할 System.Reflection.Metadata 소개
; https://www.sysnet.pe.kr/2/0/11930

.NET Framework: 924. C# - Reflection으로 변경할 수 없는 readonly 정적 필드
; https://www.sysnet.pe.kr/2/0/12256

.NET Framework: 1045. C# - 런타임 시점에 이벤트 핸들러를 만들어 Reflection을 이용해 구독하는 방법
; https://www.sysnet.pe.kr/2/0/12609

.NET Framework: 1046. C# - 컴파일 시점에 참조할 수 없는 타입을 포함한 이벤트 핸들러를 Reflection을 이용해 구독하는 방법
; https://www.sysnet.pe.kr/2/0/12610

닷넷: 2155. C# - .NET 8 런타임부터 (Reflection 없이) 특성을 이용해 public이 아닌 멤버 호출 가능
; https://www.sysnet.pe.kr/2/0/13436

닷넷: 2249. C# - 부모의 필드/프로퍼티에 대해 서로 다른 자식 클래스 간에 Reflection 접근이 동작할까요?
; https://www.sysnet.pe.kr/2/0/13608




리플렉션을 이용해 닷넷 LicenseManager를 우회할 수 있는 사례

닷넷에는 LicenseManager라는 타입이 제공되어 기본적으로 이를 이용해 쉽게 라이선스 적용을 할 수 있습니다. 이 타입의 기본적인 사용법은 다음의 글에서 이미 살펴봤었습니다.

닷넷 System.ComponentModel.LicenseManager를 이용한 라이선스 적용
; https://www.sysnet.pe.kr/2/0/1045

그리고 우회할 수 있는 사례도 소개한 적이 있군요. ^^

AppDomain.GetEntryAssembly()를 우회하는 방법
; https://www.sysnet.pe.kr/2/0/566

라이선스까지도 뛰어넘는 .NET Profiler
; https://www.sysnet.pe.kr/2/0/1046

오늘은 우회할 수 있는 경우의 수를 하나 더 발견했습니다.

해당 어셈블리는 통신을 연결하기 전 다음과 같은 식의 라이선스 체크를 하는 코드를 포함하고 있었습니다.


public class MySocketServer : BaseClass
{
    // ...[생략]...
    public override void ConnectToServer()
    {
        if (this.State != ConnectionState.Open)
        {
            License license = MyLicense.GetLicense(LicenseManager.CurrentContext, typeof(MySocketServer), this, false);
            if (license == null)
            {
                throw new ProductException();
            }
            try
            {
                base.ConnectToServer();
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }
}

라이선스 체크는 서버에 연결하기 전 단 한번만 하고 있었으며, 그 외의 모든 실질적인 코드 수행은 internal로 정의된 BaseClass 클래스의 메서드에 일임하고 있었습니다.

물론, 이것이 구조적으로는 좋지만 라이선스 우회에는 아주 쉬운 사례중의 하나가 됩니다. 왜냐하면, 해당 인스턴스를 new로 생성한 다음 base.ConnectToServer만 호출해 주면 되기 때문입니다.

static class Program
{
    static void Main(string[] args)
    {
        MySocketServer dc = new MySocketServer();
        MethodInfo mi = typeof(BaseClass).GetMethod("ConnectToServer");
        mi.InvokeNotOverride(dc, null);
    }
}

사실 이것 때문에 지난번 글이 씌여진 것입니다.

override 메서드가 정의된 타입의 인스턴스로 base 메서드를 호출하는 방법
; https://www.sysnet.pe.kr/2/0/1564




개인적으로 역공학등의 방법을 이용해 라이선스를 무력화시키는 것을 일부러 공부하거나 하지는 않습니다. 단지, 프로그래머로써 공부하다 보니 어쩔 수 없이 보이게 되는 부분들이 있습니다.

어쨌든, 이 글을 통해서 여러분들 중에 라이선스를 적용한 제품을 판매하고 있다면 이런 결함이 있는 것은 아닌지 한번쯤 검토해 보는 것도 좋을 듯 싶습니다. 제 경험상, 서버 용 제품으로 판매하는 경우는 라이선스가 다소 허술해도 되지만... 불특정 다수의 클라이언트를 대상으로 판매하는 경우라면 이를 심각하게 고려해 봐야 합니다.





[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 6/9/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 16  17  18  19  20  21  22  23  24  25  26  27  28  [29]  30  ...
NoWriterDateCnt.TitleFile(s)
13277정성태3/6/202315202개발 환경 구성: 668. 코드 사인용 인증서 신청 및 적용 방법(예: Digicert)
13276정성태3/5/202315525.NET Framework: 2102. C# 11 - ref struct/ref field를 위해 새롭게 도입된 scoped 예약어 [1]
13275정성태3/3/202316023.NET Framework: 2101. C# 11의 ref 필드 설명
13274정성태3/2/202314742.NET Framework: 2100. C# - ref 필드로 ref struct 타입을 허용하지 않는 이유
13273정성태2/28/202312547.NET Framework: 2099. C# - 관리 포인터로서의 ref 예약어 의미
13272정성태2/27/202313667오류 유형: 850. SSMS - mdf 파일을 Attach 시킬 때 Operating system error 5: "5(Access is denied.)" 에러
13271정성태2/25/202313666오류 유형: 849. Sql Server Configuration Manager가 시작 메뉴에 없는 경우
13270정성태2/24/202313160.NET Framework: 2098. dotnet build에 /p 옵션을 적용 시 유의점
13269정성태2/23/202314925스크립트: 46. 파이썬 - uvicorn의 콘솔 출력을 UDP로 전송
13268정성태2/22/202314484개발 환경 구성: 667. WSL 2 내부에서 열고 있는 UDP 서버를 호스트 측에서 접속하는 방법
13267정성태2/21/202315530.NET Framework: 2097. C# - 비동기 소켓 사용 시 메모리 해제가 finalizer 단계에서 발생하는 사례파일 다운로드1
13266정성태2/20/202314127오류 유형: 848. .NET Core/5+ - Process terminated. Couldn't find a valid ICU package installed on the system
13265정성태2/18/202315708.NET Framework: 2096. .NET Core/5+ - PublishSingleFile 유형에 대한 runtimeconfig.json 설정
13264정성태2/17/202317818스크립트: 45. 파이썬 - uvicorn 사용자 정의 Logger 작성
13263정성태2/16/202313920개발 환경 구성: 666. 최신 버전의 ilasm.exe/ildasm.exe 사용하는 방법
13262정성태2/15/202315972디버깅 기술: 191. dnSpy를 이용한 (소스 코드가 없는) 닷넷 응용 프로그램 디버깅 방법 [1]
13261정성태2/15/202315675Windows: 224. Visual Studio - 영문 폰트가 Fullwidth Latin Character로 바뀌는 문제 [1]
13260정성태2/14/202315283오류 유형: 847. ilasm.exe 컴파일 오류 - error : syntax error at token '-' in ... -inf
13259정성태2/14/202313788.NET Framework: 2095. C# - .NET5부터 도입된 CollectionsMarshal
13258정성태2/13/202316238오류 유형: 846. .NET Framework 4.8 Developer Pack 설치 실패 - 0x81f40001
13257정성태2/13/202315802.NET Framework: 2094. C# - Job에 Process 포함하는 방법 [2]파일 다운로드1
13256정성태2/10/202314084개발 환경 구성: 665. WSL 2의 네트워크 통신 방법 - 두 번째 이야기
13255정성태2/10/202316133오류 유형: 845. gihub - windows2022 이미지에서 .NET Framework 4.5.2 미만의 프로젝트에 대한 빌드 오류
13254정성태2/10/202315406Windows: 223. (WMI 쿼리를 위한) PowerShell 문자열 escape 처리
13253정성태2/9/202315308Windows: 222. C# - 다른 윈도우 프로그램이 실행되었음을 인식하는 방법파일 다운로드1
13252정성태2/9/202313268오류 유형: 844. ssh로 명령어 수행 시 멈춤 현상
... 16  17  18  19  20  21  22  23  24  25  26  27  28  [29]  30  ...