赛题描述
送分题,flag格式flag{}。
-
拿到题,先file一下
debug32: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpre
是个32位的ELF文件,运行一下./debug32
,什么都没有?
拉进IDA查看一下,发现main函数中还真的什么都没有。
int __cdecl main()
{
return 0;
}
shift+f12(查找所有字符串),发现.rodata:080485F0 0000000E C Printing flag
,于是跟踪找到sub_804849B();
sub_804849B()这个函数中是向屏幕中打印flag的
解体方法有二
一.直接复制sub_824849B()函数代码到VSCode,添加头文件和mian(),这里注意,在最后要使其停止,故在最后v3[5] = 0
,代码如下:
#include<stdio.h>
int main()
{
int i,j;
unsigned int v3[6];
v3[0] = 377943446;
v3[1] = 1447490871;
v3[2] = 1987467046;
v3[3] = 938813270;
v3[4] = 3334903478;
v3[5] = 0;
for ( i = 0; i <= 5; ++i )
{
for ( j = v3[i]; j; j >>= 8 )
putchar((char)(((unsigned __int8)j >> 4) | 16 * j));
}
return 0;
}
二.main函数中调用这个函数,所以我们可以用GDB来使主函数调用这个打印flag的这个函数(这里参考了网上大佬的writeup)O.o)
调试过程
- 首先加载文件:
-
gdb debug32
- 然后再主函数设置断点:
-
gdb-peda$ break __libc_start_main Breakpoint 1 at 0x8048370
- 然后运行该程序:
-
gdb-peda$ run Starting program: /root/file/debug32 [----------------------------------registers-----------------------------------] EAX: 0xf7ffd918 --> 0x0 EBX: 0xf7ffd000 --> 0x22f3c ECX: 0xffffd154 --> 0xffffd32b ("/root/file/debug32") EDX: 0xf7fe9880 (push ebp) ESI: 0x1 EDI: 0x80483a0 (xor ebp,ebp) EBP: 0x0 ESP: 0xffffd12c --> 0x80483c1 (hlt) EIP: 0xf7e1c540 (<__libc_start_main>: call 0xf7f21289) EFLAGS: 0x292 (carry parity ADJUST zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0xf7e1c53a: xchg ax,ax 0xf7e1c53c: xchg ax,ax 0xf7e1c53e: xchg ax,ax => 0xf7e1c540 <__libc_start_main>: call 0xf7f21289 0xf7e1c545 <__libc_start_main+5>: add eax,0x197abb 0xf7e1c54a <__libc_start_main+10>: push ebp 0xf7e1c54b <__libc_start_main+11>: push edi 0xf7e1c54c <__libc_start_main+12>: push esi No argument [------------------------------------stack-------------------------------------] 0000| 0xffffd12c --> 0x80483c1 (hlt) 0004| 0xffffd130 --> 0x804855a (push ebp) 0008| 0xffffd134 --> 0x1 0012| 0xffffd138 --> 0xffffd154 --> 0xffffd32b ("/root/file/debug32") 0016| 0xffffd13c --> 0x8048570 (push ebp) 0020| 0xffffd140 --> 0x80485d0 (repz ret) 0024| 0xffffd144 --> 0xf7fe9880 (push ebp) 0028| 0xffffd148 --> 0xffffd14c --> 0xf7ffd918 --> 0x0 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Breakpoint 1, 0xf7e1c540 in __libc_start_main () from /lib32/libc.so.6 gdb-peda$
-
修改EIP的值为这个函数的起地址
-
gdb-peda$ set $eip = 0x804849b
- 然后继续运行程序即得flag
-
gdb-peda$ c Continuing. Printing flag i_has_debugger_skill Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x0 EBX: 0xf7ffd000 --> 0x22f3c ECX: 0xf7fb5870 --> 0x0 EDX: 0xa ('\n') ESI: 0x1 EDI: 0x80483a0 (xor ebp,ebp) EBP: 0x0 ESP: 0xffffd130 --> 0x804855a (push ebp) EIP: 0x80483c1 (hlt) EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x80483b6: push esi 0x80483b7: push 0x804855a 0x80483bc: call 0x8048370 <__libc_start_main@plt> => 0x80483c1: hlt 0x80483c2: xchg ax,ax 0x80483c4: xchg ax,ax 0x80483c6: xchg ax,ax 0x80483c8: xchg ax,ax [------------------------------------stack-------------------------------------] 0000| 0xffffd130 --> 0x804855a (push ebp) 0004| 0xffffd134 --> 0x1 0008| 0xffffd138 --> 0xffffd154 --> 0xffffd32b ("/root/file/debug32") 0012| 0xffffd13c --> 0x8048570 (push ebp) 0016| 0xffffd140 --> 0x80485d0 (repz ret) 0020| 0xffffd144 --> 0xf7fe9880 (push ebp) 0024| 0xffffd148 --> 0xffffd14c --> 0xf7ffd918 --> 0x0 0028| 0xffffd14c --> 0xf7ffd918 --> 0x0 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x080483c1 in ?? ()
flag:flag{i_has_debugger_skill}
总结:
-
第一种方法稍微有点没有技术含量,出题人意思应该是希望我们运用第二种方式来解决,这里我也学到一种新的工具
GDB
。 -
参考资料:https://luobuming.github.io/2019/02/15/2018-10-06-gdb/(这里讲了GDB的安装)