SQLi
SQLi

Reputation: 13

POSTing Pastebin API to create a past in Python and get a correct reply, yet the pasted data is incorrect

So I am attempting to code a program that POSTs towards Pastebin and creates a new paste. The posting, requesting, etc is all going fine - yet when I check the actual Paste, it is just a single word in the source code. I sent the POSTed data to https://httpbin.org/post and all the data is fine, yet I get the wrong pasted data.

Code:

#!/usr/bin/python3

import requests
import argparse
import sys

epilog = """Usage: sourcepaste [ FILENAME ] [ LANGUAGE ] [ OPTIONS ]

          Example use(s):
                sourcepaste testfile.py python 2 6M
                sourcepaste source.cpp cpp
                sourcepaste js.js javascript 1
                """

parser = argparse.ArgumentParser(description='A CLI-based way to post on Pastebin',
                                 prog="sourcepaste",
                                 epilog=epilog)
parser.add_argument('source',
                    help='the file of your source code')
parser.add_argument('language',
                    help='the language of your source code | check langs.txt for all available languages')
parser.add_argument('privacy', nargs='?',
                    help='how private you want your post | 0 = Public, 1 = Unlisted, 2 = Private | Default = 0')
parser.add_argument('time', nargs='?',
                    help="""when your post should expire | N(ever), 10M(inutes), 1H(our), 1D(ay),
                         1W(eek), 2W(eeks), 1M(onth), 6M(onths), 1Y(ear) | Default = 1W(eek)""")

parse_args = parser.parse_args()

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36',
    'Content-Type': 'application/x-www-form-urlencoded'
}

with open(parse_args.source, "r") as source_code_read:
    source_code_content = source_code_read.read()

if (len(sys.argv) - 1) == 2:
    data = f"api_dev_key=<my-dev-key>&api_paste_code={source_code_content}&api_option=paste&api_user_key=<my-user-key>&api_paste_expire_date=1W&api_paste_private=0&api_paste_name={parse_args.source}@{parse_args.language}&api_paste_format={parse_args.language}"
elif (len(sys.argv) - 1) == 3:
    data = f"api_dev_key=<my-dev-key>&api_paste_code={source_code_content}&api_option=paste&api_user_key=<my-user-key>&api_paste_expire_date=1W&api_paste_private={parse_args.privacy}&api_paste_name={parse_args.source}@{parse_args.language}&api_paste_format={parse_args.language}"
elif (len(sys.argv) - 1) == 4:
    data = f"api_dev_key=<my-dev-key>&api_paste_code={source_code_content}&api_option=paste&api_user_key=<my-user-key>&api_paste_expire_date={parse_args.time}&api_paste_private={parse_args.privacy}&api_paste_name={parse_args.source}@{parse_args.language}&api_paste_format={parse_args.language}"

pageget = requests.post("https://pastebin.com/api/api_post.php", headers=headers, data=data)

print(pageget.content)

My shell inputs:

./sourcepaste test.py python 2 N

Example reply:

https://pastebin.com/IuHbDt

Content at link:

{test_content} - no other pieces of the code

Would love some help on this; to me it's very strange how the POST data is correct, the reply is fine, yet the actual paste is incorrect.

Thanks!

Upvotes: 1

Views: 914

Answers (1)

Yevhenii Kosmak
Yevhenii Kosmak

Reputation: 3860

Your mistake is trying to gather data into a string. It should be a dict. On the other, it works well. However, there are some technical issues with it. For example, the way you collect POST parameters into data, it could be done much better. But I feel the aren't the reason for your question.

So I reworked your solution a little, now it works:

import requests
import argparse
import sys

API_DEV_KEY = "<MY_API_DEV_KEY>"

epilog = """Usage: sourcepaste [ FILENAME ] [ LANGUAGE ] [ OPTIONS ]

          Example use(s):
                sourcepaste testfile.py python 2 6M
                sourcepaste source.cpp cpp
                sourcepaste js.js javascript 1
                """

parser = argparse.ArgumentParser(description='A CLI-based way to post on Pastebin',
                                 prog="sourcepaste",
                                 epilog=epilog)
parser.add_argument('source',
                    help='the file of your source code')
parser.add_argument('language',
                    help='the language of your source code | check langs.txt for all available languages')
parser.add_argument('privacy', nargs='?',
                    help='how private you want your post | 0 = Public, 1 = Unlisted, 2 = Private | Default = 0')
parser.add_argument('time', nargs='?',
                    help="""when your post should expire | N(ever), 10M(inutes), 1H(our), 1D(ay),
                         1W(eek), 2W(eeks), 1M(onth), 6M(onths), 1Y(ear) | Default = 1W(eek)""")

parse_args = parser.parse_args()

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36',
    'Content-Type': 'application/x-www-form-urlencoded'
}

with open(parse_args.source, "r") as source_code_read:
    source_code_content = source_code_read.read()

data = None
if (len(sys.argv) - 1) == 2:
    data = {
        "api_dev_key": API_DEV_KEY,
        "api_paste_code": source_code_content,
        "api_option": "paste",
        "api_paste_expire_date": "1W",
        "api_paste_private": "0",
        "api_paste_name": f"{parse_args.source}@{parse_args.language}",
        "api_paste_format": parse_args.language,
    }

if data:
    response = requests.post("https://pastebin.com/api/api_post.php", headers=headers, data=data)
    print(response.content)

Result:

enter image description here

You can see, I reworked your script only for two params: source and language. I have no doubts, now you can add all extra params you need by yourself.

Upvotes: 0

Related Questions