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 |