ISCC2018_leftleftrightright-Writeup
leftleftrightright(150)
这个题学到了不少东西,值得认真写一下
下载好文件后发现是upx的壳,upx -d直接脱掉后运行,发现是经典的check输入的题目(作为一个linuxer,首先用wine模拟运行了一下,这也为我后来的解题减少了不少麻烦,后边会说到)
ISCC2018_re150 [master●●] file leftleftrightright.exe
leftleftrightright.exe: PE32 executable (console) Intel 80386, for MS Windows, UPX compressed
ISCC2018_re150 [master●●] upx -d ./leftleftrightright.exe
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2013
UPX 3.91 Markus Oberhumer, Laszlo Molnar & John Reiser Sep 30th 2013
File size Ratio Format Name
-------------------- ------ ----------- -----------
18432 <- 10752 58.33% win32/pe leftleftrightright.exe
Unpacked 1 file.
ISCC2018_re150 [master●●] file leftleftrightright.exe
leftleftrightright.exe: PE32 executable (console) Intel 80386, for MS Windows
ISCC2018_re150 [master●●] chmod +x leftleftrightright.exe
ISCC2018_re150 [master●●] ./leftleftrightright.exe
0009:fixme:msvcp:_Locinfo__Locinfo_ctor_cat_cstr (0x32fcbc 1 C) semi-stub
aaaaaaa
0009:fixme:msvcp:_Locinfo__Locinfo_ctor_cat_cstr (0x32fd1c 1 C) semi-stub
try again!
请按任意键继续...%
拖到IDA里分析之前,先搜索了一波字符串,发现存在IsDebuggerPresent和疑似加密后的flag:s_imsaplw_e_siishtnt{g_ialt}F,如果需要调试,要先nop掉IsDebuggerPresent,先静态分析,拖到IDA里F5大法,main函数的伪代码和汇编都很乱,但大致可以看出把我们的输入经过一通操作后扔给sub_401090()函数check,通过即为正确的flag,同时能看出flag的长度为29(0x1D)
if ( sub_401090(v16) || v15 < 0x1D || (v17 = "flag is right!", v15 > 0x1D) )
v17 = "try again!";
v18 = sub_401BF0(std::cout, v17, sub_401E30);
std::basic_ostream<char,std::char_traits<char>>::operator<<(v18, v19);
system("pause");
这时首先想的是通过调试快速确定怎么对输入进行变化的,于是到windows下试图用Ollydbg调试(调试之前要先找到对IsDebuggerPresent的调用并nop掉,可以在IDA的import页面通过x交叉引用找到),这时遇到了第一个问题:文件在windows下直接crash
扔进OD单步调试,很快就能定位到crash出现的位置
crash出现的原因不难分析,此时[ds + 0x40600]是一个不可读的地址,这时候想起来windows vitia(writeup用的是windows 2008 server)及其以上版本引入了aslr技术,导致程序载入的基址是随机的,如果取值的地址是写死的(比如这道题),就很可能跳到不可读的地址,程序crash,细节可以看这里
一些trick:
- OD把代码当成数据分析时,可以选中,点退格让OD重新分析
- ctrl + A可以重新分析当前模块的代码,也能把误识别的数据转为代码
同时找到了一个很方便的工具可以固定程序的载入地址,固定程序的载入地址随机化后,打开程序,终于可以正常工作了,于是上OD调试,跟了几步指令后忽然意识到,check函数没有进行查表,亦或这些操作,只有很简单的位移,这说明我们的输入并不会发生改变,只会发生移位,如果我们能得到一串字符移位后的结果,就可以找到移位的规律,进而恢复出flag
//check函数不会改变输入
int __cdecl sub_401090(unsigned int a1)
{
int v1; // ecx
const char *v3; // esi
unsigned int v4; // edx
bool v5; // cf
unsigned __int8 v6; // al
unsigned __int8 v7; // al
unsigned __int8 v8; // al
if ( !a1 )
return 0;
v3 = "s_imsaplw_e_siishtnt{g_ialt}F";
v4 = a1 - 4;
if ( a1 < 4 )
{
LABEL_6:
if ( v4 == -4 )
return 0;
}
else
{
while ( *(_DWORD *)v1 == *(_DWORD *)v3 )
{
v1 += 4;
v3 += 4;
v5 = v4 < 4;
v4 -= 4;
if ( v5 )
goto LABEL_6;
}
}
v5 = *(_BYTE *)v1 < (const unsigned __int8)*v3;
if ( *(_BYTE *)v1 != *v3 )
return -v5 | 1;
if ( v4 != -3 )
{
v6 = *(_BYTE *)(v1 + 1);
v5 = v6 < v3[1];
if ( v6 != v3[1] )
return -v5 | 1;
if ( v4 != -2 )
{
v7 = *(_BYTE *)(v1 + 2);
v5 = v7 < v3[2];
if ( v7 != v3[2] )
return -v5 | 1;
if ( v4 != -1 )
{
v8 = *(_BYTE *)(v1 + 3);
v5 = v8 < v3[3];
if ( v8 != v3[3] )
return -v5 | 1;
}
}
}
return 0;
}
于是我们直接在check函数之后下断点
运行,输入29位不同的数据后观察
找到了移位前后的字符串,这样就可以恢复flag了,脚本如下:
ISCC2018_re150 [master●●] cat solve.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__Auther__ = 'M4x'
encrypt = "s_imsaplw_e_siishtnt{g_ialt}F"
before = "abcdefghijklmnopqrstuvwxyzABC"
after = "onpqmlrskjtuihvwgfxyedzAcbBCa"
flag = [encrypt[after.find(c)] for c in before]
print "".join(flag)
ISCC2018_re150 [master●●] python solve.py
Flag{this_was_simple_isnt_it}
ISCC2018_re150 [master●●]
以上是写writeup时偶然发现的新解法,新解法出现的原因应该是windows 2008 server的load机制与windows 10不同,windows 2008 server的更低级,原解法如下:
固定exe的装载基址后,发现运行到cin时,程序又crash了,这时才想到windows10下dll的装载基址也是随机的,通过比较aslr_disabler.exe处理前后的exe,发现只对pe头的一个字段改了一位(可以通过010 editor的compare功能看出),于是想到了两种思路:
- 找到exe调用的dll,通过修改pe头固定其基址
- 在od调试的过程中手动指定其基址
很明显第一种方法得不偿失,麻烦不说,很有可能造成系统环境的崩溃。于是尝试在OD调试的过程中指定dll的基址,试了一下发现要改的地方太多,放弃了。这个时候想到用wine模拟时程序可以正常运行,于是搜索了一下调试wine加载的程序的方法,google的所有结果都指向一个工具winedbg,按照man手册的说明,还可以以gdb模式启动,尝试了一下,发现在自己电脑上各种报错,把patch后的exe发给一个用arch的大佬学弟试了一下,一次就成了(吐血),比较后发现是wine的版本问题,于是果断卸载了apt安装的2.0的wine,手动编译了一个3.8的wine,然后winedbg --gdb ./leftleftrightright.exe,终于跑起来了,之后的方法就和使用ollydbg时一样了,直接下断点查看处理前后的字符串即可
patch后的exe和解题脚本可以在我的github上找到
一些补充:
- 这道题目不难,但确实学到了不少东西,美中不足是把加密后的flag硬编码太弱了,根据题目名称leftleftrightright很容易猜出正确flag(我在编译wine时试了几次已经猜出了flag)
- winedbg使用gdb模式启动时,如果使用pwndbg作为插件,会卡到怀疑人生,使用peda或者gef就会快得多(这也是大佬学弟告诉我的)
- 刚开始也尝试过在windows vista以下的版本(如windows xp)上运行exe,但不兼容,搜索字符串可以看出这个程序是用vs2015编译的,搜索了一波发现除非重新编译,否则不能在exe上运行
- 通过以上分析可以得出load的随机化程度 wine ≈ xp < windows 2008 server < win10,这也能看出微软在安全性上做了不少工作
- 程序中还有一些0xcc(int 3),但分析过之后发现这些字节全在函数之间,不会被调用,因此对调试不会造成影响
- 如果非要去除的话,可以参考如下idapython脚本,patch完记得保存(Edit -> Patch Program -> Apply Patches to Input File)
- 如果非要去除的话,可以参考如下idapython脚本,patch完记得保存(Edit -> Patch Program -> Apply Patches to Input File)
- 对于一些细节,我还是没想明白,比如如何高效安全的固定dll的装载基质,IsDebuggerPresent在wine下为何失效(不patch此处的exe也可用winedbg调试),能否不重新编译使vs2015生成的exe兼容xp,为何从源码编译的wine会有下图中的报错以及如何解决(apt安装的2.0版wine没有如下报错)
- 如果有师傅对以上问题以及这篇writeup有任何见解,欢迎指教
ISCC2018_leftleftrightright-Writeup的更多相关文章
- 2016第七季极客大挑战Writeup
第一次接触CTF,只会做杂项和一点点Web题--因为时间比较仓促,写的比较简略.以后再写下工具使用什么的. 纯新手,啥都不会.处于瑟瑟发抖的状态. 一.MISC 1.签到题 直接填入题目所给的SYC{ ...
- ISCC2016 WriteUp
日期: 2016-05-01~ 注:隔了好久才发布这篇文章,还有两道Pwn的题没放,过一阵子放上.刚开始做这个题,后来恰巧赶上校内CTF比赛,就把重心放在了那个上面. 这是第一次做类似于CTF的题,在 ...
- 参加 Tokyo Westerns / MMA CTF 2nd 2016 经验与感悟 TWCTF 2016 WriteUp
洒家近期参加了 Tokyo Westerns / MMA CTF 2nd 2016(TWCTF) 比赛,不得不说国际赛的玩法比国内赛更有玩头,有的题给洒家一种一看就知道怎么做,但是做出来还需要洒家拍一 ...
- 爱春秋之戏说春秋 Writeup
爱春秋之戏说春秋 Writeup 第一关 图穷匕见 这一关关键是给了一个图片,将图片下载到本地后,打开以及查看属性均无任何发现,尝试把图片转换为.txt格式.在文本的最后发现这样一串有规律的代码: 形 ...
- 《安全智库》:48H急速夺旗大战通关writeup(通关策略)
作者:ByStudent 题目名字 题目分值 地址 MallBuilder2 350 mall.anquanbao.com.cn MallBuilder1 200 mall.anquanbao.c ...
- iscc2016 pwn部分writeup
一.pwn1 简单的32位栈溢出,定位溢出点后即可写exp gdb-peda$ r Starting program: /usr/iscc/pwn1 C'mon pwn me : AAA%AAsAAB ...
- We Chall-Training: Encodings I -Writeup
MarkdownPad Document html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,ab ...
- We Chall-Encodings: URL -Writeup
MarkdownPad Document html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,ab ...
- We Chall-Training: ASCII—Writeup
MarkdownPad Document html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,ab ...
- pwnable.kr-collision -Writeup
bof html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,addres ...
随机推荐
- itest(爱测试) 4.4.0 发布,开源BUG 跟踪管理 & 敏捷测试管理软件
itest 简介 test 开源敏捷测试管理,testOps 践行者.可按测试包分配测试用例执行,也可建测试迭代(含任务,测试包,BUG)来组织测试工作,也有测试环境管理,还有很常用的测试度量:对于发 ...
- 由于找不到opencv_world320d.dll,无法继续执行代码。解决方案
将 opencv 安装路径 目录\opencv\build\x64\vc14\bin 中 3 个后缀是.dll 的应用程序扩展复制到 C:\Windows\System32 中 完美解决!
- layui弹出表单提交后,界面model验证部分起作用
情况1----input属性中type=submit时验证都可以起作用,但是弹出层表单的返回值不能获取,所以用ajax二次提交后会出现重复添加数据的问题 情况2----input属性中type=but ...
- [ERR] Node goodsleep.vip:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
解决方案 以前的cluster节点信息 保留 要删除 dump.rdb node.conf集群启动时自动生成文件
- CMS系统
CMS是Content Management System的缩写,意为"内容管理系统" 对于内容管理,业界还没有一个统一的定义,不同的机构有不同的理解: 内容管理系统是企业信息化建 ...
- 第三章:使用ListView展示数据
一.ImageList:存储图像集合 Images 存储的所有图像 ImageSize 图像的大小 ColorDepth 颜色数 TransparentColor 被视为透明的颜色 先设置ColorD ...
- 小白的java学习之路 “ 类和对象”
一.※ 万物皆对象 二.对象的两个特征: 属性:对象具有的各种特征 方法:对象执行的操作 对象:用来描述客观事物的一个实体,由一组属性和方法构成 三.封装: 对象同时具有属性和方法两项特性 对象的属性 ...
- 解决苹果手机app store下载软件超过200M后必须使用wifi的终极方法(亲测有效)
前言 最近使用苹果手机下载一款大小为300M左右的软件时弹出如下提示 因为平时主要使用wifi下载,偶尔用自己的流量也没有超过200M,所以用了这么久才发现苹果手机有这样一个限制. 这让我有些郁闷 ...
- gcc,g++,make,cmake的区别
首先介绍一下GCC:GNU Compiler Collection(GNU 编译器集合),在为Linux开发应用程序时,绝大多数情况下使用的都是C语言,因此几乎每一位Linux程序员面临的首要问题都是 ...
- 使用xshell
将选定的文本自动复制到剪贴板 并且 鼠标向右按钮定义为粘贴剪贴板内容