Challenge 33을 지금부터 풀겠다.
먼저 첫번째 페이지는 http://webhacking.kr/challenge/bonus/bonus-6/
그냥 Wrong이라고 표시되어 있을 뿐이고, phps를 살펴보면 아래와 같다.
if($_GET[get]=="hehe")
{
echo("<a href=###>Next</a>");
}
else
{
echo("Wrong");
}
?>
GET 요청 방식을 사용하네. 참 쉽다.
URL 주소창에 http://webhacking.kr/challenge/bonus/bonus-6/index.php?get=hehe 라고 적으면된다.
하지만 이걸로 끝날 200점짜리 문제가 아니었다.
http://webhacking.kr/challenge/bonus/bonus-6/lv2.php
레벨 2로 넘어갔다.
<?
if($_POST[post]=="hehe" && $_POST[post2]=="hehe2")
{
echo("<a href=##>Next</a>");
}
else
{
echo("Wrong");
}
?>
이번엔 POST 방식으로 보내야한다.
POST 방식? 이게 뭘까? 하는 사람은 HTTP 전송 POST방식을 공부하는 것이 좋다.
뭐 여러가지 방법으로 데이터를 수정해 보낼 수 있겠지만, 나는 그 위대한 Burp suite을 사용하기로 했다.
이전에 테스트하며 캡처해둔 POST 데이터 요청을 참고하여 만들었다. 일일이 다 치면 바보다 바보
POST /challenge/bonus/bonus-6/lv2.php HTTP/1.1
Host: webhacking.kr
Content-Length: 21
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://webhacking.kr/challenge/bonus/bonus-6/lv2.php
Accept-Encoding: gzip, deflate, sdch
Accept-Language: ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: PHPSESSID=****사용자 쿠키값****
Connection: close
post=hehe&post2=hehe2
쿠키는 알아서 수정하길 바란다.
어쨌든 이걸 보내면 또.. 아 또야..
http://webhacking.kr/challenge/bonus/bonus-6/33.php
삼삼이가 존재한다.
<?
if($_GET[myip]==$_SERVER[REMOTE_ADDR])
{
echo("<a href=##.php>Next</a>");
}
else
{
echo("Wrong");
}
?>
우리 삼삼이는 이상한 걸 요청한다.
$_SEVER[REMOTE_ADDR] 이라는 것인데
이것은 php에서 해당 웹페이지에 접속한 사용자의 IP 주소를 가져오는 것이다.
나는 공유기 없이 직접 연결하여 사용하므로 공인 주소를 적었다.
GET 방식이니까 burp suite 같은거 안 써도된다.
http://webhacking.kr/challenge/bonus/bonus-6/33.php?myip=****자신의 아이피****
이제 끝났을까?
아니다.
http://webhacking.kr/challenge/bonus/bonus-6/l4.php
역시 점수는 따기 어렵다.
보니까 hint : 1462208149 이 적혀있고 뭔지 모르겠어서 phps를 살펴보았다.
<?
if($_GET[password]==md5(time()))
{
echo("<a href=###>Next</a>");
}
else
{
echo("hint : ".time());
}
?>
GET방식인데, 패스워드가 현재시간을 md5로 encrypt 한 것이다.
여기서는 1462208149초라는 것이다. 새로고침 할 때마다 바뀌는데 이거 괜찮을까??
http://webhacking.kr/challenge/bonus/bonus-6/l4.php?password=5939b59753733cfffa4dc0bf060f5c88
초마다 바뀌어서 통과를 할 수가 없다.
그래서 미리 앞선 값(예를 들어, 1462208200초)을 md5로 암호화했다.
그리고 그냥 F5키를 눌렀다.
이 부분은 나중에 파이썬으로 스크립트를 작성해봐야겠다.. 지금은 새벽 두시라 하기가 싫다.
어쨌든 통과했다.
http://webhacking.kr/challenge/bonus/bonus-6/md555.php
하.지.만. 게임은 끝나지 않지!
졸리지만 다섯번째 서브문제의 phps를 열어본다.
<?
if($_GET[imget] && $_POST[impost] && $_COOKIE[imcookie])
{
echo("<a href=###>Next</a>");
}
else
{
echo("Wrong");
}
?>
미친 것이다.
GET과 POST와 쿠키를 동시에 요청한다.
어떤 값은 필요없고 그냥 존재하면 된다.
정말 귀찮은 문제라고 할 수 있다.
나는 구글 크롬을 애용해서 확장프로그램인 EditThisCookie가 있다.
이걸 사용해서 쿠키값 imcookie를 생성하고 그 안에 아무거나 썼다.
이제 GET과 POST를 날려줄 차례다.
http://webhacking.kr/challenge/bonus/bonus-6/md555.php?imget=1
GET 방식은 위처럼 날려준다.
붙여넣고 엔터치기 전에, burp suite의 intercept를 on해두고 POST값도 날려줄 것이다.
POST /challenge/bonus/bonus-6/md555.php?imget=1 HTTP/1.1
Host: webhacking.kr
Content-Length: 8
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://webhacking.kr/challenge/bonus/bonus-6/md555.php?imget=1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: PHPSESSID=****사용자 쿠키값****; imcookie=1
Connection: close
impost=1
이런 식으로 GET과 POST 그리고 Cookie를 함께 보내준다. 이러면 앞서 쿠키를 추가한 의미가 없는데?
그럼 이제 끝인가?
http://webhacking.kr/challenge/bonus/bonus-6/gpcc.php
아니 켠김왕이야.
마지막이면 좋겠다고 생각하는 phps 이다.
<?
if($_COOKIE[test]==md5("$_SERVER[REMOTE_ADDR]") && $_POST[kk]==md5("$_SERVER[HTTP_USER_AGENT]"))
{
echo("<a href=###>Next</a>");
}
else
{
echo("hint : $_SERVER[HTTP_USER_AGENT]");
}
?>
그러니까 쿠키에는 사용자 IP주소를 md5암호화한 값이 들어가고,
POST 요청값에는 사용자의 User agent 정보가 md5 암호화하여 들어간다는 것이다.
간단하다.
POST /challenge/bonus/bonus-6/gpcc.php HTTP/1.1
Host: webhacking.kr
Content-Length: 35
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://webhacking.kr/challenge/bonus/bonus-6/gpcc.php
Accept-Encoding: gzip, deflate, sdch
Accept-Language: ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: PHPSESSID=****사용자 쿠키값****; test=c4f1d2b9426d421c9d3d7195fcd08a82
Connection: close
kk=781f28764725b80e6d143a985ebb2806
이렇게 6번째 서브 문제가 끝이났다.
모든 문제가 끝이 났다고 말한 적이 없다.
http://webhacking.kr/challenge/bonus/bonus-6/wtff.php
의지가 충만해진다..
$_SERVER[REMOTE_ADDR]=str_replace(".","",$_SERVER[REMOTE_ADDR]);
if($_GET[$_SERVER[REMOTE_ADDR]]==$_SERVER[REMOTE_ADDR])
{
echo("<a href=###>Next</a>");
}
else
{
echo("Wrong<br>".$_GET[$_SERVER[REMOTE_ADDR]]);
}
?>
사용자의 IP를 저장하는데 .을 삭제해서 저장한다.
그렇게 .이 삭제된 사용자 IP가 있으면 Next.
http://webhacking.kr/challenge/bonus/bonus-6/wtff.php?192168102=192168102
예를들어 192.168.10.2 의 아이피를 가지고 있을 때 위처럼 GET으로 보내면 된다.
http://webhacking.kr/challenge/bonus/bonus-6/ipt.php
이제 다음 문제가 뜬다고 하더라도 놀랍지 않다.
<?
extract($_GET);
if(!$_GET[addr]) $addr=$_SERVER[REMOTE_ADDR];
if($addr=="127.0.0.1")
{
echo("<a href=###>Next</a>");
}
else
{
echo("Wrong");
}
?>
이건 뭐 그냥 그대로 작성하면된다.
http://webhacking.kr/challenge/bonus/bonus-6/ipt.php?addr=127.0.0.1
하지만 이해하는 것이 필요하니 extract($_GET)에 대한 나름대로의 설명을 하겠다.
우리가 html 로그인 form을 작성한다면 method=post 그리고 action=login_action.php로 넘길 것이다.
그럼 login_action.php에서는 항상 하던대로 $id = $_POST['id']; 이렇게 POST로 전송되어지는 값을 받아오겠지?
이때 php 상단에 extract($_POST)를 적으면 register_globals를 ON하든 말든
$_POST를 쓰지않고 $id; 만 쓰면된다.
이렇게 편한 것을 왜 안 쓰는지 잘 모르겠다.
찾아보니 그 이유는 php 코딩상 오류가 심하기 때문이다.
첫번째로 그 변수에 들어간 값이 POST로 온건지 GET으로 온건지 분간할 수 없다. (GET과 POST를 둘다 extract할때)
두번째는 php 내에서 조건문을 무시할 수 있다.
<?php
extract($_POST);
if ( $password == '1234Tistory') {
$auth = 1;
}
if ( $auth == 1 ) {
echo "어드민 계정은....";
// 기타 관리자 권한의 내용
}
?>
개발자는 $password를 form에서 post로 보내겠지만,
해커가 $auth=1 을 POST로 보낼 경우, 비밀번호 필요 없이 인가되지 않은 정보를 열람할 수 있다는 것이다.
요즘은 이런 곳이 없겠지만, 자신이 귀찮다고 고의로 서버에 취약점을 남겨두는건
회사에서 잘리는 것은 물론, 형사처벌이 가해질 수도 있으니 제대로 공부해서 실수를 하지 않는 것이 좋다.
결과적으로 위 문제의 $addr은 치환을 하던말던간에 어떤 값이 GET으로 보내진지 서버에서 모르기 때문에,
공격자 입장에서 손쉽게 답을 찾을 수 있다.
http://webhacking.kr/challenge/bonus/bonus-6/nextt.php
<?
for($i=97;$i<=122;$i=$i+2)
{
$ch=chr($i);
$answer.=$ch;
}
if($_GET[ans]==$answer)
{
echo("<a href=###>Next</a>");
}
else
{
echo("Wrong");
}
?>
오늘 잠자기는 글렀다고 생각한다.
for문은 아스키 코드를 사용하는 모습이다.
for($i=97;$i<=122;$i=$i+2)
소문자 a 부터 z까지, 변수 i를 2씩더하며 (a 다음은 c) 반복문을 실행한다.
a c e g i k m o q s u w y
이게 답이다.
http://webhacking.kr/challenge/bonus/bonus-6/nextt.php?ans=acegikmoqsuwy
왜 그럴까?
호기심은 공부에 가장 좋다.
그 이유는 for 문에서 자세히 보면 $anwser 뒤에 점이 붙어있다.
이건 오타가 아니라 필요하기에 쓴 것이다.
$ch=chr($i); 는 변수 i의 아스키 코드 값을 문자로 바꿔줄 것이다.
아스키 문자를 $anwser에 계속 더해주는 것으로 보면된다.
php의 echo에서 보듯이 변수와 변수 사이나 변수와 문자열 사이의 점은 그 둘을 이어주는 매개체라고 보면 쉽다.
http://webhacking.kr/challenge/bonus/bonus-6/forfor.php
<?
$ip=$_SERVER[REMOTE_ADDR];
for($i=0;$i<=strlen($ip);$i++)
{
$ip=str_replace($i,ord($i),$ip);
}
$ip=str_replace(".","",$ip);
$ip=substr($ip,0,10);
@mkdir("answerip/$ip");
$answer=$ip*2;
$answer=$ip/2;
$answer=str_replace(".","",$answer);
$pw="###";
$f=fopen("answerip/$ip/$answer.$ip","w");
fwrite($f,"Password is $pw\n\nclear ip : $_SERVER[REMOTE_ADDR]");
fclose($f);
?>
마지막이라고 좀 더 복잡해졌다.
하지만 하나하나 풀어보면 쉬울 것이다.
// 변수 ip에 사용자 IP를 저장한다.
$ip=$_SERVER[REMOTE_ADDR];
// 사용자 IP의 길이만큼 변수 i를 사용해 반복문을 실행한다.
for($i=0;$i<=strlen($ip);$i++) {
// 사용자 IP에서 변수 i와 매칭되는 값을 아스키 코드값으로 바꾼다.
$ip=str_replace($i,ord($i),$ip);
}
여기서 for문은 사용자 IP의 모든 숫자를 모두 아스키 코드값으로 바꾼다고 보면 쉽다.
// 변수 IP에 담긴 모든 점을 삭제한다.
$ip=str_replace(".","",$ip);
// 첫번째 자리부터 10번째까지의 숫자만 변수 ip에 저장한다.
$ip=substr($ip,0,10);
// @는 오류코드를 생략한다. 그리고 answerip/****변수 ip의 값**** 디렉토리를 생성한다.
@mkdir("answerip/$ip");
// 변수 ip에 2를 곱한 값을 변수 answer에 저장한다.
$answer=$ip*2;
// 변수 ip에 2를 나눈 값을 변수 answer에 저장한다.
$answer=$ip/2;
// 변수 answer에 있는 모든 점을 삭제한다.
$answer=str_replace(".","",$answer);
// 비밀번호 값 초기화
$pw="###";
// answerip/****$ip의 값****/****$answer.$ip의 값**** 파일을 쓰기모드로 연다.
$f=fopen("answerip/$ip/$answer.$ip","w");
// 비밀번호는 $pw라고 적고 ip는 사용자 ip를 저장한다.
fwrite($f,"Password is $pw\n\nclear ip : $_SERVER[REMOTE_ADDR]");
// 파일을 닫는다.
fclose($f);
이걸 일일이 계산해야할까?
아니다. phps에 코드가 다 주어졌기 때문에 복붙하면 된다.
간단하게 온라인 php 컴파일러를 사용한다.
http://www.tutorialspoint.com/execute_php_online.php
<html>
<head>
<title>Online PHP Script Execution</title>
</head>
<body>
<?php
$ip="****사용자 IP주소****";
for($i=0;$i<=strlen($ip);$i++)
{
$ip=str_replace($i,ord($i),$ip);
}
$ip=str_replace(".","",$ip);
$ip=substr($ip,0,10);
@mkdir("answerip/$ip");
$answer=$ip*2;
$answer=$ip/2;
$answer=str_replace(".","",$answer);
echo "answer ip/$ip/$answer.$ip"; # 답이 나오는 구문
?>
</body>
</html>
이렇게 작성하고 Execute 를 클릭을 누르면 답이 나온다.
http://webhacking.kr/challenge/bonus/bonus-6/answerip/5515510755/27577553775.5515510755
주소창에 위와 같이 붙여넣기 해서
이제 http://webhacking.kr/index.php?mode=auth 여기로 이동해서
플래그 칸에 패스워드를 넣으면된다.
'워게임 > 웹해킹kr' 카테고리의 다른 글
웹해킹kr 38번 문제 풀이 (0) | 2016.05.24 |
---|---|
웹해킹kr 54번 문제 풀이 (0) | 2016.05.23 |
웹해킹kr 28번 문제 풀이 (0) | 2016.05.23 |
웹해킹kr 12번 문제 풀이 (0) | 2016.05.23 |
웹해킹kr 11번 문제 풀이 (0) | 2016.05.03 |