이번엔 식별과 인증을 분리하는 로직에서 생각해보고자 한다.
select pw from member where id = 'cat'
위와 같은 경우가 분리해서 검사하는 경우라 볼 수 있겠다!
그럼 저번에 했던 동시에 검사하는 경우와 그렇게 많이 다를까 싶기도 하다. 어떤 부분이 차이가 날까?
식별과 인증을 동시에 하는 로그인 로직에서의 SQLi (+Access Control)
제목이 굉장히 길다.. 작명같은거에 센스가 없는게 여기서 여실히 드러나는 ㅠㅠ 로그인 로직은 저번에 작성한 글에서의 설명과 이어서 공부해보자 쿠키와 세션 / 로그인 로직 HTTP는 연결성이
ragdo11.tistory.com
저번에는 or '1'='1 을 이용한 Logic error로 SQLi를 시도했었다. 또 comment로 패스워드 인증을 무력화 시키는 방법도 사용했다. 이번에도 그럼 그 방법대로 사용하면 되겠지!! 하고 써보면..
select pw from member where id = ''
id -> admin' or '1'='1
pw -> anything
select pw from member where id = 'admin' or '1'='1' // pw = anything
if (db_pass == in_pass)
로그인 성공!
else
로그인 실패
저번처럼 인젝션이 잘 먹혀서 로그인이 되겠지 ㅎㅎ?? -> 아님
왜 안될까? 안 되면 저 SQL 구문이 의미하는 건 뭐지?
아! 열심히 고민해보니까 패스워드는 나중에 따로 검사하니까 로직 에러를 사용해도 패스워드 인증 부분 자체를 무력화할 수 없는 거구나!
라고 생각했으면 딱 절반만 맞았다. 패스워드 인증 부분 자체를 무력화할 수 없는 건 맞는데 저 식에 or '1'='1 이 들어간 것과 안 들어간 것은 차이가 있다.
생각해보면 admin이라는 계정이 있으면 굳이 or '1'='1 을 하지 않아도 where id = 'admin' 이 부분은 참이다. 그럼 or '1'='1 구문이 들어가면?? where 절이 참이 되면서 그냥 select pw from member과 같은 SQL문이 된다. 고로 admin의 pw뿐만 아니라 다른 pw까지 전부 결과값으로 나온다.
그럼 이 bypass가 성공하기 위해서는 이번에는 where이 참이 되는 것은 의미가 없다. if 문이 참이 되어야만 bypass가 가능해진다.
여기서 사용할 수 있는 것이 union 명령어다. union 명령어로 두 select 문을 사용하되, 원래 있던 select문은 안 되게끔 하고 내가 원하는 select문을 넣어 우회해버리는 것이다.
select pw from member where id = ''
id -> 없는 값으로 아무거나' union select '같은 값
pw -> 같은 값
select pw from member where id = '/?id=' union select '1234' // pw = 1234
이렇게 되면 로그인이 우회가 된다. select를 사용할 때 컬럼 부분에 문자열을 넣으면 입력한 문자열이 그대로 출력된다는 점을 이용한 것이다.
union은 사용할 때 주의점이 있는데 앞 select 문의 column과 뒤의 select 문의 column 개수가 같아야 한다.
select 1 union select 2,3
이런 식으로 컬럼의 개수가 같지 않으면 에러가 뜨니 주의해야 한다.
다시 넘어와서 아래와 같은 형태로 union sqli를 했었다
select pw from member where id = '/?id=' union select '1234' // pw = 1234
이게 왜 bypass가 되는지 잘 모르겠다는 사람들을 위한 직접 해본 결과
어라? 분명 id가 x인 계정도 없거니와 비밀번호가 blah인 계정도 없는데 어떻게 저렇게 뜨는걸까??
select pw from test where id = 'x' union select 'blah'
첫 select문을 보면 우선 id가 x인 계정의 pw를 선택하는 것인데 x인 계정이 없으므로 아무것도 선택되지 않는다. 하지만 두 번째 select문은 blah라는 문자열을 출력하도록 되어 있다. 그래서 row인 pw은 그대로 남은 채 blah가 출력되어 저런 것이 가능해지는 것이다! 비밀번호 입력 칸에 blah를 넣으면 우회 성공!
하지만 이 방법으로는 bypass는 가능하지만 원하는 계정으로 접속하지 못한다는 단점은 있다.
만약 SQL문이 아래와 같은 식으로 작성되어 있다면?
select id, pw from member where id = ''
if (db_pass == in_pass)
로그인 성공
else
로그인 실패
union을 이용해서 원하는 계정으로 접속할 수 있게 된다. 위에서의 sqli와 같이 union의 컬럼 개수를 맞춰서 시도해본다면??
원하는 계정으로 로그인 할 수 있게 된다!! 신기하죠?
'SQL Injection > SQL Injection' 카테고리의 다른 글
Union Based SQLi (0) | 2024.06.13 |
---|---|
식별과 인증 동시/분리 처리 + Hash 실습 파트 (0) | 2024.06.11 |
식별과 인증 동시/분리 처리 + Hash (0) | 2024.06.11 |
식별과 인증을 분리해서 검사하는 로직에서의 SQLi - 2 (1) | 2024.06.11 |
식별과 인증을 동시에 하는 로그인 로직에서의 SQLi (+Access Control) (0) | 2024.06.10 |