LEVEL 1
소스코드를 확인해보면 패스워드를 비교하는 로직에 패스워드가 하드코딩되어있음을 알 수 있습니다.
LEVEL 2
우클릭을 하면 아래와 같은 메시지가 뜹니다.
LEVEL 2에 접속하고 Response 패킷을 Paros로 잡아 body부분의 html코드에서 위의 메시지를 찾아봅니다.
그러면 아래와 같이 if문을 확인할 수 있습니다.
우클릭을 우회하는 방법은 두가지가 있습니다.
1. if문 자체를 없앤다.
2. if문은 그대로 return 값을 true로 바꾼다.
저는 2번 방법으로 진행할 건데 값을 true로 바꿔야 하니 paros에서 아래와 같이 트랩을 잡아줍니다.
paros로 들어온 response패킷에서 return값을 true로 바꿔주고 alert는 없애고 continue합니다.
그러면 아래와 같이 우클릭이 가능해집니다.
사실 이렇게 안하고 개발자 도구에 들어가서 소스를 확인하면 됩니다.
그러면 아래와 같은 swf(플래시)파일을 발견할 수 있습니다.
http://www.try2hack.nl/levels/level2.swf파일을 다운받아줍니다.
또, 다운 받은 level2.swf파일을 열기 위해 Sothink SWF Decompiler도 설치해줍니다.
참고로 Sothink SWF Decompiler은 플래시 파일에 있는 이미지, 사운드, 스크립트 등을 추출할 수 있는 프로그램입니다. 아래의 링크에서 다운로드받을 수 있습니다.
http://www.sothink.com/product/flashdecompiler/download.htm
설치한 Sothink SWF Decomplier로 level2.swf를 열어보면 아래와 같이 username과 password를 얻을 수 있습니다.
LEVEL 3
LEVEL3으로 넘어가면 바로 password를 입력하는 창이 나타납니다.
여기에 틀린 password를 입력하면 바로 디즈니랜드 홈페이지로 넘어갑니다~
paros로 확인해보았습니다. PASSWORD="AbCdE"라는 부분이 보입니다. 그러나 이것은 거짓말!
아래에 보이는 src 속성은 외부 스크립트 파일의 URL을 지정하는 속성입니다.
그렇다면 위에서 지정한 JavaScript파일을 확인해보기 위해 다운받아봅시다.
http://www.try2hack.nl/levels/JavaScript
여기서 PASSWORD를 얻을 수 있었습니다.
LEVEL 4
원래는 LEVEL4페이지에 들어가면 아이디와 패스워드를 입력받는 폼이 보여야하지만 저는 안보였습니다.
소스코드를 살펴보니 object태그가 보입니다.
object태그는 문서안에 html, audio, video, 플러그인(Flash, Java Applets)등을 삽입하는 태그입니다
classid 속성은 URI을 나타냅니다.
PassdLeve4.class라는 자바클래스 파일이 보입니다. 이 파일이 뭔지 살펴보기 위해 다운받아봅시다.
http://www.try2hack.nl/levels/PasswdLevel4.class
class파일은 이미 컴파일되어진 파일이기 때문에 이것을 디컴파일 해야합니다.
그래서 저는 JD-GUI를 다운받았습니다.
http://jd.benow.ca/#jd-gui-download
실행을 시키면 아래와 같은 창이 뜹니다.
여기서 아까 다운받은 PasswdLevel4.class파일을 열어줍시다.
아래와 같이 뭔가 아이디와 패스워드를 비교하는 듯한 구문은 찾았으나 아이디랑 패스워드는 발견할 수 없었습니다.ㅠ
어짜피 아이디와 패스워드 폼도 안보였기 때문에 다른 방법을 찾아보기로 했습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | import java.applet.Applet; import java.applet.AppletContext; import java.awt.Button; import java.awt.Component; import java.awt.Container; import java.awt.Font; import java.awt.Label; import java.awt.TextComponent; import java.awt.TextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.util.EventObject; public class PasswdLevel4 extends Applet implements ActionListener { private URL finalurl; String infile; String[] inuser = new String[22]; int totno = 0; InputStream countConn = null; BufferedReader countData = null; URL inURL = null; TextField txtlogin = new TextField(); Label label1 = new Label(); Label label2 = new Label(); Label label3 = new Label(); TextField txtpass = new TextField(); Label lblstatus = new Label(); Button ButOk = new Button(); Button ButReset = new Button(); Label lbltitle = new Label(); void ButOk_ActionPerformed(ActionEvent paramActionEvent) { int i = 0; for (int j = 1; j <= this.totno / 2; j++) { if ((this.txtlogin.getText().trim().toUpperCase().intern() == this.inuser[(2 * (j - 1) + 2)].trim().toUpperCase().intern()) && (this.txtpass.getText().trim().toUpperCase().intern() == this.inuser[(2 * (j - 1) + 3)].trim().toUpperCase().intern())) { this.lblstatus.setText("Login Success, Loading.."); i = 1; String str1 = this.inuser[1].trim().intern(); String str2 = getParameter("targetframe"); if (str2 == null) { str2 = "_self"; } try { this.finalurl = new URL(getCodeBase(), str1); } catch (MalformedURLException localMalformedURLException) { this.lblstatus.setText("Bad URL"); } getAppletContext().showDocument(this.finalurl, str2); } } if (i == 0) { this.lblstatus.setText("Invaild Login or Password"); } } void ButReset_ActionPerformed(ActionEvent paramActionEvent) { this.txtlogin.setText(""); this.txtpass.setText(""); } public void actionPerformed(ActionEvent paramActionEvent) { Object localObject = paramActionEvent.getSource(); if (localObject == this.ButOk) { ButOk_ActionPerformed(paramActionEvent); } else if (localObject == this.ButReset) { ButReset_ActionPerformed(paramActionEvent); } } public void destroy() { this.ButOk.setEnabled(false); this.ButReset.setEnabled(false); this.txtlogin.setVisible(false); this.txtpass.setVisible(false); } public void inFile() { new StringBuffer(); try { this.countConn = this.inURL.openStream(); this.countData = new BufferedReader(new InputStreamReader(this.countConn)); String str; while ((str = this.countData.readLine()) != null) { if (this.totno < 21) { this.totno += 1; this.inuser[this.totno] = str; str = ""; } else { this.lblstatus.setText("Cannot Exceed 10 users, Applet fail start!"); destroy(); } } } catch (IOException localIOException1) { getAppletContext().showStatus("IO Error:" + localIOException1.getMessage()); } try { this.countConn.close(); this.countData.close(); } catch (IOException localIOException2) { getAppletContext().showStatus("IO Error:" + localIOException2.getMessage()); } } public void init() { setLayout(null); setSize(361, 191); add(this.txtlogin); this.txtlogin.setBounds(156, 72, 132, 24); this.label1.setText("Please Enter Login Name & Password"); this.label1.setAlignment(1); add(this.label1); this.label1.setFont(new Font("Dialog", 1, 12)); this.label1.setBounds(41, 36, 280, 24); this.label2.setText("Login"); add(this.label2); this.label2.setFont(new Font("Dialog", 1, 12)); this.label2.setBounds(75, 72, 36, 24); this.label3.setText("Password"); add(this.label3); add(this.txtpass); this.txtpass.setEchoChar('*'); this.txtpass.setBounds(156, 108, 132, 24); this.lblstatus.setAlignment(1); this.label3.setFont(new Font("Dialog", 1, 12)); this.label3.setBounds(75, 108, 57, 21); add(this.lblstatus); this.lblstatus.setFont(new Font("Dialog", 1, 12)); this.lblstatus.setBounds(14, 132, 344, 24); this.ButOk.setLabel("OK"); add(this.ButOk); this.ButOk.setFont(new Font("Dialog", 1, 12)); this.ButOk.setBounds(105, 156, 59, 23); this.ButReset.setLabel("Reset"); add(this.ButReset); this.ButReset.setFont(new Font("Dialog", 1, 12)); this.ButReset.setBounds(204, 156, 59, 23); this.lbltitle.setAlignment(1); add(this.lbltitle); this.lbltitle.setFont(new Font("Dialog", 1, 12)); this.lbltitle.setBounds(12, 14, 336, 24); String str = getParameter("title"); this.lbltitle.setText(str); this.ButOk.addActionListener(this); this.ButReset.addActionListener(this); this.infile = new String("level4"); try { this.inURL = new URL(getCodeBase(), this.infile); } catch (MalformedURLException localMalformedURLException) { getAppletContext().showStatus("Bad Counter URL:" + this.inURL); } inFile(); } } | cs |
일단 아이디와 패스워드를 비교하여 일치하면 "Login Success, Loading.."이라는 문구를 보여주는거 같습니다. 그 후 finalurl 변수에 URL객체를 생성하여 넣고 getAppletContext().showDocument로 무언갈 하고 있습니다. 무슨 역할을 하나 구글링했더니 해당 URL로 보내주는거 같습니다.
그렇다면 finalurl변수에는 다음 레벨의 url이 들어가는 것이겠군요!
getCodeBase()메서드와 str1을 이용하여 URL객체를 생성했습니다. getCodeBase()메서드가 무엇인지 찾아봤습니다. 애플릿 코드가 있는 URL객체를 반환한다고 합니다.
그렇다면 http://www.try2hack.nl/levels/ 을 반환하겠군요.
소스코드를 살펴보니 inURL변수를 발견했습니다. 마찬가지로 getCodeBase()메서드와 infile변수를 이용하여 어떠한 URL을 생성하고 있었습니다. infile변수에는 어떤 값이 담기나 보았더니 level4가 담겼습니다. 따라서 inURL은 http://www.try2hack.nl/levels/level4 이라는 URL을 생성한다는 것을 알아내고 직접 들어가봤습니다.
그랬더니 파일이 다운받아졌고 그 파일에 아래와 같은 내용이 담겨져 있었습니다.
맨 윗줄은 inuser배열에 담겨 str1에 들어가서 finalurl변수를 만들어내고 있었습니다.
따라서 http://www.try2hack.nl/levels/level5-fdvbdf.xhtml이 다음 단계 URL임을 알 수 있었습니다.
밑에는 아이디와 패스워드 같습니다.
해결 끝!