페이지에 접속해보면 Login 버튼이 존재한다. 우리의 목표는 TheMaster 계정으로 로그인 하는것이다.



Login 버튼을 눌러보면 Monkey 계정으로 로그인 된 것을 확인 할 수 있다.


        <b>Welcome to Level 10</b><br><br>
        Target: Bypass the login. Login as TheMaster<br>
        <br><br><br>
        <form method="post">
            <input type="hidden" name="login" value="YToyOntzOjg6InVzZXJuYW1lIjtzOjY6Ik1vbmtleSI7czo4OiJwYXNzd29yZCI7czoxMjoiMDgxNXBhc3N3b3JkIjt9">
            <input type="submit" value="Login" name="dologin">
        </form>
        <br><br><br>
    Welcome Monkey. You are just a normal user!



소스를 확인해보면 Login 버튼을 눌렀을 때 login 파라미터로 YToyOntzOjg6InVzZXJuYW1lIjtzOjY6Ik1vbmtleSI7czo4OiJwYXNzd29yZCI7czoxMjoiMDgxNXBhc3N3b3JkIjt9가 전달되는 것을 알 수 있다. 이를 base64 디코딩하면 a:2:{s:8:"username";s:6:"Monkey";s:8:"password";s:12:"0815password";}가 나온다. PHP Serialize 함수의 결과이기 때문에 이를 수정하여 base64로 인코딩 후 login 파라미터에 태워 보내주면 로그인 할 수 있을 것이다.



boolean 타입으로 password 변수를 지정해준 후 1을 넘겨주어 true를 반환시키면 TheMaster 계정으로 로그인 할 수 있다.

'Wargame > RedTiger:OverTheWire' 카테고리의 다른 글

[RedTiger] Level 9  (0) 2017.11.06
[RedTiger] Level8  (0) 2017.11.01
[RedTiger] Level7  (0) 2017.11.01
[RedTiger] Level6  (0) 2017.11.01
[RedTiger] Level5  (0) 2016.10.19

Wargame.kr

Web_700

php? c?



힌트로 주어진 것은 integer type에 대해 알고 있냐는 것과 32bit 어플리케이션이라는 것입니다.

문제를 확인해보도록 하죠.



접속하면 D1과 D2를 입력 할 수 있는 텍스트박스와 try버튼이 있습니다.

get source를 눌러 소스를 보도록 하죠.



D1과 D2의 값을 POST로 받네요. 각각 input1, input2 변수에 저장을 합니다.

그리고 /tmp/p7을 실행시키는데, POST로 입력받은 d1의 값을 argv로 받습니다.

만약 실행시킨 결과 값이 1이 아니면서 result의 값과 d2에서 입력받는 값이 같을 경우 flag를 뱉는 구조네요.

p7.c도 한번 확인해보도록 합시다.



간단한 코드입니다.

argv[1]을 int형으로 바꿔준 후, 0보다 작을 경우 1을 출력시키는 nono() 함수로 분기하고, i를 5 증가시킨 후 i가 4보다 클 경우 1 출력, 5보다 작을 경우 i의 값을 출력시켜주는 코드입니다.

간단한 코드이지만 약간 말이 안되는 부분이 있죠. i가 0보다 작아서도 안되고 4보다 커서도 안된다. 하지만 i는 중간에 5가 증가되기 때문에 이 조건에 부합시키는 수는 있을수가 없죠.

하지만 32비트 어플리케이션에서는 int형이 4바이트 제한이기 때문에 값의 범위가 -2147483648 ~ 2147483647 까지입니다.

따라서 2147483643 이상의 값을 입력 받을 경우 값이 0 또는 -로 출력이 될 것입니다.

p7.c를 그대로 긁어와 컴파일 하여 실행시켜보았습니다.



우리의 예상대로 - 값이 출력이 되었습니다.

이를 그대로 POST로 날려줍시다.

날려줄때, 문제 페이지에서는 D1의 maxlength가 9로 제한이 되어있으니, 개발자 도구 또는 프록시 툴을 이용하여 제한을 풀던지, 값을 날려주던지 합시다.

저는 burp suite를 이용해 파라미터를 날려주었습니다.



짠! flag를 깔끔하게 뱉어줍니다.

이 문제는 700점이라고 하기에는 조금 쉬운 감이 없지 않아 있네요..

'Wargame > Wargame.kr' 카테고리의 다른 글

[Wargame.kr] Web_800_jff3_magic  (0) 2016.05.30
[Wargame.kr] Web_800_QnA  (0) 2016.05.27
[Wargame.kr] Web_700_ip log table  (0) 2016.05.27
[Wargame.kr] Web_700_lonely guys  (0) 2016.05.26
[Wargame.kr] Web_700_dmbs335  (0) 2016.05.26

Wargame.kr

Web_700

dmbs335




드디어 700점대 문제로 넘어왔습니다.

이번에도 web 문제네요. SQL Injection 문제입니다. 살펴보도록 하죠.



들어가보니 게시판이 하나 있습니다. 검색을 할 수 있는 공간이 있고 컬럼을 선택 할 수도 있습니다. and와 or은 subject|content 컬럼을 선택했을 경우의 연산입니다.

소스를 확인해봅시다.



30라인을 확인 해 보면 parse_str($_SERVER['QUERY_STRING']);이란 구문이 있습니다.

parse_str 함수는 파라미터로 전달받은 문자열을 PHP 변수로 변환시켜주는 함수입니다.

이 때, PHP 내부에서 쓰이고 있는 변수명을 문자열로 전달 할 경우 해당 변수의 값이 바뀌기도 합니다.

이 문제는 이러한 parse_str 함수의 취약점을 이용한 문제입니다.

$_SERVER['QUERY_STRING']은 HTTP에서 GET 요청을 했을 때, 그 문자열을 반환해주는 구문입니다.

예를 들어, 


http://wargame.kr:8080/dmbs335/?search_cols=subject&keyword=1&operator=or 라는 GET요청을 때렸다면


$_SERVER['QUERY_STRING'] -> search_cols=subject&keyword=1&operator=or 이 될 것입니다.


그렇다면 우리는 GET 요청으로 PHP상에서 취약한 부분을 찾아 변수의 값을 변환해주면 될 것입니다.

where_clause 변수에 실질적인 where구문의 쿼리가 들어갑니다.

47라인을 보면 query_parts 변수가 존재 할 경우 where_clause문에 해당 변수의 내용을 넣어주는 부분이 있는데, 이는 그 위의 search_cols 변수가 존재 할 경우 들어갑니다.

따라서 search_cols 변수에 preg_match문에 부합되지 않는 값을 넣어주고, query_parts 변수에 우리가 원하는 쿼리문을 집어 넣어준다면 keyword에 추가되는 addslashes 함수를 우회하여 쿼리를 실행시킬 수 있을 것입니다.





query_parts 변수에 union 구문을 집어 넣어주었습니다.

결과 값이 1,2,3,4로 나타나는 것을 확인 할 수 있습니다.



테이블명을 알아내기 위해 select구문을 서브쿼리로 집어 넣어 실행시켜주었더니 41번째에 해당하는 테이블에서 플래그를 담고 있는 테이블로 의심되는 값이 튀어나왔습니다.



다음으로 컬럼 값을 알아내기 위해 table_name의 조건을 위에서 알아 낸 테이블명으로 설정 해 준 후 쿼리를 때렸더니 f1ag라는 컬럼명을 뱉어냈습니다.



위에서 알아낸 값들을 이용하여 Key값을 따낼 수 있었습니다.






References

- God of Webhacking Zairo(http://zairo.tistory.com)

Wargame.kr

Web_550

type confusion




php의 data type에 관련된 문제같습니다. 문제를 확인해봅시다.


텍스트박스 하나와 check 버튼 하나가 우릴 맞이해주고있습니다.

view-source 링크를 타고 소스를 확인 해 보죠.




gen_key 함수에서 uniqid 함수와 sha1 암호화를 통해 키를 생성하는데, usleep 함수때문에 프로그래밍을 통한 때려맞추기는 못할 듯 싶습니다.

그렇다면 답은 if문에 있을 것입니다.

if문을 지나게 되면 json 형식으로 code 값에 true를, flag 값에 Key값을 넣어 return 해주네요.

util.js 부분을 살펴봅시다.



아까 소스에서 확인했던 code 부분이 true 일 때 flag를 뱉어주네요.




구글링을 통해 확인 한 php 비교연산 테이블입니다.

"php"라는 문자열과 TRUE의 값을 비교했을 때 TRUE를 반환하는 것을 알 수 있습니다.

우리가 json의 key value에 true를 넣어준다면 if문이 우회가 될 것입니다.

네. 생각대로 flag를 뱉어줍니다.




References

- Chris Smith_(PHP Magic Tricks: Type Juggling)

'Wargame > Wargame.kr' 카테고리의 다른 글

[Wargame.kr] Web_600_SimpleBoard  (0) 2016.05.21
[Wargame.kr] Web_600_tmitter  (0) 2016.05.20
[Wargame.kr] Web_550_strcmp  (0) 2016.05.18
[Wargame.kr] Web_500_md5 password  (0) 2016.05.18
[Wargame.kr] Web_500_md5_compare  (2) 2016.05.18

Wargame.kr

Web_550

strcmp




550점대로 넘어왔습니다. strcmp 함수의 취약점을 이용한 문제인것같습니다.



문제에 접속하니 패스워드와 체크하는 버튼이 우릴 기다리고 있습니다.

view-source를 눌러 소스를 확인해봅시다.



POST로 값을 입력받아 password 변수와 비교를 하여 strcmp 함수의 결과로 0을 반환시키면 Flag를 뱉어주네요.

password 변수의 경우 더미값을 이용한 rand()로 생성한 랜덤값이기 때문에 추측하기 어렵습니다.

따라서 정상적인 방법으로는 패스워드를 맞출 수 없습니다.


이렇게 다른 패스워드 값을 넣어준다면  Wrong passwrod.. 메시지를 출력합니다.

구글링을 통해 찾아보니 PHP 5.3+ 버전에서는 strcmp 함수에 string 값이 아닌 Array 값을 입력 해 주었을 때 0을 반환한다고 합니다.

이러한 특성을 이용하여 인증을 우회해봅시다.



burpsuite를 이용하여 POST로 값을 요청해주었습니다.

password 값을 배열로 인식하도록 만들어준 후, 값을 요청해 준 결과 플래그를 뱉어내는 것을 확인 할 수 있습니다.

'Wargame > Wargame.kr' 카테고리의 다른 글

[Wargame.kr] Web_600_tmitter  (0) 2016.05.20
[Wargame.kr] Web_550_type confusion  (0) 2016.05.19
[Wargame.kr] Web_500_md5 password  (0) 2016.05.18
[Wargame.kr] Web_500_md5_compare  (2) 2016.05.18
[Wargame.kr] Web_500_fly me to the moon  (0) 2016.05.17

Wargame.kr

Web_500

md5_compare


이번 문제는 md5를 비교하는 문제인 것 같습니다.

그냥 단순하게 다른 값을 가지고 비교를 하라고 하네요.




문제에 접속했을 때의 화면입니다. value1과 value2를 비교하는 폼이 있네요.

view-source를 클릭하여 소스를 확인 해 보도록 하죠.


v1은 ctype_alpha함수로 알파벳만 들어와야 하며, v2는 is_numeric 함수를 사용하여 숫자만 들어와야 합니다.

하지만 세 번째 if문에서는 md5로 hash한 값이 같아야만 chk 변수가 true로 남아있을 수가 있네요.




이는 php magic hash 취약점을 이용하여 우회 할 수 있습니다.

이는 문자열이 아닌 0e로 시작되는 값을 서로 비교할때, 문자열이 아닌 float형으로 인식하게 되면서 0의 지수형을 나타내는 변수로 바뀌게 됩니다. 그래서 0=0 꼴로 인식하게 되어 true를 반환하게 됩니다.





'Wargame > Wargame.kr' 카테고리의 다른 글

[Wargame.kr] Web_550_strcmp  (0) 2016.05.18
[Wargame.kr] Web_500_md5 password  (0) 2016.05.18
[Wargame.kr] Web_500_fly me to the moon  (0) 2016.05.17
[Wargame.kr] Web_500_DB is really GOOD  (0) 2016.05.17
[Wargame.kr] Web_450_login filtering  (0) 2016.05.17

Wargame.kr

Web_450

login filtering




계정을 가지고 있지만 정지된 상태라고 합니다.

필터링을 우회 할 수 있는 지 알아보는 문제입니다.




소스를 확인 해 보면 mysql_real_escape_string 함수로 addslash를 하고 있습니다. 이로 인해 single quotation과 같은 sql 문에 영향을 끼칠 수 있는 특수문자는 제한이 되었습니다. sql injection을 이용하지 않고 id가 guest 또는 blueh4g일 때 flag를 출력해 주는 것 같습니다.




소스 아래에 주석으로 blocked 된 계정 정보를 알려주고 있습니다.



guest/guest로 로그인 했을 때의 화면입니다.

your account is blocked라는 메시지를 출력하고 끝나네요. 



여기서 ID 부분에 guest가 아닌 대문자를 추가 해 준다면, 쉽게 우회가 가능합니다.

원리는 MYSQL에서는 대/소문자 구분을 하지 않지만 php에서는 대/소문자를 구분하기 때문에 $id에는 대문자로 입력이 되지만, 쿼리문이 실행 될 때는 guest와 동일한 결과 값이 출력됩니다. 따라서 $id는 guesT이지만, 쿼리의 결과값인 $row['id']는 존재하기 때문에 플래그가 출력이 됩니다.

'Wargame > Wargame.kr' 카테고리의 다른 글

[Wargame.kr] Web_500_fly me to the moon  (0) 2016.05.17
[Wargame.kr] Web_500_DB is really GOOD  (0) 2016.05.17
[Wargame.kr] Web_450_WTF_CODE  (0) 2016.05.17
[Wargame.kr] Web_450_flee button  (0) 2016.05.16
[Wargame.kr] Web_300_QR CODE PUZZLE  (0) 2016.05.16

[H3X0R CTF 2016]

Web_63

php_encrypt



대회 중반에 공개된 63점짜리 Web 문제입니다. 파일을 다운 받은 후 압축을 풀면 php_encrpyt.php라는 파일이 나타납니다. 이 파일을 열어보면 아래 그림과 같은 소스가 나타납니다.



대회 이름에 맞게 변수명이 약간 복잡하게 되어 있습니다. 직접 계산해서 돌려도 되지만, 편하게 php 서버를 돌려 값을 찾아내도록 하겠습니다.

먼저, 알아 낼 수 있는 것들을 알아내보죠.


$_b는 ord

$_는 ?

두 번째 $__는 $_GET['?']입니다.

그렇다면 11번째 라인의 $__[0]은 $_GET['?'][0]으로 볼 수 있겠네요. 1, 2, 3도 마찬가지로 생각 할 수 있습니다.



해당 php소스를 돌려보면 위와 같은 결과 값이 나옵니다. 소스대로, 일정 조건을 만족하지 않으면 ?와 !를 출력하게 됩니다.

이 조건을 만족하는 4자리의 값이 flag일 것 같네요.



해당하는 값을 echo로 바로 때려줍시다.



4번째 자리는 'z'로 이미 명시되어 있기 때문에 출력하지 않았습니다.

이를 이어보면 f9!z가 되겠네요.



flag is f9!z



[H3X0R CTF 2016]

Web_10

cmp



대회 초중반쯤 공개 된 10점짜리 web 문제입니다. 친구들이랑 저녁밥 먹고 다시 들어와 보니 공개 되어 있었죠.. 확인 해 봅시다.


패스워드를 입력하는 text box와 submit 버튼 하나가 있습니다.

여기에 아무 문자나 입력을 하고 submit 해 봅시다.




A를 submit 해 보았더니 2라는 결과값을 뱉어냈습니다.



d를 입력 했을 때는 -33이 나왔습니다.


PHP strcmp() 함수의 반환값의 특성을 이용한 문제인 것 같습니다. 이 문제에서 str1은 flag, str2는 string을 가리키고 있는 것 같습니다.

아스키 코드 상으로 A보다 2만큼 위에 있는 문자는 C입니다. 



C를 입력해주니 15라는 값을 반환 해 주었습니다. C에 이어 다른 글자를 입력 해 주었을 때 위와 같이 양/음수로 나누어 출력을 해 주었습니다.



다른 문자들을 집어 넣어 2번째 문자는 0임을 알 수 있었습니다. 올바른 문자를 입력 했을 때 반환하는 숫자 값이 1씩 줄어드는 것을 보니, 이 값은 남은 string의 길이 같습니다. flag의 총 글자 수는 16인 것을 여기서 알 수 있었습니다.



사실 python으로 스크립트를 작성하여 브포를 돌려볼까도 생각 해 봤지만, 음수도 있고, 반환하는 숫자 값도 일정하지 않아 직접 손으로 브포를 했습니다...

(저 숫자가 남은 글자 수인 것을 알아 낸 타이밍이 4자 이상 찾았을 때라... 귀찮기도 했습니다.)



flag is C0MP4R3_15_900D!



+ Recent posts