Skip to the content.

HaruulZangi U18 2022 Web challenge Writeups (Round 1)

Cloud Engineer

Монгол инженерууд заримдаа тохиргоогоо буруу хийх юм тэ? flag.txt файлыг олоорой. Холбоос: https://cloud-engineer.u18.haruulzangi.mn/

Хэрэв тухайн холбоосоор орж үзвэл дараах үүлний зураг гарч ирэх болно. Cloud Engineer

Source code-г нь харж үзэхэд тухайн зураг нь Google Cloud Storage дээр байрлаж байгаа нь харагдана. Source code of Cloud Engineer

Тухайн зургийн холбоосоор ороод clouds.jpeg хасаад ороход тухайн folder доторх файлууд XML-р харагдах болно. Files in the folder

Тэгвэл ард нь flag.txt нэмээд ороод үзэхэд flag гарч ирэх болно 😊

HZU18{Cl00ud_St0r@g#_f3830d5c1b}

Donut Name System

Наба DNS-ыг Donut Name System гэж боддог. Тэр системд нууцуудаа хадгалаж болох юм уу? Холбоос: https://donut-name-system.u18.haruulzangi.mn/

Мэдээж дүрмийн дагуу тухайн холбоосоор орж үзнэ 😂

Donuts

Өөдөөс маш амттай харагдаж буй donut гарч ирлээ. Гэхдээ энд donut ямар ч хамаагүй шүү 👌. Даалгаврын нэрийг харвал DNS юм байна гэдгийг ойлгож болно. Тэгвэл source code-н хараад үзье.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Donut Name System</title>
<meta name="flag" content="See: dns.u18.haruulzangi.mn" />
</head>
<body>
<img src="./keep-donuts-fresh.jpeg" />
</body>
</html>

Сайн харвал <meta name="flag" content="See: dns.u18.haruulzangi.mn" /> хэсэг маш онцгойрч харагдана. See: гэдэг утгаас нь харахад биднийг энэ домэйн нэр дээрх DNS-г шалгаад үз гэсэн hint өгч байгаа мэт 🤔 Тухайн домэйн дээрх DNS-г шалгахын тулд бидэнд digкомманд хэрэг болно. Хэрэв суулгаагүй бол sudo apt install dnsutils гээд бичээд суулгах боломжтой. За тэгвэл шалгаад үзье. dig dns.u18.haruulzangi.mn гэж бичихэд бидэнд хэрэгтэй мэдээлэл гарч ирсэнгүй. image Тэгвэл flag мань TXT record дээр байх магадлалтай гэж үзээд dig dns.u18.haruulzangi.mn txt гэж шалгаад үзье. image Бидний хэрэгтэй flag гарч ирлээ 🤟

HZU18{DNS_3v3rywh3r3_e7b5960100}

My customers

Хасаа өөрийн гэсэн хувцасны брендийнхээ урьдчислан захиалга авах API хийжээ. Одоогоор 100 хэрэглэгч бүртгүүлээд байна. User-ын ID-г нэмэгддэг тоогоор хийх нь зөв үү? Холбоос: https://my-customers.u18.haruulzangi.mn/user

Тухайн холбоосоор орж үзэхэд доорх текст гарч ирнэ.

image

Эндээс харвал энгийн User API байх бөгөөд https://my-customers.u18.haruulzangi.mn/user/1 гээд үзэхэд 1 гэсэн id-тай хэрэглэгчийн мэдээллийг гаргах болно.

{"id":1,"firstName":"Mekhi","lastName":"D'Amore","email":"Zachary_Kuhn53@hotmail.com","phone":"1-377-678-4096 x81626","address":"458 Wintheiser Place","city":"East Vitoberg","state":"Oklahoma","zip":"57905","company":"Emmerich and Sons","avatar":"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/496.jpg"}

Тэгвэл эхлээд 100 дээр шалгахад User not found гэсэн бичиг гарна. Үүн дээрээс харвал 0-ээс 99 хүртэл id-тай хэрэглэгчид байгаа гэсэн үг.

Магадгүй 0-ээс 99 хүртэл flag байгаа үгүйг мэдэх код бичиж үзье.

import  requests
  
for i in range(0, 100):
	userID = str(i)
	URL = "https://my-customers.u18.haruulzangi.mn/user/" + userID
	page = requests.get(URL)
	content = str(page.content.decode('utf8'))
	if  content.find('HZU18{') != -1:
		flag = content[content.find('HZU18{'):]
		break
	else:
		flag = "Oldsongui"
		
print("Flag: ", flag)

image Амжилттай flag-аа олж чадлаа! 😊

HZU18{9b36fa+NICE_LIST_0e7635b84cefe035}

Vaccine

Вакцин бол нэг ёсны injection юм даа. Холбоос 1: https://vaccine.u18.haruulzangi.mn/vaccine Холбоос 2: https://vaccine.u18.haruulzangi.mn/vaccine/1

Эхний холбоосоор орж үзэхэд 5-н төрлийн вакцины json мэдээлэл байгаа харагдана: image Дараагийн холбоосоор ороход 1 гэсэн id-тай вакцины мэдээлэл харагдана. Энэ холбоосноос харахад PostgreSQL ашигласан байгааг анзаарч болно. image За тэгвэл энгийн SQL Injection хийж үзэцгэе. Бид хамгийн эхлээд ямар ямар table байгааг мэдэх хэрэгтэй. Үүнд SELECT table_name FROM information_schema.tables-г ашиглаж үзье. https://vaccine.u18.haruulzangi.mn/vaccine/1;SELECT%20table_name%20FROM%20information_schema.tables гээд үзэхэд бүх table мэдээлэл гарч ирэх болно.

image Эндээс flag гэх table байх бөгөөд энэ дээр injection хийцгэе. SELECT * FROM flag ашиглан https://vaccine.u18.haruulzangi.mn/vaccine/1;SELECT%20*%20FROM%20flag гэж ороход бидний flag гарч ирнэ 🤟 image

HZU18{sQL-!nj3ct3on—nice}

Arithmetic expression

Мэддэг тооноос чинь арай өөр байх болно. Холбоос: https://math.u18.haruulzangi.mn/

Тухайн холбоосоор ороход дараах бодлого гарч ирнэ image Гэхдээ 5 секунд тутам тухайн бодлого солигдон шинэ бодлого гарч ирнэ. Тэгэхээр бидэнд гараар бодох ямар ч боломж байхгүй. Зөвхөн өөрсдөө script бичиж л flag-аа авах боломжтой. Сайн анзаарахад нийт 5н md5-аар encrypt хийгдсэн тоо байх бөгөөд бидэнд хамгийн түрүүнд үүнийг decrypt хийх хэрэгтэй. Хамгийн эхлээд гараар аргаар 10 орчим тоог https://www.md5online.org/md5-decrypt.html дээр decrypt хийж үзэхэд бүгд 0-ээс 100 хүртэлх тоонууд байв. Тэгвэл зөвхөн 0-100 хооронд дурын тоо байна гэж үзээд тухайн бүх тоог md5 encrypt хийж array дотор хадгалъя.

import  hashlib
arr=[]
for  i  in  range(0, 100):
	hash = str(i)
	result = hashlib.md5(hash.encode('utf-8'))
	arr.append(result.hexdigest())

Үүний дараа тухайн encrypt хийгдсэн тоог энгийн тоо болгодог function бичье.

def  find(num):
	for  i  in  range(0, 100):
		if(arr[i] == num):
			return  i

Эцэст нь тухайн веб-н source кодоос тухайн тоонуудаа авч бодоод илгээдэг код бичье. Гэхдээ илгээхдээ хашаа Post request хийх ёстойгоо шалгах хэрэгтэй. Source code харвал:

<form action="/sum" method="POST">
	<!-- Бодлого -->
	<input type="text" name="sum" >
	<input type="submit" >
</form>

https://math.u18.haruulzangi.mn/sum холбоос руу {sum: Хариу} хэлбэрээр илгээх ёстойг харж болно.

from  bs4  import  BeautifulSoup
import  requests
import  hashlib
arr=[]
for  i  in  range(0, 100):
	hash = str(i)
	result = hashlib.md5(hash.encode('utf-8'))
	arr.append(result.hexdigest())

def  find(num):
	for  i  in  range(0, 100):
		if(arr[i] == num):
			return  i

def  calc(num1, num2, c):
	if  c == "+":
		return  num1 + num2
	if  c == "-":
		return  num1 - num2
	if  c == "*":
		return  num1 * num2
	if  c == "/":
		return  num1 / num2

URL = "https://math.u18.haruulzangi.mn/"
page = requests.get(URL)
soup = BeautifulSoup(page.content, "html.parser")
numbers = soup.find("form")
txt = numbers.text.split()
sum = calc(find(txt[6][1:]), find(txt[8][:-1]), txt[7])
sum1 = calc(find(txt[0]), find(txt[2]), txt[1])
sum2 = calc(sum1, find(txt[4]), txt[3])
total = calc(sum2, sum, txt[5])
url = 'https://math.u18.haruulzangi.mn/sum'
mathResult = {'sum': total}
res = requests.post(url, data = mathResult)
print(res.text)

Дээрх script ажиллуулахад flag гарч ирэх болно.

hz{u_r_so_good_at_math}

Chanasan tolgoi

Толгой хэр чухал байдаг вэ? Холбоос: https://chanasan-tolgoi.u18.haruulzangi.mn/

Мэдээж ордгоороо холбоосоор ороод харвал маш амттай чанасан толгой гарч ирнэ 😋 image

Source code шалгахад хоосон хэрэгтэй юм байсангүй. Тэгвэл сайн даалгавраа уншаад бодоцгооё.

Чанасан Толгой

Толгой буюу англиар Header. Тэгвэл эндээс бодоод үзэхэд тухайн веб руу request хийхэд ямар Header-тэй байгааг шалгацгаая. Ингэхдээ (Chrome) F12 -> Network -> Ctrl+R (Refresh хийх хэрэгтэй). image Refresh хийсний дараа ийм дүр зураг бид харах болно. Тухайн холбоос дээр 2 товшоод бидэнд Header information харуулна. Сайн ухаад үзэхэд Response Headers дотор flag-аа олох боломжтой. image

HZU18{M0ng0l1@n_f00d_v3ry_t@stY}

Shiir

CRA гэж юу вэ? яадаг юм бол оо? Холбоос: https://shiir.u18.haruulzangi.mn/

Холбоосоор орох үед доорх зураг гарч ирнэ. image

CRA гэдэг нь Create React App гэсэн үгний товчлол бөгөөд анзаарахад ReactJS дээр бичсэн вебсайт байв. За тэгээд доторх кодыг нь харахад /static/js/main.53234283.js нэртэй JS файл олдоно. ReactJS учир энд бүх хэрэгтэй мэдээлэл байгаа гэж ойлгож болно. Ороод үзэхэд маш урт Javascript байх болно. image Хамгийн энгийн бүхэн сайхан гэдэг шиг CTRL+F дараад HZ гэж бичээд хайхад бидний flag гарч ирнэ 👌

HZU18{d0_n0t_US3_ENV-f0r_s3cr3tZZ}

Stay consistent

Тууштай байдал амжилтанд хүргэнэ Холбоос: https://searchid.u18.haruulzangi.mn

Вебсайт руу ороход доорх дүр зураг гарч ирнэ. image

Go to гэж байгаа юм чинь тухайн хаягаар орж үзье. image Дахиад шинэ хаяг гараад ирлээ. Дахин орж үзэхэд дахин шинэ хаяг гарч ирнэ. Даалгавар дээр Тууштай байдал амжилтанд хүргэнэ гэсэн юм чинь маш олон удаа энэ үйлдлийг давтаж байж бид флагаа олж авч чадах байх. Тийм учраас гараар хийвэл маш удах тул script бичицгээе.

import  requests
from  bs4  import  BeautifulSoup

newLink = "/"
for  i  in  range(0, 1010):
	URL = "https://searchid.u18.haruulzangi.mn" + newLink
	page = requests.get(URL)
	soup = BeautifulSoup(page.content, "html.parser")
	content = soup.find("div")
	txt = content.text.split()
	newLink = txt[2]
	print(i, content.text)

Энэ script нь тухайн үйлдлийг 1010 удаа давтана. Уг script-г ажиллуулахад 1002 дэх үйлдэл дээр flag мань гарч ирж байгааг харах боломжтой 😊 image hz{yeaa_finally_u_got_it}

Untrustworthy filtering

See how pregreplace works Холбоос: https://pregreplace.u18.haruulzangi.mn

Холбоосоор ороход доорх зүйл гарч ирнэ. image

See the source code дээр дараад орвол: image PHP дээр бичсэн код гарч ирнэ. preg_replace() нь тухайн текст дотор үг олоод тэрийг нь өөр үгээр оруулах функц юм. Жишээ нь:

<?php
$str = 'Sain uu, Sanchir?';
echo preg_replace('/Sanchir/', 'Bataa', $str);
?>

Гэсэн код байлаа гэхэд Sanchir гэсэн нэр Bataa болж солигдоод Sain uu, Bataa? болно гэсэн үг юм. За тэгвэл кодыг сайн анзаараад харвал id гэсэн GET parament аваад HaRuUl18ZaNGi18U18 гэдэг үгийг хасвал (учир нь сольж байгаа утга дээр ‘’ байгаа тул хасагдана) буцаад HaRuUl18ZaNGi18U18 үлдэж байвал flag гарч ирнэ гэдгийг харж болно. Логикоор бодоход HaRuUl18ZaNGi18U18 үгийг голоор нь 2 хуваагаад дунд нь энэ үгээ бүтнээр нь холбоход болно гэсэн үг: HaRuUl18HaRuUl18ZaNGi18U18ZaNGi18U18 Тодруулсан хэсгээг хасвал буцаад HaRuUl18ZaNGi18U18 үг үүснэ. Ингээд холбоосны араас id нэмж өгөөд https://pregreplace.u18.haruulzangi.mn/?id=HaRuUl18HaRuUl18ZaNGi18U18ZaNGi18U18 гэж орвол flag мань гарч ирэх болно.

hz{3asy-Funkshin-bYpaSS}