블라인드로 문제파일만 받아서 풀었기에 풀고나니 10솔브 문제였다 뭐든지 마음가짐이 중요한것같다.
next.js의 지식이 부족하기에 문제는 정말 어려웠고 server.js도 라우팅도 모두 동적으로 해준다는것을 깨닫는데 시간이 조금 걸렸다.
ioEYWhJqZO폴더에서 flag를 출력하는 함수와 이폴더의 페이지에서만 button클릭시 동작하는 부분이 있는것을 볼수있다.
저함수를 실행시키는 방법을 찾는데 많은 시간을 사용했고
test버튼을 클릭시에 다음과 같이 통신하는것을 확인했고 codegate의 웹문제에서 action값을 변조시킨것처럼 이번에도 action을 바꾸면 될것같았다.
/_next/static/chunks/app/ioEYWhJqZO/page-46ecf19b8ba66948.js경로에서 중요한 action id값을 찾았다.
(self.webpackChunk_N_E = self.webpackChunk_N_E || []).push([[7646], {
8357: function(e, t, n) {
Promise.resolve().then(n.bind(n, 2114))
},
5925: function(e, t, n) {
"use strict";
Object.defineProperty(t, "$", {
enumerable: !0,
get: function() {
return i
}
});
let l = n(5181);
function i(e) {
let {createServerReference: t} = n(7320);
return t(e, l.callServer)
}
},
2114: function(e, t, n) {
"use strict";
n.r(t),
n.d(t, {
default: function() {
return a
}
});
var l = n(9533)
, i = n(1229);
n(5181);
var r = n(5925);
(0,
r.$)("816774a06b36f5211070d9d4f10f18e74c47f4ec");
var s = (0,
r.$)("27cb19eb91692fce6e188119e76dc4ccbd21679d");
let c = e => {
let {task: t, onToggleComplete: n, onDelete: i} = e;
return (0,
l.jsxs)("div", {
style: {
display: "flex",
alignItems: "center",
marginBottom: "10px"
},
children: [(0,
l.jsx)("input", {
type: "checkbox",
checked: t.completed,
onChange: () => n(t.id),
style: {
marginRight: "10px"
}
}), (0,
l.jsx)("button", {
style: {
display: "none"
},
onClick: () => s(),
children: "Test"
}), (0,
l.jsx)("span", {
style: {
textDecoration: t.completed ? "line-through" : "none",
flex: 1
},
children: t.name
}), (0,
l.jsx)("button", {
onClick: () => i(t.id),
style: {
marginLeft: "10px"
},
children: "Delete"
})]
})
}
;
var a = () => {
let[e,t] = (0,
i.useState)([])
, [n,r] = (0,
i.useState)("")
, [s,a] = (0,
i.useState)("all")
, [o,d] = (0,
i.useState)(1)
, p = n => {
t(e.map(e => e.id === n ? {
...e,
completed: !e.completed
} : e))
}
, u = n => {
t(e.filter(e => e.id !== n))
}
;
return (0,
i.useEffect)( () => {
console.log("Current tasks:", e)
}
, [e]),
(0,
l.jsxs)("div", {
style: {
padding: "20px",
fontFamily: "Arial, sans-serif"
},
children: [(0,
l.jsx)("h1", {
children: "Task Manager"
}), (0,
l.jsxs)("div", {
style: {
marginBottom: "20px"
},
children: [(0,
l.jsx)("input", {
type: "text",
value: n,
onChange: e => {
r(e.target.value)
}
,
placeholder: "Enter new task",
style: {
padding: "10px",
width: "300px",
marginRight: "10px"
}
}), (0,
l.jsx)("button", {
onClick: () => {
n.trim() && (t([...e, {
id: o,
name: n,
completed: !1
}]),
r(""),
d(o + 1))
}
,
style: {
padding: "10px"
},
children: "Add Task"
})]
}), (0,
l.jsxs)("div", {
style: {
marginBottom: "20px"
},
children: [(0,
l.jsx)("label", {
style: {
marginRight: "10px"
},
children: "Filter: "
}), (0,
l.jsxs)("select", {
value: s,
onChange: e => {
a(e.target.value)
}
,
children: [(0,
l.jsx)("option", {
value: "all",
children: "All"
}), (0,
l.jsx)("option", {
value: "completed",
children: "Completed"
}), (0,
l.jsx)("option", {
value: "incomplete",
children: "Incomplete"
})]
})]
}), (0,
l.jsx)("div", {
children: ( () => {
switch (s) {
case "completed":
return e.filter(e => e.completed);
case "incomplete":
return e.filter(e => !e.completed);
default:
return e
}
}
)().map(e => (0,
l.jsx)(c, {
task: e,
onToggleComplete: p,
onDelete: u
}, e.id))
})]
})
}
}
}, function(e) {
e.O(0, [4170, 6842, 1744], function() {
return e(e.s = 8357)
}),
_N_E = e.O()
}
]);
이후 action id값을 다른것으로 변조해줬더니 flag를 받았다.
'웹' 카테고리의 다른 글
nodejs로 파일 업로드 필터링 우회 방법 (0) | 2025.04.09 |
---|---|
dicectf-web-공부 (0) | 2025.04.08 |
Codegate2025-공부 (0) | 2025.04.02 |
codegate 2025-Masquerade (0) | 2025.03.30 |
WACon2022-Kuncɛlan 공부 (4) | 2022.06.29 |