국민체력100 (KSPO) 웹사이트 API 분석 보고서
분석 대상: https://nfa.kspo.or.kr
분석 목적: 튼튼머니 스포츠활동 인증(출석체크) 프로세스 역공학
1. 사이트 개요
국민체력100은 대한민국 국민체육진흥공단(KSPO)이 운영하는 국민 체력 관리 플랫폼입니다.
"튼튼머니"는 체육시설 방문 시 QR 코드를 스캔하여 출석체크하면 포인트가 적립되는 인센티브 프로그램입니다.
1.1 서비스 흐름 (공식)
사용자 → 체육시설 방문 → QR 코드 스캔 → 로그인 → 출석체크(포인트 적립) ↓ (30분 이상 운동 후) 퇴장 시 QR 재스캔 → 2차 인증
1.2 발견된 핵심 URL 구조
|
구분 |
URL |
메소드 |
설명 |
|
로그인 페이지 |
/member/login/memberLogin.kspo |
GET |
CSRF 토큰(csSignature) 발급 |
|
로그인 API |
/member/login/memberLoginActJs.kspo |
POST |
AJAX 로그인 + 출석체크 |
|
포인트 확인 |
/spoint/isNotPointsAccumulationPeriodJs.kspo |
POST |
인센티브 적립 기간 확인 |
2. 인증 프로세스 상세 분석
2.1 Step 1: 로그인 페이지 접근 (CSRF 토큰 취득)
요청:
핵심 파라미터:
|
파라미터 |
값 |
설명 |
|
standGrpCd |
04 |
표준그룹코드 (고정값) |
|
refTb |
SPORTS_FACILITY_VISIT |
참조테이블 (스포츠시설 방문) |
|
spoFaciSn |
정수 |
스포츠시설 일련번호 (핵심 식별자) |
응답에서 추출:
csSignature: CSRF 방지 토큰, 세션마다 새로 발급
유효시간: 약 5~10분 (세션 의존)
2.2 Step 2: AJAX 로그인 (출석체크 실행)
요청:
POST Body:
2.3 Step 3: 응답 코드 분석
응답 형식 (JSON):
발견된 응답 코드 전체 목록:
|
코드 |
분류 |
의미 |
동작 |
|
INF_LOGIN_101 |
✅ 성공 |
정상 로그인 완료 |
세션 생성 |
|
INF_LOGIN_103 |
✅ 성공 |
스포츠활동 인증 + 인센티브 적립 |
포인트 적립됨 |
|
INF_COMM_103 |
✅ 성공 |
정상 적립 완료 |
포인트 적립됨 |
|
ERR_LOGIN_117 |
❌ 실패 |
ID/PW 불일치 |
재시도 필요 |
|
ERR_LOGIN_104 |
🔒 잠금 |
비밀번호 5회 오류 |
비밀번호 찾기 필요 |
|
ERR_LOGIN_107 |
💤 휴면 |
휴면계정 |
계정 복구 필요 |
|
ERR_LOGIN_108 |
🔄 통합 |
회원 통합 필요 |
사이트에서 처리 |
|
ERR_LOGIN_109 |
⚠️ 초과 |
주 1회 초과 참여 |
다음 주까지 대기 |
|
ERR_SPOINT_105 |
ℹ️ 안내 |
스포츠활동 인증 안내 |
정보 메시지 |
|
ERR_SPOINT_107 |
🏢 시설오류 |
적립 불가 시설 |
spoFaciSn 확인 |
|
ERR_SPOINT_110 |
✅ 완료 |
오늘 이미 체크인 완료 |
중복 방지 |
|
ERR_SPOINT_111 |
🚫 종료 |
인센티브 사업 종료 |
서비스 종료 |
3. QR 코드 분석
3.1 QR 코드 URL 구조
3.2 핵심 발견
QR 코드 = 로그인 URL: QR은 단순히 spoFaciSn이 포함된 로그인 페이지 URL
시설 식별: spoFaciSn 파라미터가 유일한 시설 식별자
2단계 프로세스: QR 문서에는 "30분 이상 운동 후 퇴장 시 QR 재스캔" 명시
1차: 입장 시 QR 스캔 → 출석체크
2차: 30분 후 퇴장 시 QR 재스캔 → 포인트 확정
3.3 spoFaciSn 구조
형식: 1~4자리 정수 (1 ~ 9999+)
유효한 번호: 약 2,446개 (전수 조사 결과)
번호와 시설의 관계: 1:1 매핑 (하나의 번호 = 하나의 시설)
조회 불가: 공개 API로 spoFaciSn → 시설명 역조회 불가능
4. 보안 분석
4.1 적용된 보안 메커니즘
|
보안 기능 |
구현 방식 |
우회 가능성 |
|
CSRF 방지 |
csSignature 토큰 |
매 요청 시 새로 취득하면 우회 |
|
세션 관리 |
JSESSIONID 쿠키 |
쿠키 유지로 관리 |
|
AJAX 검증 |
X-Requested-With 헤더 |
헤더 추가로 우회 |
|
Referer 검증 |
Referer 헤더 체크 |
올바른 Referer 설정으로 우회 |
|
중복 방지 |
ERR_SPOINT_110 응답 |
서버 측 1일 1회 제한 |
|
주 1회 제한 |
ERR_LOGIN_109 응답 |
서버 측 제한, 우회 불가 |
5. 시설 데이터 분석
5.1 데이터 수집 결과
전국 체육시설 데이터를 크롤링하여 수집한 결과:
총 시설 수: 약 2,446개
데이터 필드: 시설명(nm), 주소(addr), 시도(sd), 시군구(sgg), 전화번호(tel), 등록번호(sn)
지역 분포: 전국 17개 시·도
5.2 spoFaciSn vs 등록번호
|
구분 |
spoFaciSn |
등록번호(sn) |
|
출처 |
QR 코드 URL |
시설 검색 API |
|
용도 |
출석체크 식별 |
시설 관리 식별 |
|
매핑 |
역조회 불가 |
공개 조회 가능 |
6. API 호출 시퀀스 다이어그램
7. 전수 탐색 (Brute-Force) 분석
7.1 방법론
사용자가 시설의 spoFaciSn을 모를 때, 유효한 번호 목록(2,446개)을 모두 시도하여 찾는 방식:
1. csSignature 1회 취득
2. 각 spoFaciSn에 대해 로그인 POST 요청
3. 응답 코드로 시설 판별:
- INF_LOGIN_103/INF_COMM_103 → 적립 성공 = 올바른 시설!
- ERR_SPOINT_110 → 이미 체크인 완료 (구분 불가)
- ERR_SPOINT_107 → 잘못된 시설
7.2 성능 최적화
|
최적화 기법 |
효과 |
|
csSignature 1회 취득 재사용 |
GET 요청 2,445개 절약 |
|
병렬 배치 처리 (5~20개 동시) |
속도 5~20배 향상 |
|
발견 즉시 중단 |
불필요한 요청 차단 |
|
csSignature 만료 자동 갱신 |
연속 에러 방지 |
예상 소요 시간: 약 3~10분 (네트워크 상태 및 동시 요청 수에 따라 다름)
8. 기술적 제약사항
csSignature 만료: 약 5~10분 후 만료, 갱신 필요
세션 관리: JSESSIONID 쿠키 유지 필수
동일 세션 제한: 같은 세션에서 반복 로그인 시 일부 요청 실패 가능
HTTPS 필수: HTTP → HTTPS 리다이렉트 적용
모바일 User-Agent: 모바일 UA 설정 시 안정적 응답
9. 법적 고지
⚠️ 이 분석은 교육 및 연구 목적으로만 작성되었습니다.
자동 출석체크는 서비스 이용약관에 위반될 수 있습니다.
실제 시설을 방문하지 않고 사용하는 것은 부정 사용에 해당할 수 있습니다.
이 문서의 정보를 사용하여 발생하는 결과에 대해 작성자는 책임지지 않습니다.
이것은 실제로 적용이 되는 곳입니다.
어쨰서인지 빨리 달는 이유가 이거임 ㅋㅋ
======================================================================
튼튼머니 적립시설 목록
수집:
총 3,186개
======================================================================
──────────────────────────────────────────────────
[] 1개
──────────────────────────────────────────────────
[강원] 63개
──────────────────────────────────────────────────
[경기] 798개
──────────────────────────────────────────────────
[경남] 198개
──────────────────────────────────────────────────
[경북] 81개
──────────────────────────────────────────────────
[광주] 103개
──────────────────────────────────────────────────
[대구] 105개
──────────────────────────────────────────────────
[대전] 103개
──────────────────────────────────────────────────
[부산] 221개
──────────────────────────────────────────────────
[서울] 961개
──────────────────────────────────────────────────
[세종] 31개
──────────────────────────────────────────────────
[울산] 56개
──────────────────────────────────────────────────
[인천] 148개
──────────────────────────────────────────────────
[전남] 60개
──────────────────────────────────────────────────
[전북] 69개
──────────────────────────────────────────────────
[제주] 24개
──────────────────────────────────────────────────
[충남] 92개
──────────────────────────────────────────────────
[충북] 72개
재신청 및 세부적인 이유 리스트들 극히일부
QR유출 재신청 시설 우선승인
QR유출 재신청 우선승인"
QR유출 재신청 우선승인"
QR코드 유출 시설 재신청 우선승인"
QR코드 유출 정지시설 재신청 우선승인"
적립시설 신규승인(25.12.10)
전남지역 우선승인"
적립시설 신규승인(25.12.09)
적립시설 승인(6/13)
경북지역 우선승인"
제주지역 우선승인"
조회결과 카카오톡채널로 모집신청 받고있으며 수영프로그램 운영중 신규시설승인(26.3.25)"
사업자등록증 확인 및 대표자 오타 수정 ()"
해당 주소지로 인터넷 검색 결과 실외골프연습장 정상 운영 확인 및
적립시설 신규승인(26.03.25)"
(2547) 사업자등록번호 휴폐업 조회 결과 폐업시설 확인
(6636) 사업자등록증 확인 및 적립시설 신규승인(26.03.25)"
파트너스시설 재승인(25.11.24)"
대충 구조는 이럼
사실 이거 만들고 피드백하고 리버싱하느라 글좀못썻음
다음꺼는 알리코인 자동 출책을 만들생각인데
이게 좀 상당히 어렵네요
원본: 네이버 블로그
댓글
댓글 쓰기