728x90
반응형

[MariaDB_Audit] CVE-2026-3494 #1 :: Security_Analysis


새로운 현상 발견 

4개의 쿼리를 사용하면서, 테스트를 했을 때 오히려 11.8.6 이상의 버전에서 로그가 기록이 되지 않는 현상이 두개가 발견되었다. 

 - PoC Query #2 | PoC Query #3 


PoC Query #2_뭐지..?

# MariaDB 10.3.39
20260412 13:28:22,77f802a94157,root,localhost,53,79,QUERY,mysql,'SELECT * FROM user',1046
20260412 13:34:38,77f802a94157,root,localhost,53,80,QUERY,mysql,'select * from mysqql.user',1146

# MariaDB 11.8.6
20260412 13:34:38,67aec2205de2,root,localhost,10,82,QUERY,mysql,'select * from mysqql.user',1146

# MariaDB 11.8.5
20260412 13:34:38,90bb7eb5918d,root,localhost,9,79,QUERY,mysql,'select * from mysqql.user',1146
20260412 13:34:56,90bb7eb5918d,root,localhost,9,80,QUERY,mysql,'SELECT * FROM user',1046

 (1) Database를 선택하지 않고 (2) 존재하지 않는 테이블에 대해 SELECT를 수행했을 때,

     11.8.5 이하 버전에서는 1046 에러가 기록되었지만, 11.8.6 에서 기록되지 않았다. 


PoC Query #3_이건 또 뭘까

# MariaDB 10.3.39
20260412 14:08:05,77f802a94157,root,localhost,56,92,QUERY,mysql,'SET PASSWORD\n\nfor \'u01\'@\'localhost\' = PASSWORD(*****)',0

# MariaDB 11.8.6
   # 기록되지 않음
   # Not Record 

# MariaDB 11.8.5
20260412 14:08:05,90bb7eb5918d,root,localhost,10,88,QUERY,mysql,'SET PASSWORD\n\nfor \'u01\'@\'localhost\' = PASSWORD(*****)',0

 MariaDB 재단에서 PoC Query #3에 대해 쿼리를 수행했을 때 로그가 남지 않도록 삭제된 것을 미리 확인했었다. 

 기록이 되지 않는 것이 맞다. 

그럼.. 패치를 통해서 기록이 되도록 업데이트 된 것이라고 볼 수 있을까..? 라는 의문이 사라지지 않았다. 


MariaDB Jira 제보 

 의문이 해결되지 않아, MariaDB Jira에 이번 패치를 통한 로그에 대해 오히려 적용이 잘못된 것 아닌지를 알아보고자 제보를 했다. 

[MDEV-39310] During validation of CVE-2026-3494, we identified potential audit logging regression in MariaDB 11.8.6. - Jira


MariaDB Chief Architect 과의 댓글을 통한 의견 공유 

활동(댓글)을 통해 Sergei Golubchik과 계속된 의견을 공유하면서 질의를 하였다. 

처음으로 Sergei Golubchik가 달아놓은 댓글에는 아래 내용이 포함되어 있었다.

I couldn't repeat 1), a query that fails with "No database selected" is logged with server_audit_events='QUERY_DCL,QUERY_DDL,QUERY_DML' just fine.

2) is intentional and is completely unrelated to multi-lines or inline comments, see the original commit, referenced from CVE, you can see that removing SET PASSWORD from the log is part of the commit

I couldn't repeat 3), furthermore if you check the test case for the server_audit plugin, you can see that multi-line select with embedded comments is part of the regression suite.

 

1번은 테스트 할 수 없었고, 2번은 의도한것이고, 3번은 이해가 되지 않는 듯했다. 

 결국, Docker 파일을 통해 환경을 다시 구현했고, 관련 코드를 제공하여 직접 수행해볼 수 있도록 환경을 제공했다. 

GitHub - Kelnor/CVE-2026-3494_Verfication: Reproduction and Analysis of CVE-2026-3494 · GitHub


MariaDB Chief Architect 는 "일관성" 을 주장 

1번 테스트에 대해, SELECT 문이라는 것을 인식하기 전 이라고 한다. 

 즉, 11.8.5 버전 이하에서는 수행한 Query가 어떤 DML인지에 대해서 우선적으로 판단했지만, 

 11.8.6 에서는 DML이라고 판단하기 이전에, 해당 Query가 정상적인 쿼리인지에 대해 검증하는 로직이 추가된 것으로 판단했다. 

 데이터베이스가 없는데, 없는 DB에 SELECT를 했으니 이건 DML이 아닌 다른 오류라는 것이다. 

 

2번 테스트에 대해, Sergei Golubchik 는 한가지 예시를 제시했다. 

SET @a=1, password=password('qqq');

Sergei Golubchik는 위 Query와 같이, 이전에 사용된 동작이 버그들을 일으켰다는 내용으로 제시했다. 

 또한, 일관성에 관한 문제라고 얘기했다. 


또다시 추측

2번 테스트에 대해, Sergei Golubchik가 제시한 쿼리를 보다보니, 약간 이해가 되었다. 

SET 구문은 여러 작업을 콤마(,) 로 묶어서 한번에 실행할 수 있는데,

SET @a=1 는 DML이고, password=password('qqq'); 는 DCL 이라는 점에서, 과연 Audit_Plugin이 해당 쿼리에 대해, QUERY_DML로 로깅 해야할지, QUERY_DCL로 로깅해야할지 혼돈이 올 수 있다는 것을 깨달았다. 

만약 내가 사용한 쿼리처럼 SET PASSWORD에 관한 구문은 QUERY_DCL로 분류될 수 있지만,

QUERY_DML로 분류될 수 있는 상황이 발생할 수도 있다는 것이다. 

 

또한,  Sergei Golubchik는 "일관성" 이라고 했던 것이 생각났다. 

 

아.. 일관성 유지를 위해 그냥 QUERY 로 설정한 것 이구나.. 

일단 마무리.. 

Sergei Golubchik과의 의견 공유는 일단락 되었다. 

재단에서는 이번 조치가 일관성을 유지하기 위한 측면이라고 하는데,

나는 조금 생각이 다르긴 했지만, 보안 및 가용성 부분을 계속 얘기한다고 해서 이번 패치가 바뀌지 않을 것이라고 판단했다. 

댓글을 통해 MariaDB Parser 설계에 대해 내가 인지하지 못한 부분이 있었던 것 같다고 마무리했다.


그럼에도 보안업자로서.. 

변경된 패치를 통해서 내 의견은 다음과 같다.

모든 행위에 대해서 기록하려면 "QUERY_DML", "QUERY_DCL", "QUERY_DDL" 로 설정되어 있던 것을 "QUERY"로 변경해야 한다는 것이다. 

그러면 운영 입장에서 가용성에 문제가 생길 수 있다고 생각한다. 

기관의 규모가 클수록, QUERY로 모든 로그를 기록하면 하루에도 {N}GB 이상의 로그가 쌓일 수 있을 것이고, 

용량이 가득찰 경우, 과거의 로그가 삭제되거나 혹은 새로운 로그가 기록되지 않을 수 있을 것이라고 본다. 

 

물론, 원격 로그서버가 구축되어 있고, 연동되어있다면 말을 달라진다. 

다만, 모든 회사가 syslog 서버가 있는 것이 아니기 때문에, QUERY가 다시 세분화 될 필요가 있을 것이라고 판단한다. 

 

만약.. 비용이 어느정도 있다면..?

QUERY로 설정하여 모든 로그를 남기면서,

1. ELK, Splunk와 같은 syslog 를 구축하는 것

 

비용이 불가능하다면..?
1. server_audit_excl_users 설정으로 모니터링이 불필요한 시스템 계정 및 애플리케이션 계정의 로깅을 제외하는 방법도 고려해볼 수 있을 것이라고 판단한다. 


최종 결론

이번 CVE-2026-3494는 QUERY의 혼돈 및 일관성적인 측면을 적용하기 위한 패치였다. 

무조건 기록되지 않는 것이 아니라, 분류 미스로 인한 문제였으며, 이를 모두 기록하기 위해 세분화가 아닌 단순한 설정으로의 변경이다. 


새로운 지식 습득

11.8.5 이하의 버전에서 기록이 되지 않을 수 있다는 것이 어떤 내용인지 자세하게 알 수 있었고,

보안컨설팅을 나갔을 때  그 기관에서 MariaDB를 사용하고 있고, server_audit가 활성화 되어있다면,

server_audit_events를 통해 현재 적용된 설정을 확인해보고, events가 DCL, DML, DDL로 세분화 되어 설정되어 있는 경우에

QUERY로 설정해야만 모든 행위를 기록할 수 있다고 말할 수 있게 되었다. 

 

 

728x90
반응형

'Security > CVE_DB' 카테고리의 다른 글

[MariaDB_Audit] CVE-2026-3494 #1  (0) 2026.08.30
728x90
반응형

CVE-2026-3494

MariaDB 11.8.5 이하 버전에서 server_audit 플러그인의 server_audit_events QUERY_DCL, QUERY_DML, QUERY_DDL 필터링으로 설정된 경우, 사용자가 Query에 이중 하이픈(--) 또는 해시(#) 를 포함하여 실행 시 해당 문장이 기록되지 않는다는 주석 처리 우회에 관한 취약점이다. 

Server_Audit 플러그인?

server_audit 플러그인은 "감사 목적의 로그를 남기기 위한 별도의 기능" 이라고 이해를 해야한다. 

MariaDB는 server_audit 플러그인을 사용하지 않더라도, 기본적으로 아래와 같이 로그를 남긴다. 

로그 종류  목적 예시
Error Log 서버 오류 및 상태 서버 시작, 종료, 오류 등
General Query  서버가 받은 모든 SQL  SELECT, INSERT, UPDATE 등
Slow Query 오랜 시간동안 작동된 SQL 실행 후 5초 넘은 Query
Binary Log 데이터 변경 이력 및 복제 INSERT, UPDATE, DELETE, CREATE, ALTER, SET 등

 

위 기본 로그를 통해서 장애 발생(Error), 데이터 변경(General), 데이터 삭제(Binary)에 관하여 행위를 추적할 수 있다. 

 

근데, 왜 server_audit 플러그인을 사용해야 하는가?

"감사 목적(사용자 활동 추적)" 으로 사용하기 위해서다. 

육하원칙( "누가", "언제", "어디에서", "무엇을", "어떻게", "왜" )처럼 사용자의 활동을 추적하기 위해 사용되는 플러그인이다. 

 


커밋 내역

MariaDB 재단에서 공개한 Commit 을 통해 테스트한 결과를 보면 다음과 같다. 

 


추측 및 1차 결론 

MariaDB 재단에서 테스트 한 결과를 통해 확인해보면

11.8.5 이하에서 "해시(#)" 혹은 "이중 하이픈(--)" 과 같은 주석이 달려있을 때 기록이 되지 않던 현상이 있다고 했는데, 새로 패치한 것에 보면 해당 로그가 삭제되었다. 

오히려, 11.8.6 버전에서 해당 로그가 나오지 않도록 변경한 것처럼 해석이 되었다. 

그래서 MariaDB 10.3.39 / 11.8.5 / 11.8.6 에서 테스트를 진행했다. 


PoC Env

- MariaDB 10.3.39 | MariaDB 11.8.5 | MariaDB 11.8.6


PoC Query #1 

에러가 발생하지 않은 정상적인 Query에 대해 어떻게 기록되는지를 먼저 파악하기 위해 진행 
MariaDB [(none)]> select host, user from mysql.user;
+-----------+------+
| host      | user |
+-----------+------+
| %         | root |
| localhost | root |
+-----------+------+
2 rows in set (0.001 sec)
# MariaDB 10.3.39
20260412 13:24:28,77f802a94157,root,localhost,53,78,QUERY,mysql,'select host, user from mysql.user',0

# MariaDB 11.8.6
20260412 13:24:28,67aec2205de2,root,localhost,10,80,QUERY,mysql,'select host, user from mysql.user',0

# MariaDB 11.8.5
20260412 13:24:28,90bb7eb5918d,root,localhost,9,77,QUERY,mysql,'select host, user from mysql.user',0

PoC Query #2

에러를 발생시켰을 때 어떻게 Query가 기록되는지도 보기 위해 진행했으나, 오히려 더 머리가 복잡해졌다. 
MariaDB [(none)]> SELECT * FROM user;
ERROR 1046 (3D000): No database selected

MariaDB [(none)]> SELECT * FROM mysqql.user;
ERROR 1146 (42S02): Table 'mysqql.user' doesn't exist
# MariaDB 10.3.39
20260412 13:28:22,77f802a94157,root,localhost,53,79,QUERY,mysql,'SELECT * FROM user',1046
20260412 13:34:38,77f802a94157,root,localhost,53,80,QUERY,mysql,'select * from mysqql.user',1146

# MariaDB 11.8.6
20260412 13:34:38,67aec2205de2,root,localhost,10,82,QUERY,mysql,'select * from mysqql.user',1146

# MariaDB 11.8.5
20260412 13:34:38,90bb7eb5918d,root,localhost,9,79,QUERY,mysql,'select * from mysqql.user',1146
20260412 13:34:56,90bb7eb5918d,root,localhost,9,80,QUERY,mysql,'SELECT * FROM user',1046

PoC Query #3

Commit 내역에 나온 Query를 통해 기록이 어떻게 변경되었는지 확인 하기 위해 수행했으나, 머리가 계속 복잡해졌다. 
MariaDB [(none)]> SET PASSWORD
    -> # I'm trying to test for CVE-2026-3464
    -> FOR 'u01'@'localhost' = password('Test1234!');
Query OK, 0 rows affected (0.001 sec)
# MariaDB 10.3.39
20260412 14:08:05,77f802a94157,root,localhost,56,92,QUERY,mysql,'SET PASSWORD\n\nfor \'u01\'@\'localhost\' = PASSWORD(*****)',0

# MariaDB 11.8.6
   # 기록되지 않음
   # Not Record 

# MariaDB 11.8.5

20260412 14:08:05,90bb7eb5918d,root,localhost,10,88,QUERY,mysql,'SET PASSWORD\n\nfor \'u01\'@\'localhost\' = PASSWORD(*****)',0

PoC Query #4

PoC Query #3과 비슷한 맥락의 코드를 사용하여 추가확인 
MariaDB [(none)]> SELECT
    -> # CVE-2026-3464 Test #2
    -> HOST, USER from mysql.user;
+-----------+------+
| HOST      | USER |
+-----------+------+
| %         | root |
| localhost | root |
| localhost | u01  |
+-----------+------+
3 rows in set (0.001 sec)
# MariaDB 10.3.39
20260412 13:49:23,77f802a94157,root,localhost,54,85,QUERY,mysql,'SELECT \n\nHOST, USER from mysql.user',0

# MariaDB 11.8.6
20260412 13:49:23,67aec2205de2,root,localhost,10,86,QUERY,mysql,'SELECT \n\nHOST, USER from mysql.user',0

# MariaDB 11.8.5
20260412 13:49:23,90bb7eb5918d,root,localhost,9,83,QUERY,mysql,'SELECT \n\nHOST, USER from mysql.user',0

PoC 결과

오히려 머리가 복잡해졌다. 

11.8.5 이하에서 기록이 되지 않을 수 있다고 했는데, 기록이 되고 있는 것처럼 보여졌고 오히려 변경된 버전에서 기록이 안되는 것 같다고 생각이 들었다. 

내가 테스트를 잘못한 것인가 생각이 들었고, 추가 확인이 필요하다고 판단했다. 


다음글 에서 추가 진행

728x90
반응형

'Security > CVE_DB' 카테고리의 다른 글

[MariaDB_Audit] CVE-2026-3494 #2  (0) 2026.08.30
728x90
반응형

 

회사 내부 망에서 여러 운영 환경이 있다. 

 

각 운영 환경을 WEB으로 들어갈 때 DNS 등록이 되어있지 않은 모두 IP로 접속하고 있는데 

내부 DNS 서버를 구축해서 URL 로 변경해볼까 한다. 

 

굳이 안해도.. 다들 IP로 잘 접근하지만, 

그래도 URL로 해놓는 것이 더 직관적이니까.. 변경 할 것이고, 지금 운영환경들의 External_URL 또한 변경해 줄 것이다. 


1. Rocky Linux 9.5 준비 


2. 최신 업데이트 적용

 

해당 서버를 내부 DNS 서버로 쓸 것이기 때문에, 

내부 IP에 대해서는 현재 적용하는 서버로 먼저 질의를 하지만, 외부 도메인은 8.8.8.8(Google) 로 Forwarding 할 것이며, 

일단 BIND 패키지를 설치 할 것이므로, nameserver는 8.8.8.8로 지정한다. 

 

외부로 ping은 되지만 /etc/resolv.conf 에 "nameserver" 설정이 없어서 문제가 발생했다. 

해당 파일(/etc/resolv.conf) 에 "nameserver 8.8.8.8" 을 넣어주고 다시 시도했다. 

정상적으로 dnf가 진행된다. 


3. DNS 서버 관련 파일 설치

[root@localhost ~] dnf install bind bind-chroot* -y


4. DNS  설정파일 적용 ( /etc/named.conf )

# [ /etc/named.conf ]

options {
        listen-on port 53 { 127.0.0.1; };
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        secroots-file   "/var/named/data/named.secroots";
        recursing-file  "/var/named/data/named.recursing";
        allow-query     { localhost; };
        allow-transfer  { none; };
        recursion yes;

        managed-keys-directory "/var/named/dynamic";
        geoip-directory "/usr/share/GeoIP";
        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";
        include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "scn.gitlab.com" IN {
        type master;
        file "scn.gitlab.com.zone";
        allow-update { none; };
};

zone "scn.vcenter.com" IN {
        type master;
        file "scn.vcenter.com.zone";
        allow-update { none; };
};

zone "scn.esxi.com" IN {
        type master;
        file "scn.esxi.com.zone";
        allow-update { none; };
};

zone "scn.technical.com" IN {
        type master;
        file "scn.technical.com.zone";
        allow-update { none; };
};

/*
zone "." IN {
        type hint;
        file "named.ca";

5. Zone 파일 설정 

 ∞ /var/named/scn.gitlab.com.zone

$TTL 86400
@   IN  SOA  ns1.scn.gitlab.com. admin.scn.gitlab.com. (
        2025111201
        3600
        1800
        604800
        86400 )

    IN  NS  ns1.scn.gitlab.com.

ns1     IN  A   { DNS Server IP }
@  IN  A   { Gitlab Server IP }

 

 ∞ /var/named/scn.vcenter.com.zone

$TTL 86400
@   IN  SOA  ns1.scn.vcenter.com. admin.scn.vcenter.com. (
        2025111201
        3600
        1800
        604800
        86400 )

    IN  NS  ns1.scn.vcenter.com.

ns1     IN  A   { DNS Server IP }
@ IN  A   { vcenter Server IP }

 

 ∞ /var/named/scn.esxi.com.zone

$TTL 86400
@   IN  SOA  ns1.scn.esxi.com. admin.scn.esxi.com. (
        2025111201
        3600
        1800
        604800
        86400 )

    IN  NS  ns1.scn.esxi.com.

ns1    IN  A   { DNS Server IP }
@   IN  A   { ESXi Server IP }

 

∞ /var/named/scn.technical.com.zone

$TTL 86400
@   IN  SOA  ns1.scn.technical.com. admin.scn.technical.com. (
        2025111201
        3600
        1800
        604800
        86400 )

    IN  NS  ns1.scn.technical.com.

ns1         IN  A   { DNS Server IP }
@   IN  A   { Technical Server IP }

6. 소유권 변환 및 파일 검증 

# 소유권 변경
[root@localhost named]# sudo chown root:named /var/named/*.zone
[root@localhost named]# sudo chmod 640 /var/named/*.zone

# /etc/named.conf 파일 검증 
[root@localhost named]# named-checkconf
[root@localhost named]#

# Zone 파일 검증
[root@localhost named]# sudo named-checkzone scn.gitlab.com /var/named/scn.gitlab.com.zone
zone scn.gitlab.com/IN: loaded serial 2025111201
OK
[root@localhost named]# sudo named-checkzone scn.esxi.com /var/named/scn.esxi.com.zone 
zone scn.esxi.com/IN: loaded serial 2025111201
OK
[root@localhost named]# sudo named-checkzone scn.vcenter.com /var/named/scn.vcenter.com.zone 
zone scn.vcenter.com/IN: loaded serial 2025111201
OK
[root@localhost named]# sudo named-checkzone scn.technical.com /var/named/scn.technical.com.zone 
zone scn.technical.com/IN: loaded serial 2025111201
OK

7. DNS Server(named) 등록 및 실행

[root@localhost named]# systemctl enable named
Created symlink /etc/systemd/system/multi-user.target.wants/named.service → /usr/lib/systemd/system/named.service.
[root@localhost named]#
[root@localhost named]# systemctl restart named
[root@localhost named]#
[root@localhost named]# systemctl status named
● named.service - Berkeley Internet Name Domain (DNS)
     Loaded: loaded (/usr/lib/systemd/system/named.service; enabled; preset: disabled)
     Active: active (running) since Wed 2025-11-12 11:48:44 EST; 7s ago
    Process: 72202 ExecStartPre=/bin/bash -c if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi (code=exited, status=0/SUCCESS)
    Process: 72211 ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} $OPTIONS (code=exited, status=0/SUCCESS)
   Main PID: 72212 (named)
      Tasks: 14 (limit: 48898)
     Memory: 43.0M
        CPU: 194ms
     CGroup: /system.slice/named.service
             └─72212 /usr/sbin/named -u named -c /etc/named.conf

Nov 12 11:48:44 localhost.localdomain named[72212]: all zones loaded
Nov 12 11:48:44 localhost.localdomain named[72212]: running
Nov 12 11:48:44 localhost.localdomain named[72212]: network unreachable resolving './DNSKEY/IN': 2001:500:2f::f#53
Nov 12 11:48:44 localhost.localdomain named[72212]: network unreachable resolving './NS/IN': 2001:500:2f::f#53
Nov 12 11:48:44 localhost.localdomain named[72212]: network unreachable resolving './DNSKEY/IN': 2001:7fd::1#53
Nov 12 11:48:44 localhost.localdomain named[72212]: network unreachable resolving './NS/IN': 2001:7fd::1#53
Nov 12 11:48:44 localhost.localdomain systemd[1]: Started Berkeley Internet Name Domain (DNS).
Nov 12 11:48:44 localhost.localdomain named[72212]: managed-keys-zone: Initializing automatic trust anchor management for zone '.'; DNSKEY ID 20326 is now trusted, waiving the normal 30-day waiting period.
Nov 12 11:48:44 localhost.localdomain named[72212]: managed-keys-zone: Initializing automatic trust anchor management for zone '.'; DNSKEY ID 38696 is now trusted, waiving the normal 30-day waiting period.
Nov 12 11:48:44 localhost.localdomain named[72212]: resolver priming query complete

8. Client 서버 설정

  • Client(gitlab, vCenter, ESXi, technical) 에서 /etc/resolv.conf 에 nameserver 10.10.30.253 으로 설정 변경
# /etc/resolv.conf
nameserver 10.10.30.253

[root@localhost ~] search scn.gitlab.com scn.vcenter.com scn.esxi.com scn.technical-exam.com

# 테스트
[root@localhost ~] dig scn.gitlab.com
[root@localhost ~] dig scn.vcenter.com
[root@localhost ~] dig scn.esxi.com
[root@localhost ~] dig scn.technical.com

9. 내부 방화벽 설정

  • Fortigate 80E 에서 Split DNS 설정 
    • SSL-VPN 사용자는 위 4개의 주소에 대해 10.10.30.253 으로 DNS 적용
    • 나머지 사용자는 8.8.8.8 로 DNS 적용


10. 접속 테스트

728x90
반응형

'Security' 카테고리의 다른 글

Ransomware  (0) 2025.07.06
728x90
반응형

약 2년전, Synology NAS에 Gitlab을 구축했었다. 

gitlab, Synology NAS(DS220+) 연동

 

gitlab, Synology NAS(DS220+) 연동

재직 중인 회사에는 파일서버용으로 Synology NAS를 사용한다. 프로그램 및 스크립트에 대한 소스코드를 포함하여 다양한 엑셀 문서를 보관하는데, gitlab, github 등 형상관리를 하지도 않았고, NAS는

securitypositive.tistory.com

 

그러고 나서 SMTP 연동까지 했었다. 

SMTP 연동 (Feat. Synology DS220+ Gitlab)

 

SMTP 연동 (Feat. Synology DS220+ Gitlab)

지난번 소스코드 형상관리를 위한 Synology NAS에 Gitlab을 연동했었다. < 관련글 > : gitlab, Synology NAS(DS220+) 연동 형상관리를 위한 GitLab 서버도 만들어놨고, 프로젝트도 올려놓았다. 이제 실제 스크립

securitypositive.tistory.com

 

구축하고 나서 약 1년 동안 써오다가 Synology NAS DSM의 "Container Manager"가 불안정하여

가상화서버에 VM OS(Rocky)를 추가하고 GitLab을 구축한 후 데이터를 옮겼었다. 

그 과정에 대해서 별도로 글을 쓰지는 않았는데 마침 오늘 글을 쓸 기회가 생겼다.. 

ESXi Server 의 RAID 구성이 터져버렸거든요

 

ESXi 를 설치할 때 RAID 구성을 미러링으로 변경했어야 했는데... 

테스트용 OS, DBMS, WEB/WAS, k8s, docker 등 여러환경을 구축하다보니 테스트환경이 많아질 것 이라고 판단하여

HDD 9.6TB 모든 용량을 쓰는걸로 협의했고, RAID0 으로 구성했었다. 

 

근데.. Slot 11, 12, 13번에서 Foreign이 발생했다

그러다보니.. import를 다시 했는데 12,13번은 돌아왔지만 11번은 Foriegn 상태가 복원이 안되었다. 

 

뭐 하여튼.. 여기서부터 데이터가 조금씩 분산저장 되던게 유실되길래.. 전원 끄고 GitLab을 백업하려고 했는데.. 

ESXI UI에서 gitlab VM이 꺼진것처럼 보였으나, 실제로 꺼지는 중에 tar를 하여.. 

 

데이터 파일이 헤더만 남기고 날라갔다.. 

그래서 GitLab을 다시 구축할 기회가 생겼다. 


1. Rocky Linux 9.5 준비 

docker 를 설치하여 gitlab 공식 이미지를 설치해도 되지만, 

Synology NAS DSM의 Container Manager에서도 Docker의 gitlab 이미지를 쓴 것 인데,

불안정하고 간헐적으로 Gitlab 페이지에 접속이 되지 않는 502 Bad Request 에러가 발생했었다. 

그래서 좀더 안정적이라고 판단되는 OS에 Repository를 통해 설치 할 것이다. 


2. 최신 업데이트 적용

 

최소버전으로 Rocky Linux 9.5를 설치했는데.. Mirror List 오류가 났지만 DNS 문제이다. 

 

외부로 ping은 되지만 /etc/resolv.conf 에 "nameserver" 설정이 없어서 문제가 발생했다. 

해당 파일(/etc/resolv.conf) 에 "nameserver 8.8.8.8" 을 넣어주고 다시 시도했다. 

정상적으로 dnf가 진행된다. 


3. 종속성(Dependency) 추가

Rocky 9.5 의 공식 Mirrorlist에서는 Gitlab CE Repository 를 기본적으로 제공하지 않는다. 

[root@localhost ~] dnf -y install curl vim policycoreutils python3-policycoreutils git perl postfix


4. Gitlab Repository 추가

gitlab/gitlab-ce - Results for ol/9 in gitlab/gitlab-ce

 위 주소에서 자신의 환경에 맞는 rpm 파일을 찾는다 

[root@localhost ~] curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash

 


5. Gitlab 설치 

[root@localhost ~] sudo yum install gitlab-ce-18.5.1-ce.0.el9.x86_64


6. 초기 설정 변경

[root@localhost ~] vi /etc/gitlab/gitlab.rb

#external_url 'http://gitlab.example.com' 
external_url 'http://{server_ip}'

 


7. 페이지 접속 확인

 ※ 만약 페이지에 접속이 되지 않는 다면 방화벽 룰셋을 추가해줘야 한다. 

 ※ 방화벽 룰셋 추가는 7-1로 이동. 


7-1. 방화벽 룰셋 추가 

# HTTP 
[root@localhost ~] firewall-cmd --permanent --add-service=http 
[root@localhost ~] firewall-cmd --reload 

# HTTPS
[root@localhost ~] firewall-cmd --permanent --add-service=https
[root@localhost ~] firewall-cmd --reload


8. 로그인 시도 

  초기 ID : root

  초기 비밀번호 : /etc/gitlab/initial_root_password에 존재


9. 관리자 비밀번호 변경

 

 

SMTP는 기존 Synology NAS 에 있는 내용을 참고하여 하면 적용된다.. 

근데.. 형상관리 다 날라갔는데 어떡할지.. 참 큰 고민이다.. 

728x90
반응형
728x90
반응형

마지막으로 제작한 부분에서 학습한 결과를 가지고 예측을 시도했었다. 

진단 Tool 제작_5 (결과 모델링 및 학습)

 

진단 Tool 제작_5 (결과 모델링 및 학습)

직접 진단한 결과를 DB에 저장까지 했으니, 이 결과들을 가지고 취약점 예측 모델을 만들어야 한다. 진단 Tool 제작_4 (데이터 저장) 내가 생각한 학습 모델은 다음과 같다.     1). DB에 저장된 현

securitypositive.tistory.com

 

그때, 6대를 가지고 진행했고, 오탐률은 5.4% ~ 14.7% 의 오탐률이 나왔었다. 

[오탐률] 최소 : 5.4% / 최대 : 14.7%

[정탐] 최소 : 68 / 최대 : 74

[오탐] 최소 : 4 / 최대 : 10

 

그래서 오탐률을 줄여보고자 했다. 

 

5번 글을 쓰고 나서 2주일에 걸쳐 데이터를 500개로 정도로 늘렸고, 테스트를 다시 해보았으나 데이터의 종류에 따라 결과가 상이하게 나왔다.

데이터 종류는 총 2종류이다. 


1. 테스트서버에 설정파일에 대한 설정 값 변경 (300개)

  → 이것은 ESXi에 VM(CentOS)을 올려놓고, 각 항목별로 설정값을 계속 변경해서 TRUE, FALSE에 대한 결과를 삽입

  → 예를들어, 1번 항목에 TRUE로 가능한 설정이 3개면, 설정을 계속 변경해가면서 3개의 테스트 파일을 생성

    → 단, 나머지 항목에 대해서는 결과값 동일 

 

2. 이 프로젝트를 진행 하던 당시에, 투입되어 진단하던 취약점 점검 결과 (200개)

  → 실제 운영중인 기관의 리눅스서버 결과파일을 가지고 취약점 진단을 진행하여 판단된 TRUE, FALSE에 대한 결과를 삽입 

  → 모든 항목에 대해 결과값이 동일할 수도 있고, 동일하지 않을 수도 있음

  → 일부 항목에 대해서는 모두 같을수도 있고, 모두 다를수도 있음 


이렇게 총 500개의 데이터를 학습시켰고, 

DB의 각 항목별 RESULT Column에 취약점 점검 결과를 넣어놓았다. 

 

이후, 학습된 모델을 통해서 학습할 때 사용한 원본 텍스트 파일 500개를 모두 진단해보았다. 

이 결과는 DB의 각 항목별 Predict_RESULT Column에 들어가도록 저장했다.


결과

이번에는 데이터의 개수와 상관없이, 데이터의 종류에 따라 다르게 수치가 급변하였다. 

 

1번 결과 (테스트서버에서 설정값 변경한 결과) 

  → [오탐률] 최소 : 0% / 최대 :2.63%

  → [정탐] 최소 : 78 / 최대 : 76 

  → [오] 최소 : 2 / 최대 : 0

 

2번 결과 (실제 기관의 특성을 반영한 결과) 

  → [오탐률] 최소 : 15.38% / 최대 : 32.05%

  → [정탐] 최소 : 53 / 최대 : 66

  → [정탐] 최소 : 12 / 최대 : 25


원인파악

1번 결과와 2번 결과의 차이가 너무 달라서 어떤 문제가 발생했는지 생각해보았다. 

 

  → 1번 결과의 경우

    → 항목번호 1번에서 TRUE로 가능한 설정이 3개면,

    → 300개의 데이터중 297개는 FALSE, 3개는 TRUE

    → 더군다나, 3개의 결과값이 모두 다르기 때문에 TRUE가 발생할 수 있는 조건이 제한적일 수 밖에 없음 

 

  → 2번 결과의 경우

    → 명확하게 TRUE, FALSE가 남는 항목은 있지만

    → 기관별로 설정하는 방법이 모두 다르기 때문에 설정이 다 다름

    → TRUE의 경우도 테스트서버에서 봤던 것보다 더 다양하게 출력되고,


문제가 되는 항목 예시

[NFS] 접근제어 미비 
→ 양호
    → NFS 서비스가 비활성화 되어있거나,
    → 불가피하게 활성화 되어 있으면 접근 가능한 사용자가 지정되어 있으면서 root_squash 설정이 적용되어 있는 경우

  → 취약
    → NFS 서비스가 불필요하게 활성화 되어있으면서,
    → 접근제어 설정이 되어있지 않고, no_root_squash 설정이 적용되어 있는 경우 

양호 

    → NFS 서비스 비활성화 (1번 경우)

[root@localhost ~]# ps -ef | grep nfsd | grep -v "grep"
# 결과가 안나오면 비활성화 되어있는 것


    → NFS 서비스 활성화 및 접근제어 설정 확인 (2번 경우)

    → 접근제어 : 192.168.0.10 

    → 권한 : Read Write

    → root_squash 적용 

# nfsd가 활성화되어있는 타당한 목적이 있어야 함 => 담당자 인터뷰 필요
[root@localhost ~]# ps -ef | grep nfsd | grep -v "grep"
root     1060     1  0 09:01 ?        00:00:00 [nfsd]

[root@localhost ~]# cat /etc/exports 
/home/share 192.168.0.10(rw,sync,root_squash)

취약

    → NFS 서비스 활성화 (1번 경우)

# 불필요하게 nfsd가 활성화 되어있는 경우
[root@localhost ~]# ps -ef | grep nfsd | grep -v "grep"
root     1060     1  0 09:01 ?        00:00:00 [nfsd]


    → NFS 서비스 활성화 및 접근제어 설정 확인

    → 접근제어 : 모두 허용 (2번 경우)

    → 권한 : Read Write

    → root_squash 미적용 (3번 경우)

[root@localhost ~]# cat /etc/exports 
/home/share 0.0.0.0/0(rw,sync)

양호 vs 취약

    → 양호는 2가지의 경우가 존재 ( 비활성화 / 모든 조건이 만족한 경우 )

    → 취약은 최소 3가지의 경우가 존재함 

    → 공유된 디렉토리가 여러개일 경우 그 디렉터리에 대해 모두 확인이 필요함

    → 여러번 학습되었다고 해서, 계속 양호처리할 수는 없음

    → 공유 디렉터리를 쓰다가, 불필요해서 삭제후, 1년후에 만들었다고 가정

    → 다시 용도를 파악해야하는데, 그러면 또다시 인터뷰 혹은 연관지을 수 있는 증거가 필요함 

    → 기존 양호처리 결과의 내용은 무시되어야 함.

    → 즉, 경우의 수가 더 많아짐


결론

    → 이러한 꽤 많은 항목들로 인해, 학습된 500개의 데이터는 학습을 위한 제대로된 데이터가 아님 으로 판단

    → 학습 데이터 또한 학습 데이터를 만들어주는 인공지능이 필요할 것으로 생각되며, 

    → 저 인공지능을 개발하는데에 많은 시간이 소요될 것으로 판단하여, 잠정 중단 


추가의견

    → 이 프로젝트는, 기관에서 보안솔루션(서버접근제어, 원격로그서버, 방화벽, UTM 등) 을 적용함에 따라

    → 서버에는 보안설정을 하지 않는 것에 대해, 현재 취약점 점검 시 선 취약 으로 판단 후 담당자 인터뷰를 통해 양호로 변경하는 과정을

    → 최소화 하기 위해서 진행했던 프로젝트 

    → 즉, 최종적인 목표는 담당자 인터뷰를 최소화하고, 기관의 특성이 반영되어진 자동화 취약점 점검을 목표로 한 것이였으나, 

 

    → 올해 발생한 굵직한 보안사고들(KT, 롯데카드, YES24 등)을 되돌아 봤을 때, 이 프로젝트는 잠정중단하는 것이 맞다고 판단함

    → 이 프로젝트가 시작되었던 목적부터 다시 생각을 해야 함 

    → 설정 값에 대한 1:1 매핑은 점검이 가능하나,  일부 항목에 대해서는 담당자 인터뷰가 필수로 포함이 되어야 한다는 것.

    → 또한 담당자 인터뷰를 하다보면 대부분 동일하게 하는 얘기는 "접근제어솔루션", "원격로그서버 사용" "상단방화벽에서 제어" 등 보안시스템에서 해결하고 있으므로 양호로 봐도 되지 않냐는 것 

    → 담당자 인터뷰를 최소화하고, 기관의 특성을 반영하여 알아서 점검 해주는게 목표였는데, 저 보안솔루션 사용에 따라 서버 및 DBMS에 자체설정을 하지 않는것이 과연 맞는지에 대한 의문이 발생해서 이 프로젝트는 잠정 중단. 

 

 

728x90
반응형
728x90
반응형

 

필기 5번, 실기 6번만에 드디어 정보보안기사에 합격했다. 

 

하지만 이건 운이 좋았다고 생각한다. 

시험 보러 갈 때 많은 사람들이 한달 넘게 공부를 하고 간다고 한다. 

 

근데 나는 업무가 많고 바쁘다는 핑계로 공부를 1주일 이상 해본적이 없었다. 

 

2022년에 필기시험 3번(1,2,4회) 을 모두 봤고, 4회차에 합격했었다. 

이 때도 아마 필기시험을 보러 갈 때 한 2일정도 1시간 가량 책을 봤었을 것이다. 

4회차에 합격한 것도 너무 좋은 운이라고 생각했었다. 

 

이후 4번의 실기를 도전했다. 

22년(4회) 실기, 23년(1,4회) 실기, 24년(1회) 실기 까지 총4번 봤으나 공부를 항상 대충하던 내가 실기에 붙을 가능성은 없었다. 

 

결국 필기 합격의 유효기간은 끝나버렸고, 24년(4회) 필기를 다시 시작했다. 

이 시험에서 조차 필기시험을 떨어지고 나니, 내가 공부를 너무 안한다는 생각이 들었다. 

 

너무 심하게 공부를 안하는 구나 싶었던 나는 25년도부터 공부를 시작했다. 

25년 (1회) 필기시험을 위해 기존에 보던 책을 안보고, 새로운 책을 다시 샀고 

이론은 절대 안보고 기출문제를 3번씩은 풀고 그냥 외워버렸다. 

 

결국 필기에 다시 합격했다. 

이제 실기만 다시 보면 됐었다. 

 

25년 (1회) 실기를 이어서 바로 도전했으나, 난 내가 알고있는대로 썻다고 생각했는데 처참한 점수가 나왔다. 

고객센터에 문의도 해볼까 했지만 나무위키에 작성된 내용을 보고 고객센터에 문의조차 넣지 않았다. 

 

"내가 좀 더 자세하게 확실한 내용만 적었어야 했는데 그게 안됐나 보다"

라고 생각하고 그냥 넘겼다. 

 

이후 25년(2회) 실기 시험을 보기 위해서 3주정도 최소 매일 1시간씩은 책을 봤다. 

주말에도 보고, 평일에 퇴근하고서도 책을 봤다. 

 

네이버 알기사 카페에 있는 글을 보면 1~2달 내내 공부한 사람들도 있는 반면, 내 공부량은 한없이 적었음에도 운이 좋았는지 합격했다. 

 

이제는 어떤 자격증을 도전할지 고민이다. 

다른 자격증도 필요하지만, 토익도 도전해볼까 한다. 

 

 

728x90
반응형
728x90
반응형

 

몇일 전, 스크립트를 변경하고자 MySQL 가상환경을 4개 켰다. 

 

4개 모두 정상적으로 켜졌으나, 1개의 가상환경에 대해 root 비밀번호를 잃어버려서 초기화를 해야했다. 


이 과정에서 문제가 발생했다. 

 

현재 해결은 되었지만, 이건 해결이라고 보기 어렵다. 

 

몇시간동안 삽질하면서 찾고 반영한 내용을 기록해보았다. 


Environment 

- OS : Windows Server 2012 R2

- DB : MySQL 5.5.57 


Problem

- root 계정 비밀번호를 분실하여, 초기화가 필요

- 초기화를 위해 net stop mysql 명령어를 사용하여 서비스 종료 후

- --skip-grant-tables --console 명령으로 MySQL을 실행 한 뒤

- 또 다른 터미널(CMD)를 실행하여 mysql -u root 명령을 실행하자

- --skip-grant-tables --console을 실행한 터미널에서 오류가 발생하면서 강제 종료되는 현상 발생


Terminal #1

- skip-grant-tables --console 을 실행했을 때 정상적으로 실행된 것처럼 출력

C:\Program Files\MySQL\MySQL Server 5.5\bin>mysqld --defaults-file="C:\Program F
iles\MySQL\MySQL Server 5.5\my.ini" --skip-grant-tables --console
250722 17:48:51 [Note] --secure-file-priv is set to NULL. Operations related to
importing and exporting data are disabled
250722 17:48:51 [Note] mysqld (mysqld 5.5.57) starting as process 2896 ...
250722 17:48:51 [Note] Plugin 'FEDERATED' is disabled.
250722 17:48:51 InnoDB: The InnoDB memory heap is disabled
250722 17:48:51 InnoDB: Mutexes and rw_locks use Windows interlocked functions
250722 17:48:51 InnoDB: Compressed tables use zlib 1.2.3
250722 17:48:51 InnoDB: Initializing buffer pool, size = 107.0M
250722 17:48:51 InnoDB: Completed initialization of buffer pool
250722 17:48:51 InnoDB: highest supported file format is Barracuda.
250722 17:48:51  InnoDB: Waiting for the background threads to start
250722 17:48:52 InnoDB: 5.5.57 started; log sequence number 1595675
250722 17:48:52 [Note] Server hostname (bind-address): '0.0.0.0'; port: 3306
250722 17:48:52 [Note]   - '0.0.0.0' resolves to '0.0.0.0';
250722 17:48:52 [Note] Server socket created on IP: '0.0.0.0'.
250722 17:48:52 [Note] mysqld: ready for connections.
Version: '5.5.57'  socket: ''  port: 3306  MySQL Community Server (GPL)

Terminal #2

- Terminal #1에서 MySQL 서비스가 정상적으로 실행된 것을 확인 후, 

- Terminal #2 에서 mysql -u root 로 실행하였더니, SQL 로 접속이 되었으나, 쿼리 입력 시 mysql 다운 발생

C:\Users\Administrator>mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.57

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select user,host from mysql.user;

## 오류 발생

Log Check

- --skip-grant-tables --console 터미널에 출력된 로그 확인

08:47:07 UTC - mysqld got exception 0xc0000006 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed,
something is definitely wrong and this may fail.

key_buffer_size=57671680
read_buffer_size=65536
max_used_connections=1
max_threads=100
thread_count=1
connection_count=1
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 89360 K  b
ytes of memory
Hope that's ok; if not, decrease some variables in the equation.

Thread pointer: 0xdc23fb0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
7ff624421027    mysqld.exe!?MYSQLparse@@YAHPEAVTHD@@@Z()
7ff6243126a1    mysqld.exe!?parse_sql@@YA_NPEAVTHD@@PEAVParser_state@@PEAVObject
_creation_ctx@@@Z()
7ff62431a31c    mysqld.exe!?mysql_parse@@YAXPEAVTHD@@PEADIPEAVParser_state@@@Z()

7ff62431b262    mysqld.exe!?dispatch_command@@YA_NW4enum_server_command@@PEAVTHD
@@PEADI@Z()
7ff62431c15c    mysqld.exe!?do_command@@YA_NPEAVTHD@@@Z()
7ff624342176    mysqld.exe!?do_handle_one_connection@@YAXPEAVTHD@@@Z()
7ff624342234    mysqld.exe!handle_one_connection()
7ff6244ce3ef    mysqld.exe!win_pthread_mutex_trylock()
736b2fdf    MSVCR90.dll!_endthreadex()
736b3080    MSVCR90.dll!_endthreadex()
7ffa6f70168d    KERNEL32.DLL!BaseThreadInitThunk()
7ffa719e4629    ntdll.dll!RtlUserThreadStart()

Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (dc7f510): select @@version_comment limit 1Connection ID (thread ID): 1
Status: NOT_KILLED

The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.

오류 코드 ( 0xc0000006 )

- 0xc0000006 (STATUS_IN_PAGE_ERROR) : 블루 스크린/오류 코드 - 나무위키

프로세스가 메모리의 특정 페이지에 접근하려 했으나,
그 페이지를 디스크에서 읽어오지 못하여 오류가 발생하는 경우
 

블루 스크린/오류 코드

출처 출처 2 마이크로소프트 공식 블루 스크린 코드 문서(영어) 마이크로소프트 공식 NTSTATUS 코드 문서(영어

namu.wiki

 


가능한 문제 나열

 1. MySQL 실행파일 및 모듈 손상(mysqld.exe, MSVCR90.dll 등)

 2. MySQL Data 파일 손상(ibdata1, *.frm, *.MYD 등)

 3. 디스크 불량(배드 섹터)

 4. 백신 및 보안 프로그램이 mysqld를 차단

 5. 32bit vs 64bit 충돌

 6. Visual C++ Redistributable 누락 또는 손상

 7. 내부 VM의 파일 시스템 오류 

 8. 메모리 설정 변경 


제외 시킨 문제

- 디스크 불량(배드 섹터)

  - 현재 MySQL이 설치된 환경은 ESXi 내부에 VM(Windows)을 설치하였고, 

  - Windows Server 2012 R2에 MySQL 5.5.57을 설치해놓은 상황

  - 만약, ESXi Host에서 디스크의 배드섹터가 발생한 것이라면, 다른 VM에서도 문제가 발생되어야 함. 

  - 현재 ESXi Host에는 60여개의 VM이 존재하며, 모두 정상으로 확인했으므로, 디스크 배드섹터의 가능성은 없다고 판단

 

- 백신 프로그램이 mysqld 차단

 - ESXi 내부 VM에 설치한 환경이며, 해당 서버는 스크립트 테스트 용도로써, 최근 Windows Server 가 아닌, EOS 된 서버

 - 요즘 서버, PC 처럼 방화벽에 실시간 감시 기능은 존재하지 않고, 백신프로그램을 통한 차단이 필요한데, 

 - 백신 프로그램 설치가 되어 있지 않으므로 해당 문제도 아니라고 판단 

 

- 32bit vs 64bit 설치 오류 , 

 - 설치 파일을 해당 환경에서 구축 후 방화벽을 Open 하여 다운받았으며, 

 - 64bit로 설치한 파일인 것을 다운로드 폴더에서 확인 완료

 

 


조치 시도

- Visual C++ Redistributable 누락 또는 손상

 - 또한, 설치 오류 문제는 아니였고, MySQL을 설치 후 스크립트 테스트 목적으로 1년간 사용했었으므로, 

 - 갑작스러운 Visaul C++ 누락은 아니라고 판단 했으나, 조치 시도 

 - 제어판(프로그램 추가)을 통해 "Visual C++" 관련에 대해 Repair 하였으나, 오류는 그대로 였으므로 이 문제도 아니라고 판단 

 

- 내부 VM의 파일 시스템 오류 

 - 윈도우 서버 이므로 cmd를 통해 "chkdsk /f C:\" 명령을 통해 재부팅하면서 로컬디스크(C)에 문제가 있는지 점검

 - 문제 발견되지 않음 

 

- MySQL 실행파일 및 모듈 손상 / 데이터 파일 손상

 - 위 문제들을 조치해보았지만 해결되지 않아,

 - mysqld.exe, MSVCR90.dll 등 실행파일에 오류가 발생한 경우라고 판단하고, 해당 파일을 업데이트 시도 하려고 함

 - Source(ZIP)를 사용하여 설치했으므로, 실행파일 및 각종 모듈만 덮어쓰기하면 되지만, 

 - 해당 서버 및 DB가 어떠한 데이터도 저장되어있지 않은 껍데기만 있는 DB라는 점을 인식하고 있었기 때문에

 - data 폴더 또한 삭제하고 전체적으로 덮어쓰기를 함 


해결방안 #1

 - 메모리 설정 값을 확인 (높게 잡혀있다면 축소하는 방안도 고려)

 - 아래 설정 적용 후 mysqld --skip-grant-tables --console 실행 및 mysql -u root 확인

[mysqld]
key_buffer_size=16M
sort_buffer_size=512K
read_buffer_size=512K
max_connections=10

해결방안 #2

 - 실행파일 및 데이터파일 손상에 대해 "덮어쓰기" 혹은 "Repair"을 통한 복구 

 < Source ZIP >

 

< MSI Setup >


해결

- 데이터베이스 접속 성공 및 root 비밀번호 초기화 완료

C:\Program Files\MySQL\MySQL Server 5.5\bin>mysql -u root

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.57 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
mysql> use mysql;
Database changed

mysql> update user set password=password('Test1234!') where user='root';
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3  Changed: 3  Warnings: 0

mysql>
mysql>
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

후기

 여기까지 알아내는데에 거의 3~4시간 정도가 걸렸다. 

 원인도 다양하게 있어서 제외 시킬 것 제외하고, 이것저것 모두 시도해보았지만,

 결국 실행파일 및 데이터파일에 문제가 있었다고 판단했다. 

 느낌이지만, 실행파일 및 모듈 파일이 문제였을 것이다. 

 만약, 데이터 파일에 문제가 생긴 것이라면 "운영" 환경에서는 정말 답이 없을 것 같았다. 

 물론, 내 환경이 테스트 서버라는 점에서 이러한 시도가 가능했을 것이고, 

 "운영" 환경 이었다면, 데이터를 다 날리는 이러한 행위또한 불가능 했을 것이다. 

 아마 "master/slave" 설정을 통해 오류가 발생하기 직전의 상태로 원복시켰어야 할 것이고, 

 그랬다면 기관의 입장에서는 "서비스 장애로 인한 손해배상" 도 발생했을 수 있었을 것이다. 

 내 시도가 결코 올바른 대처였다고 생각하지는 않지만, 가능한 환경이었기에 해볼 수 있는 조치라고 생각한다. 

 

728x90
반응형

'Operating System > Unix&Linux' 카테고리의 다른 글

CentOS 9 Stream Mirrorlist 오류  (0) 2025.06.01
CentOS7 Mirrorlist Update  (2) 2024.07.14
Snort 설정(conf)  (0) 2023.10.10
Snort 2.9 설치  (0) 2023.10.09
Ubuntu 16.04 LTS Setup Chrome Browser  (0) 2019.01.16
728x90
반응형

6년전, 나는 랜섬웨어에 관한 연구(공부)를 진행했던 적이 있다. 

 

VM에 Windows를 올려서 랜섬웨어로 의심되는 파일들을 여러가지 다운받았고, 실제로 감염을 시켰었다. 

감염 시키고 바로 네트워크 연결을 끊은 후 FTK Imager를 통해서 이미지를 만들었고,

감염이 되지 않은 VM에 이미지 파일을 올려서 분석을 했었다. 

 

이외에도, 파이썬을 통해서 기초적인 랜섬웨어를 모방할 수 있는 코드를 만들어 보았었고, 

만든 후 VM에 업로드 해서 파일을 암호화 시켜보았었다. 

https://github.com/KKongten/Ransomware

 

GitHub - KKongten/Ransomware

Contribute to KKongten/Ransomware development by creating an account on GitHub.

github.com

이 코드가 그때 만들었던 기초적인 코드였다. 

 

이제와서 생각해보면, 6년전에 내가 연구라고 생각했던 행위나, 코드를 만들었던 것들은..

침해사고 분석도 아니고, 랜섬웨어를 깊게 분석한 것도 아닌 이도저도 아닌 그냥 찍먹정도의 수준이였던 것이였다. 

 

최근 나는 다시 랜섬웨어에 관심이 생겼다.

고객사의 협력업체에서 랜섬웨어에 감염된 PC가 있다는 연락을 받은 후 너무나 감사하게도 분석을 할 수 있는 기회가 있었다. 

 

6년전에 뭣도 아닌 경험이 나에게 분석할 수 있는 기회가 주어졌다는것에 너무 감사했다. 

그치만 도움은 전혀 되지 않았다. 

 

그래서 이번에 다시 랜섬웨어를 공부해볼까 한다. 


랜섬웨어란..?

랜섬웨어(Ransomware)는 사용자의 데이터를 암호화 하거나 접근을 하지 못하게 제한 한 뒤, 이를 복구 해주겠다는 대가로 금전을 요구하는 악성코드의 일종

  - 금전은 대부분 암호화폐(비트코인)를 요구


랜섬웨어가 일반적인 악성코드와 다른점

  일반적인 악성코드 랜섬웨어
목적 정보 탈취, 감시, 시스템 장악 금전 취득 ( 파일 및 시스템 암호화 ) 
수익 모델 탈취한 정보 판매(딥, 다크웹), 계정 판매 복호화 대가로 금전 요구
기능 구조 키로거, 백도어, 브라우저 데이터 추출 등 파일 암호화, 복호화 키 관리, 랜섬노트 표시
탐지 가능성 은밀하게 작동하여 탐지 어려움 시스템 이용 불가, 재부팅, 경고문구등으로 즉시 탐지 가능
지속성 오랜기간 숨어서 활동 가능 단기간 안에 파일 전부 암호화 가능
급력 특정 타깃을 대상으로 위주로 활동 무차별 감염 

랜섬웨어 분류

랜섬웨어는 공격 유형에 따라 3가지로 분류된다. 

  1. Crypto Ransomware : 사용자 파일을 암호화 하는 유형

  2. Locker Ransomware : 시스템 자체를 잠그는 유형

  3. Hybrid Ransomware : 위 두가지 방식을 동시에 사용하는 유형 


감염 단계

  1. 초기 감염

     - 이메일 첨부파일, 웹사이트 방문(Drive-By-Download), Exploit Kit, 악성 매크로가 포함된 Office 문서, PDF 문서, PE 실행파일 등을 통해서 감염 진행

 

  2. 암호화 키 생성

     - AES-128/256 등 여러 기법을 통해 파일을 암호화 하며, RSA-2048 등의 공개키로 암호화되어 공격자만 복호화가 가능함 

 

  3. 파일 탐색 및 암호화

     - 암호화 타깃 검색 (확장자 탐색 : .docx, .xlsx, .pdf, .jpeg, .png, .hwp 등)

     - 임의 확장자를 부여하면서 암호화하고 원본 파일은 삭제함

 

  4. 복구 방지 및 은폐 

     - VSS(Shadow Copy) 파일, 이벤트 로그를 삭제하며, 탐지 회피 기술을 적용 

 

  5. 랜섬노트 및 사용자 협박

     - 암호화 후 재부팅 된 이후 바탕화면에 유일하게 확인이 가능한 "README.txt" 파일을 제공하거나, 

     - 바탕화면을 변경시켜서 랜섬웨어에 감염되는 다는 것을 인지시킴 

     - N시간 내로 금전(비트코인)을 보내지 않으면 영원히 파일을 복구할 수 없다는 협박성을 강조함 

 

  6. 대가 지불 및 복호화

     - 지불 완료되면 공격자는 복호화 툴을 제공함, 일부 랜섬웨어 공격자는 지불 후에도 복호화를 제공하지 않음


코드 업데이트

   1. 암호화 키 부분 업데이트 예정

       -> 연구 목적이었기 때문에 암복호화를 편하게 하기 위해서 "고정키"를 사용했었음

       -> 이 부분을 랜덤 AES 키를 사용하고, RSA 기법을 사용하여 암호화 예정 

       -> 복호화 기능 또한 코드를 변경하여 랜덤 키값을 확인할 수 있도록 변경 예정

 

   2. 네트워크 통신 ( 안함 ) 

       -> 내 VM이 아닌, 다른 환경에 감염을 목적으로 한다면 C&C 서버 등을 통해 정보 유출이나,

           공격자 서버와 통신, 추가 감염, 키 분배 등의 다양한 목적을 위해서 네트워크 통신 기능이 필요로 함.

       -> 연구 목적이므로, 이 부분에 대해서는 별도로 추가 개발 하지 않음 

 

   3. 타깃 지정 

       -> 지정된 폴더를 탐색하는 방향으로 되어 있던 코드에서

       -> 전체 디스크를 대상, 파일 확장자를 기준으로 감염 타깃을 설정하는 부분을 업데이트 예정

 

   4. 은닉 기능 추가 및 백업 삭제

       -> VSS 등 사용자가 만들어놓은 백업에 대해 삭제하는 방향으로 업데이트

       -> 프로세스, 백그라운드, 이벤트로그 등에서 탐지되지 않도록 우회 코드 추가 예정

 

   5. 실행방법 업데이트 

       -> GUI를 통해서 암호화/복호화를 진행했던 방식에서

       -> 초기 감염방법으로 실행이 되었을 때 "시작 프로그램" 폴더에 등록을 하고, 

       -> PC 부팅 시 자동 실행되도록 변경 예정 

 

코드가 업데이트 되는 과정은 Velog에 업로드 예정 

728x90
반응형

'Security' 카테고리의 다른 글

DNS 서버 구축  (0) 2025.11.18
728x90
반응형

 

CentOS 9 Minimal 버전으로 설치 후 dnf 로 업데이트를 하려고 진행했으나 오류가 발생하였다. 

[root@localhost ~]# dnf update

CentOS Stream 9 - BaseOS                                                                                                                                                                                                                                      0.0  B/s |   0  B     00:00
Errors during downloading metadata for repository 'baseos':
  - Curl error (6): Couldn't resolve host name for https://mirrors.centos.org/metalink?repo=centos-baseos-9-stream&arch=x86_64&protocol=https,http [Could not resolve host: mirrors.centos.org]
Error: Failed to download metadata for repo 'baseos': Cannot prepare internal mirrorlist: Curl error (6): Couldn't resolve host name for https://mirrors.centos.org/metalink?repo=centos-baseos-9-stream&arch=x86_64&protocol=https,http [Could not resolve host: mirrors.centos.org]

 

중요 오류내용 :  "Couldn't resolv host name ~ " 

DNS 이름을 확인할 수 없어서 발생하는 네트워크 문제이다. 

 

최소 버전으로 설치를 하다보면 DNS 관련 구성이 누락되면서 설치가 되는 경우가 일부 존재한다. 

이 때  확인해야 할 것은 세가지로 좁혀진다. 

 

1. 외부 인터넷 연결 확인

[root@localhost ~]# ping -c 4 8.8.8.8

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=112 time=37.8 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=112 time=37.7 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=112 time=38.1 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=112 time=37.5 ms

--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 37.520/37.764/38.051/0.192 ms

 

외부 인터넷으로 연결이 되어있는지부터 확인해야 한다. 

 

최소 버전으로 설치를 하다보니 IPv4 가 DHCP로 할당되어 있을 텐데, 만약 외부 Ping이 나가지 않는다면

nmtui 혹은 nmcli를 통해서 네트워크 구성을 먼저 살펴야 한다. 

 

현재는 외부로 Ping이 잘 되고 있으니, 다음 확인할 내용으로 넘어갔다. 


2. DNS 설정 확인

[root@localhost ~]# cat /etc/resolv.conf

# 정상 
# [ /etc/resolv.conf ]
nameserver 8.8.8.8
nameserver 1.1.1.1

 

본인은 여기서 문제가 발생했다. 

최소 버전으로 설치를 하다보니 /etc/resolv.conf 파일 자체가 없던 것이다.

최소 버전으로 설치를 하면서 DNS 구성의 일부 파일이 누락이 되었고, 이로 인해 /etc/resolv.conf 파일이 없어서 DNS 를 찾지 못한것이 문제였다. 

 

그리하여 /etc/resolv.conf 를 만들었고, 그 안에 기존 설정을 넣어주었다. 

[root@localhost ~]# bash -c 'echo -e "nameserver 8.8.8.8\nnameserver 1.1.1.1" > /etc/resolv.conf'

[root@localhost ~]# ls -al /etc/resolv.conf
-rw-r--r--. 1 root root 38 Jun  1 10:01 /etc/resolv.conf
[root@localhost yum.repos.d]# cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 1.1.1.1

 

이후 dnf update를 실행했더니 정상으로 돌아왔다. 


3. 방화벽 혹은 프록시 확인

회사와 같은 기관 내부의 경우 방화벽이나 프록시에 의해서 차단되었을 수 있다. 

이 경우는 회사 보안정책 담당자에게 문의 후 조치가 필요하다. 

그러나 개인의 경우 해당사항이 없을 것이다. 


4. EOS 로 인한 Mirrorlist 중단

CentOS 7, 8등과 같이 OS가 EOS 된 경우 Mirrorlist 또한 중단된다. 

이 경우에는 epel-release 와 같은 별도의 경로를 mirrorlist로 변경하여 설치해야 한다.

 

728x90
반응형

'Operating System > Unix&Linux' 카테고리의 다른 글

[TroubleShooting] MySQL 실행 불가  (3) 2025.07.28
CentOS7 Mirrorlist Update  (2) 2024.07.14
Snort 설정(conf)  (0) 2023.10.10
Snort 2.9 설치  (0) 2023.10.09
Ubuntu 16.04 LTS Setup Chrome Browser  (0) 2019.01.16

+ Recent posts