阅读量
**426169**
|
访问网站文件log文件,发现ThinkPHP 远程命令执行漏洞
废话不多说直接怼脚本
flag{
767bc73bedd446b5891ac3f2a3329bfb3502114647cda27b3dbdf0119c261022}
(1)Chalenge 1
第一关给出模N,加密指数e和明文m,明文512位,但低72位被隐藏,因此Stereotyped messages攻击,用sage求出明文低位。得出明文低72位为1902981400650064329651。再通过给出m + 1902981400650064329651,得出整个明文。
(2)Challenge 2
第二关是知道p高位隐藏低128位,p高位攻击,sage求出最小根即是解。得出p的值后gmpy2.invert解出私钥d,即可解出c的明文m。
(3)Challenge 3
这一关已知私钥d 低512位,利用Partial Key Exposure Attack(部分密钥泄露攻击)可破解得出模因子p,再通过p求解出d,然后是常规解密。
(4)Challenge 4
加密指数e=3,三个模和三个密文[n1,n2,n3][c1,c2,c3],明显的广播攻击(Hastad’s broadcast attack),利用中国剩余定理解出M=m**3,再gmpy2.iroot(M,3)得出明文。
(5)Challenge 5
给出两个明文关系M = km + A,由此可知是相关明文攻击,Franklin-Reiter attack可解出明文m。
得出明文:
(6)Challenge 6
从给出的已知条件,d=N0.27,(d<N0.292) 满足boneh_durfee attack条件,可利用该算法解出私钥d。
整理后各challenge输出的结果。
利用脚本提交各关m值,到第六关得出flag。
闯不同的关根据关卡由0变为1更改金手指变量,经过搜索得到最大关卡为ff,所以将有变化的值都改为ff(还不知道具体是哪个),
判断简单
输入44个字符进行加密
判断为base64加密
取出对比的字符串进行解密得出flag
扫描目录拿到代码进行分析
分析代码
注册 test1@qq.com 123123
上传图片木马
更改cookie获得shell
爆破
解题
random.seed(int(time.time()))
while 1:
number = random.randint(0,2**64)
print io.recvuntil("[-]")
io.sendline(str(number))
res = io.recvuntil("[+]")
print res,
if 'completed' in res:
break
while 1:
print io.recvuntil('[-]'),
num1 = io.recvuntil("n", drop = True)
print num1
print io.recvuntil('[-]'),
num2 = io.recvuntil("n", drop = True)
print num2
try:
o = subprocess.check_output(["java", "ReplicatedRandomTest", num1, num2])
#print o.split("n")
num3 = o.strip()
print num3
except:
num3 = '1'
print io.recv()
io.sendline(num3)
res = io.recv()
print res
if 'completed' in res:
break
while 1:
target=random.getrandbits(32)
print io.recv()
io.sendline(str(target))
res = io.recv()
print res
if 'completed' in res:
break
io.interactive()
在main函数参数输入处存在溢出点,可进行溢出利用,构造rop攻击,但got表中无其他函数,只有__libc_start_main函数,无法有效泄漏出libc地址。可以通过里面已有的函数和一些gadgets,实现对__libc_start_main的got表进行修改,将其末尾三个字节修改为system。末尾12位属于偏移量,可从libc文件中获取,高8位为原始地址,没有进行修改。只剩中间12位为随机值,需要爆破,命中概率1/4096。修改got表后,再次调用__libc_start_main函数,实现对system(command)的调用,因为程序未提供输入条件,无法直接getshell,只能执行单个命令行。为了成功调用rop需要进行栈迁移,这该利用中,将栈迁移至0x804a040+0x300的位置。
图1、生成payload的代码
图2、爆破代码
(1) 利用爆破脚本执行ls -l 的命令,查看服务器当前目录下是否存在flag。后发现存在一个名为_the_flag_dir_name_you_shold_guess的文件夹。疑似存在flag。
(2) 利用爆破脚本执行ls the_flag_dir_name_you_shold_guess 的命令,查看服务器是否存在flag,发现存在flag.txt
(3)利用爆破脚本执行find ./ -iname flag* | xargs cat 的命令,获取flag。
该程序在函数update_hash处,存在漏洞点。abs(offset) % 15 语句是为了获取用户输入的偏移量,又防止用户输入超长度偏移量进行溢出攻击。但offset如果设置0x80000000时,这条语句执行的结果就变为0xfffffff8,突破了原有的限制,可以进行向上溢出,溢出对象的虚表位置。通过这个漏洞可以对对象的虚表地址进行修改。
(1) 申请一个类型的str的对象obj1,并申请相应的str数组。
(2) 利用update_hash 漏洞,将其虚表改为int对象的虚表。
(3) 调用obj1的查看函数,则该对象直接调用int对象的查看函数,将步骤1中写入数组地址打印出来,泄漏堆地址。
(4) 调用obj1的写入函数,在对象中写入该对象自己的地址。
(5) 将obj1的类型改为str型,查看第一个数组的内容,用次方法可以泄漏出程序段地址。
(6) 已知程序段地址和got表的偏移量,计算出got表的地址。将scanf的got地址写入arrary[1],将该数组的位置写入arrary[0]。后续步骤原理和3-5相同,可通过查看arrary[0]的内容将got表内数据地址打印出来,由此泄漏出libc地址。
(7) 泄漏出libc地址后,利用__environ变量泄漏出栈地址,原理和6 相同。
(8) 已知栈地址,利用数据对象的写函数,实现对栈地址的写入,将main函数的返回值写入one_gadget,并将返回值以下0xf0的栈区清空,调用环境满足one_gadgets的条件。
(9) 直接选择选项4,退出,获取shell。
图1、代码图
图二、获取flag
下载源代码,发两现有是两个功能相同的代码,一个是32位版,一个是64位版,用IDA分别分析,发现两个版本均为静态编译,存在栈溢出,32位溢出点为0x110,64位为0x118,刚好相差8个字节。
使用ROPgat针对某一版本作出payload,本地调试通过后远程测试,存在sha256计算验证,加上验证脚后,发现无法到获取shell。分析原因,认为payload需同时满足32位与64位攻击成功的条件才能成功。
如满足上述条件,根据32位与64位溢出点不同,payload需构造成
0x110 pad
0x4 32位ret n
0x4 32位payload 返回地址
0x8 64位 ret
n byte 64位 payload
….. 32位 payload
即可保证同一payload在32下与64位下都可成功。再次ROPgat一下获得合适的n值,
修改payload远程测试成功,cat flag文件,获得加密flag,再使用decode.py解密得到flag,加上flag{``}
提交成功
1. 强网先锋ap
拿到原代吗,测试用gdb运行一下,在heap chunks,发现有趣的结果:
使用ida分析,发现change()函数中可以在堆中溢出。
可以使change溢出泄露libc地址,再用change覆盖堆中的puts地址为system地址即可拿到shell。编写payload成功拿到shell,cat flag即获得flag
Justre:
IDA分析程序,发现程序经过了2个函数的判断,返回都为1时输出flag
第一个函数读取输入的前10位,前8位和后2位分别转化成两个数字,并与405018地址的内容进行运算,最后判断运算后的值与404148地址的内容是否相等,判断96个字节。如果相等,则将405018开始的96个字节写入4018A0地址(这是第二个判断函数的首地址),也就是说,必须第一个函数通过以后,才能得到第二个函数正确的内容。
接下来分析运算过程,可以从低字节开始爆破,判断是否符合条件
最后确定前10个字符为1324228811
接下来分析第二个函数,用peid分析是一个des加密,然后看到密钥为24个字符,因此应该是3des加密,于是编写脚本进行解密:
把两部分拼起来就是flag:13242288110dcc509a6f75849b