攻防世界--REVERSE新手练习区writeup

re1

下载下来是一个exe文件,先运行下

攻防世界--REVERSE新手练习区writeup_第1张图片

随便输入当然不对,于是用ida打开,但是没有发现main函数,那么flag应该这里就不是用算法生成的,直接丢到linux下使用strings命令查看flag的相关字段

攻防世界--REVERSE新手练习区writeup_第2张图片

game

依次输入1,2,3,4,5,6,7,8 就能获得flag

攻防世界--REVERSE新手练习区writeup_第3张图片

当然这样是不能满足我们学习欲望的,打开ida,还是没有main函数,按shift+f12查看.rdata段的信息,flag如果显示应该是有提示的,所以留意下有flag字样的地方

攻防世界--REVERSE新手练习区writeup_第4张图片

双击进去,看旁边有个sub_45E940的函数,点进去F5反C代码

攻防世界--REVERSE新手练习区writeup_第5张图片

攻防世界--REVERSE新手练习区writeup_第6张图片

看它每个变量地址都是差1排的,然后再到最低比的for循环处,*(&v3 + i),这里比如说(&v3 + 1)就是v4,同理后面的*(&v60 + i)也是这么计算的,总共生成56个字符

攻防世界--REVERSE新手练习区writeup_第7张图片

算法逻辑很清晰,使用v3~v59v60 ~ v116 进行异或操作,之后的结果在和0x13进行一次异或操作,写出python脚本

v3=[18,64,98,5,2,4,6,3,6,48,49,65,32,12,48,65,31,78,62,32,49,32,1,57,96,3,21,9,4,62,3,5,4,1,2,3,44,65,78,32,16,97,54,16,44,52,32,64,89,45,32,65,15,34,18,16,0] 
v60=[123,32,18,98,119,108,65,41,124,80,125,38,124,111,74,49,83,108,94,108,84,6,96,83,44,121,104,110,32,95,117,101,99,123,127,119,96,48,107,71,92,29,81,107,90,85,64,12,43,76,86,13,114,1,117,126,0] 

flag = ''
for i in range(0, 56):
    tmp = v3[i] ^ v60[i]
    flag += chr(tmp ^ 0x13)
print flag

攻防世界--REVERSE新手练习区writeup_第8张图片

Hello, CTF

下载下来是个exe文件,运行一下大概也是输入flag才能返回true之类的

攻防世界--REVERSE新手练习区writeup_第9张图片

ida32位打开(对于exe文件如果ida64位F5不了,就换32位的),这次有main函数

攻防世界--REVERSE新手练习区writeup_第10张图片

那么v10是我们输入,v13的值就是上面的的a437261636b4d65,点进去可以看到它的值

攻防世界--REVERSE新手练习区writeup_第11张图片

好了,问题是v13是我们输入的,只能有17位,而这里的v10有34位,34位刚好是17位的倍数,16进制转字符,刚好位数相同因此hex解码一下,获得flag

攻防世界--REVERSE新手练习区writeup_第12张图片

攻防世界--REVERSE新手练习区writeup_第13张图片

open-source

下载下来是一个c文件,直接给了源码,看逻辑是要输入3个参数,都满足4个if判断后会根据输入的3个参数进行计算获得flag

攻防世界--REVERSE新手练习区writeup_第14张图片

这里第一个填0xcafe转10进制的51966,第二个是要满足除17余8,并且除5不能余3, 因为计算量不大,枚举几个就能算出值为25,第三个值就是h4cky0u

编译下code.c文件

gcc code.c -o code

然后运行,答案为c0ffee

simple-unpack

这道题下载下来是个二进制文件,看到题目提示是有个壳的,而题目估计就是upx壳了,当然可以winhex看看,也能看到

攻防世界--REVERSE新手练习区writeup_第15张图片

kali下能够直接脱upx

upx -d simple2

然后直接用stringsflag字符串即可

攻防世界--REVERSE新手练习区writeup_第16张图片

insanity

下载下来是个二进制文件,放到linux中先用file看看是多少位,然后用对应位数的ida打开文件

直接用shift +F12看到存储数据的段中就有flag

攻防世界--REVERSE新手练习区writeup_第17张图片

logmein

二进制文件先看文件信息

运行下,是要猜flag

攻防世界--REVERSE新手练习区writeup_第18张图片

那么用ida打开分析流程

攻防世界--REVERSE新手练习区writeup_第19张图片

问题在于v7和v8进行异或运算处, v8的值已经知道了,而v7的值要转换成字符串,在28537194573619560LL上按R键就能转换

但是这里就有大端序和小端序的概念,因为绝大部分电脑都是小端序所有要把这个字符串反转,所以最后的python脚本如下

a = ':\"AL_RT^L*.?+6/46'
b = 'ebmarah'[::-1]
ans = ""

print len(a)
print a
print len(b)
print b

for i in range(0,len(a)):
    print a[i] + " " + b[i % 7]
    ans += chr(ord(a[i]) ^ ord(b[i % 7]))
print ans

攻防世界--REVERSE新手练习区writeup_第20张图片

no-strings-attached

依旧是二进制文件,先用file查看,再丢入ida

进入main函数后,前面3个估计就是输出前面2行的代码,不用管它,点开authenticate()函数

攻防世界--REVERSE新手练习区writeup_第21张图片

有个decrypt()函数,看名字对s进行了解密,继续跟进也看不懂是啥,估计flag在程序运行中会出现,但是因为种种原因,最后不会输出到界面,于是在linux下使用gdb动态调试,从中找到flag值

攻防世界--REVERSE新手练习区writeup_第22张图片

正常调一遍的时候进入到authenticate()就会开始解密,汇编过程太复杂我看不懂,所以我把断点下在decryp()执行后的地方,看地址可以用ida看到

攻防世界--REVERSE新手练习区writeup_第23张图片

下断点

攻防世界--REVERSE新手练习区writeup_第24张图片

跑起来后,查看$eax寄存器所指的的地址的内容即可,至于为什么看eax寄出去,看了别人的writeup都没有说清楚,我估计看上面的汇编代码,之后把eax寄存器放到[ebp+s2]地址里面去了,所以解密值可能在$eax寄存器所指的地址中

x/10sw $eax

x/:查看内存的命令

10:显示10行

s:用字符串形式表示

w:4个字节为一个单位

攻防世界--REVERSE新手练习区writeup_第25张图片

python-trade

用python编写的程序生成了pyc文件,安装反py的插件即可

pip install uncompyle

uncompyle6 Py.pyc

当然可用重定向下输出的内容到 文件中

攻防世界--REVERSE新手练习区writeup_第26张图片

看看代码逻辑无非就是把flag异或然后base64编码,于是按照逻辑写个解码的流程

import base64

correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'

tmp = base64.b64decode(correct)
result = ''
for i in tmp:
    x = ord(i) - 16
    x = x ^ 32
    result += chr(x)

print result

运行即可获取flag

攻防世界--REVERSE新手练习区writeup_第27张图片

csaw2013reversing2

下载下来是个exe文件,题目提示运行就有flag,但是运行是乱码,于是用ida看看流程

攻防世界--REVERSE新手练习区writeup_第28张图片

在if之后MessageBoxA就开始输出flag的信息了,而flag估计是lpMen的值,那么应该是在if处进行了编码操作

攻防世界--REVERSE新手练习区writeup_第29张图片

仔细看这段汇编代码,在ds:IsDebuggerPresent处判断是否使用调试器,如果不是会跳到loc_4010B9,但是如果是调试器会在int 3处被中断,上面的call_sub40102A后进行的跳转判断也无法满足,但是我们要通过判断所以必须要使一个条件满足

根据汇编代码的从下至下运行,也就不改什么判断语句了,直接把 jz short loc_4010B9改成nop,就不会跳到loc_4010B9了,但是之后会运行__debugkreak(),也就int 3,于是也把这句改成nop

有了思路,打开OD

在main函数下个断点,跑起程序,修改2个地方的指令

攻防世界--REVERSE新手练习区writeup_第30张图片

双击指令,会弹框,填上nop,点击汇编即可。

攻防世界--REVERSE新手练习区writeup_第31张图片

接下来一直F7运行程序,进入csaw2013.00251000函数后观察

攻防世界--REVERSE新手练习区writeup_第32张图片

getit

下载下来是二进制文件直接运行啥也没有,用file查看是64位的,丢到ida64位中分析

攻防世界--REVERSE新手练习区writeup_第33张图片

观察到整个流程是给一个flag.txt文件中写flag,但是最后把这个文件给删除了,但是如果是写文件的话,在文件流还没关闭的情况下,应该是存在内存中的,所以用gdb调试

值应该是在stream里面,我这里把断点下在fclose前面,查看下地址

攻防世界--REVERSE新手练习区writeup_第34张图片

接下来运行gdb,我断点下在0x04008b9,看它把rax付给rdi,后面备注是stream,也就是flag值,最后run,直接查看rdi的值,就是flag

攻防世界--REVERSE新手练习区writeup_第35张图片

maze

下载下来是个二进制文件,题目提示是走迷宫,用ida打开

攻防世界--REVERSE新手练习区writeup_第36张图片

第一个逻辑是s1的值从输入端接受, 要求长度为24,前5个字符是ntcf{,最后个字符是}

接下来就是循环

攻防世界--REVERSE新手练习区writeup_第37张图片

这里因为前面要求是24个字符,所以第一个if(strlen(&s1)-1 > 5)肯定过,要想循环接受 v6要为真,但是前循环了了16次,并且上面的sub_400690(asc_601060,HIDWORD(v10),(unsigned int)v10)要过判定

点进去查看这个函数,表示是 [空格]或者'#' 就返回真,否则返回假,返回假就结束了整个程序

攻防世界--REVERSE新手练习区writeup_第38张图片

之后对上面4个sub_xxx()函数进行查看,点进去再退出来,函数参数会变得更加准确

攻防世界--REVERSE新手练习区writeup_第39张图片

之前的v10变成v9了,大致逻辑如下

sub_400650() 输入O,v9的下一位减一

sub_400660()输入o,v9的下一位加一

sub_400670()输入.,v9减一

sub_400680()输入0,v9加一

最后查看成功的前面一个判定的条件asc_601060[8 * (signed int)v9]+SHIDWORD(v9) != 35

攻防世界--REVERSE新手练习区writeup_第40张图片

查看下SHIDWORD的作用https://blog.csdn.net/huiguixian/article/details/52026710

SHIDWORD(V9)也就是v9的下一位,最后查看下要匹配的字符串asc_601060的值,直接点进去就行

是一堆符号,又因为题目提示是迷宫,根据sub_400690()函数中算法取的是v9下一位 + v9 * 8的偏移,可以得出迷宫每行是8个字符,把这个字符串赋值出来,手动每8个字符换行

攻防世界--REVERSE新手练习区writeup_第41张图片

得到迷宫,而最后判断条件是为走到#,所以最后的思路就很清晰了

O向左走

o向右走

.向上走

0向下走

*是墙,#是目标,[空格]是路

走完加上nctf{},刚好24位

最后答案是nctf{o0oo00O000oooo..OO}

你可能感兴趣的:(攻防世界--REVERSE新手练习区writeup)