Angr은 정적, 동적으로 Symbolic 분석에 사용된다.

INSTALL

pyenv

$ curl https://pyenv.run | bash

.bashrc 파일에 다음 내용을 추가한다.

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi
$ exec "$SHELL"
$ pyenv install 3.7.2

아마 뭐가 없다면서 에러가 발생할 것이다. 필요한 패키지를 설치해주자.

$ sudo apt-get install build-essential libffi-dev libbz2-dev zlib1g-dev libreadline-dev libsqlite3-dev libssl-dev
$ pyenv install 3.8.2
$ pyenv global 3.8.2

pyenv-virtualenvwrapper

$ git clone https://github.com/pyenv/pyenv-virtualenvwrapper.git $(pyenv root)/plugins/pyenv-virtualenvwrapper

.bashrc 파일을 열어서 다음 내용을 추가한다.

pyenv virtualenvwrapper_lazy
$ exec "$SHELL"

angr

$ mkvirtualenv angr
$ workon angr
$ pip install angr
$ deactivate

angr라는 가상 프로젝트에 angr 패키지를 설치할 수 있다.

Example

angr를 사용하는 방법을 바이너리를 빌드해서 연습해보자. angr 공식 깃헙에 있는 예제 중 하나이다.

//fauxware.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

char *sneaky = "SOSNEAKY";

int authenticate(char *username, char *password)
{
    char stored_pw[9];
    stored_pw[8] = 0;
    int pwfile;

    // evil back d00r
    if (strcmp(password, sneaky) == 0) return 1;

    pwfile = open(username, O_RDONLY);
    read(pwfile, stored_pw, 8);

    if (strcmp(password, stored_pw) == 0) return 1;
    return 0;

}

int accepted()
{
    printf("Welcome to the admin console, trusted user!\n");
}

int rejected()
{
    printf("Go away!");
    exit(1);
}

int main(int argc, char **argv)
{
    char username[9];
    char password[9];
    int authed;

    username[8] = 0;
    password[8] = 0;

    printf("Username: \n");
    read(0, username, 8);
    read(0, &authed, 1);
    printf("Password: \n");
    read(0, password, 8);
    read(0, &authed, 1);

    authed = authenticate(username, password);
    if (authed) accepted();
    else rejected();
}

password가 "SOSNEAKY"이면 접근이 가능한 간단한 바이너리다. 접근이 가능/불가능을 판별하는 것은 accepted(), rejected() 중 무엇이 실행되었느냐이다. 따라서 이로 구분지어 accepted()로 접근한 input 값을 받아보자.

Load fauxware

>>> from angr import *
>>> p = Project('./fauxware')

Find the address of function

>>> p.loader.find_symbol('main')
<Symbol "main" in fauxware at 0x40071d>
>>> p.loader.find_symbol('accepted')
<Symbol "accepted" in fauxware at 0x4006ed>
>>> p.loader.find_symbol('rejected')
<Symbol "rejected" in fauxware at 0x4006fd>

simgr()

Simulation Managers로 시뮬레이션을 하는 함수이다. 자세한건 풀이를 보면서 이해하자.

explore()을 사용할 때, find와 avoid를 인자로 넣어주어 어떤 주소로 찾을지 피할지를 알려준다.

Exploit Code

from angr import *

p = Project('./fauxware')

FIND = p.loader.find_symbol('accepted').rebased_addr
AVOID = p.loader.find_symbol('rejected').rebased_addr

simgr = p.factory.simgr()
simgr.explore(find=FIND, avoid=AVOID)

flag = simgr.found[0].posix.dumps(0)
print(flag)
(angr) l0z1k@ubuntu:~/Fuzzing/angr/fauxware$ python ex.py
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00SOSNEAKY\x00'

'Reversing' 카테고리의 다른 글

angr - (3) Solving CTF Challenges  (0) 2020.04.29
angr - (2) Claripy  (0) 2020.04.28
IDA binary patch  (0) 2020.04.23
StolenByte  (0) 2020.03.21
OEP  (0) 2020.03.21

+ Recent posts