首页
社区
课程
招聘
[原创]看雪CTF.TSRC 2018 团队赛 第九题 谍战
2018-12-19 10:31 2996

[原创]看雪CTF.TSRC 2018 团队赛 第九题 谍战

2018-12-19 10:31
2996
这个题能够做出来,还是有点运气的....在跟踪程序获取输入sn的过程中,都没有找到相关的代码,不管是对GetWindowTextW下断,还是跟踪WM_GETTEXT消息以及消息循环。最后无奈的查看了窗口创建过程的函数sub_403E70,看起来有点复杂。不过到是发现这个程序使用了DirectX的API,猜测与sn有关的运算可能转到GPU了,所以调试器也跟踪不到。


查了下文档D3D11CreateDeviceAndSwapChain这个函数是创建一个用于渲染的设备和交换链接,第一次接触DirectX,一开始也不太理解这个函数。继续浏览了后面的代码,发现很多函数的调用来自pDevice或pImmediateContext对象中的方法。所以需要制定一个D3D11的类型识别库来识别ID3D11Device和ID3D11DeviceContext对象,方便分析这些方法的作用和用途,我这里用的是kkhaike大神制作的til。


这个地方创建了一个顶点着色器,和两个像素着色器。byte_4AC4B8、unk_4AC2C8和byte_4AB6A0是HLSL( 高阶着色器语言 )的字节码。后面的代码主要是创建缓存、更新资源和设置渲染目标以及图像的绘制等,然后就是来到了消息循环处。消息循环处一些这样的代码,代码如下:

这里使用了顶点着色器和一个像素着色器。我的猜测是该题根据sn的输入来绘制正确与否的提示信息,相关的运算在这两个着色器中。所以需要分析这两个着色器的HLSL字节码。在分析字节码之前,也花了较多的时间学了下HLSL。借鉴了下ccfer大神在看雪京东2018CTF第10题的wp的D3D反汇编方法。反汇编得到的一个像素着色器的代码如下:
//
// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
//
//
// Buffer Definitions: 
//
// cbuffer cb
// {
//
//   float4x4 v;                        // Offset:    0 Size:    64
//   float4x4 p;                        // Offset:   64 Size:    64
//   float4x4 w;                        // Offset:  128 Size:    64
//   float4 c1;                         // Offset:  192 Size:    16 [unused]
//   float4 c2;                         // Offset:  208 Size:    16 [unused]
//   uint4 val;                         // Offset:  224 Size:    16 [unused]
//
// }
//
//
// Resource Bindings:
//
// Name                                 Type  Format         Dim Slot Elements
// ------------------------------ ---------- ------- ----------- ---- --------
// cb                                cbuffer      NA          NA    0        1
//
//
//
// Input signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// POSITION                 0   xyzw        0     NONE   float   xyzw
// TEXCOORD                 0   xy          1     NONE   float   xy  
// COLOR                    0   xyzw        2     NONE   float   xyzw
//
//
// Output signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_POSITION              0   xyzw        0      POS   float   xyzw
// TEXCOORD                 0   xy          1     NONE   float   xy  
// COLOR                    0   xyzw        2     NONE   float   xyzw
//
vs_4_0
dcl_constantbuffer cb0[12], immediateIndexed
dcl_input v0.xyzw
dcl_input v1.xy
dcl_input v2.xyzw
dcl_output_siv o0.xyzw, position
dcl_output o1.xy
dcl_output o2.xyzw
dcl_temps 2
dp4 r0.x, v0.xyzw, cb0[8].xyzw
dp4 r0.y, v0.xyzw, cb0[9].xyzw
dp4 r0.z, v0.xyzw, cb0[10].xyzw
dp4 r0.w, v0.xyzw, cb0[11].xyzw
dp4 r1.x, r0.xyzw, cb0[0].xyzw
dp4 r1.y, r0.xyzw, cb0[1].xyzw
dp4 r1.z, r0.xyzw, cb0[2].xyzw
dp4 r1.w, r0.xyzw, cb0[3].xyzw
dp4 o0.x, r1.xyzw, cb0[4].xyzw
dp4 o0.y, r1.xyzw, cb0[5].xyzw
dp4 o0.z, r1.xyzw, cb0[6].xyzw
dp4 o0.w, r1.xyzw, cb0[7].xyzw
mov o1.xy, v1.xyxx
mov o2.xyzw, v2.xyzw
ret 
// Approximately 15 instruction slots used
顶点着色器的代码如下:
//
// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
//
//
// Buffer Definitions: 
//
// cbuffer cb
// {
//
//   float4x4 v;                        // Offset:    0 Size:    64 [unused]
//   float4x4 p;                        // Offset:   64 Size:    64 [unused]
//   float4x4 w;                        // Offset:  128 Size:    64 [unused]
//   float4 c1;                         // Offset:  192 Size:    16 [unused]
//   float4 c2;                         // Offset:  208 Size:    16 [unused]
//   uint4 val;                         // Offset:  224 Size:    16
//
// }
//
//
// Resource Bindings:
//
// Name                                 Type  Format         Dim Slot Elements
// ------------------------------ ---------- ------- ----------- ---- --------
// samLinear                         sampler      NA          NA    0        1
// tx0                               texture  float4          2d    0        1
// tx1                               texture  float4          2d    1        1
// cb                                cbuffer      NA          NA    0        1
//
//
//
// Input signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_POSITION              0   xyzw        0      POS   float       
// TEXCOORD                 0   xy          1     NONE   float   xy  
// COLOR                    0   xyzw        2     NONE   float       
//
//
// Output signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_Target                0   xyzw        0   TARGET   float   xyzw
//
ps_4_0
dcl_constantbuffer cb0[15], immediateIndexed
dcl_sampler s0, mode_default
dcl_resource_texture2d (float,float,float,float) t0
dcl_resource_texture2d (float,float,float,float) t1
dcl_input_ps linear v1.xy
dcl_output o0.xyzw
dcl_temps 4
ine r0.xyz, cb0[14].xyzx, l(0, 0, 0, 0)
and r0.x, r0.y, r0.x
and r0.x, r0.z, r0.x
ult r0.y, l(0x3b9aca00), cb0[14].x
and r0.x, r0.y, r0.x
ult r0.yz, cb0[14].xxyx, cb0[14].yyzy
and r0.x, r0.y, r0.x
and r0.x, r0.z, r0.x
ult r0.y, cb0[14].z, l(-1)
and r0.x, r0.y, r0.x
udiv r0.yzw, null, cb0[14].zzxy, l(0, 0x000186a0, 0x000186a0, 0x000186a0)
imad r1.xyz, r0.zwyz, l(0xfffe7960, 0xfffe7960, 0xfffe7960, 0), cb0[14].xyzx
udiv r2.x, r3.x, r0.z, l(10)
udiv null, r1.w, r2.x, l(10)
udiv r2.xyzw, null, r0.zzzw, l(100, 1000, 10000, 100)
udiv null, r2.xyzw, r2.xyzw, l(10, 10, 10, 10)
imul null, r1.w, r1.w, l(1000)
imad r1.w, r3.x, l(10000), r1.w
imad r1.w, r2.x, l(100), r1.w
imad r1.w, r2.y, l(10), r1.w
iadd r1.w, r2.z, r1.w
ieq r1.x, r1.x, r1.w
and r0.x, r0.x, r1.x
udiv r1.x, r2.x, r0.w, l(10)
udiv null, r1.x, r1.x, l(10)
udiv r3.xyzw, null, r0.wwyy, l(1000, 10000, 100, 1000)
udiv null, r3.xyzw, r3.xyzw, l(10, 10, 10, 10)
imul null, r1.x, r1.x, l(1000)
imad r1.x, r2.x, l(10000), r1.x
imad r1.x, r2.w, l(100), r1.x
imad r1.x, r3.x, l(10), r1.x
iadd r1.x, r3.y, r1.x
ieq r1.x, r1.y, r1.x
and r0.x, r0.x, r1.x
udiv r1.x, r2.x, r0.y, l(10)
udiv r1.y, null, r0.y, l(10000)
udiv null, r1.xy, r1.xyxx, l(10, 10, 0, 0)
imul null, r1.x, r1.x, l(1000)
imad r1.x, r2.x, l(10000), r1.x
imad r1.x, r3.z, l(100), r1.x
imad r1.x, r3.w, l(10), r1.x
iadd r1.x, r1.y, r1.x
ieq r1.x, r1.z, r1.x
and r0.x, r0.x, r1.x
movc r0.yzw, r0.xxxx, r0.yyzw, cb0[14].zzxy
iadd r1.x, r0.w, r0.z
iadd r1.x, r0.y, r1.x
iadd r1.x, r1.x, l(0x0000374f)
ieq r1.x, r1.x, l(0x00017334)
and r0.x, r0.x, r1.x
imad r1.xy, l(3, 6, 0, 0), r0.zyzz, r0.wzww
iadd r1.xy, r1.xyxx, l(0x0000374f, 0x0000a5ed, 0, 0)
iadd r1.xy, -r0.ywyy, r1.xyxx
ieq r1.xy, r1.xyxx, l(0x0000d146, 0x00040ad5, 0, 0)
and r0.x, r0.x, r1.x
ishl r0.w, r0.w, l(1)
iadd r0.y, r0.w, r0.y
iadd r0.y, r0.y, l(0x00006e9e)
iadd r0.y, -r0.z, r0.y
ieq r0.y, r0.y, l(0x000182c1)
and r0.x, r0.y, r0.x
and r0.x, r1.y, r0.x
if_nz r0.x
  sample o0.xyzw, v1.xyxx, t0.xyzw, s0
  ret 
else 
  sample o0.xyzw, v1.xyxx, t1.xyzw, s0
  ret 
endif 
ret 
// Approximately 70 instruction slots used

像素着色器主要的功能是向量点积的运算。顶点着色器的代码中有一断if then else的判断引起了我的注意,常量缓存的结构中只使用了uint4 val这个成员,这是一个大小为4的向量,元素类型为unsigned int,猜测可能是绘制出输入正确与否的提示信息。一开始看着代码一脸茫然,然后就是根据mdsn的文档,转换到相应的算术表达式,这简直是一个体力活。。。
r0.y = cb0.z / 100000
r0.z = cb0.x / 100000
r0.w = cb0.y / 100000
#r0.x用作条件判断
r1.x = r0.z*(-100000)+cb0.x #r1.x等于10进制数cb0.x的低5位
r1.y = r0.w*(-100000)+cb0.y #r1.y等于10进制数cb0.y的低5位
r1.z = r0.y*(-100000)+cb0.z #r1.z等于10进制数cb0.z的低5位

r2.x = r0.z/10
r3.x = r0.z%10				#r3.x等于10进制数cb0.x的十万位
r1.w = r2.x%10				#r1.w等于10进制数cb0.x的百万位

r2.x = r0.z / 100
r2.y = r0.z / 1000
r2.z = r0.z / 10000
r2.w = r0.w / 100
r2.x = r2.x % 10				#r2.x等于10进制数cb0.x的千万位
r2.y = r2.y % 10				#r2.y等于10进制数cb0.x的亿位
r2.z = r2.z % 10				#r2.z等于10进制数cb0.x的十亿位
r2.w = r2.w % 10				#r2.w等于10进制数cb0.x的千万位
r1.w = r3.x*10000+r1.w*1000+r2.x*100+r2.y*10+r2.z
#condition ieq (r1.w==r1.x) cb0.x是一个对称数,转换到10进数为10位

#r0.w = cb0.y / 100000
#r0.y = cb0.z / 100000
r1.x = r0.w / 10
r2.x = r0.w % 10				#r2.x等于10进制数cb0.y的十万位
r1.x = r1.x % 10				#r1.x等于10进制数cb0.y的百万位

r3.x = r0.w / 1000			
r3.y = r0.w / 10000
r3.z = r0.y / 100			
r3.w = r0.y / 1000			
r3.x = r3.x % 10				
r3.y = r3.y % 10				
r3.z = r3.z % 10				
r3.w = r3.w % 10				
r1.x= r2.x*10000+r1.x*1000+r2.w*100+r3.w*10+r3.y
#condition ieq (r1.y==r1.x) r1.y等于10进制数cb0.y的低5位


r1.x = r0.y/10
r2.x = r0.y%10				#r2.x等于10进制数cb0.z的十万位
r1.y = r0.y/10000

r1.x = r1.x % 10				#r1.x等于10进制数cb0.z的百万位
r1.y = r1.y % 10				#r1.y等于10进制数cb0.z的十亿位
r1.x = r2.x*10000+r1.x*1000+r3.z*100+r3.w*10+r1.y
#condition ieq (r1.z==r1.x)
#cb0.z也是一个10位的对称数

#If r0.xxxx then r0.yzw = r0.yyzw else r0.yzw = cb0[14].zzxy
r0.y = r0.y
r0.z = r0.z
r0.w = r0.w
r1.x = r0.y+r0.z+r0.w+0x374f
#condition ieq (r1.x==0x17334) r0.y+r0.z+r0.w+0x374f==0x17334

r1.x = 3*r0.z + r0.w
r1.y = 6*r0.y + r0.z
r1.x = r1.x + 0x374f
r1.y = r1.y + 0xa5ed
r1.x = r1.x - r0.y		#r1.x = 3*r0.z + r0.w + 0x374f - r0.y
r1.y = r1.y - r0.w		#r1.y = 6*r0.y + r0.z + 0xa5ed - r0.w
#condition ieq r1.xy==(0xd146, 0x40ad5)

r0.w = r0.w << 1
r0.y = r0.w+r0.y+0x6e9e-r0.z
#condition ieq (r0.y==0x182c1)
根据之前反汇编的代码cb0[14]引用的就是val,val向量也只使用前面三个元素,通过x、y、z、w来选取相应的元素。可以看出,这三个元素都是对称数,且1000000000<val.x<val.y<val.z,根据后面的约束条件,列出方程组:
z + x + y + 0x374f = 0x17334
3*x + y + 0x374f  - z = 0xd146
6*z + x + 0xa5ed - y = 0x40ad5
2*y + z + 0x6e9e - x = 0x182c1
解得x = 17580, y = 24982,z = 38307。因为都是对称数,所以补上另一半,得到数据为1758008571,2498228942,3830770383。试了下一起输入这些数据成功通过验证

所以sn为175800857124982289423830770383


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞4
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回