Wargame/pwnable2017. 7. 25. 23:45

pwnable.kr 사이트의 bof 문제를 보면 다음과 같다.


download URL이 제공된다. 일단 다운로드를 받자.


c코드는 다음과 같다.

코드를 분석해보자.

1. main 함수 내에서 func 함수를 호출한다.

2. func 함수를 호출하면서 인자로 0xdeadbeef 를 전달한다.

3. func 함수는 인자로 int 형 변수 하나를 받는다.

4. func 함수 내에서 char형 배열 overflowme를 선언한다.

5. 변수명이 굉장히 노골적이다.

6. gets 함수를 호출해 overflowme 변수에 입력값을 저장한다.

7. 인자로 받은 값과 0xcafebabe를 비교한다.

8. 같으면 bash 실행

9. 다르면 Nah.. 출력


코드 분석을 통해 알아낸 것은 func 함수의 인자인 key 값을 변조해야 한다는 것이다.

그렇다면 어떻게 key 값을 변조할 수 있을까??

해답은 gets 함수에 있다.

gets 함수는 인자로 받은 변수에 데이터를 쓰는 함수인데, 사용자가 입력한 값을 문자열로 저장을 한다. 이 때, 변수의 크기를 넘겨서 쓸 수 있다. 즉, BOF가 발생한다.


payload를 어떻게 만들 수 있을까?

payload를 만들기 위해서는 우선 해당 프로그램을 disassemble 해야 한다.

필자는 ubunt에서 gdb 툴을 이용해 disassemble을 했다.


우선, bof 파일을 다운로드를 받은 뒤 gdb명령을 사용한다.

gdb -q bof

-q 옵션은 gdb 버전 정보 등을 출력하지 않는 옵션이라고 생각하면 된다.


set disassembly-flavor intel

이 명령어는 gdb 명령어로 intel 문법을 이용하도록 설정한다. gdb는 기본 문법이 AT&T이다.


다음 명령어로 main 함수를 디스어셈블 해보자.

disas main

main 함수를 디스어셈블해 보여준다.


main 함수의 스택을 표현하면 다음과 같다.


 

 0xdeadeef

 <-ESP

 

 

 

 

 

 

 

 

 

 EBP->

 SFP

 

 

 ret

 


func 함수를 호출할 때의 스택의 모습이다.


다음 명령으로 func 함수를 디스어셈블하면 다음과 같다.

disas func

func 함수를 디스어셈블해 보여준다.


이 함수에서 보아야 할 부분은 <+29>부터 <+35> 까지이다.

<+29>

overflowme 변수의 시작 위치와 크기를 알 수 있다.

<+32>

overflowme 변수를 esp에 저장하므로써 gets 함수 호출을 준비한다. 즉, 매개변수 설정

<+35>

gets 함수 호출


양이 조금 많아 보이지만 실제로는 작은 조각에 불과하다. 겁먹지 말고 일단 스택을 표현해보자.


 

overflowme 변수의 주소 

 <- ESP

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

overflowme 변수 메모리( 44바이트 ) 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

EBP -> 

 SFP

 

 

 ret

 

 

 func 함수의 매개변수 Key값

 


func+35 부분까지 진행 하면 위와 같이 스택을 표현할 수 있다.

ESP에 oveflowme 변수의 주소를 저장하고 gets 함수를 호출한다.

gets 함수가 반환이 되면 overflowme 변수에 입력된 값을 저장한다.

여기서 44바이트를 초과해서 입력을 해주면 아래 SFP, ret 그리고 func 함수의 매개변수인 key의 값까지도 변조가 가능하다.


key값을 변조하기 위해서 얼마나 입력해야 할까?

overflowme 변수는 44바이트 크기를 받았다. 여기에 더해 SFP, ret 까지 덮으면 그 다음이 key 값이다. 즉, 8바이트를 더한 52바이트를 입력한 후 다음 4바이트가 key값이 되는 것이다.


필자는 python을 이용해 payload를 작성했다.

payload는 다음과 같다.


(python -c 'print "A"*52 + "\xbe\xba\xfe\xca"'; cat) | nc pwnable.kr 9000


그 결과 bash/sh 이 실행이 됨을 볼 수 있다.

flag 를 읽어보자 



'Wargame > pwnable' 카테고리의 다른 글

[pwnable.kr] collision  (0) 2017.06.25
[pwnable.kr] fd  (0) 2017.06.18
Posted by Imp3rio
Wargame/pwnable2017. 6. 25. 19:15

pwnable.kr 사이트의 collision 문제를 보면 다음과 같다.

문제를 보니 MD5 해쉬 충돌과 관련된 문제인 것 같다.

해쉬 충돌이란 해쉬 함수가 서로 다른 두 개의 입력값에 대해 동일한 출력값을 갖는 것을 의미한다.


우선 ssh로 접속해 코드를 보면 다음과 같다.

우선 코드를 분석해보자.

main 함수를 보면 인자가 20바이트가 아니면 "passcode length should be 20 bytes" 문자열을 찍어내고 종료한다. 이를 통해 20바이트의 인자를 넘겨주어야 하는 것을 알 수 있다.

hashcode는 0x21DD09EC 이고, check_password() 함수의 결과 값이 hashcode와 같으면 문제가 풀리는 것 같다.


인자의 값이 0x21DD09EC와 같아야 하는데, 총 20바이트를 넘겨주어야 한다.

총 20바이트의 값이 0x21DD09EC( 4바이트 )와 같아야 하기 때문에 0x21DD09EC를 5로 나눈 값을 넘겨주면 된다.

0x21DD09EC를 5로 나누면 0x6C5CEC8이고, 0x6C5CEC8에 5를 곱하면 0x21DD09E8이 나온다.

즉, 4만큼 차이가 난다.

따라서 0x6C5CEC8 * 4 + 0x6C5CECC를 넘겨주면 된다.

이 값을 python 코드로 넘겨주도록 하자.

python -c 'print "\xC8\xCE\xC5\x06"*4+"\xCC\xCE\xC5\x06"'


위 코드를 인자로 넘겨주면 된다.

위와 같이 플래그가 툭 튀어 나온다.

이 값을 Auth에 넘겨주면 문제가 풀린다.

'Wargame > pwnable' 카테고리의 다른 글

[pwnable.kr] bof  (0) 2017.07.25
[pwnable.kr] fd  (0) 2017.06.18
Posted by Imp3rio
Wargame/webhacking2017. 6. 19. 09:36

webhacking.kr 13번 문제를 보면 다음과 같다.

SQL INJECTION 문제인 것 같고, 힌트로 select 문이 주어져있다.

페이지 소스를 보면 다음과 같다.

다른 힌트는 주어져있지 않다.


일단 어떤 문자열이 필터링되어 있는지 확인할 필요가 있다.

select를 넣어보자.

result 가 0으로 나온다.

필터링이 되는 것 같지는 않다.

힌트에 있는 문자열을 한 단어씩 넣어보면 모두 필터링 되지 않는다.

두 단어씩 끊어 입력해보면 다음과 같이 필터링이 된다.

문자열 사이에 공백이 있으면 필터링이 되는 것 같다.

공격을 하기 위해 필요한 문자열을 넣어보자.

if, union, count, length, substr 등 여러 문자열을 넣어보면 다음과 같이 필터링이 되지 않는다.


 필터링 되지 않는 것

 if, count, length, substr, min, max, concat, in, 0x

 필터링 되는 것

 union, order by, group by, limit, like


입력창에 1, 2 숫자를 넣어봤더니 각각 다음과 가같은 화면을 볼 수 있다.

1을 넣었을 때 위와 같이 result 는 1이 출력되었다.

2를 넣었을 때 위와 같이 result는 0이 출력되었다.


이를 봤을때 1은 True, 0은 False 같다는 느낌이 들었다.

즉, 참일 때와 거짓일 때의 화면이 다르다는 것이고, 이는 BLIND INJECTION을 해야 할 것 같다.


URL에 다음과 같은 쿼리문을 날려보자.

no=if((select(count(flag))from(prob13password))in(1),1,2)

위 쿼리문은 prob13password 테이블에서 flag의 개수가 1개 이면, 1을 no에 저장하고, 그렇지 않으면 2를 저장한다. no가 2가 됐기 때문에 위 처럼 result가 0으로 나왔다.

즉, flag 칼럼에 데이터가 2개 이상이 있음을 알 수 있다.

아래 쿼리문을 이용해 개수를 알아내면 flag 칼럼에 데이터가 2개 있음을 알 수 있다.

no=if((select(count(flag))from(prob13password))in(2),1,2)

min 함수와 max 함수를 이용해 데이터 각각의 길이를 알아낼 수 있다.

다음 쿼리를 이용해 알아보자.

no=if((select(min(length(flag)))from(prob13password))in(4),1,2)

길이가 가장 짧은 flag의 길이는 4임을 알 수 있다.

위 쿼리문을 이용하면 가장 긴 flag의 길이도 알아낼 수 있다.


다음 쿼리를 이용하면 한글자씩 알아낼 수 있다.

no=if((substr((select(max(flag))from(prob13password)),1,1)in(0x66)),1,2)

max(flag)의 첫 번째 글자가 0x66(f) 임을 알 수 있다.

min과 max는 최소값, 최대값을 의미하는데, 이 함수들을 이용해서 글자를 뽑아낼 때, min이 최대길이의 flag를 max가 최소길이의 flag를 가져온다. 이 것에 대해서는 조금 더 알아봐야 할 것 같다.


이를 이용한 python 코드는 다음과 같다.



위 코드의 python 파일을 아래 첨부한다.

13.py


SESSION 값은 사용자의 쿠키 값을 넣으면 된다.

최대 길이의 flag 값을 Auth에 입력하면 문제가 풀린다.

'Wargame > webhacking' 카테고리의 다른 글

[webhacking.kr] 21번 문제  (0) 2017.06.18
[webhacking.kr] 58번 문제  (0) 2017.06.18
[webhacking.kr] 54번 문제  (0) 2017.06.18
[webhacking.kr] 53번 문제  (0) 2017.06.18
[webhacking.kr] 49번 문제  (0) 2017.06.18
Posted by Imp3rio
Wargame/webhacking2017. 6. 18. 23:26

webhacking.kr 21번 문제를 보면 다음과 같다.

BLIND SQL INJECTION 하라고 한다.

BLIND SQL INJECTION을 하기 위해서는 참일 때의 화면과 거짓일 때의 화면을 알아야 한다.

즉, 참과 거짓을 판별할 수 있어야 한다.

일단 입력창에 1을 넣어보자.

url을 보면 get 방식으로 no 와id 그리고 pw가 전달되는 것을 알 수 있으며, no값이 입력창에 입력한 값이 들어가는 것을 알 수 있다.

no가 1일때 아래 Result는 True가 나온다.

no가 3 이상일 때는 다음과 같이 False가 나온다.

no를 이용해 id와 pw를 알아내야 한다.

다음과 같은 쿼리문을 넣어보자

no=3 or no=2 and length(id)=4&id=&pw=

Result가 False이다.

이번에는 다음과 같은 쿼리문을 넣어보자.

no=3 or no=2 and length(id)=5&id=&pw=

Result가 True이다.

즉, no=2인 id의 길이가 5임을 알 수 있다.


이런식으로 no=2와 no=1의 각 id 길이를 알아낼 수 있다.

그리고 substr() 함수를 이용해 id와 pw를 알아낼 수 있다.

예를 들면 다음과 같은 쿼리문을 넣으면 된다.

no=3 or no=1 and substr(id,1,1)=0x67&id=&pw=

no=1인 id의 첫번째 글자는 0x67( g )임을 알 수 있다.


하나하나 입력해보는 것보다 코드를 작성해 자동으로 알아내면 좋을 것 같다.

21.py 파일을 생성해서 다음과 같이 코딩한다.



아래 파일은 위 코드를 작성한 python 파일이다.

21.py

위 python 파일을 돌리면 no=1의 id, pw와 no=2의 id, pw를 알아낼 수 있다.

no2의 pw를 Auth에 입력하면 문제가 풀린다.



'Wargame > webhacking' 카테고리의 다른 글

[webhacking.kr] 13번 문제  (1) 2017.06.19
[webhacking.kr] 58번 문제  (0) 2017.06.18
[webhacking.kr] 54번 문제  (0) 2017.06.18
[webhacking.kr] 53번 문제  (0) 2017.06.18
[webhacking.kr] 49번 문제  (0) 2017.06.18
Posted by Imp3rio
Wargame/webhacking2017. 6. 18. 22:37

webhacking.kr 58번 문제를 보면 다음과 같다.


일단 페이지 소스를 열어보자.

kk.js 파일과 kk2.js 파일이 있다. 그리고 hackme.swf 파일도 있다.

hackme.swf 이 파일을 분석해야 되는 것 같다.

클릭해 들어가보자.

처음 화면과 다를게 없다.

이를 hackme.swf 라는 이름으로 저장하자.

safari에서 저장하면 제대로 저장되지 않는다. 그래서 firefox를 열고 해당 페이지를 다운받았다.


다운받은 파일을 hex에디터로 열어보면 다음과 같은 화면을 볼 수 있다.

맨 아래 부분쪽에 가면 url이 나오는데 이 url로 이동하면 문제가 풀린다.


'Wargame > webhacking' 카테고리의 다른 글

[webhacking.kr] 13번 문제  (1) 2017.06.19
[webhacking.kr] 21번 문제  (0) 2017.06.18
[webhacking.kr] 54번 문제  (0) 2017.06.18
[webhacking.kr] 53번 문제  (0) 2017.06.18
[webhacking.kr] 49번 문제  (0) 2017.06.18
Posted by Imp3rio
Wargame/webhacking2017. 6. 18. 22:16

webhacking.kr 54번 문제를 보면 다음과 같다.

처음 화면이 위와 같고, 시간이 지나면 password를 한글자씩 보여준다.

노가다 식으로 하나하나 받아 적어도 되지만, 일단 페이지 소스를 보도록하자.

소스를 보다보면 answer() 함수가 정의되어 있는 것을 볼 수 있다.

function answer(i)

{

x.open('GET','?m='+i,false);

x.send(null);

aview.innerHTML=x.responseText;

i++;

if(x.responseText) setTimeout("answer("+i+")",100);

if(x.responseText=="") aview.innerHTML="?";

}

aview.innerHTML 부분에 저장된 값이 출력이 되며, x.responseText에 한글자가 저장되기 때문에 한글자씩 출력이 된다.

즉, aview.innerHTML=x.responseText에서 "="를 "+="로 변경해주면 한글자씩 뒤에 붙을 것이다.

마지막 if문을 보면 x.responseText가 null이면 aview.innerHTML에 "?"를 저장한다.

즉, 마지막에 ?를 출력하게 된다.

이를 없애주면 될 것 같다.

burp suite를 이용해 response를 변조하도록 하자.

그러면 위와 같이 password가 한글자씩 뒤에 붙으면서 출력이 된다.

이 값을 Auth에 입력하면 문제가 풀린다.

'Wargame > webhacking' 카테고리의 다른 글

[webhacking.kr] 21번 문제  (0) 2017.06.18
[webhacking.kr] 58번 문제  (0) 2017.06.18
[webhacking.kr] 53번 문제  (0) 2017.06.18
[webhacking.kr] 49번 문제  (0) 2017.06.18
[webhacking.kr] 46번 문제  (0) 2017.06.18
Posted by Imp3rio
Wargame/webhacking2017. 6. 18. 21:59

webhacking.kr 53번 문제를 보면 다음과 같다.

hello wolrd 문자열만 출력되고 아무것도 없다.

일단 페이지 소스를 열어보자.

index.phps 가 주어졌다. 열어보자.

코드를 분석해보자.

hidden_table 변수에 물음표가 문자열로 저장되어 있다.

GET 방식으로 answer 를 전달받으며 이 값이 hidden_table의 값과 같으면 문제가 풀린다.

GET 방식으로 val 을 전달받으며 필터링을 거친다.

val 값을 이용해 select문을 통해 test1 값을 뽑아내며 그 값을 변수 f에 저장한다.

f에 값이 있으면 table name음 입력 하는 form이 생성된다.


일단 val값을 1부터 넣어보자.

위와 같은 화면이 나오며, 2는 guest, 3은 admin, 4는 zombie가 출력이 되며 5부터는 존재하지 않는다.

val 값을 이용해서 테이블 명을 뽑아내야 한다.

이를 위해 사용할 수 있는 것은 mysql 함수인 procedure analyse()이다.

이 함수는 필드명, 최소값, 최대값, 최소길이, 최대길이 등 해당 테이블의 정보를 나타내주는 함수이다.

필드명에는 데이터베이스명.테이블명.칼럼명이 들어있다.

즉, 이를 이용해 테이블명을 확인할 수 있다.

쿼리문을 다음과 같이 만들도록 val 값을 입력하자.

select test1 from $hidden_table where test2=1 procedure analyse()


다음과 같이 테이블명을 알 수 있다.

이 값을 입력하면 문제가 풀린다.

'Wargame > webhacking' 카테고리의 다른 글

[webhacking.kr] 58번 문제  (0) 2017.06.18
[webhacking.kr] 54번 문제  (0) 2017.06.18
[webhacking.kr] 49번 문제  (0) 2017.06.18
[webhacking.kr] 46번 문제  (0) 2017.06.18
[webhacking.kr] 39번 문제  (0) 2017.06.18
Posted by Imp3rio
Wargame/webhacking2017. 6. 18. 21:14

webhacing.kr 49번 문제는 다음과 같다.

46번 문제와 비슷한 문제인 것 같다.

우선 페이지 소스를 보자.

index.phps 가 주어져있다. 들어가 보자.

우선 코드를 분석해보자.


GET 방식으로 lv 를 전달받으며, lv에 값이 있을 때 union, from 등을 필터링하며 해당 문자열이 존재하면 아무것도 안하고 종료한다.


46번 문제와 비슷한 맹락인 것 같다.


일단 쿼리문을 다음과 같이 만들면 될 것 같다.

select id from members where lv=x or id='admin'


여기서 x는 1을 제외한 임의의 숫자다. 그 이유는 1은 zzibong을 가리키기 때문이다.

그런데 공백과 or은 필터링되기 때문에 사용할 수 없다.

or을 ||로 변경하고 공백은 없이 입력해보자.

즉, 쿼리문은 다음과 같다.

select id from members where lv=3||id='admin'


처음 화면이 나타난다.

" ' "를 없애는 기능이 켜져 있는 것 같다.

char() 함수를 이용하려고 하니까 "("와 ")"는 필터링되어 있다.

0x가 필터링되지 않았기 때문에

0x를 이용해 쿼리문을 다음과 같이 만든다.

select id form members where lv=3||id=0x61646d696e

그러면 문제가 풀린다.


이번 문제 역시 입력창에 입력하면 안되고 URL에 직접 입력해야 한다.

'Wargame > webhacking' 카테고리의 다른 글

[webhacking.kr] 54번 문제  (0) 2017.06.18
[webhacking.kr] 53번 문제  (0) 2017.06.18
[webhacking.kr] 46번 문제  (0) 2017.06.18
[webhacking.kr] 39번 문제  (0) 2017.06.18
[webhacking.kr] 38번 문제  (0) 2017.06.18
Posted by Imp3rio
Wargame/webhacking2017. 6. 18. 20:51

webhacking.kr 46번 문제를 보면 다음과 같다.

우선 SQL INJECTION이라고 출력되어 있으니 SQL INJECTION 문제인 것 같다.

일단 페이지 소스를 보자.

index.phps가 힌트로 주어졌으니 일단 들어가 소스를 보도록 하자.

소스코드를 분석해보자.

GET 방식으로 lv 값을 전달받으며, lv 값에 공백, /, *, % 가 있으면 없앤다.

그리고 union, select, from, challenge, 0x, limit, cash 가 있으면 종료한다.

select문을 이용해 가져온 데이터 값을 변수 q에 저장한다.

q 값이 있고, lv 값이 있으며 q[0]의 값이 admin이면 문제가 풀린다.


일단 1을 입력해 보면 다음과 같은 화면을 볼 수 있다.

lv 값을 1로 넘겼을 때 변수 q의 값은 "zzibong"인 것을 알 수 있다.

다른 값을 넘기면 아무것도 출력이 되지 않는다.


우선 query문을 다시 보자

select id,cash from members where lv=$_GET[lv]

이를 우회하기 위해 다음과 같은 쿼리문을 만들면 될 것 같다.

select id,cash from members where lv=x or id='admin'

x는 1이 아닌 임의의 값이면 된다.

이유는 lv=1은 zzibong의 값이기 때문이다.


위에서 처럼 쿼리문을 만들 때 공백을 넣으면 안된다. 입력된 값에서 공백을 없애버리는 필터링이 걸려있기 때문이다. 이를 우회하기 위해서는 %0A나 %0D를 이용하면 된다.

또한 입력창에 입력을 하면 안된다. 그 이유는 입력창에 입력된 값은 GET 요청을 할 때 URL 인코딩이 되어 전달되기 때문이다. 따라서 URL에 직접 입력을 해야 한다.

아래와 같은 공격구문을 URL에 넣으면 다음과 같은 화면을 볼 수 있다.

3%0Aor%0Aid='admin'

처음 화면이 나타난다.

" ' "를 없애는 기능이 켜져있는 것 같다.

이를 우회하기 위해 char() 함수를 이용한다.

다음과 같이 입력을 하면 문제가 풀린다.

3%0Aor%0Aid=char(97,100,109,105,110)



'Wargame > webhacking' 카테고리의 다른 글

[webhacking.kr] 53번 문제  (0) 2017.06.18
[webhacking.kr] 49번 문제  (0) 2017.06.18
[webhacking.kr] 39번 문제  (0) 2017.06.18
[webhacking.kr] 38번 문제  (0) 2017.06.18
[webhacking.kr] 35번 문제  (0) 2017.06.18
Posted by Imp3rio
Wargame/webhacking2017. 6. 18. 20:25

webhacking.kr 39번 문제를 보면 다음과 같다.

입력창 말고는 아무것도 없다.

우선 페이지 소스를 보면 다음과 같다.

index.phps가 힌트로 주어져있다.

일단 들어가 보도록 하자.

소스가 나와 있다. 분석을 해보자.


pw 변수에는 물음표가 문자열로 저장되어 있다.

POST 방식으로 받은 id에 값이 있으면 " \ "는 없애고, " ' "는 " '' "로 바꾼다.

substr() 함수를 이용해 id 값을 15글자로 잘라낸다.

select 문으로 데이터를 가져온다.

가져온 데이터가 "good"이면 문제가 풀린다.

그런데 select문을 자세히 보면 " ' "가 안닫혀 있다.

즉, 입력할 때 '를 반드시 입력해야 한다는 것이다.

하지만 " ' "를 입력하면 " '' "로 변환되기 때문에 문제가 된다.

어떻게 해야 할까 고민하면서 코드를 다시 보니

substr()함수를 이용해 15글자를 잘라낸다.

즉, 15번째 글자가 " ' "이면 총 16글자가 되며 마지막 두글자는 " '' "이다.

하지만 substr() 함수를 이용해 15글자로 잘라내기 때문에 " ' "를 입력할 수 있다.


이를 이용해 문제를 해결하면 된다.

admin         ' 을 입력하면 다음과 같이 문제가 풀린다.


'Wargame > webhacking' 카테고리의 다른 글

[webhacking.kr] 49번 문제  (0) 2017.06.18
[webhacking.kr] 46번 문제  (0) 2017.06.18
[webhacking.kr] 38번 문제  (0) 2017.06.18
[webhacking.kr] 35번 문제  (0) 2017.06.18
[webhacking.kr] 23번 문제  (0) 2017.06.09
Posted by Imp3rio