RE January 03, 2020

0CTF逆向writeup

Words count 4.6k Reading time 4 mins. Read count 0

一、Elemnet

这题当时在算时,解出来的精度不够,所以一直提交writeup不正确,当时觉得很可惜哎,工具没找对~后来看了大佬的writeup,果然时精度的问题,他说手动调试那个值,直到精确为止,于是开始了复现之旅…..

看看ida:

image.png

image.png

image.png

一开始,从上往下分析逻辑,。接下来看看为何是这样:

image.png

这个函数将输入的大写转成小写(上网查),继续

image.png

输入44个字节,以-为分隔符号,切割出12个字符,那么flag{a-b-c},其中a和b和c都是16进制的数。

image.png

这堆东西,一开始看不懂,v12是一个数组,v15是个只有动态调试才能知道的东西,这里我特地去gdb里动态调试,一步步地看清了程序的流程,然后v16就是看v15的值为条件去算的,v11是叠加的值,循环12次,叠加算出v11的值

image.png

第一次v9是0,那么不退出程序的话,v11就必须是0x391bc2164f0a,所以我去动态调试了(b *0x400950),不断si,可以看到

image.png

image.png

我们的输入是flag{abcdef…..}输入放到了RAX寄存器中,v11放到了R15,最后要比较R15和RAX是否相等,这里RBX寄存器就是那个我们不知道的数组v12[v10]里面搞出来的东西,所以第一个输入a直接是R15的值,突然觉得刚刚那堆处理没有什么用,输入只是转成了某种形式去处理,最后输入还是不变,难怪最后会说输入就是你的flag,通过动态调试终于明白了整个程序!

接下来进入了下一层

image.png

这里v17是怎么的出来的,我们动态调试看了一波,发现是转成浮点数,然后v23就是赋予的值,这时v9++了,那么下一次,v11就失去了作用,继续切割,后面的函数可知,看来v24就是第二段输入,v25就是我们的第三段输入。看到这里,发现了一个东西!if里面是三角形的三边关系,同时要满足v23<v24<v25,还有海伦公式求面积v20,v21是外接圆的半径,v22是内切圆的半径,看到式子,很明显,v21和v22肯定是0,这样方程就出来了,2个未知数,两个方程:

1
2
3
4
5
6
7
8
9
10
#coding = utf8
import struct
from sympy import *
b = Symbol('b')
c = Symbol('c')
num1 = 19400354808065.54
num2 = 47770539528273.91
a = 62791383142154
print(solve([((0.5*(sqrt((a+b+c)*(a+b-c)*(c-a+b)*(a+c-b))))/(a+b+c)-num1),((a*b*c)/(sqrt((a+b+c)*(a+b-c)*(c-a+b)*(c+a-b)))-num2)],[b,c]))
#flag{391bc2164f0a-4064e4798769-56e0de138176}

这里解出来:

image.png

很好,再把b,c转成16进制,得到:flag{391bc2164f0a-4064e4798768-56e0de138176},但是输入不对,因为精度问题,又跪了,于是从最后一位开始浮动2位,那么就是有16种可能,4064e4798766到4064e479876a,56e0de138174到56e0de138178,4*4组合,最后终于输入正确!

image.png

这题当初做的时候就是因为精度不够,没解出来,做了90%,哎,不过大佬手动调确实是可靠,我没想到(tcl)~

总结到这里,另一题还在看。

0%