36D杯-逆向-BBBigEqSet和tiny

admin 2022年1月5日23:15:51评论50 views字数 4134阅读13分46秒阅读模式

>

This site is best viewed in a modern browser with JavaScript enabled.

### id="flarum-content">

36D杯-逆向-BBBigEqSet和tiny

v0id

BBBigEqSet
main函数很大,而且不能F5
所以传统艺能——找规律
.text:00000000000011C7 movzx eax, [rbp+s]//取flag的一个字符
.text:00000000000011CE movsx eax, al
.text:00000000000011D1 imul edx, eax, 9421h//乘一个常数以后放入edx
.text:00000000000011D7 movzx eax, [rbp+var_FF]//取flag的一个字符
.text:00000000000011DE movsx eax, al
.text:00000000000011E1 imul eax, 60CDh//乘常数
.text:00000000000011E7 add edx, eax//加到edx中
.text:00000000000011E9 movzx eax, [rbp+var_FE]
.text:00000000000011F0 ...........
通过找输出错误提示的交叉引用
.text:0000000000001AC5 cmp eax, 1AE5186Ah
.text:0000000000001ACA jnz loc_49663//不相等则错误
所以思路很清晰了,提取出所有运算,就是 ax1+bx2+c*x3+...=常数的形式
最开始想用z3解方程,没想到效率感人,所以改用numpy。
//ida提取脚本
instr=0x11c7#起始指令的地址
end_addr=0x4963c#指令结束的地址
numpy_out=""#方便写脚本,让ida直接输出numpy的矩阵数组
flag=[]#flag数组用于存放方程未知数的系数
cmps=[]#cmps数组存放方程右侧的常数
while(instr<=end_addr):
dis_asm = idc.GetMnem(instr)
if(dis_asm=="imul"):
if(idc.GetOpType(instr,1)==5):#如果第二个OPCODE是立即数,主要为了区分 imul edx, eax, 9421h和 imul eax, 60CDh两种格式
flag.append(idc.GetOperandValue(instr,1))
else:
flag.append(idc.GetOperandValue(instr,2))
if(dis_asm=="cmp"):
cmps.append(idc.GetOperandValue(instr,1))
ctr=0
numpy_out+="["
for i in flag:
numpy_out+=str(i)
ctr=ctr+1
if(ctr==128):#因为flag一共128位,这时我们的矩阵结束,添加"]"符号
numpy_out+="],"
break;
numpy_out+=","
flag=[]
instr=idc.NextHead(instr)
#print numpy_out这句用来输出方程的所有组系数
numpy_out=""
for i in cmps:
numpy_out+=(str(i)+",")
print numpy_out#输出方程右侧的常数

提取出矩阵后,就可以用x = linalg.solve(a, b)函数计算出flag,这里有个坑,x数组是float数组,不能直接chr()转换。
而不知道为啥int出来再转换会跟原来的数不一样(求py大佬解决我的疑问)
但是我们可以把x输出再复制进去,就ok了,得到flag:flag{Soooo000_LooOOOOOOOOggO99g99_s1muLtaNeOus_EEEQuat10n5_Y0UUUUUUuuu_cAA44AANNnnN_SOOOOOOLVE_IT17TT11771ITIT!!!_8ShotDshP90ab}(这128位的flag你心动了吗)

tiny
应该是我这辈子见过最小的ELF了。。。而且ida打开会报错
修改一下elf控制端序的magic试试(正常大端序为02,小端序为01,这个00肯定不正常)
竟然可以了,就是代码....有点迷惑

00000101:00010020 public start
//本来想调试一波的,但是一直Segmentation fault (core dumped),只能硬着头皮看汇编了。
_00000101:00010020 start proc near ; DATA XREF: start+A↓o
_00000101:00010020 pop ebx //这里随便调试一个elf,就能看出来,pop的第三次获取的是运行的参数
_00000101:00010021 pop ebx
_00000101:00010022 pop ebx

───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000│ rsp 0x7fffffffe640 ◂— 0x2
01:0008│ 0x7fffffffe648 —▸ 0x7fffffffe873 ◂— 0x6667682f746e6d2f ('/mnt/hgf')
02:0010│ 0x7fffffffe650 —▸ 0x7fffffffe894 ◂— 0x736772615f796d /* 'my_args' */

03:0018│ 0x7fffffffe658 ◂— 0x0
04:0020│ 0x7fffffffe660 —▸ 0x7fffffffe89c ◂— 0x622f3d4c4c454853 ('SHELL=/b')
05:0028│ 0x7fffffffe668 —▸ 0x7fffffffe8ac ◂— 0x6574783d4d524554 ('TERM=xte')
06:0030│ 0x7fffffffe670 —▸ 0x7fffffffe8c0 ◂— 'USER=root'
07:0038│ 0x7fffffffe678 —▸ 0x7fffffffe8ca ◂— 0x524f4c4f435f534c ('LS_COLOR')

_00000101:00010023 xor ecx, ecx
_00000101:00010025 push ecx
_00000101:00010026 inc ecx
_00000101:00010027 inc ecx //ecx=2
_00000101:00010028 jmp short loc_1002E
_00000101:00010028 ; ---------------------------------------------------------------------------
_00000101:0001002A dd offset start //瞎猜这里应该是elf解析entry_point的地方,出题人留出了这里
_00000101:0001002E ; ---------------------------------------------------------------------------
_00000101:0001002E
_00000101:0001002E loc_1002E: ; CODE XREF: start+8↑j
_00000101:0001002E pop eax //eax=0
_00000101:0001002F push 8AF45207h
_00000101:00010034 push 93F9A63h
_00000101:00010039
_00000101:00010039 loc_10039: ; CODE XREF: start+2D↓j
_00000101:00010039 mov edi, [ebx+ecx*4-4]//先取输入后四位,再取前四位 (flag)
_00000101:0001003D ror edi, 3//循环右移3位
_00000101:00010040 push 5D99429h
_00000101:00010045 pop edx //edx=5D99429h
_00000101:00010046 pop esi //esi第一次=93F9A63h,第二次=8AF45207h (key)
_00000101:00010047 xor esi, edi
_00000101:00010049 xor edx, esi
_00000101:0001004B or eax, edx//观察下面可以发现,eax决定返回值,为了返回1(按照题目的hint),我们必须让edx=0
//即 5D99429h=ROR(flag的四位,3)^key
_00000101:0001004D loop loc_10039
_00000101:0001004F xor ebx, ebx
_00000101:00010051 test eax, eax
_00000101:00010053 setnz bl ; status
_00000101:00010056 xor eax, eax
_00000101:00010058 inc eax
_00000101:00010059 int 80h ; LINUX - sys_exit
_00000101:00010059 start endp ; sp-analysis failed

可以写出脚本
def ROR(n,r):
n = n&0xffffffff
return ((n>>r) | (n<<(32-r)))&0xffffffff
def hex_2_str(x):
s=""
while(x!=0):
s+=str(chr(x%0x100))
x/=0x100
return s
print hex_2_str(ROR((0x8AF45207^0x5D99429),32-3))+hex_2_str(ROR((0x93F9A63^0x5D99429),32-3))
#ror(flag,x)的逆算法是ror(flag,32-x)

得到flag:flag{t1nyPr0g}


Kr0ne

弱类型,之前用numpy有遇到,a = int(a+0.5,10)就行了,顺便膜大佬


  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年1月5日23:15:51
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   36D杯-逆向-BBBigEqSet和tinyhttp://cn-sec.com/archives/720173.html

发表评论

匿名网友 填写信息