HCTF wzwzDingDing writeup
2014-11-21 11:55
447 查看
CTF以前也没怎么参加过,参加也是抱大腿,这次师弟拉着我玩HCTF,就分析了一下里面wzwzDingDing 这个题目。
这个题目是一个64位的驱动,在ida里分析了一下。
首先找到正常的驱动分发函数里,看看这个驱动都完成什么功能。下面是驱动分发函数中,比较iocontrol code的地方。
然后进入每个处理分支,观察一下都做了什么。发现每个分支都有一个特点,满足相应的条件判断,就会将全局变量dword_148E0某位置为F。
比如: 88102004这个分支,当从ring3输入字符串为"^lejAJ]O" "MNIII" 时,会分别置dword_148E0第六位 第五位为F,两次在ring3调用DeviceIoControlcode即可。
后面的分支每次按条件要求,依次在ring3调用DeviceIoControlcode, 让驱动走完每个iocontrol code的处理分支。
注意:8810200c的分支是判断ring3的映像文件名是否含有HCTF这几个字符。
流程还需要走一个其它分支,这里就选择了0x88102014,就是jmp loc12788,这个分支会给第一位置F
接着写个ring3的程序,跑一下看看什么情况
发现驱动直接crash在下面这个call里,调用到栈上的一个地址
到这就太想吐槽了,crash在这后,发现里面有一部分代码,还有类似循环的代码,还以为要怎么补成一个计算flag的算法,尼玛最后知道就是补成栈平衡就行,真是没做过ctf啊,太天真了。。
这题还有一个一直疑惑的问题,就是补的字节怎么从用户态传到内核,驱动知识太匮乏了。。因为看到在调用[rsp+0xC8+P]之前,有一部分代码,是往shellcode的位置写9个字节。推想应该是从ring3传进来的,然后在驱动里补齐。如下图所示这段代码:
补什么就不写了,平衡堆栈就行了,flag就是补的字节,有点坑。
前面也看到了对mdl的操作,貌似也没有映射用户态的内存。也应该不是从ring3的输入缓冲传进来的。 谁知道怎么搞,求指导,纠结~~~
这个题目是一个64位的驱动,在ida里分析了一下。
首先找到正常的驱动分发函数里,看看这个驱动都完成什么功能。下面是驱动分发函数中,比较iocontrol code的地方。
然后进入每个处理分支,观察一下都做了什么。发现每个分支都有一个特点,满足相应的条件判断,就会将全局变量dword_148E0某位置为F。
比如: 88102004这个分支,当从ring3输入字符串为"^lejAJ]O" "MNIII" 时,会分别置dword_148E0第六位 第五位为F,两次在ring3调用DeviceIoControlcode即可。
后面的分支每次按条件要求,依次在ring3调用DeviceIoControlcode, 让驱动走完每个iocontrol code的处理分支。
注意:8810200c的分支是判断ring3的映像文件名是否含有HCTF这几个字符。
流程还需要走一个其它分支,这里就选择了0x88102014,就是jmp loc12788,这个分支会给第一位置F
接着写个ring3的程序,跑一下看看什么情况
<span style="font-size:14px;"> HANDLE hDev = CreateFile("\\\\.\\Hctf",GENERIC_READ |GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING ,0, NULL); DWORD code=0; DWORD dwShellcodeSize=0x104; char InBuf[] = "^lejAJ]O"; char mniii[]="MNIII"; char ret[]="\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3"; char OutBuf[0x100]={0}; DWORD dwRetBytes = 0; char OutBuf2[0x100]={0}; DeviceIoControl(hDev, 0x88102004,InBuf, 0x9, OutBuf, 0x100, &dwRetBytes, 0); DeviceIoControl(hDev, 0x88102004,mniii, 0x6, OutBuf, 0x100, &dwRetBytes, 0); DeviceIoControl(hDev, 0x88102008,ret, 16, OutBuf, 0x100, &dwRetBytes, 0); DeviceIoControl(hDev, 0x8810200c,ret, 16, OutBuf, 0x100, &dwRetBytes, 0); DeviceIoControl(hDev, 0x8810200c,ret, 16, OutBuf, 0x100, &dwRetBytes, 0); DeviceIoControl(hDev, 0x88102014,ret, 16, OutBuf, 0x100, &dwRetBytes, 0); DeviceIoControl(hDev, 0x88102010,ret, 16, OutBuf2, 0x100, &dwRetBytes, 0); CloseHandle(hDev);</span>
发现驱动直接crash在下面这个call里,调用到栈上的一个地址
到这就太想吐槽了,crash在这后,发现里面有一部分代码,还有类似循环的代码,还以为要怎么补成一个计算flag的算法,尼玛最后知道就是补成栈平衡就行,真是没做过ctf啊,太天真了。。
这题还有一个一直疑惑的问题,就是补的字节怎么从用户态传到内核,驱动知识太匮乏了。。因为看到在调用[rsp+0xC8+P]之前,有一部分代码,是往shellcode的位置写9个字节。推想应该是从ring3传进来的,然后在驱动里补齐。如下图所示这段代码:
补什么就不写了,平衡堆栈就行了,flag就是补的字节,有点坑。
前面也看到了对mdl的操作,貌似也没有映射用户态的内存。也应该不是从ring3的输入缓冲传进来的。 谁知道怎么搞,求指导,纠结~~~
相关文章推荐
- 2017 火种CTF Writeup
- CTF writeup:实验吧,天下武功唯快不破
- 看雪wifi万能钥匙CTF年中赛 第四题 writeup(2)
- CUIT CTF WriteUp-BP断点
- Bugku ctf writeup--web篇--报错注入
- 33c3 CTF web WriteUp
- 2017-0CTF-simplesplin-write up
- 0ctf flagen writeup
- CTF writeup: rbash 逃脱方法
- 中级CTF:VID writeup
- 中级CTF:GetFlag writeup
- bugkuCTF Writeup (Web)31-35
- bugkuCTF Writeup (Web)36-40
- CUIT CTF WriteUp-最简单的加解密
- "百度杯"CTF 9月2日 WriteUp.md
- CTF-i春秋网鼎杯第一场misc部分writeup
- 0ctf login writeup
- 0ctf 部分web writeup.md
- IDF-CTF-牛刀小试 writeup
- 2017 429 ichunqiu ctf smallest(pwn300) writeup