기본 콘텐츠로 건너뛰기

SHA-2017-Teaser-Round_Website Attack

SHA-2017 Teaser-Round Network

Website Attack write up

문제 풀이를 위한 pcap파일이 주어진다.

PCAP 은 Packet Capture 의미로 네트워크 트래픽을 캡쳐하기 위한
API 로 구성이 되어 있다. 윈도우로 포팅되어 있는 것은 WinPcap 이며, 유닉스 환경에서는 libpcap 이다. libpcap 과 winpcap 라이브러리를 이용하여 캡쳐된 패킷을 파일로 저장하거나, 저장된 패킷을 읽고 또는 다른 프로그램에서 라이브러리를 이용해 패킷파일을 분석/편집 등을 할 수 있다. 이를 이용한 대표적인 패킷 캡쳐 프로그램이 tcpdump 나 wireshark 이다.
출처 : 패킷인사이드

와이어 샤크를 이용하여 pcap을 열어보면 TCP, IPA 패킷이 저장되어 있는 것을 확인할 수 있다. IPA 패킷 내용을 확인해보면 HTTP 패킷으로 보이므로 분석의 용이성을 위해서 HTTP 패킷으로 변환하여 분석하도록 한다.

Wireshark -> Analyze -> Enabled Protocol -> GSM over IP 체크 해제
참고 URL
Data which has been sent over TCP\IP has been recognized by wireshark as “IPA” Protocol
[Malformed Packet: GSM over IP]

패킷의 흐름을 살펴보면 다음과 같다.

Created with Raphaël 2.1.2237237208208GET /?action=search&word=&sort=stockEncrypt/Encoding302 FoundGET /?action=display&what=[encrypt string]

여기서 word의 값만 변경되는 데 총 3개의 word를 요청한다.

kl
Trad
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

각각의 word 값을 암호화된 값에 짝지어보면 다음과 같다.

kl : ce3926706794d911
Trad : f1274d671988ce151a0b
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA : e4146d4252bafb3b38212df186497a7479d5e95af4796e7573a65e6849952032e4146d4252bafb3b38212df186497a7479d5e95af4796e7573a65e6849952032e4146d4252bafb3b38212df186497a7479d5e95af4796e7573a65e6849952032e4146d4252bafb3b38212df186497a7479d5e95af4796e7573a65e6849952032e4146d4252bafb3b38212df186497a74799edb6fda5b44

여기서 문자열 수에 관련된 한 가지 규칙을 찾을 수 있다.

평문 평문 문자열 수 암호화한 문자열 수 문자열 수 방정식
kl 2 16 16 = 2x + y
Trad 4 20 20 = 4x + y
A*146 146 302 302 = 146x + y

암호화 키 재사용 시 평문 문자열로 복호화가 가능한 취약점이 있는 RC4 평문공격을 시도해보자.

RC4 알고리즘은 암호화 키를 이용하여 긴 바이트 문자열(키 스트림)을 생성한 후 긴 바이트 문자열(키 스트림)을 이용하여 일반 텍스트와 함께 암호문을 생성한다.

만약 우리가 다른 평문 문자열과 암호화한 문자열을 알고 있고 암호화 키가 동일하다면 다음과 같이 식을 세울 수 있다.

두 식을 합치면 다음과 같은 결론을 얻을 수 있다.

RC4 , Is it possible to find the key if we know the plaintext and ciphertext?

POC

targetCipher = "af7d6f4240be9a2d31252290ef5b7e797dd7fc3be66d6d6766b5375a79b84d42"
sourceCipher= "e4146d4252bafb3b38212df186497a7479d5e95af4796e7573a65e6849952032"
plainText = "4141414141414141414141414141414141414141414141414141414141414141"
result = ""
for i in range(len(targetCipher) / 2):
        aa = ord(targetCipher[i*2:i*2 + 2].decode('hex'))
        bb = ord(sourceCipher[i*2:i*2 + 2].decode('hex'))
        cc = ord(plainText[i*2:i*2 + 2].decode('hex'))

        result = result + chr(aa ^ bb ^ cc)
print result

파이썬 코드를 실행해보면 (CASE WHEN (SELECT SUBSTR(sql,1이 출력되는 것을 확인할 수 있다.
동일한 방법으로 다른 암호문을 복호화 해보자. WiresharkExport Object -> HTTP기능을 사용하면 HTTP 패킷만 따로 저장할 수 있다. 해당 기능을 이용하여 패킷을 저장한 후 파이썬 스크립트를 수행하자.

from os import listdir
fileNames = listdir("/Users/seungyonglee/ctf/sha_2017/HTTP")

for fileName in fileNames:
    cipherString = fileName[23:]
    result = ""
    for I in range(len(cipherString) / 64 + 1):
            a = cipherString[I*64:(I+1)*64]
            b = "e4146d4252bafb3b38212df186497a7479d5e95af4796e7573a65e6849952032"
            c = "4141414141414141414141414141414141414141414141414141414141414141"
            for i in range(len(a) / 2):
                    aa = ord(a[i*2:i*2 + 2].decode('hex'))
                    bb = ord(b[i*2:i*2 + 2].decode('hex'))
                    cc = ord(c[i*2:i*2 + 2].decode('hex'))

                    result = result + chr(aa ^ bb ^ cc)
    print result

실행 결과 다음과 같이 Blind SQL Injection 수행 문자열을 확인할 수 있다.

(CASE WHEN (SELECT SUBSTR(flag,5,1) FROM secret_flag LIMIT 0,1) = ‘{’ THEN stock ELSE price END
(CASE WHEN (SELECT SUBSTR(flag,5,1) FROM secret_flag LIMIT 0,1) = ‘z’ THEN stock ELSE price END
(CASE WHEN (SELECT SUBSTR(flag,5,1) FROM secret_flag LIMIT 0,1) = ‘y’ THEN stock ELSE price END
(CASE WHEN (SELECT SUBSTR(flag,5,1) FROM secret_flag LIMIT 0,1) = ‘x’ THEN stock ELSE price END
(CASE WHEN (SELECT SUBSTR(flag,5,1) FROM secret_flag LIMIT 0,1) = ‘s’ THEN stock ELSE price END
(CASE WHEN (SELECT SUBSTR(flag,5,1) FROM secret_flag LIMIT 0,1) = ‘r’ THEN stock ELSE price END
(CASE WHEN (SELECT SUBSTR(flag,5,1) FROM secret_flag LIMIT 0,1) = ‘q’ THEN stock ELSE price END

공격에 성공한 값만 보기 위해서 스크립트를 수정하자.

from os import listdir

fileNames = listdir('/Users/seungyonglee/ctf/sha_2017/HTTP')

# Decrypt routine, without changes
def decrypt(z):
    result = ""
    for I in range(len(z) / 64 + 1):
        a = z[I*64:(I+1)*64]

        b = "e4146d4252bafb3b38212df186497a7479d5e95af4796e7573a65e6849952032"
        c = "4141414141414141414141414141414141414141414141414141414141414141"
        for i in range(len(a) / 2):
            aa = ord(a[i*2:i*2 + 2].decode('hex'))
            bb = ord(b[i*2:i*2 + 2].decode('hex'))
            cc = ord(c[i*2:i*2 + 2].decode('hex'))

            result = result + chr(aa ^ bb ^ cc)
    return result

# A flag placeholder (string is immutable :/ )
flag = [' ' for _ in range(40)]

# For all files
for fileName in fileNames:
    f = open('/Users/seungyonglee/ctf/sha_2017/HTTP/' + fileName, 'r')
    fc = f.read()
    # If it's a hit (the ordering of products is different)
    if fc.find('hyper') < fc.find('Traditional'):
        # fileName[23:] == Get only the ciphertext from filename
        r = decrypt(fileName[23:])

        # If the SQLi attempt targeted flag (not the SQL schema!)
        if r.find('flag') != -1:
            chi = r.find("'") + 1
            if chi != 0:
                ch = r[chi]
            indi = r.find(',') + 1
            if indi != 0:
                ind = r[indi:indi+2]
                if ind[1] == ',':
                    ind = ind[0]
            if chi != 0:
                print ind, ch
                flag[int(ind)] = ch

print ''.join(flag)

flag가 출력되는 것을 확인할 수 있다.

flag{7307e3ee8da198ca4a7f9b1f8b018d8e}

출처: Website Attack (Network).md

이 블로그의 인기 게시물

데일 카네기 인간관계론 정리

Remove-Server-Header

응답 메시지 내 서버 버전 정보 제거 1. Apache 1) 조치 방법 “/etc/htpd/conf/httpd.conf” 파일 안에서 1. ServerTokens OS → ServerTokens Prod 2. ServerSignature On → ServerSignature Off 로 변경한 후 아파치를 재시작하면 헤더 값의 아파치 버전 정보 및 OS 정보를 제거할 수 있다. 2) 참고 URL http://zetawiki.com/wiki/CentOS_ 아파치_보안권장설정_ServerTokens_Prod,_ServerSignature_Off 2. IIS 1) 조치 방법 IIS 6.0 urlscan_setup 실행. 설치. \windows\system32\inetsrv\urlscan\urlscan.ini 파일을 열어 다음 수정(RemoveServerHeader=0 을 RemoveServerHeader=1 로 변경) 서비스에서 IIS Admin Service 재시작. IIS 7.0 IIS 관리자를 열고 관리하려는 수준으로 이동합니다. 기능 보기에서 HTTP 응답 헤더를 두 번 클릭합니다. HTTP 응답 헤더 페이지에서 제거할 헤더를 선택합니다. 작업 창에서 제거를 클릭하고 예를 클릭합니다. 2) 참고 URL IIS 6.0 : http://gonnie.tistory.com/entry/iis6- 응답헤더-감추기 IIS 7.0 : https://technet.microsoft.com/ko-kr/library/cc733102(v=ws.10).aspx 3. jetty 1) 조치 방법 “jetty.xml” 파일에서 jetty.send.server.version=false 설정 2) 참고 URL http://attenuated-perspicacity.blogspot.kr/2009/09/jetty-61x-hardening.html 4. Nginx ...

American Fuzzy Lop And Address Sanitizer

American Fuzzy Lop And Address Sanitizer Address Sanitizer(ASAN) 단지 gcc/clang에 -fsanitize=address 옵션을 추가하는 것으로 간단히 사용할 수 있지만 그 효과는 충분하다. Example Out Of Bounds Read #include <stdio.h> int main() { int a[ 2 ] = { 3 , 1 }; int i = 2 ; printf ( "%i\n" , a[i]); } 예제 파일을 OutOfBoundsRead.c 로 생성하고 ASAN 옵션을 지정하여 clang 으로 컴파일하자. clang -g -fsanitize = address -fno -omit -frame -pointer OutOfBoundsRead . c -o OutOfBoundsRead 생성된 OutBoundsRead 파일을 실행하면 다음과 같은 결과를 볼 수 있다. ================================================================= ==3678==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc0ba87428 at pc 0x47b7db bp 0x7ffc0ba87390 sp 0x7ffc0ba87388 READ of size 4 at 0x7ffc0ba87428 thread T0 ==3678==WARNING: Trying to symbolize code, but external symbolizer is not initialized! #0 0x47b7da (/root/ASAN/OutOfBoundsRead+0x47b7da) #1 0x7faba0260f44 (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) #2 0x...