phase1 풀이 : https://warroom.tistory.com/114

 

[Bomb_lab]-Phase 1

해당 문제를 실행하면 이런 문장이 보여집니다.. 우선 gdb를 이용해 천천히 분석해보겠습니다. 해당 문제는 보호기법이 심하게 걸려있지 않아 코드를 그대로 볼 수 있게 되어있었습니다. 보면 우선 read line 함..

warroom.tistory.com

 

다음 문제를 풀어보겠습니다.

이번에는 phase_2를 분석해 보기 위해 0x12a4로 접근합니다

phase_2

보시면 우선 read_six_numbers라는 함수가 눈에 띔으로 해당 함수부터 분석을 하겠습니다.

read_six_numbers

우선 sscanf함수가 쓰인것을 볼 수 있습니다. 코드를 보면 0x2d51에 있는 문자열을 확인해 값을 몇개나 입력 받는지 알 수 있을 것 같습니다.

물론 해당 문자열확인 방법 외에도 sscanf함수가 인자를 6개 받는다는 것을 알 수 있습니다. 64bit Linux 운영체제에서는 인자값을 전달하는 레지스터를 순서대로 사용합니다. `rdi, rsi, rdx, rcx, r8. r9`가 해당 순서입니다. 따라서 위  read_six_numbers함수의 코드를 보시면 rsi에 해당하는 값이 이미 존재하는 상태에서 rdx에 값을 그대로 넣고, rcx에는 `rsi+0x4`, r8에는 `rsi+0x08`순으로 들어가게 됩니다. 해당 코드를 대충 생각해 보면 `sscanf("data1, "%d %d %d %d %d %d", data2, data2+4, data2+8. data2+ 12, data2+16, data+20)`이런 식으로 코드가 작성 되었다는 것을 생각할 수 있습니다. 그 뒤에 eax값과 5를 비교하는 코드가 존재합니다. jle임으로 `eax<=5`일 경우 explode_bomb로 가는 것을 알 수 있습니다. 따라서 eax는 6이여야 합니다. (참고로 eax는 sscanf의 return값)

 

자 이제 다시 read_six_numbers로 돌아가 생각해 보면 위 부분이 핵심인 것을 알 수 있습니다. `mov rsi, rsp`코드는 rsi에 rsp의 스택주소를 넘겨주고 해당 값을 인자로 받습니다. 해서 위에서 `rsi+알파`가 들어간 것입니다. rsi에 들어간 값들은 rsp에서 offset값으로 주소를 참조하면 각각 값이 들어있는것을 볼 수 있습니다. 다음  코드들을 보면 `DWORD PTR [rsp], 0x0`과 `DWORD PTR [rsp+0x4], 0x1`가 작성되어있습니다 DWORD PTR은 4바이트씩 참조한다는 말이고, []는 주소를 참조한다는 말 임으로, 아까 sscanf에서 넣어준 data2와 data2+4를 가르키는 것을 알 수 있습니다. data2 참일 경우와 data2+4가 1이 아닐 경우 참이여서 explode_bomb을 실행시키기 때문에 data2 = 0, data2+4 = 1인 것을 알 수 있습니다.

다음 핵심부분은 해당 코드 입니다.

보시면 rbx에 rsp주소를 담는것을 볼 수 있습니다. 그 뒤 phase_2+66으로 뛰어 eax를 사용해 연산하는 것을 볼 수 있습니다. 연산한 결과값을 rbx+8의 값과 비교하는데 해당 부분을 코드로 작성해보면 [rbx+8] = [rbx]+[rbx+4]가 됩니다. 따라서 해당 문제의 정답은 피보나치 수열이 된다는 것을 알 수 있습니다.

 

ps. 다른 문제들도 많이 풀어보았는데, 해당 문제는 보통 피보나치수열 혹은 2의 제곱수 나열이 정답인것 같습니다.

'computer_architecture > lab' 카테고리의 다른 글

[Bomb_lab]-Phase 3  (0) 2019.10.03
[Bomb_lab]-Phase 1  (0) 2019.09.11

해당 문제를 실행하면 이런 문장이 보여집니다.. 우선 gdb를 이용해 천천히 분석해보겠습니다.

main

해당 문제는 보호기법이 심하게 걸려있지 않아 코드를 그대로 볼 수 있게 되어있었습니다. 보면 우선 read line 함수를 이용해 입력을 받고, phase_1함수를 들어가는 것을 볼 수 있습니다.

phase_1

phase_1 함수를 열어보면 이런식으로 코드가 작성되어있는 것을 볼 수 있습니다.. 코드를 분석하면 `0x2aac`를 입력받은 값과 비교하는 strings_not_equal함수에 들어가는 것이 확인됩니다. 비교한 결과값이 같지 않을 경우 explode_bomb함수가 실행됩니다.

`0x2aac`를 보면 `Wow! Brazil is big.`이라는 문자열이 들어있는 것을 볼 수 있습니다.

해당 문자열을 입력하면 다음 단계로 넘어가는 것을 볼 수 있습니다.

 

아 참고로 해당 문제들은 파일마다 문제와 정답이 조금씩 다른 것 같습니다.

'computer_architecture > lab' 카테고리의 다른 글

[Bomb_lab]-Phase 3  (0) 2019.10.03
[Bomb_lab]-Phase 2  (0) 2019.09.11

heap공부를 하던 중 해당 사이트를 알았다.

https://github.com/scwuaptx/HITCON-Training

 

scwuaptx/HITCON-Training

For Linux binary Exploitation. Contribute to scwuaptx/HITCON-Training development by creating an account on GitHub.

github.com

위 사이트를 clone하면 터미널에 설치할 수 있다.

$ cd ~
$ git clone https://github.com/scwuaptx/HITCON-Training.git 
$ cd HITCON-Training && chmod u+x ./env_setup.sh && ./env_setup.sh

위 처럼 명령어를 치자.

$ apt-get install docker docker.io

docker을 이용해야 함으로 docker도 설치.

$  cd HITCON-Training
$ ./docker.sh

docker.sh를 실행시켜주자.
참고로 생각보다 좀 오래걸리는듯하다.

$ Got permission denied while trying to connect to the Docker daemon socket at unix......

docker.sh를 실행했을 때, 이런식으로 에러가 뜨는 경우가 있는데

$ sudo usermod -a -G docker $USER
$ sudo service docker restart

이런 식으로 명령어를 쳐주고 다시 실행해보자.
그래도 에러가 뜰 경우 우분트를 껏다 켜보면 된다.

참고

http://www.kwangsiklee.com/2017/05/%ED%95%B4%EA%B2%B0%EB%B0%A9%EB%B2%95-solving-docker-permission-denied-while-trying-to-connect-to-the-docker-daemon-socket/

불러오는 중입니다...

 

아...정말로 이 문제 풀다가 pwnable과 손절할뻔 했다....

우선 main문은 별게 없다. 그냥 buf에 보고싶은 값을 10진수로 입력받으면 해당 값을 주소로 변환해서 출력해주고, src에 값을 입력해주면 print_message에서 출력해준다음 끝나는 문제이다.

print_message함수를 자세히 보면 dest에 데이터를 넘겨주고 출력하는데 아까 main문에서 본 read함수의 입력값보다 dest의 값이 훨씬 작음으로 bof가 일어난다. 해당 함수의 ret를 잘 덮어 system함수값을 입력해주면 끝날 것 같다......라고 생각했는데 libc의 sh를 사용하지 않고 풀어야했다.(문제 난이도 급상승...)

일단 sh를 적을 공간이 필요했는데, bss에 적기에는 여분의 공간이 너무 적었다....해서, 스택을 이용해 문제를 풀기로 했다.

스택에 "sh"를 넣고 슥 풀면 문제가 해결된다. (절대 쓰기 귀찮아서 안쓰는게 아님)

'war game > game' 카테고리의 다른 글

[practice]-2015410208  (0) 2019.08.17
[practice]-2015410212  (0) 2019.08.12
[practice]-19950320  (0) 2019.07.28
[practice]-daRk_TempLer  (0) 2019.07.23
[practice]-rain_dROP  (0) 2019.07.23
Writer - hoodbilen

pwntools란?


시스템해킹(pwnable)에 필요한 기능들을 최대한 집대성해 만든 파이썬 모듈이다. 실제로는 프레임워크라고 더 자주 표현한다.

How to install?


$ apt-get update
$ apt-get install python2.7 python-pip python-dev git libssl-dev libffi-dev build-essential
$ pip install --upgrade pip
$ pip install --upgrade pwntools

추가 정보는 아래 확인.

https://github.com/Gallopsled/pwntools

USE


$ vi test.py
$ python test.py

이런 식으로 작성하고, 실행시킬 수 있다.

process & remote


process함수는 로컬 바이너리에 대해 익스플로잇을 테스팅해볼 때 사용하는 함수이고, remote함수는 원격 서버를 대상으로 실제 익스플로잇을 작동시킬 때 사용하는 함수이다.

from pwn import *
p = process('./test') # local 파일 test를 대상으로 exploit 실행함.
p = remote('warroom.kr', 123456) # warroom.kr의 123456번 포트에 있는 바이너리를 대상으로 exloit 실행함.

send


pwntools에는 send와 관련된 다양한 함수가 있다.

from pwn import *
p = process('./test')

p.send('A') # ./test에 'A'를 입력한다.
p.sendline('A') # ./test에 'A'+'\n'을 입력한다.
p.sendafter('hello', 'A') # ./tets가 'hello'를 출력하면, 'A'를 입력한다.
p.sendlineafter('hello', 'A') # ./test가 'hello'를 출력하면 'A'+'\n'을 입력한다.

send, sendline, sendafter, sendlineafter 을 사용할 때는 process값을 받은 p.를 꼭 붙여주어야 한다.

recv


pwntools에는 recv와 관련된 다양한 함수가 있다.

from pwn import *
p = process('./test')

data = p.recv(1024) # p가 출력하는 데이터중 최대 1024바이트의 데이터를 받아서 data에 저장
data = p.recvn(5) # p가 출력하는 데이터중 정확히 5바이트를 받아서 data에 저장
data = p.recvline() # p가 출력하는 데이터중 개행문자를 만날 때 까지를 data에 저장
data = p.recvuntil('hello') # hello라는 문자열을 p가 출력할 때 까지 받아서 data에 저장
data = p.recvall() # 연결이 끊어지거나 프로세스가 종료될 때까지 받아서 data에 저장

주의해서 봐야할 것은 p.recvp.recvn 의 차이점인데, p.recv()는 최대 n 바이트를 받는 것 이기 때문에, 1024바이트를 다 채워 받지 못해도 에러를 발생시키지 않지만, p.recvn()의 경우 정확히 인자만큼의 데이터를 받지 못하면 계속 대기한다.

recv,recvline,recvn,recvuntil, recvall은 불필요한 문자까지 입력받은 후 send를 할때도 사용할 수 있다. 불필요한 문자를 입력받을 때는 data = 를 제외하고 p.recvline() 처럼 단독으로 사용하면 된다.

packing & unpacking


대부분의 CPU는 little endian을 이용한다. 익스플로잇을 작성하다 보면 어떤 값을 little endian스트링으로 변경하거나, 또는 역의 과정을 거쳐야 하는 경우가 자주 있는데, 이를 쉽게 할 수 있도록 pwntools에서는 함수로 제공한다.

ex)

#test.py
from pwn import *

data32 = 0x41424344
data64 = 0x4142434445464748

print p32(data32)
print p64(data64)

data32 = "ABCD"
data64 = "ABCDEFGH"

print hex(u32(data32))
print hex(u64(data64))
$python test.py
DCBA
HGFEDCBA
0x44434241
0x4847464544434241

log


from pwn import *
context.log_level = 'debug' # 서버 혹은 바이너리와 이 익스플로잇간에 오고가는 모든 데이터를 화면에 hexdump형식으로 출력해줌

debug


from pwn import *
p = process('./test')
gdb.attach(p)

익스플로잇을 실행하는 중간에 debug를 하고 싶을때 원하는 위치에서 위 명령어를 사용하면 새 창에서 해당 프로그램이 gdb로 보여진다. 정확하게 원하는 값이 채워졌는지, 릭이 정확하게 되었는지, 스택주소, 데이터 등을 볼 때 유용하다.

interactive


쉘을 획득한 경우이거나, 익스플로잇의 특정 경우에 직접 입력을 주면서 디버깅을 해보고 싶다면 사용하게 되는 함수. 익스플로잇과 프로세스와의 연결을 stdin, stdout <=> process로 바꿔준다.

pwntools 익스플로잇이 끝났을 때 쉘을 따지 않아도 $ 가 나오는 이유가 이것 때문이다.

from pwn import *
p = process('./test')
p.interactive()

ELF


리눅스에서 작동하는 실행파일 ELF 에는 각종 정보가 기록되어 있다. 그 중 대표적인 것이 GOT, PLT 인데, pwntools를 통해 이런 값들을 쉽게 구해올 수 있다.

from pwn import *
e = ELF('./test')
puts_plt = e.plt['puts'] # ELF ./test에서 puts()의 PLT주소를 찾아서 puts_plt에 넣는다.
read_got = e.got['read'] # ELF ./test에서 read()의 GOT주소를 찾아서 read_got에 넣는다.

해당 문서는 pwntools를 사용하면서 자주 마주치는 함수들에 대해서만 간략히 소개한 문서이다.

자세한 사용법을 알고싶은 사람은 아래 공식 주소를 참고.

https://docs.pwntools.com/en/stable/index.html

'hacking > tool' 카테고리의 다른 글

mac IDA create structure  (0) 2019.08.08

+ Recent posts