728x90

 

이 문제는  blind sql injection문제이다. 이부분에 대해서는 나중에 따로 정리할것이다. 일단 이 문제를 풀어보자. 일단 비밀번호의 길이를 알아내야된다. 그것까지 코딩하려고 했는데 그냥 귀찮아서 대충 추측해보았다.

 

 

비밀번호의 길이가 10이하라고 넣으니 참이 나왔다. 그럼 5이하라고 넣어보자.

 

 

그랬더니 거짓이 나왔다. 이제 중간인 7로 해보자.

 

 

거짓이 나왔다. 그럼 이제 8부터 넣어보자.

 

 

비밀번호의 길이는 8이였다. 운좋게 길이가 얼마 안되서 금방 찾았다. 길이를 아는것만으로도 시간을 많이 단축시킬수있다. 이제 코딩을 해보자. 나는 파이썬으로 보통 코딩을 한다.

 

 

결과값이 28초 정도만에 나왔다. 이제 저걸 그냥 넣으면 된다. ?pw=295d5844라고 쳐보자.

 

 

문제가 풀렸다. 다른 blind sql injection에 비해서는 쉬운 문제였던것 같다.

 

 

728x90

 

이제는 goblin이다. 이 문제는 앞선 두 문제와 달리 쿼터들도 필터링하고 있다. 일단 no를 guest가 아니도록 맞춰줘야된다. 저 소스 코드만 보고는 guest의 no값을 모르니 걍 넣어보는게 좋을것같다.

 

no에 0부터 넣어보는데 바로 1에서 잡혔다. 그럼 1말고 다른값들을 넣으면 될것같다. 걍 0을 넣자. 그리고 이제 id를 admin으로 맞춰줘야되겠다. 일단 쿼터들을 필터링하고 있으니 걍 admin을 16진수값으로 변환하여 넣어주자. 물론 그냥 넣으면 숫자취급하니깐 0x를 붙여주긴 해야된다.

 

 

파이썬을 이용하여 간단하게 변환해주었다. 파이썬을 알기전에는 c로 몇줄 더 쳤어야됬는데 편해졌다. 일단 저 값을 이용하여 풀면 될것같다. 대충 페이로드를 짜보면 ?no=0 or id=0x61646d696e로 하면 풀릴것같다.

 

 

이렇게 풀리게된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90

 

이제 2번 문제로 왔다. 소스 코드를 보는데 아까 1번문제랑 거의 같았다. 다른건 id가 admin으로 와야된다는 것이다. 그래서 그냥 id를 admin으로 맞춰주고 뒤에 모든 구문을 주석처리해보자.

 

 

별다른 문제없이 풀렸다. 참고로 페이로드는 ?id=admin'%23이였다.

728x90

이곳의 문제는 소스코드를 그냥 화면에 표시해놓는다. 일단 소스코드를 살펴보면 일단 몇가지 것들을 막는것같다. 그런데 첫번째 문제라서 그렇게 많이 막는것은 아니라서 일단 간단하게 or로 풀면될 것 같다.

 

일단 기본적으로 php?id=a'or'1=1'%23으로 날려보자. 여기서 %23은 #을 의미하는데 여기서는 url에 치는것이므로 #을 url encoding해 준 값을 넣어주는것이다.

 

 

바로 풀렸다. 진짜 아주 기본적인 sql injection이였다.

728x90

 

문제를 들어가면 또 이렇게 아이디와 비밀번호를 입력할수있는 창만 주어져있다. 일단 들어와보니 저렇게 뭔가를 쳐놨다. 글자수보니 비밀번호도 guest로 했을 것 같다. 일단 Login을 눌려보자.

 

 

들어가보니 admin으로 로그인하면 풀리는 문제라고 친절하게 써줬다.

 

 

그리고 이 문제를 들어가기전에 힌트를 보면 저렇게 padding oracle 취약점을 아냐고 물어보고있다. 내가 앞에 문제들을 건너뛰고 이 문제를 푸는 이유기도 한 padding oracle 취약점은 이 블로그의 관련글에 설명해두었다.

 

 

일단 쿠키값을 보면 L0g1n이라는 이름으로 되어있고 값이 나와있다.

 

 

쿠키값이 무슨 역할을 하는지 알아보기 위해서 아무값이나 넣고 새로고침하니 iv가 유효하지 않다고 뜬다. 일단 그러면 guest를 암호화하려면 패딩은 무조건 했을것이다. 그리고 iv를 유추해야될것이다. 이래서 padding oracle attack을 쓰라고 한것같다. 저것들을 이용해서 코드를 짜보자. 일단 iv를 유추하고 그다음 xor연산을 이용하여 키를 만들면 될것이다.

 

 

10분정도 지나니 키가 나왔다. 아직 안익숙해서 그런지 굉장히 어려운 문제였다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

[wargame.kr] 13번 tmitter 풀이!!!  (0) 2017.12.27
[wargame.kr] 12번 type confusion 풀이!!!  (0) 2017.12.27
[wargame.kr] 11번 strcmp 풀이!!!  (0) 2017.12.27
728x90

 

문제를 들어가면 이런 글씨만 써져있다. 그럼 일단 소스를 보자.

 

 

 

어 소스를 보니 저기 밑쪽에 무슨 버튼이 있다고 한다. 저기 구석에 보니 버튼이 있다. 일단 소스도 봤으니 그냥 저것들 url뒤에 붙여보자.

 

 

그랬더니 이런 방대한 로그의 기록들이 나온다. 저기 위에 쿼리전송을 통해 필요한 값들을 찾으면 될것같다.

 

verb:get AND request:flag AND response:200

이렇게 입력해주면 될것같다. verb칸에는 get가 있으면 되고 request칸에는 flag가 들어가고 response에는 200이 뜨는 값을 AND로 묶어서 보내주자.

 

 

 

그랬더니 그거에 맞는 로그들이 나왔다. 그런데 보면 죄다 log.search.php가 앞에 붙어있는데 하나만 그게 없다. 그러면 쟤가 아마도 진짜 flag를 뱉어내는 아이일것이다. 한번 url에 쳐보자.

 

역시 flag를 뱉어냈다.

 

 

 

 

 

 

 

 

 

 

728x90

SSRF란?

SSRF는 Server-side Request Forgery의 약자이다. CSRF와 달리 서버가 직접 호출해서 발생하는 문제이다. 이를 통해서 외부에서 내부망에 대해 접근하거나 스캔하고 각종 보안장비들을 피해갈 수 있다.

 

SSRF는 사용자 입력을 받아 서버가 직접 다른 웹이나 포트에 직접 접근해서 데이터를 가져오는 기능들에서 주로 발생한다. 별로 없을 것 같은 기능이지만 실제로 굉장히 많이 쓰이고 있는 기능이다.

 

URI의 구조

일단 URI를 처음 들어본 사람도 있을것이다. URI를 간단히 설명하면 URL과 URN을 합친것이다. 물론 URL과 URN은 교집합이 존재한다. 간단히 예시를 들어보자.

 

http://www.skyhell.co.kr:80/main/photo.php?url=apple#top

 

위에 임의로 URI를 만들어 보았다. 이제 저 URI를 하나하나 분석해 보자.

 http: 

 프로토콜

 www

 서브도메인 

 skyhell

 도메인

 co

 ccTLD(Country Code Top Level Domain) 

 kr

 TLD(Top Level Domain) 

 80 

 포트

 main 

 경로 

 photo 

 페이지 

 php 

 확장자 

 url=apple 

 파라미터 

 top 

 Anchor 

 

위의 예시에서 http:에서 main까지가 URL이고 www부터 apple#까지가 URN이다. 그리고 그 두개를 합친것이 URI가 되는것이다.

URL Parser

각각의 언어들마다 URI을 분석하는 parser가 있다. 이 parser들은 분석하는 과정이 약간씩 다르고 parser도 완벽하지 않아서 모든 사용자의 입력을 예상할수 없다. 여기서 취약점이 나올 수 있다.

 

SSRF in cURL

이렇게 입력을 해주면 당연히 google로 접속해야 될것 같지만 korec 홈페이지로 접속이 됩니다. 어떻게 이런일이 일어났을까? URL parser들이 url을 분리하는 부분이 달라서 특정 부분들은 다시 도메인으로 인지시킬 수 있다. curl같은 경우에는 @의 오른쪽을 도메인으로 사용하기 때문에 웹에서는 google.com으로 인지하는것으로 끊어졌지만 내부 curl로 넘어오는순간 오른쪽 부분을 도메인으로 보고 호출하는 것이다.

 

위처럼 개행문자를 이용하는 방법도 있다. 지금 로컬서버로 연결을 끊어놔서 그렇지만 열어두면 앞에 로컬서버로도 들어가지고 뒤에 korec 홈페이지로도 들어가진다.

이것도 개행문자를 쓰는것과 비슷한데 간단히 CR과 LF를 이용하는 방법이다.

 

SSRF 공격

 

php는 http://Wrapper를 지원하기 때문에 fopen(), include/require, cURL등에 인자로 http://url형태를 넘겨 외부 도메인에 있는 리소스를 가져올 수 있다. http://이외에도 다양한 Wrapper를 사용할 수 있고 위의 함수들 뿐만 아니라 user input을 참고해서 외부 request를 보내는 상황이면 어디서든지 발생할 수 있다.

상위 디렉토리 우회는 " ../ "로 한다. 이때 웹서버 루트가 아니라 파일시스템 루트까지 가능하다.

확장자 우회는 " %00 ", " ? ", " # "으로 한다.

?url=http://localhost/server-status를 통해 localhost service에 접근한다.

?url=file:///etc/passwd를 통해 file system에 접근한다.

server application에서 사용하는 request방식에 따라 이 밖의 url schema도 사용할 수 있다. (dict://, gopher://, 1dap://)

 

이제 제대로 공격을 하는 방법을 보자

먼저 필터링 하지 않는 url을 알아야 된다.

http://127.0.0.1:20/?@google.com:80/

http://127.0.0.1:20/#@google.com:80/

http://google.com:80+&@google.com:80#+@127.0.0.1:22/

http://127.0.0.1:22/+&@google.com:80#+@google.com:80/

http://google.com:80+&@127.0.0.1:22/#+@google.com:80/

 

url blacklist라는 것이 있다. blacklist로 막은 것들은 우회가 가능하다.

http://hello@www.korec.kr/

아까 curl처럼 이것도 이렇게 하면 @의 왼쪽에 있는 것들은 무시된다. 원래는 id:pw@url 형식으로 사용하도록 되어있기 떄문이다.

 

그리고 이제 필터링 하지 않는 url을 찾아냈을때, 이를 이용해서 어떻게 localhost에 접근하는지 알아보자.

localhost등을 넘기다가 필터링 당하는 경우라던지 url schema를 gopher://등으로 변경해야 하는 경우, 또 데이터를 가공해야 되는 경우에 open redirect 취약점이 존재한다면 그것을 이용해 일단 내 서버로 요청하게 한 다음에 내 서버에서 요청을 적당히 처리하여 반환하도록 할수있다.

 

SSRF를 이용해 서버가 어떤 데이터를 수신했을때 그 데이터가 적절한 형태인지 체크한다면 형식을 맞춰주어야한다. 보통 Forged request를 보내는 타겟이 내 서버가 되기 때문에 형식을 맞춰 보내는것은 어렵지 않은데 victim으로 보내야되는 데이터가 php source같이 실행되어야 하는 경우 형식을 맞춰주면서 그냥 데이터가 되어버려서 실행이 되지 않는다. 그래서 이를 우회해야된다. command curl은 패턴을 지정하여 여러 request를 보낼수있는데 이때 모든 response가 concatenate되기 때문에 이를 이용해 형식을 맞출수있다.

curl http://mserv.com/[1-3].php

 

 

 

 

'Hacking > Web Hacking' 카테고리의 다른 글

NoSQL Injection  (0) 2018.01.21
728x90

내가 하는 스터디 활동중에 리버싱 문제를 만드는 활동이 있다. 그 활동을 하면서 구글링도 많이 해보고 주위에 잘하는 분들께도 많이 물어봤는데 구글링을 하면서 리버싱 문제를 푸는 블로그는 진짜 많은데 리버싱 문제를 만드는 블로그는 거의 없었다. 그래서 이번 포스팅은 내가 잘하시는 분들께 들은 것들과 내가 구글링하면서 찾은것들을 모아서 아주 간단한 리버싱 문제를 만들어 보는것으로 하려고한다.

 

 

일단 나는 visual studio 2017를 이용해서 문제를 만들었다. 컴퓨터를 포맷해서 버젼은 15.5.2이다. 기본적으로 이번 문제는 c++를 이용해서 만들어보려고 한다. c++를 좀더 능숙하게 쓰는데도 도움이 될것같다. 위와같이 기본적인 틀을 잡아보았다.

 

 

일단 이번 컨셉은 암호다. 간단한 암호를 코딩했다.

 

 

다른곳에서 미리 키를 암호화 해놓고 그 암호화된 암호문을 가지고 그 암호문을 복호화한 값을, 즉 평문을 넣었을때 cc를 리턴하는 함수 tt를 만들었다.

 

 

그리고 위와 같이 aa를 정의해주고 tt함수의 값을 #pragma를 이용하여 data segment에 있는 .bbs(비초기화 데이터 영역)에 올려준다. 이러면 헥스덤프를 떠도 나오지 않는다.

 

 

그리고 main문도 이렇게 완성해주면 된다.

#include 
#include 
using namespace std;

char *decrypt(char *dest, const char *encryptstr);

char *tt() {
	char *cc = new char[100];
	cc = decrypt(cc, "TzdsRecUbswJ");
	return cc;
}

string aa;
int count = 0;
#pragma data_seg (."kpnc")
string passwd = tt();
#pragma data_seg ()
string buff = " ";

int main() {
	cout << "input pw: ";
	cin >> aa;

	if (aa != passwd)
		cout << "input error!" << endl;
	else
		cout << "correct!" << endl;

	system("pause");

	return 0;
}

char *decrypt(char *dest, const char *encryptstr) {
	char *origin;
	for (origin = dest; *encryptstr; dest++, encryptstr++) {
		if (isupper(*encryptstr)) {
			*dest = (*encryptstr - 'A' + 21) % 26 + 'A';
		}
		if (islower(*encryptstr)) {
			*dest = (*encryptstr - 'a' + 16) % 26 + 'a';
		}
		if (isdigit(*encryptstr)) {
			*dest = (*encryptstr - '0' + 7) % 10 + '0';
		}
		if (isalnum(*encryptstr) == 0) {
			*dest = *encryptstr;
		}
	}
	*dest = '\0';

	return origin;
}

 

이렇게 하면 완성본이 나오게 된다. 아주 기본적인 암호+리버싱 문제가 완성되었다.

 

 

728x90

gdb-peda 설치하는법

 

1. git clone https://github.com/longld/peda.git ~/peda

2. echo "source ~/peda/peda.py" >> ~/.gdbinit

3. echo "DONE! debug your program with gdb and enjoy"

 

위 표의 3개를 순서대로 쳐주면 gdb-peda를 쓸수있다.

 

gdb-peda의 기능

 

 

그냥 disas main을 하면 일반 gdb처럼 글자색이 동일하다.

 

 

그러나 pdisas main을 하게되면 글자색이 구분되어 있어 훨씬 보기 편해진다.

 

 

또 메타스플로잇에 내장되어있는 패턴 페이로드 생성기가 peda에 내장되어 있어서 일일이 메타스플로잇에서 패턴을 생성하고 복붙하는 작업을 줄일수있다.

 

 

또한 pattern search를 사용하면 패턴 시작위치부터 EIP까지의 거리를 알수있다.

 

 

그리고 ropsearch "검색어"를 통해 쓸만한 가젯들을 찾아낼수도 있다.

 

 

 

그리고 공격 유형에 맞게 쉘코드를 생성해주는 기능도 있다.

 

 

또한 skeleton이라는 기능이 있는데 이 기능은 바이너리 공격 코드를 자동으로 생성해주는 기능이다. 바이너리 공격 형태와 생성할 파일명을 위와같이 설정해주면된다. 이러면 공격자는 생성된 파이썬코드의 일부만 수정하여 간편하게 공격을 할수있다.

 

#!/usr/bin/env python
#
# Template for local argv exploit code, generated by PEDA
#
import os
import sys
import struct
import resource
import time

def usage():
    print "Usage: %s target_program" % sys.argv[0]
    return

def pattern(size=1024, start=0):
    try:
        bytes = open("pattern.txt").read(size+start)
        return bytes[start:]
    except:
        return "A"*size

def nops(size=1024):
    return "\x90"*size

def int2hexstr(num, intsize=4):
    if intsize == 8:
        if num < 0:
            result = struct.pack("<q", num)
        else:
            result = struct.pack("<Q", num)
    else:
        if num < 0:
            result = struct.pack("<l", num)
        else:
            result = struct.pack("<L", num)
    return result

i2hs = int2hexstr

def list2hexstr(intlist, intsize=4):
    result = ""
    for value in intlist:
        if isinstance(value, str):
            result += value
        else:
            result += int2hexstr(value, intsize)
    return result

l2hs = list2hexstr

def exploit(vuln):
    padding = pattern(0)
    payload = [padding]
    payload += ["PAYLOAD"] # put your payload here
    payload = list2hexstr(payload)
    args = [vuln, payload]
    env = {"PEDA":nops()}
    resource.setrlimit(resource.RLIMIT_STACK, (-1, -1))
    resource.setrlimit(resource.RLIMIT_CORE, (-1, -1))
    os.execve(vuln, args, env)

if __name__ == "__main__":
    if len(sys.argv) < 2:
        usage()
    else:
        exploit(sys.argv[1])

 

이것이 sol.py의 소스코드이다.

 

 

context라는 기능도 있는데 이것을 치면 메모리/코드구조를 gdb에 비해 보기쉽게 나타내준다. 물론 context code라는 식으로 입력하면 따로따로 볼수도 있다.

 

 

그리고 또 find라는 명령어를 통해 특정 스트링도 찾을수있다.

 

 

 

checksec이랑 aslr이라는 명령어로 보호기법이 걸려있는지 체크도 할수있다.

 

마무리

위에 말했던 기능말고도 strings같은 굉장히 많은 기능들이 있다. phelp라는 명령어를 통해 한번 자세히 알아보면 좋을것같다.

 

 

 

 

 

 

 

 

 

 

 

'Hacking > Tool' 카테고리의 다른 글

yafu  (0) 2018.02.09
NoSQLMap  (0) 2018.01.22
728x90

 

이 문제에 대한 힌트이다. 32글자까지만 들어갈수있다. 이걸 이용해서 풀수있을것 같다.

 

이번 문제는 첫화면을 조금 신경써서 만든것 같다. 일단 admin이라는 id가 필요하다고 했으니 만들러 가보자. Sign Up을 클릭해보자.

 

 

와 이것도 예쁘게 꾸며놨다. 일단 소스를 보자.

 

 

소스를 보면 id와 pw에 길이제한이 걸려있다. 길이제한을 대충 늘린다음에 admin을 치고 띄워쓰기로 33번째에 a를 쳐서 admin으로 가입하는게 가장 좋을것같다. 그렇게 해주고 Sign in을 눌려보자.

 

 

왼쪽 상단에 이렇게 ID와 PW를 입력할수있는 창이 생겼다. 아까 가입한걸로 로그인 해보자.

 

 

이렇게 flag가 떴다. 이번것은 trim함수에 관한 취약점인것 같다.

 

 

 

+ Recent posts