<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>bulrange.log</title>
        <link>https://velog.io/</link>
        <description>클라우드 연구하고 통신사 취업을 목표로 하고 있는 돌선생..</description>
        <lastBuildDate>Thu, 23 Apr 2026 16:26:03 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. bulrange.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/yoo_j" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[AWS 프리티어 활용하기[1]]]></title>
            <link>https://velog.io/@yoo_j/AWS-%ED%94%84%EB%A6%AC%ED%8B%B0%EC%96%B4-%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B01</link>
            <guid>https://velog.io/@yoo_j/AWS-%ED%94%84%EB%A6%AC%ED%8B%B0%EC%96%B4-%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B01</guid>
            <pubDate>Thu, 23 Apr 2026 16:26:03 GMT</pubDate>
            <description><![CDATA[<p>AWS를 활용해서 공용 서버 환경을 구축하기 위해서 구글 계정으로 프리티어 요금제를 선택하여 AWS계정을 하나 만들었다.</p>
<p>(사실 예전에 연구용으로 사용하려고 발급받았던 계정이 있는데 프리티어가 만료되고 언젠가부터 5000원씩 빠져나가길래 확인해봤는데 퍼블릭 IP 하나가 삭제되지 않고 남아있던 문제가 있어서 계정을 영구삭제 했다.)</p>
<p>이번에는 헛돈 쓰지 않도록 조심해서 사용하도록 해야지</p>
<ol>
<li>AWS 계정 생성 목적</li>
</ol>
<p>-&gt; 부트캠프에서 하는 프로젝트 공용환경(서버 구축)
-&gt; AWS 활용 능력 함양하기</p>
<ol start="2">
<li>EC2 인스턴트를 통해서 SSH 로 접속할 수 있는 공용 서버를 구축해보고자 한다.</li>
</ol>
<p>아래와 같이 아무것도 없는 계정 생성</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/1280b1ba-7f18-4cd0-87f2-d1437e8153f1/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/3207322a-7255-4983-a401-dc0a8d2eee68/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/cf7f3609-338a-4921-9773-b5c39b6aba8c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/6ce1b16a-aacb-497b-8af3-018d94022257/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/db185b95-173e-4207-b7d1-a9cb45c6ae3b/image.png" alt="">
오른쪽 위 인스턴스 시작 버튼을 누르면 다음과 같은 화면 확인 가능하다.
<img src="https://velog.velcdn.com/images/yoo_j/post/a94cc32c-da2b-4214-835f-82ba4abed5b2/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/bf5c0739-b251-4e98-be37-d38f6c9c0743/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/7ea34962-6756-40d9-be39-d0960ee6c4b8/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/b9f1e38a-0ad1-4885-995c-ac1348227094/image.png" alt=""></p>
<p>보안그룹은 일단 디폴트로.. 
<img src="https://velog.velcdn.com/images/yoo_j/post/2048ee96-365d-47be-9af7-33f195d7a2fd/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/1e933827-2b7d-4bf4-a09e-55f0f1db9860/image.png" alt=""></p>
<p>실행중 확인</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/b3089b3c-a791-4de1-9e79-37a10326827c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/f40bfc8c-87df-4fb6-84ba-66724b96618b/image.png" alt=""></p>
<p>만들때 참고했던 영상
: <a href="https://www.youtube.com/watch?v=1Ra-L9o1GeE">https://www.youtube.com/watch?v=1Ra-L9o1GeE</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git 사용법 정리/실습]]></title>
            <link>https://velog.io/@yoo_j/Git-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%A0%95%EB%A6%AC%EC%8B%A4%EC%8A%B5</link>
            <guid>https://velog.io/@yoo_j/Git-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%A0%95%EB%A6%AC%EC%8B%A4%EC%8A%B5</guid>
            <pubDate>Sun, 22 Mar 2026 10:28:30 GMT</pubDate>
            <description><![CDATA[<p>git 을 사용하면 코드간 공유가 쉬워지고 여러모로 협업할 때 도움이 된다.
실무에서도 실제로 많이 쓰이고 
이번 부트캠프에서 특강 주제로 git 사용법에 대해서 학습했는데, 도움이 되는 것 같아서 정리해서 다시금 복기 해보려고한다.</p>
<p>일단  git의 모든것을 알 수 없으니 가장 많이 쓰는 것만. </p>
<p>git add . </p>
<p>git commit -m &quot;ddsfdf&quot;</p>
<p>git push (원격 저장소 구성했을때)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[인터페이스 개념]]></title>
            <link>https://velog.io/@yoo_j/%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EA%B0%9C%EB%85%90</link>
            <guid>https://velog.io/@yoo_j/%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EA%B0%9C%EB%85%90</guid>
            <pubDate>Sun, 22 Mar 2026 10:24:16 GMT</pubDate>
            <description><![CDATA[<p>인터페이스(Interface)는 서로 다른 두 시스템, 장치, 혹은 소프트웨어 사이에서 정보나 신호를 주고받는 접점, 경계면 또는 연결 매개체를 의미합니다. 기기와 사용자(UI), 하드웨어 간(USB, 커넥터), 소프트웨어 간(API)의 상호작용을 위해 미리 정의된 규칙이나 물리적 연결을 모두 포함.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[웹 페이지 만들기 실습]]></title>
            <link>https://velog.io/@yoo_j/%EC%9B%B9-%ED%8E%98%EC%9D%B4%EC%A7%80-%EB%A7%8C%EB%93%A4%EA%B8%B0-%EC%8B%A4%EC%8A%B5</link>
            <guid>https://velog.io/@yoo_j/%EC%9B%B9-%ED%8E%98%EC%9D%B4%EC%A7%80-%EB%A7%8C%EB%93%A4%EA%B8%B0-%EC%8B%A4%EC%8A%B5</guid>
            <pubDate>Sun, 22 Feb 2026 18:02:06 GMT</pubDate>
            <description><![CDATA[<p>xampp 설치 후 진행
여러가지 도구들을 한데 모아놓은.. 그런 프로그램?</p>
<p>xampp 에 대한 자세한 설명은 여기서..
<a href="https://ko.wikipedia.org/wiki/XAMPP">https://ko.wikipedia.org/wiki/XAMPP</a></p>
<p>-&gt; XAMPP는 크로스 플랫폼 웹 서버 자유 소프트웨어 꾸러미이다. 아파치 웹 서버, MariaDB, PHP, 펄을 포함하고 있다. GNU 일반 공중 사용 허가서로 배포되며 자유롭고 쓰기 쉬운 웹 서버이다. 마이크로소프트 윈도우, 리눅스, 솔라리스, 맥 오에스 텐 등에서 동작하며 주로 웹 개발에 사용된다.</p>
<p>개발 환경 구성을 좀 더 쉽게 할 수 있다는 장점이 있다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/ed6b5e63-8b67-426b-afdc-584391101baf/image.png" alt=""></p>
<p>단순 인사말 출력하는 페이지를 출력해보려고 한다.
아래와 같은 경로에 아래와 같은 내용으로 PHP 파일 만들어서 저장해주고
<img src="https://velog.velcdn.com/images/yoo_j/post/31e6a2ae-c0e1-4c8f-bf5e-5706b115466c/image.png" alt=""></p>
<p>localhost/HELLOPHP.php 로 이동해주면, 설정된 경로에 따라서 HELLOPHP.php 파일에 적힌 내용이 웹페이지 형식에 맞게 출력된것 
<img src="https://velog.velcdn.com/images/yoo_j/post/2c4088bb-8c90-43f8-8cae-ec96b16c0a98/image.png" alt=""></p>
<p>이제 나머지 과제 수행을 진행해보면,</p>
<p>과제에서 요구한것.</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/db0ea60a-098e-4dba-9de2-02cb4ee3198d/image.png" alt=""></p>
<p>작성한 php 코드 내용</p>
<p>-&gt; 파일 저장 위치는 C:\xampp\htdocs<br>이름은 login.php 로 저장하였다.</p>
<pre><code>&lt;?php
$message = &quot;&quot;;

if ($_SERVER[&quot;REQUEST_METHOD&quot;] == &quot;GET&quot; &amp;&amp; isset($_GET[&quot;userid&quot;])) {
    $id = $_GET[&quot;userid&quot;];
    $pw = $_GET[&quot;userpw&quot;];

    if ($id == &quot;admin&quot; &amp;&amp; $pw == &quot;1234&quot;) {
        $message = &quot;로그인 성공!&quot;;
    } else {
        $message = &quot;로그인 실패!&quot;;
    }
}
?&gt;

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;로그인 페이지&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h2&gt;GET 방식 로그인&lt;/h2&gt;

&lt;form method=&quot;GET&quot;&gt;
    아이디: &lt;input type=&quot;text&quot; name=&quot;userid&quot;&gt;&lt;br&gt;&lt;br&gt;
    비밀번호: &lt;input type=&quot;password&quot; name=&quot;userpw&quot;&gt;&lt;br&gt;&lt;br&gt;
    &lt;input type=&quot;submit&quot; value=&quot;로그인&quot;&gt;
&lt;/form&gt;

&lt;p&gt;&lt;?php echo $message; ?&gt;&lt;/p&gt;

&lt;/body&gt;
&lt;/html&gt;
</code></pre><p>로그인 페이지를 구현하려고 하였으며 실행시키면</p>
<p>아래와 같다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/afb3e84f-098a-46eb-a8c1-d5cfedcf5f12/image.png" alt=""></p>
<p>로그인에 성공하였을 경우 
<img src="https://velog.velcdn.com/images/yoo_j/post/101abf1d-9944-4652-a0f0-5520f14e7941/image.png" alt=""></p>
<p>실패하였을 경우</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/02fa2a3e-8e8c-4971-8438-dd26864c9d3a/image.png" alt=""></p>
<p>다만, 데이터 베이스 연동은 안했고, 단순 하드코딩 방식을 사용하였으며 get  방식이라서 주소창에 모든 정보가 그대로 노출된다는 단점이 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[미션 수행 - shodan 사용 취약점 검색 ]]></title>
            <link>https://velog.io/@yoo_j/%EB%AF%B8%EC%85%98-%EC%88%98%ED%96%89-shodan-%EC%82%AC%EC%9A%A9-%EC%B7%A8%EC%95%BD%EC%A0%90-%EA%B2%80%EC%83%89</link>
            <guid>https://velog.io/@yoo_j/%EB%AF%B8%EC%85%98-%EC%88%98%ED%96%89-shodan-%EC%82%AC%EC%9A%A9-%EC%B7%A8%EC%95%BD%EC%A0%90-%EA%B2%80%EC%83%89</guid>
            <pubDate>Sun, 08 Feb 2026 22:56:01 GMT</pubDate>
            <description><![CDATA[<p>과제에서 주어진 내용 </p>
<p>취약한 사이트에 직접 접속 금지</p>
<p>공격·스캔 금지</p>
<ul>
<li><p>IP 검색엔진 검색 결과만 사용</p>
</li>
<li><p>결과물: “젠킨스가 설치된 한국 서버 수”</p>
</li>
</ul>
<br>

<hr>
<p>수행 내역 </p>
<ol>
<li>shodan 접속</li>
</ol>
<p><a href="https://www.shodan.io/">https://www.shodan.io/</a></p>
<br>

<ol start="2">
<li>검색 쿼리 만들기</li>
</ol>
<p>목표: 한국에 위치한 Jenkins 서버 수</p>
<p>기본 조건 3가지</p>
<ul>
<li><p>Jenkins 서비스</p>
</li>
<li><p>한국 (KR)</p>
</li>
<li><p>웹 서비스 (보통 8080, 80, 443)</p>
</li>
</ul>
<hr>
<p>결과 (쿼리 만들때 필터 사용하려면 가입해야한다고 해서 가입해줬습니다.)
<br></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/220559f6-4280-4e79-ba0a-e632e72fca7c/image.png" alt=""></p>
<br>

<p>퀴리의 경우  product:&quot;Jenkins&quot; country:&quot;KR&quot; 이렇게 작성하였으며, 의미는</p>
<p>product:&quot;Jenkins&quot;
→ Shodan이 Jenkins 서비스로 식별한 서버</p>
<p>country:&quot;KR&quot;
→ 대한민국에 위치한 IP</p>
<p>검색 후에는 이렇게 화면이 표시 됩니다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/1b6a65f4-352a-4eda-b99d-f82d004f4b04/image.png" alt=""></p>
<p>왼쪽에 표시된 값을 보면 총 젠킨스가 설치된 한국 서버 수는 1,737 대로 확인됩니다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/d3e0084f-e029-4ae9-ba3a-04ccee43b656/image.png" alt=""></p>
<p>근데 paripark 은 뭐...뭘까요?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[알고리즘 위클리 챌린지 [그래프 탐색3] 문풀]]></title>
            <link>https://velog.io/@yoo_j/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9C%84%ED%81%B4%EB%A6%AC-%EC%B1%8C%EB%A6%B0%EC%A7%80-%EA%B7%B8%EB%9E%98%ED%94%84-%ED%83%90%EC%83%893-%EB%AC%B8%ED%92%80</link>
            <guid>https://velog.io/@yoo_j/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9C%84%ED%81%B4%EB%A6%AC-%EC%B1%8C%EB%A6%B0%EC%A7%80-%EA%B7%B8%EB%9E%98%ED%94%84-%ED%83%90%EC%83%893-%EB%AC%B8%ED%92%80</guid>
            <pubDate>Sun, 08 Feb 2026 22:43:30 GMT</pubDate>
            <description><![CDATA[<p>문제는 이렇게 되어있기는 한데,, 최소 경로 길이를 구하라면서 왜 이동한 행렬을 출력해야하는건지..? 잘 모르겠음.. 계속 오답 떠서.. 시간을 가지고 좀 고민해보기로..
<img src="https://velog.velcdn.com/images/yoo_j/post/b66ae984-bac3-49b9-ac9c-a3e37ba7fcda/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[알고리즘 위클리 챌린지 [그래프 탐색2] 문풀]]></title>
            <link>https://velog.io/@yoo_j/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9C%84%ED%81%B4%EB%A6%AC-%EC%B1%8C%EB%A6%B0%EC%A7%80-%EA%B7%B8%EB%9E%98%ED%94%84-%ED%83%90%EC%83%892-%EB%AC%B8%ED%92%80</link>
            <guid>https://velog.io/@yoo_j/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9C%84%ED%81%B4%EB%A6%AC-%EC%B1%8C%EB%A6%B0%EC%A7%80-%EA%B7%B8%EB%9E%98%ED%94%84-%ED%83%90%EC%83%892-%EB%AC%B8%ED%92%80</guid>
            <pubDate>Sun, 08 Feb 2026 22:09:11 GMT</pubDate>
            <description><![CDATA[<p>문제는 아래와 같으며
<br></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/ce007811-be5c-4390-8035-631d9282ccc5/image.png" alt=""></p>
<p>정답 코드 및 문제 요약 해설은</p>
<br>

<ul>
<li>문제에서 주어진 조건</li>
</ul>
<p>: 정점 개수 N</p>
<p>: 간선 개수 M</p>
<p>간선은 단방향</p>
<p>간선 정보:
→ S E 는 S에서 E로만 이동 가능</p>
<p>1번 정점에서 DFS 탐색 시작</p>
<p>DFS로 방문한 정점의 순서를 출력</p>
<p>여기서 말하는 DFS 알고리즘은
DFS (Depth First Search) 깊이 우선 탐색이며,</p>
<p>한 방향으로 끝까지 들어갔다가
더 이상 갈 곳이 없으면 되돌아오는 탐색 방식이다.</p>
<p>아래는 정답 코드</p>
<br>

<pre><code>import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.readline

from collections import defaultdict

N, M = map(int, input().split())
graph = defaultdict(list)

for _ in range(M):
    s, e = map(int, input().split())
    graph[s].append(e)

visited = [False] * (N + 1)

def dfs(current):
    visited[current] = True
    print(current, end=&#39; &#39;)

    # 핵심: 역순 탐색
    for next_node in reversed(graph[current]):
        if not visited[next_node]:
            dfs(next_node)

dfs(1)</code></pre><br>

<p>해설 및 주석은 아래 코드</p>
<pre><code>import sys
sys.setrecursionlimit(10**6)   # 재귀 깊이 제한 증가
input = sys.stdin.readline

from collections import defaultdict

# 1. 정점 수 N, 간선 수 M 입력
N, M = map(int, input().split())

# 2. 그래프를 인접 리스트 형태로 저장
graph = defaultdict(list)

# 3. 간선 정보 입력 (단방향)
for _ in range(M):
    s, e = map(int, input().split())
    graph[s].append(e)

# 4. 방문 여부 체크 배열
visited = [False] * (N + 1)

# 5. DFS 함수 정의
def dfs(current):
    # 현재 정점 방문 처리
    visited[current] = True

    # 방문 순서 출력
    print(current, end=&#39; &#39;)

    #핵심 포인트
    # 인접 정점을 역순으로 탐색
    for next_node in reversed(graph[current]):
        if not visited[next_node]:
            dfs(next_node)

# 6. 1번 정점부터 DFS 시작
dfs(1)
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[알고리즘 위클리 챌린지 [그래프 탐색1] 문풀 ]]></title>
            <link>https://velog.io/@yoo_j/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9C%84%ED%81%B4%EB%A6%AC-%EC%B1%8C%EB%A6%B0%EC%A7%80-%EA%B7%B8%EB%9E%98%ED%94%84-%ED%83%90%EC%83%891-%EB%AC%B8%ED%92%80</link>
            <guid>https://velog.io/@yoo_j/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9C%84%ED%81%B4%EB%A6%AC-%EC%B1%8C%EB%A6%B0%EC%A7%80-%EA%B7%B8%EB%9E%98%ED%94%84-%ED%83%90%EC%83%891-%EB%AC%B8%ED%92%80</guid>
            <pubDate>Sun, 08 Feb 2026 21:29:45 GMT</pubDate>
            <description><![CDATA[<p>문제는 사진과 같으며, 
<img src="https://velog.velcdn.com/images/yoo_j/post/34b47767-d391-463b-9a41-702ba12a2bfe/image.png" alt=""></p>
<p>답은,, 파이썬 기준으로 아래와 같으며 마지막 두줄을 추가하였다.</p>
<br>
<br>

<pre><code>import sys
from collections import defaultdict, deque

input = sys.stdin.readline

N, M = map(int, input().split())

Graph = defaultdict(list)

for _ in range(M):
    s, e = map(int, input().split())
    Graph[s].append(e)   # 단방향

start = 1
Visited = [False] * (N + 1)
q = deque()

q.append(start)
Visited[start] = True

while q:
    current = q.popleft()
    print(current, end=&quot; &quot;)

    for next_node in Graph[current]:
        if not Visited[next_node]:
            Visited[next_node] = True
            q.append(next_node)
</code></pre><p>문제에 대한 요약은 다음과 같다.</p>
<p>정점의 개수: N</p>
<p>간선의 개수: M</p>
<p>간선 정보가 주어짐</p>
<ul>
<li>단방향 그래프</li>
</ul>
<p>BFS 알고리즘으로
정점 1번에서 시작해서
탐색되는 정점의 순서를 출력하라</p>
<p>문제에서 주어진 조건의 핵심 포인트는,</p>
<p>시작 정점은 항상 1</p>
<p>BFS (Queue 사용)</p>
<p>정답으로 방문 순서 출력</p>
<p>여기서 BFS는 = Breadth-First Search (너비 우선 탐색)을 의미한다.</p>
<p>그래프(또는 트리)에서
가까운 노드부터 차례대로 탐색하는 방법.</p>
<p>즉, 시작 정점에서 거리가 가까운 노드부터 먼저 방문하는 탐색 방법이다.
-&gt; 따라서 이에 대한 주석 및 코드 해설은 </p>
<pre><code># sys 모듈: 빠른 입력을 위해 사용
import sys

# defaultdict: 그래프를 쉽게 만들기 위해
# deque: BFS에서 사용할 큐 자료구조
from collections import defaultdict, deque

# input을 sys.stdin.readline으로 바꿔서 입력 속도 향상
input = sys.stdin.readline


# -----------------------------
# 1. 입력 받기
# -----------------------------

# N: 정점(노드)의 개수
# M: 간선의 개수
N, M = map(int, input().split())


# -----------------------------
# 2. 그래프 생성
# -----------------------------

# defaultdict(list):
# 존재하지 않는 key에 접근해도 자동으로 빈 리스트 생성
# → Graph[x].append(y) 할 때 KeyError 방지
Graph = defaultdict(list)

# 간선 정보를 입력받아 그래프에 저장
for _ in range(M):
    s, e = map(int, input().split())
    # s에서 e로 가는 단방향 간선
    Graph[s].append(e)

    # 만약 무방향 그래프라면 아래 줄도 추가해야 함
    # Graph[e].append(s)


# -----------------------------
# 3. BFS 초기 설정
# -----------------------------

# 문제에서 시작 정점은 항상 1번
start = 1

# 방문 여부를 저장하는 배열
# 인덱스를 정점 번호 그대로 쓰기 위해 N+1 크기
Visited = [False] * (N + 1)

# BFS에서 사용할 큐 (FIFO 구조)
q = deque()


# -----------------------------
# 4. 시작 정점 처리
# -----------------------------

# 시작 정점을 큐에 넣는다
q.append(start)

# 시작 정점은 방문 처리
# 큐에 넣을 때 방문 체크하는 것이 중요
Visited[start] = True


# -----------------------------
# 5. BFS 탐색 시작
# -----------------------------

# 큐가 빌 때까지 반복
while q:
    # 큐의 맨 앞에서 하나 꺼냄 (가장 먼저 들어온 노드)
    current = q.popleft()

    # 현재 방문한 노드를 출력
    # BFS 방문 순서 그대로 출력됨
    print(current, end=&quot; &quot;)

    # 현재 노드와 연결된 모든 이웃 노드 탐색
    for next_node in Graph[current]:

        # 아직 방문하지 않은 노드라면
        if not Visited[next_node]:

            # 방문 처리 (중복 방문 방지)
            Visited[next_node] = True

            # 큐에 넣어서 나중에 탐색
            q.append(next_node)
</code></pre><p>위와 같다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[악성코드 분석 입문 과정]]></title>
            <link>https://velog.io/@yoo_j/%EC%95%85%EC%84%B1%EC%BD%94%EB%93%9C-%EB%B6%84%EC%84%9D-%EC%9E%85%EB%AC%B8-%EA%B3%BC%EC%A0%95</link>
            <guid>https://velog.io/@yoo_j/%EC%95%85%EC%84%B1%EC%BD%94%EB%93%9C-%EB%B6%84%EC%84%9D-%EC%9E%85%EB%AC%B8-%EA%B3%BC%EC%A0%95</guid>
            <pubDate>Sun, 08 Feb 2026 21:13:19 GMT</pubDate>
            <description><![CDATA[<h2 id="악성-코드-분석-네가지-접근-방법">악성 코드 분석 네가지 접근 방법</h2>
<ol>
<li>자동화 분석</li>
<li>정적 속성 분석</li>
<li>대화형 동적 분석</li>
<li>수동 코드 역공학 분석</li>
</ol>
<p>-
근데 이 강의도 2017년..; 이지만, 실제로 사이트 접속해보면 최근에도 업데이트는 하고 있는 듯 하다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/5f335b53-782f-4a75-9f61-cd61dbcf6c7a/image.png" alt=""></p>
<p>깃헙.</p>
<p><a href="https://github.com/malware-traffic/indicators">https://github.com/malware-traffic/indicators</a></p>
<hr>
<p>가상머신 튜토리얼은 패스 -&gt; vmware 사용 또는 virtual box </p>
<p>이전에 사용하던 우분투 (쿠버네티스 클러스터로 구성했던거) 재활용 하려고 한다..
윈도우 가상머신은 따로 추가로 설치해줬다.</p>
<p>아래는 윈도우 가상머신 설치할때 필요한 iso 파일 다운로드 링크
<a href="https://www.microsoft.com/ko-kr/software-download/windows11">https://www.microsoft.com/ko-kr/software-download/windows11</a></p>
<p>윈 11 가상머신을 설치할때는 무조건 메모리  4GB 이상으로.. (기본 설정으로 설치하면 오류남!!)</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/d32a8599-9e57-4f3c-8d8a-720a8683f70d/image.png" alt=""></p>
<p>디스크 사이즈도 64 이상으로 !!
<img src="https://velog.velcdn.com/images/yoo_j/post/14485ab4-cff8-43e6-9fdc-b5f18f8379db/image.png" alt=""></p>
<p>인증 키는 Windows 11 Pro: W269N-WFGWX-YVC9B-4J6C9-T83GX</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/f127e909-f14f-4942-83c4-542f60b6bb61/image.png" alt=""></p>
<p>실습환경이 너무 .. 예전....이긴 한데 일단 진행</p>
<p>가상 머신에서 악성코드를 분석하는 이유</p>
<ol>
<li>악성 코드 host pc에서 실행 시 감염 위험..!</li>
<li>악성 코드 분석을 위해 반복적으로 수행 / 초기화 (스냅샷)</li>
</ol>
<hr>
<p>분석 도구들 설치 (가상 머신 내에서..)</p>
<ul>
<li>7-zip : <a href="https://www.7-zip.org/">https://www.7-zip.org/</a></li>
<li>sysinternals Suite : <a href="https://learn.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite">https://learn.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite</a></li>
</ul>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/8a05107e-bb69-403d-bc99-c3865ecfc835/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[정보보안 전문가 부트캠프 교육 내용 정리 ]]></title>
            <link>https://velog.io/@yoo_j/%EC%A0%95%EB%B3%B4%EB%B3%B4%EC%95%88-%EC%A0%84%EB%AC%B8%EA%B0%80-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%EA%B5%90%EC%9C%A1-%EB%82%B4%EC%9A%A9-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@yoo_j/%EC%A0%95%EB%B3%B4%EB%B3%B4%EC%95%88-%EC%A0%84%EB%AC%B8%EA%B0%80-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%EA%B5%90%EC%9C%A1-%EB%82%B4%EC%9A%A9-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 26 Jan 2026 01:44:05 GMT</pubDate>
            <description><![CDATA[<h1 id="파이썬---문법-및-문제-풀기">파이썬 - 문법 및 문제 풀기</h1>
<p>문자열 조건 체크 </p>
<pre><code>#Password Checker

# 방법1
while True:
    results = []
    psw = input(&quot;Enter password: &quot;)

    print()

    if not any(i.isdigit() for i in psw):
        results.append(&quot;최소 1개 이상의 숫자가 포함되야 해요.&quot;)
    if not any(i.isupper() for i in psw):
        results.append(&quot;최소 1개 이상의 대문자가 포함되야 해요.&quot;)
    if len(psw) &lt; 8:
        results.append(&quot;패스워드 길이는 8자 이상 입력해 주세요.&quot;)
    if len(results) == 0: # not results
        print(&quot;비밀번호 형식이 맞습니다.&quot;)
        break
    else:
        print(&quot;아래와 같이 비밀번호 조건이 맞지 않습니다.&quot;)
        for txt in results:
            print(&quot;--&gt;&quot;, txt)

</code></pre><br/>
    <br/>
        <br/>
            <br/>
                <br/>
                    <br/>




<p>알고리즘 챌린지 실습 문제 1 번 (1/22)</p>
<pre><code>N, M = map(int, input().split())
matrix = []

for _ in range(M):
    matrix.append(list(map(int, input().split())))

# 여기부터

answer = 0 # 개수 초기화 

for i in range(M): #배열의 행 탐색
    for j in range(N):
        if matrix[i][j] == 1:
            answer += 1 #배열 값이 1인지 확인하고 1이면 개수 증가

print(answer)
 # 전체적으로 이중 반복문 돌면서 배열 탐색



&lt;br/&gt;
    &lt;br/&gt;
        &lt;br/&gt;
            &lt;br/&gt;
                &lt;br/&gt;
                    &lt;br/&gt;
</code></pre><p>알고리즘 챌린지 실습 문제 2 번 (1/22) - N * M배열에서 2x2의 격자 합이 큰 경우를 출력하기</p>
<pre><code>N, M = map(int, input().split())

# 2차원 배열 입력 받는 부분
matrix = []
for _ in range(N):
    matrix.append(list(map(int, input().split())))

# 2×2 격자 합의 최댓값을 저장할 변수
# 음수도 나올 수 있으므로 매우 작은 값으로 초기화 하는 과정.. 
max_sum = -10**9

# 완전 탐색 시작
# 2×2 격자의 왼쪽 위 좌표 (i, j)를 기준으로 탐색
for i in range(N - 1):
    for j in range(M - 1):

        # 현재 위치에서 2×2 격자의 합 계산 - 반복문 돌면서
        current_sum = (
            matrix[i][j] +
            matrix[i][j + 1] +
            matrix[i + 1][j] +
            matrix[i + 1][j + 1]
        )

        # 최댓값 갱신
        if current_sum &gt; max_sum:
            max_sum = current_sum

# 최종 결과 출력
print(max_sum)</code></pre><p>■ ■ □
■ ■ □</p>
<p>□ ■ ■
□ ■ ■</p>
<p>■ ■ □
■ ■ □</p>
<p>□ ■ ■
□ ■ ■</p>
<br/>
    <br/>



<h1 id="모의-해킹-웹-해킹---파일-업로드-취약점">모의 해킹 (웹 해킹) - 파일 업로드 취약점</h1>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/e55da5b1-bfaa-4635-8191-fdaa1ff3c782/image.png" alt=""></p>
<p>파일업로드 취약점이란 파일 첨부를 할 수 있는 게시판에 일반적으로 허용된 파일(이미지 파일, 워드 파일 등)이외의 개발자가 실수로 서버측에서 악의적인 스크립트가 포함된 소스파일(.JSP, .PHP, ASP등..)을 제대로 된 필터링(확장자)을 하지않아 공격자가 이런 취약점을 이용하여 악성 쉘코드를 등재 후 서버 상에서 쉘코드를 실행시켜 DB 소스코드, 각종 디렉토리 파일들을 획득 및 서버를 장악할 수 있는 매우 위험한 취약점이다. </p>
<p> 파일 업로드 취약점에 대해서 이해하기 위해서는 웹 쉘이 뭔지 알아야한다.</p>
<h3 id="웹-쉘">웹 쉘</h3>
<p> <img src="https://velog.velcdn.com/images/yoo_j/post/3aeb1b9d-77ed-44a2-af07-73d5bce56045/image.png" alt=""></p>
<p>웹쉘은 web + shell의 합성어로써, web은 우리가 알고 있는 웹이며, shell은 사용자와 운영체제의 커널 간 인터페이스 역할을 하는 명령어 해석기이고, </p>
<p>따라서, 웹쉘은 웹에서 사용하는 명령어 해석기라고 이해할 수 있다. -&gt; 이걸 통해서 <strong>시스템 명령</strong>을 사용할 수 있기에 위험!! 웹쉘은 서버사이드 스크립트에서 실행되어야함</p>
<p>웹쉘과 파일 업로드 취약점</p>
<p>웹쉘은 사용자 입력 값을 전달받아 시스템 명령어를 실행하여 결과를 출력하는 소스코드로, 서버 사이드 스크립트(Server-Side Script) 형태로 웹 어플리케이션 측에서 해석이 되어야 하기 때문에  서버 사이드 스크립트 확장자인 php, jsp, aspx 등으로 업로드가 되어야 한다.</p>
<h3 id="웹-쉘-종류">웹 쉘 종류</h3>
<p>아래 깃허브에 웹쉘을 모아둔게 있는데 종류가 다양하다. 
(웹쉘 자체가 공격을 의미하는건 아님. -&gt; 웹에서 시스템 명령을 시행하기위한 일종의 도구이니 참고,, 나중에 웹 개발 할때 필요하면 아래 페이지에서 참고해서 좀 따와도 될듯)</p>
<p><a href="https://github.com/tennc/webshell">https://github.com/tennc/webshell</a></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/f74d38bd-93e4-48a6-831d-2ae78cd968ad/image.png" alt="">
 근데 지금 확인해보니까 2021 이 마지막 업로드인것 같아서, 다른 웹쉘이 있는지 확인해보려고 했다.</p>
<p> <a href="https://github.com/lexisrepo/Shells">https://github.com/lexisrepo/Shells</a></p>
<p> <a href="https://github.com/topics/webshell?o=asc&amp;s=stars">https://github.com/topics/webshell?o=asc&amp;s=stars</a>
 깃허브 토픽으로 검색해서 봐도 되고.. 여러가지 활용방안이 있으니 참고</p>
<p> 실습 해보고 싶으면 
 아래 깃허브 참고해서 실습해도 될듯하다..(한국어로 잘 나와있음) 근데 이것도 8년전이라.. 
 <a href="https://github.com/rinechran/Hws">https://github.com/rinechran/Hws</a></p>
<br/>
    <br/>

<br/>
    <br/>

<br/>
    <br/>





<h1 id="추가적으로-보안-이슈-갈무리-보안-뉴스">추가적으로 보안 이슈 갈무리 (보안 뉴스)</h1>
<p><a href="https://www.boannews.com/media/view.asp?idx=141228&amp;page=1&amp;kind=1">https://www.boannews.com/media/view.asp?idx=141228&amp;page=1&amp;kind=1</a></p>
<p><a href="https://www.boannews.com/media/view.asp?idx=140532&amp;page=2&amp;kind=1">https://www.boannews.com/media/view.asp?idx=140532&amp;page=2&amp;kind=1</a>
-&gt; 내부자에 의한 개인 정보 유출이 심화 되는 추세..?</p>
<p><a href="https://www.boannews.com/media/view.asp?idx=141644">https://www.boannews.com/media/view.asp?idx=141644</a> 
파일 업로드 취약점의 확장판.. 느낌의 공격이라서 기사 가져옴</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 공부/ 리눅스 구조 (2) - 문제 ]]></title>
            <link>https://velog.io/@yoo_j/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EA%B3%B5%EB%B6%80-%EB%A6%AC%EB%88%85%EC%8A%A4-%EA%B5%AC%EC%A1%B0-2-%EB%AC%B8%EC%A0%9C</link>
            <guid>https://velog.io/@yoo_j/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EA%B3%B5%EB%B6%80-%EB%A6%AC%EB%88%85%EC%8A%A4-%EA%B5%AC%EC%A1%B0-2-%EB%AC%B8%EC%A0%9C</guid>
            <pubDate>Thu, 20 Mar 2025 10:44:37 GMT</pubDate>
            <description><![CDATA[<p>지난 시간 올렸던 운영체제 개념에 추가로, 복습용 문제를 만들었다.</p>
<p>고등학생때 처음 알게된 플랫폼인데 간단하게 문제 만들어서 풀기에 좋은 사이트, 어플리케이션이다.
<img src="https://velog.velcdn.com/images/yoo_j/post/0929ba0d-4544-4e28-8c1e-2e56040f7a45/image.png" alt=""></p>
<p>퀴즐렛.</p>
<p>아래 들어가면 내가 만들어둔 문제 풀 수 있는데, 난이도는 매우 쉬운편이므로.. 
참고도하도록</p>
<p><a href="https://quizlet.com/user/Yoo-j/folders/147132962?i=zk7wv&amp;x=1xqt">https://quizlet.com/user/Yoo-j/folders/147132962?i=zk7wv&amp;x=1xqt</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 공부/ 리눅스 구조]]></title>
            <link>https://velog.io/@yoo_j/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EA%B3%B5%EB%B6%80-%EB%A6%AC%EB%88%85%EC%8A%A4-%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@yoo_j/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EA%B3%B5%EB%B6%80-%EB%A6%AC%EB%88%85%EC%8A%A4-%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Thu, 13 Mar 2025 21:05:07 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/yoo_j/post/a19e0d4a-c4e0-48ec-863e-4d58f9f1bf19/image.png" alt="">
중구난방으로 공부 시작.. </p>
<p>실습과 그림으로 배우는 리눅스 구조라는 책을 한권 공부 해보려고 한다. </p>
<p>근데 초장부터 막힌다...</p>
<p>암튼 막히는 부분을 이야기 해보자면,</p>
<p>3장 프로세스 관리 챕터에서 아래와 같은 코드가 주어지는데,</p>
<p><a href="https://github.com/satoru-takeuchi/linux-in-practice/blob/master/03-process-management/fork.c">https://github.com/satoru-takeuchi/linux-in-practice/blob/master/03-process-management/fork.c</a></p>
<pre><code>#include &lt;unistd.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;err.h&gt;

static void child()
{
    printf(&quot;I&#39;m child! my pid is %d.\n&quot;, getpid());
    exit(EXIT_SUCCESS);
}

static void parent(pid_t pid_c)
{
    printf(&quot;I&#39;m parent! my pid is %d and the pid of my child is %d.\n&quot;,
           getpid(), pid_c);
    exit(EXIT_SUCCESS);
}

int main(void)
{
    pid_t ret;
    ret = fork();
    if (ret == -1)
        err(EXIT_FAILURE, &quot;fork() failed&quot;);
    if (ret == 0) {
        // child process came here because fork() returns 0 for child process
        child();
    } else {
        // parent process came here because fork() returns the pid of newly created child process (&gt; 1)
        parent(ret);
    }
    // shouldn&#39;t reach here
    err(EXIT_FAILURE, &quot;shouldn&#39;t reach here&quot;);
}입력하세요</code></pre><p> fork()함수의 실행 프로세스에 대한 부분이다. 
 여기서 pid_t가 뭔지 몰라서 한참 생각 및 서치 해봤는데, 자료형이다..
 프로세스 id 를 나타내는 자료형이라고 하는데, 이것 조차도 모르다니.. 반성해라 나 자신,, 다시 처음으로 돌아가서 공부해야할것같다..</p>
<p> 그리고 아래 다른 사람이 작성한 글을 가져왔는데 이 자료형을 쓰는 이유라고 한다. (무려 2010년에 작성되어 있는..)_</p>
<p> ssize_t, size_t, pid_t 는 고전적인(primitive) 자료형이라 한다.
일반적으로 헤더에 선언되어 있는데, 사실 C의 typedef 선언을 통해서 정의되어 있다.</p>
<p>즉 새롭게 등장한 것이 아니라, 잘 알고 있는 int, float, long과 같은 기본 자료형을 가지고,
이름만 바꾸어 정의해 놓은 것이다. 이러한 자료형들은 꽤 오래 전부터 존재하고 있엇다.</p>
<p>그렇다면 도대체 왜 이러한 것을 정의해 놓고 사용하는 것일까??
int, short, float 라고 하면 사용하기 편할 텐데..</p>
<p>지금은 int가 32비트라고 한다. 보편적으로 사용되는 운영체제와 컴퓨터가 32비트이기 때문이다.
과거 16비트 시설에는 int가 16비트였고 곧 64비트 시대가 도래 할 것이다.
즉, 시스템에 따라서 자료형의 표현 방식이 틀려지므로 내가 구현한 프로그램을 다른 시스템에서
실행 시키기 위해서는 코드의 수정 자체가 불가피하다.</p>
<p>그러나 4바이트의 자료형이 필요한 곳에, 지금 처럼 헤더파일에 unsigned int를 size_t로 정의해
놓고 쓰게 되면, 나중에 시스템이 변경되어서 unsigned int가 더 이상 4바이트를 나타내지 않게
되었을 때, 4바이트를 나타내는 다른 적절한 자료형을 가지고 헤더파일에 선언되어 있는 size_t를
재정의해 주기만 하면 된다.</p>
<p>즉 소스 코드는 바꾸지 않고 컴파일만 다시 한번 하면 새로운 시스템에서 잘 돌아가게 된다는 것이다.</p>
<p>이것이 int, double, short, float과 같은 특정 자료형에 종속되지 않도록, 새로운 이름의 자료형을 정의해 주는 이유가 된다.</p>
<p>보통은 다음과 같은 형식으로 정의한다.</p>
<p>size_t : unsigned 형태의 변수 선언
ssize_t : signed 형태의 변수 선언
pid_t : Process ID를 표현하기 위해서 사용</p>
<p>[출처] ssize_t, size_t, pid_t 타입 개념잡기|작성자 몽키몽키</p>
<p>그렇다고 한다.. 너무 예전에 작성된 글이라 퍼오기도 뭐하지만, 일단은 공부하면서 모르는 개념 정립을 위해서 이렇게라도 남겨둔다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[대학원 연구일지 - Istio]]></title>
            <link>https://velog.io/@yoo_j/%EB%8C%80%ED%95%99%EC%9B%90-%EC%97%B0%EA%B5%AC%EC%9D%BC%EC%A7%80-Istio</link>
            <guid>https://velog.io/@yoo_j/%EB%8C%80%ED%95%99%EC%9B%90-%EC%97%B0%EA%B5%AC%EC%9D%BC%EC%A7%80-Istio</guid>
            <pubDate>Sun, 02 Mar 2025 09:52:15 GMT</pubDate>
            <description><![CDATA[<p>앞선 쿠버네티스 글과 마찬가지로.. 대학원에서 연구 하면서 계속해서 보고 있는 시스템이 쿠버네티스 위에서 동작하는 서비스메시인 Istio 인데, 이를 제대로 문서화 해서 정리 할 필요성을 느껴 늦었지만, 다시한번 정리를 해보고자 한다.</p>
<p>아래와 같은 순서로 정리를 차근차근 해볼 예정이고, 최대한 자세하고 깊게 분석하고자 하는것이 내 목표이다.</p>
<ol>
<li><p>Istio 란 무엇인가?</p>
</li>
<li><p>Istio 의 등장 배경</p>
</li>
<li><p>Istio 아키텍쳐 - 이 부분을 최대한 상세하고 자세하게 분석해보려고 한다.(이미 진행된 부분에 플러스로)</p>
</li>
<li><p>Istio 활용 </p>
</li>
<li><p>현재 하고 있는 연구</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[대학원 연구 일지 - kubernetes ]]></title>
            <link>https://velog.io/@yoo_j/%EB%8C%80%ED%95%99%EC%9B%90-%EC%97%B0%EA%B5%AC-%EC%9D%BC%EC%A7%80-kubernetes</link>
            <guid>https://velog.io/@yoo_j/%EB%8C%80%ED%95%99%EC%9B%90-%EC%97%B0%EA%B5%AC-%EC%9D%BC%EC%A7%80-kubernetes</guid>
            <pubDate>Sun, 02 Mar 2025 09:46:47 GMT</pubDate>
            <description><![CDATA[<p>지난 1년 간은 쿠버네티스를 다루는 것(실 사용)에 좀 집중했었고, 
하다보니 느낀건 역시 기초(이론)가 탄탄해야 뭘 해도 흔들리지 않는 다는 점이었던 것같다. 그래서 늦었지만, 연구일지를 작성하면서 쿠버네티스 및 여러 가상화 기술에 대한 부분을 문서로 정리해 두려고 한다. </p>
<p>음.. 그리고 쿠버네티스 관련해서 연구하고 있다고 했는데, 면접장에서 kube-proxy 기능이 뭐냐고 물어봤을때 제대로 답변을 못해서 부끄러웠던 기억이 있다.. </p>
<p>그래서 이런 쿠버네티스에 대한 각 컴포넌트들에 대한 기능들.. 잘 정리해둬야할 것 같다는 생각에 정리해보려고 한다.</p>
<p>일단 내가 실행하고 있는 환경에서 실행되고 있는 쿠버네티스 관련 파드들이다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/f0208be5-9746-4f41-b9f2-8886a349ebfb/image.png" alt=""></p>
<p>각 설명에 대해서는 추후 업로드</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[picoctf - heap 0 문제 풀이]]></title>
            <link>https://velog.io/@yoo_j/picoctf-heap-0-%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4</link>
            <guid>https://velog.io/@yoo_j/picoctf-heap-0-%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4</guid>
            <pubDate>Sun, 02 Mar 2025 07:49:06 GMT</pubDate>
            <description><![CDATA[<p>heap 0 제목에서 느껴지는.. </p>
<p>힙 오버플로우 관련 문제,, 이긴 한데 역시 아직 이런 데이터 영역 관련해서 지식이 부족해서 인가 어렵게만 느껴진다.</p>
<p>아래 라이트업에 좀 개념이 잘 정리된것 같아서 참고했다.</p>
<p>이런 스택, 힙 관련 문제들에 대해서는 아직 지식이 부족한 것 같다는 생각이 들어서 외부자료를 참고하는 편이다. </p>
<p>아래 사이트 참고 하여 문제를 풀어 보았다.</p>
<p><a href="https://blog.stackademic.com/heap-exploitation-picoctf-heap0-challenge-f6a8d14f7b80">https://blog.stackademic.com/heap-exploitation-picoctf-heap0-challenge-f6a8d14f7b80</a></p>
<p>: 힙은 컴파일 시 크기가 알려지지 않은 데이터에 사용 &gt;&gt; 동적으로 메모리 할당하는 프로그램에 사용됨 대표적으로 malloc 함수가 있음.</p>
<p><a href="https://medium.com/@erichdryn/heap-0-picoctf-writeup-a1a20406608b">https://medium.com/@erichdryn/heap-0-picoctf-writeup-a1a20406608b</a></p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/d2d47c10-7b33-4737-a10a-f328b1781923/image.png" alt=""></p>
<p>문제 스크린샷은 위와 같음. </p>
<p>인스턴스를 실행시키면 다음과 같은 프로그램이 실행되는데,,</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/fab47f7e-cef2-4e43-84c1-f800a6ddcd96/image.png" alt=""></p>
<p>프로그램 자체만 보면 다음과 같이 번호를 선택하면 선택값에 맞는 값을 출력해주는 형식 4번을 골랐더니 looks like everything is still secure!  이라면서 .. 플래그값을 주지는 않는다.</p>
<blockquote>
<blockquote>
<p>출력값에서 주는 메세지만 보았을때는 안전하지 않게 만들어서 플래그값을 얻으라는 것.. </p>
</blockquote>
</blockquote>
<p>아직 내 레벨에서 이런 문제는 소스코드를 살펴보아야만 풀 수 있다.</p>
<p>일단 주어진 소스코드를 살펴보면,아래와 같이 c언어로 작성되어 있는 소스코드임을 알 수 있다.</p>
<pre><code>#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

#define FLAGSIZE_MAX 64
// amount of memory allocated for input_data
#define INPUT_DATA_SIZE 5
// amount of memory allocated for safe_var
#define SAFE_VAR_SIZE 5

int num_allocs;
char *safe_var;
char *input_data;

void check_win() {
    if (strcmp(safe_var, &quot;bico&quot;) != 0) {
        printf(&quot;\nYOU WIN\n&quot;);

        // Print flag
        char buf[FLAGSIZE_MAX];
        FILE *fd = fopen(&quot;flag.txt&quot;, &quot;r&quot;);
        fgets(buf, FLAGSIZE_MAX, fd);
        printf(&quot;%s\n&quot;, buf);
        fflush(stdout);

        exit(0);
    } else {
        printf(&quot;Looks like everything is still secure!\n&quot;);
        printf(&quot;\nNo flage for you :(\n&quot;);
        fflush(stdout);
    }
}

void print_menu() {
    printf(&quot;\n1. Print Heap:\t\t(print the current state of the heap)&quot;
           &quot;\n2. Write to buffer:\t(write to your own personal block of data &quot;
           &quot;on the heap)&quot;
           &quot;\n3. Print safe_var:\t(I&#39;ll even let you look at my variable on &quot;
           &quot;the heap, &quot;
           &quot;I&#39;m confident it can&#39;t be modified)&quot;
           &quot;\n4. Print Flag:\t\t(Try to print the flag, good luck)&quot;
           &quot;\n5. Exit\n\nEnter your choice: &quot;);
    fflush(stdout);
}

void init() {
    printf(&quot;\nWelcome to heap0!\n&quot;);
    printf(
        &quot;I put my data on the heap so it should be safe from any tampering.\n&quot;);
    printf(&quot;Since my data isn&#39;t on the stack I&#39;ll even let you write whatever &quot;
           &quot;info you want to the heap, I already took care of using malloc for &quot;
           &quot;you.\n\n&quot;);
    fflush(stdout);
    input_data = malloc(INPUT_DATA_SIZE);
    strncpy(input_data, &quot;pico&quot;, INPUT_DATA_SIZE);
    safe_var = malloc(SAFE_VAR_SIZE);
    strncpy(safe_var, &quot;bico&quot;, SAFE_VAR_SIZE);
}

void write_buffer() {
    printf(&quot;Data for buffer: &quot;);
    fflush(stdout);
    scanf(&quot;%s&quot;, input_data);
}

void print_heap() {
    printf(&quot;Heap State:\n&quot;);
    printf(&quot;+-------------+----------------+\n&quot;);
    printf(&quot;[*] Address   -&gt;   Heap Data   \n&quot;);
    printf(&quot;+-------------+----------------+\n&quot;);
    printf(&quot;[*]   %p  -&gt;   %s\n&quot;, input_data, input_data);
    printf(&quot;+-------------+----------------+\n&quot;);
    printf(&quot;[*]   %p  -&gt;   %s\n&quot;, safe_var, safe_var);
    printf(&quot;+-------------+----------------+\n&quot;);
    fflush(stdout);
}

int main(void) {

    // Setup
    init();
    print_heap();

    int choice;

    while (1) {
        print_menu();
    int rval = scanf(&quot;%d&quot;, &amp;choice);
    if (rval == EOF){
        exit(0);
    }
        if (rval != 1) {
            //printf(&quot;Invalid input. Please enter a valid choice.\n&quot;);
            //fflush(stdout);
            // Clear input buffer
            //while (getchar() != &#39;\n&#39;);
            //continue;
        exit(0);
        }

        switch (choice) {
        case 1:
            // print heap
            print_heap();
            break;
        case 2:
            write_buffer();
            break;
        case 3:
            // print safe_var
            printf(&quot;\n\nTake a look at my variable: safe_var = %s\n\n&quot;,
                   safe_var);
            fflush(stdout);
            break;
        case 4:
            // Check for win condition
            check_win();
            break;
        case 5:
            // exit
            return 0;
        default:
            printf(&quot;Invalid choice\n&quot;);
            fflush(stdout);
        }
    }
}
코드를 입력하세요</code></pre><p>플래그 값을 출력하는 조건에 대한 부분은 아래와 같다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/6ae86497-8cff-4561-98bd-432e1bd7527c/image.png" alt=""></p>
<p>safe_var에 저장되어 있는 값이 bico 값이 아니게 만들어야만 플래그 값을 얻을 수 있는 구조..</p>
<p>이제 이 코드에서 취약한 부분을 살펴보면 일단, scanf 라는 취약한 함수를 사용하는 것을 알 수 있다. </p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/66152148-85e9-4383-adb5-4d07c6141e76/image.png" alt="">
scanf 는 공백 문자가 발견될 때까지 키보드에서 모든 입력 데이터를 받기 때문에 취약한 함수라고 여겨진다. (입력데이터에 대한 검증 필요)</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/2a57a3ed-181b-4349-84c5-aa97bc02c7d9/image.png" alt="">
그리고 프로그램 자체에서 1을 입력하면, 변수의 위치를 출력해주기도 하는데 이를 이용해서 
pico 변수가 0x6131c1b722b0 위치에 있고,
손상시킬 bico 변수의 위치는 0x6131c1b722d0에 있다는 것을 알 수 있음
 이 두 위치를 빼면 0x20, 즉 10진수로 32가 됨.</p>
<p>최소 33바이트의 문자열을 입력하여 오버플로우를 발생시켜야함.. </p>
<p>C에서 <strong>문자 하나(char)</strong>는 <strong>1바이트(8비트)</strong>임.</p>
<p><em>참고 사항</em> 문자열은 항상 \0(널 문자, NULL terminator)이 포함</p>
<p>즉, &quot;pico&quot;는 5바이트(&#39;p&#39; &#39;i&#39; &#39;c&#39; &#39;o&#39; &#39;\0&#39;), &quot;bico&quot;도 5바이트(&#39;b&#39; &#39;i&#39; &#39;c&#39; &#39;o&#39; &#39;\0&#39;) 차지</p>
<p>아래와 같이 2번 선택 후 오버플로우 발생시킨뒤 다시 4를 입력하면 플래그 값을 획득할 수 있음</p>
<p> <img src="https://velog.velcdn.com/images/yoo_j/post/b61c645f-1078-4396-ad10-6aa69f967ae7/image.png" alt=""></p>
<h2 id="그리고-아래는-gpt-가-도와준-풀이"> 그리고 아래는 gpt 가 도와준 풀이</h2>
<p> 이 코드의 핵심 취약점은 Heap-based Buffer Overflow입니다. </p>
<p> scanf(&quot;%s&quot;, input_data);를 사용하여 입력을 받을 때, input_data의 크기(INPUT_DATA_SIZE = 5)를 초과하는 데이터를 입력하면 safe_var의 값이 덮어써집니다.</p>
<ol>
<li>Heap 구조 분석
이 프로그램에서 동적 메모리 할당(malloc)을 통해 input_data와 safe_var를 저장하는 과정은 다음과 같습니다.</li>
</ol>
<p>input_data = malloc(INPUT_DATA_SIZE);   // 5바이트 크기 메모리 할당
strncpy(input_data, &quot;pico&quot;, INPUT_DATA_SIZE); // &quot;pico&quot; 저장</p>
<p>safe_var = malloc(SAFE_VAR_SIZE);  // 5바이트 크기 메모리 할당
strncpy(safe_var, &quot;bico&quot;, SAFE_VAR_SIZE); // &quot;bico&quot; 저장
이제 Heap의 구조를 그림으로 표현하면 다음과 같습니다.</p>
<h4 id="주소--------------데이터">주소              데이터</h4>
<hr>
<p>0x1234  | &#39;p&#39;  &#39;i&#39;  &#39;c&#39;  &#39;o&#39;  &#39;\0&#39;  |  &lt;- input_data (5바이트)
0x1239  | &#39;b&#39;  &#39;i&#39;  &#39;c&#39;  &#39;o&#39;  &#39;\0&#39;  |  &lt;- safe_var (5바이트)
즉, input_data의 5바이트 메모리 바로 뒤에 safe_var가 존재합니다.</p>
<ol start="2">
<li>취약점 분석: scanf()를 이용한 Heap Overflow
write_buffer() 함수에서 scanf(&quot;%s&quot;, input_data);를 통해 길이 제한 없이 문자열을 입력받기 때문에, input_data를 초과하는 길이의 입력을 넣으면 safe_var의 값이 덮어쓰이게 됩니다.</li>
</ol>
<p>void write_buffer() {
    printf(&quot;Data for buffer: &quot;);
    fflush(stdout);
    scanf(&quot;%s&quot;, input_data);  // 취약점: 길이 제한 없음
}
3. Exploit 과정
만약 우리가 write_buffer()에서 6글자 이상의 문자열을 입력하면 어떻게 될까요?</p>
<p>예제 입력: AAAAAbico
입력된 데이터가 Heap에 저장되는 방식:</p>
<h2 id="주소---------데이터">주소         데이터</h2>
<p>0x1234  | &#39;A&#39;  &#39;A&#39;  &#39;A&#39;  &#39;A&#39;  &#39;A&#39;  |  &lt;- input_data (5바이트)
0x1239  | &#39;b&#39;  &#39;i&#39;  &#39;c&#39;  &#39;o&#39;  &#39;\0&#39;  |  &lt;- safe_var (5바이트)
이제 6바이트 이상의 문자열을 넣어 보겠습니다.</p>
<p>입력:</p>
<p>AAAAAxxxx
Heap 메모리:</p>
<h2 id="주소---------데이터-1">주소         데이터</h2>
<p>0x1234  | &#39;A&#39;  &#39;A&#39;  &#39;A&#39;  &#39;A&#39;  &#39;A&#39;  |  &lt;- input_data (5바이트)
0x1239  | &#39;x&#39;  &#39;x&#39;  &#39;x&#39;  &#39;x&#39;  &#39;\0&#39;  |  &lt;- safe_var가 덮어씌워짐!
이제 safe_var의 값이 &quot;xxxx&quot;로 변하면서, &quot;bico&quot;가 더 이상 유지되지 않게 됩니다.</p>
<ol start="4">
<li>FLAG 획득 과정
check_win() 함수에서는 다음과 같은 조건이 있습니다.</li>
</ol>
<p>void check_win() {
    if (strcmp(safe_var, &quot;bico&quot;) != 0) {  // safe_var 값이 &quot;bico&quot;가 아니면
        printf(&quot;\nYOU WIN\n&quot;);</p>
<pre><code>    // Print flag
    char buf[FLAGSIZE_MAX];
    FILE *fd = fopen(&quot;flag.txt&quot;, &quot;r&quot;);
    fgets(buf, FLAGSIZE_MAX, fd);
    printf(&quot;%s\n&quot;, buf);
    fflush(stdout);

    exit(0);
} else {
    printf(&quot;Looks like everything is still secure!\n&quot;);
    printf(&quot;\nNo flage for you :(\n&quot;);
    fflush(stdout);
}</code></pre><p>}
즉, safe_var 값이 &quot;bico&quot;가 아니게 만들면 YOU WIN 메시지와 함께 flag.txt 파일의 내용이 출력됩니다.</p>
<p>이를 위해 다음 입력을 주면 됩니다.</p>
<p>AAAAAxxxx
이렇게 하면 safe_var가 &quot;xxxx&quot;로 변경되고, check_win()이 strcmp(safe_var, &quot;bico&quot;) != 0 조건을 만족하게 되어 FLAG가 출력됩니다.</p>
<ol start="5">
<li>Exploit 정리</li>
</ol>
<p>공격 방법
프로그램을 실행하고 2번 (Write to buffer) 옵션을 선택
write_buffer()에서 bico를 덮어쓰도록 6글자 이상의 데이터를 입력</p>
<p>AAAAAxxxx
4번 (Print Flag) 옵션을 선택하여 check_win() 실행
FLAG 출력 성공!
Exploit 예시</p>
<p>$ ./heap0
Welcome to heap0!
I put my data on the heap so it should be safe from any tampering.</p>
<p>Heap State:
[<em>] Address   -&gt;   Heap Data<br>[</em>]   0x55555575c260  -&gt;   pico
[*]   0x55555575c270  -&gt;   bico</p>
<p>Enter your choice: 2
Data for buffer: AAAAAxxxx</p>
<p>Enter your choice: 4
YOU WIN
flag{heap_overflow_success}
6. 해결 방법 (취약점 방어)
이러한 Heap Overflow를 방지하려면 다음과 같은 보안 조치를 취할 수 있습니다.</p>
<p>입력 길이 제한</p>
<p>scanf(&quot;%4s&quot;, input_data);  // 최대 4글자까지만 입력받도록 제한
또는,</p>
<p>fgets(input_data, INPUT_DATA_SIZE, stdin);
Canary 값 추가</p>
<p>safe_var 앞에 Canary 값을 추가하고, 값이 변경되었는지 확인하면 메모리 오버플로우 탐지가 가능함.</p>
<p>Heap Allocation 순서 변경</p>
<p>safe_var를 먼저 malloc()한 후, input_data를 malloc()하면 Heap Overflow를 방지할 수 있음.
Fortify Source 활성화</p>
<p>gcc 컴파일 시 -D_FORTIFY_SOURCE=2 플래그를 사용하여 scanf 등의 입력 길이를 자동으로 검사하도록 설정.</p>
<ol start="7">
<li>결론
이 코드에서 scanf(&quot;%s&quot;, input_data);를 통해 input_data의 크기(5바이트)를 초과하는 입력을 받으면 safe_var 값이 덮어쓰여 bico가 변경됨.
safe_var 값이 bico가 아니게 되면 check_win()에서 FLAG가 출력됨.
따라서, write_buffer()에서 적절한 길이 제한을 두지 않으면 Heap-based Buffer Overflow 취약점이 발생하여 공격자가 FLAG를 획득할 수 있음.</li>
</ol>
<blockquote>
<blockquote>
<p>gpt 풀이에서는 bico 값의 위치에 대한 계산부분이 없음. (이 부분을 추가 고려해서 풀어야함.)</p>
</blockquote>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[picoctf - FirstFind 문제 풀이]]></title>
            <link>https://velog.io/@yoo_j/picoctf-FirstFind-%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4</link>
            <guid>https://velog.io/@yoo_j/picoctf-FirstFind-%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4</guid>
            <pubDate>Fri, 28 Feb 2025 17:51:11 GMT</pubDate>
            <description><![CDATA[<p>해킹 공부 하면서 문제를 푸는데, picoctf 라는 사이트에 문제들이 난이도 별로 잘 정리 되어 있어서 easy 레벨만 도전 하고 있다.</p>
<p>오늘 풀어볼 문제는 Firtst Find 라는 문제이다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_j/post/28005277-c733-4363-a77e-7eca1ddbd231/image.webp" alt=""></p>
<p>문제는 위 스냅샷과 같으며, 힌트도 없는 간단한 문제이다.</p>
<p>문제 파일 다운 받아준 후, 압축 해제 후 uber-sectet.txt 라는 파일을 찾아서 읽어주면 된다..
<img src="https://velog.velcdn.com/images/yoo_j/post/130ae26d-bbce-48a1-8966-22eb16d5d7ed/image.png" alt=""></p>
<p>윈도우 환경에서 파일 탐색시에는 아래와 같은 명령어를 이용하면 편하다.</p>
<pre><code> Get-ChildItem -Recurse -Filter &quot;uber-secret.txt&quot;</code></pre><p>마지막 uber-secret.txt는 파일명이니까 상황에 따라서 잘 조정해서 쓰면된다.</p>
<p>그리고 명령어에 대한 설명은 아래와 같다.</p>
<ul>
<li><code>Get-ChildItem</code><ul>
<li>PowerShell에서 파일과 디렉터리(폴더)를 나열하는 기본 명령어</li>
<li>명령어의 줄임말로 <code>gci</code>를 사용할 수도 있음</li>
</ul>
</li>
<li><code>Recurse</code><ul>
<li>하위 디렉터리(서브 폴더)를 포함해 모든 디렉터리를 재귀적으로 검색</li>
<li>즉, 현재 디렉터리와 모든 하위 디렉터리에서 파일을 찾음</li>
</ul>
</li>
<li><code>Filter &quot;uber-secret.txt&quot;</code><ul>
<li>특정 이름 또는 패턴에 맞는 파일만 검색하도록 필터를 설정</li>
<li><code>&quot;uber-secret.txt&quot;</code> 이름과 일치하는 파일만 찾음</li>
</ul>
</li>
</ul>
<p>그래서 얻은 플래그 값은 아래와 같다.</p>
<p>picoCTF{f1nd_15_f457_ab443fd1}</p>
<hr>
<p>리눅스에서는 ? find 명령어를 쓰면 된다. 또는 fd(근데 이건 설치 필요)</p>
<p>find . -type f -name &quot;uber-secret.txt&quot;</p>
<p>명령어에 대한 설명</p>
<p>. → 현재 디렉터리부터 검색 시작
-type f → 파일(f)만 검색 (디렉터리 제외)
-name &quot;uber-secret.txt&quot; → 정확한 파일 이름을 찾음 (대소문자 구분)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[첫 가입.]]></title>
            <link>https://velog.io/@yoo_j/%EC%B2%AB-%EA%B0%80%EC%9E%85</link>
            <guid>https://velog.io/@yoo_j/%EC%B2%AB-%EA%B0%80%EC%9E%85</guid>
            <pubDate>Sat, 25 Jan 2025 12:22:25 GMT</pubDate>
            <description><![CDATA[<p>첫 페이지를 장식하는 글.. 별건 없지만,, 논문 리뷰 및 해킹 공부한것들 위주로 정리해서 나중에 포트폴리오로 쓸 수 있으면 좋겠다.. </p>
<p>공개할 수 있는 개인 정보는 올해 25살(만나이 아님)이라는 점과</p>
<p>올해 목표로서 : 취업에 필요한 역량 (연구 및 개인 공부) 을 기르고 자격증을 취득하는 것을 가지고 있음</p>
<blockquote>
<p>일단 원대한(최종) 목표는 통신사 취업을 목표로 하고 있음..
 좀더 상세한 계획은 업데이트 예정 ex) 어떤 통신사의 어떤부서? 이런 정보들은... </p>
</blockquote>
<p> 그래도 나름 첫 글이니까 목표 및 올해 계획을 작성해 봤다.</p>
<p> 화이팅...</p>
]]></description>
        </item>
    </channel>
</rss>